aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/kgdb.c
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2009-06-07 16:31:52 -0400
committerMike Frysinger <vapier@gentoo.org>2009-06-22 21:15:34 -0400
commite56e03b0cfeb997a4be9ad874c193824364942e0 (patch)
tree5a49f9a42d1577c13ee59d016bd0630c60de58d1 /arch/blackfin/kernel/kgdb.c
parentac1b7c378ef26fba6694d5f118fe7fc16fee2fe2 (diff)
Blackfin: unify memory region checks between kgdb and traps
The kgdb (in multiple places) and traps code developed pretty much identical checks for how to access different regions of the Blackfin memory map, but each wasn't 100%, so unify them to avoid duplication, bitrot, and bugs with edge cases. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin/kernel/kgdb.c')
-rw-r--r--arch/blackfin/kernel/kgdb.c297
1 files changed, 96 insertions, 201 deletions
diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c
index da28f796ad78..cce79d05b90b 100644
--- a/arch/blackfin/kernel/kgdb.c
+++ b/arch/blackfin/kernel/kgdb.c
@@ -34,15 +34,6 @@ int gdb_bfin_vector = -1;
34#error change the definition of slavecpulocks 34#error change the definition of slavecpulocks
35#endif 35#endif
36 36
37#define IN_MEM(addr, size, l1_addr, l1_size) \
38({ \
39 unsigned long __addr = (unsigned long)(addr); \
40 (l1_size && __addr >= l1_addr && __addr + (size) <= l1_addr + l1_size); \
41})
42#define ASYNC_BANK_SIZE \
43 (ASYNC_BANK0_SIZE + ASYNC_BANK1_SIZE + \
44 ASYNC_BANK2_SIZE + ASYNC_BANK3_SIZE)
45
46void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) 37void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
47{ 38{
48 gdb_regs[BFIN_R0] = regs->r0; 39 gdb_regs[BFIN_R0] = regs->r0;
@@ -463,41 +454,88 @@ static int hex(char ch)
463 454
464static int validate_memory_access_address(unsigned long addr, int size) 455static int validate_memory_access_address(unsigned long addr, int size)
465{ 456{
466 int cpu = raw_smp_processor_id(); 457 if (size < 0 || addr == 0)
467
468 if (size < 0)
469 return -EFAULT; 458 return -EFAULT;
470 if (addr >= 0x1000 && (addr + size) <= physical_mem_end) 459 return bfin_mem_access_type(addr, size);
471 return 0; 460}
472 if (addr >= SYSMMR_BASE) 461
473 return 0; 462static int bfin_probe_kernel_read(char *dst, char *src, int size)
474 if (IN_MEM(addr, size, ASYNC_BANK0_BASE, ASYNC_BANK_SIZE)) 463{
475 return 0; 464 unsigned long lsrc = (unsigned long)src;
476 if (cpu == 0) { 465 int mem_type;
477 if (IN_MEM(addr, size, L1_SCRATCH_START, L1_SCRATCH_LENGTH)) 466
478 return 0; 467 mem_type = validate_memory_access_address(lsrc, size);
479 if (IN_MEM(addr, size, L1_CODE_START, L1_CODE_LENGTH)) 468 if (mem_type < 0)
480 return 0; 469 return mem_type;
481 if (IN_MEM(addr, size, L1_DATA_A_START, L1_DATA_A_LENGTH)) 470
482 return 0; 471 if (lsrc >= SYSMMR_BASE) {
483 if (IN_MEM(addr, size, L1_DATA_B_START, L1_DATA_B_LENGTH)) 472 if (size == 2 && lsrc % 2 == 0) {
484 return 0; 473 u16 mmr = bfin_read16(src);
485#ifdef CONFIG_SMP 474 memcpy(dst, &mmr, sizeof(mmr));
486 } else if (cpu == 1) {
487 if (IN_MEM(addr, size, COREB_L1_SCRATCH_START, L1_SCRATCH_LENGTH))
488 return 0; 475 return 0;
489 if (IN_MEM(addr, size, COREB_L1_CODE_START, L1_CODE_LENGTH)) 476 } else if (size == 4 && lsrc % 4 == 0) {
477 u32 mmr = bfin_read32(src);
478 memcpy(dst, &mmr, sizeof(mmr));
490 return 0; 479 return 0;
491 if (IN_MEM(addr, size, COREB_L1_DATA_A_START, L1_DATA_A_LENGTH)) 480 }
481 } else {
482 switch (mem_type) {
483 case BFIN_MEM_ACCESS_CORE:
484 case BFIN_MEM_ACCESS_CORE_ONLY:
485 return probe_kernel_read(dst, src, size);
486 /* XXX: should support IDMA here with SMP */
487 case BFIN_MEM_ACCESS_DMA:
488 if (dma_memcpy(dst, src, size))
489 return 0;
490 break;
491 case BFIN_MEM_ACCESS_ITEST:
492 if (isram_memcpy(dst, src, size))
493 return 0;
494 break;
495 }
496 }
497
498 return -EFAULT;
499}
500
501static int bfin_probe_kernel_write(char *dst, char *src, int size)
502{
503 unsigned long ldst = (unsigned long)dst;
504 int mem_type;
505
506 mem_type = validate_memory_access_address(ldst, size);
507 if (mem_type < 0)
508 return mem_type;
509
510 if (ldst >= SYSMMR_BASE) {
511 if (size == 2 && ldst % 2 == 0) {
512 u16 mmr;
513 memcpy(&mmr, src, sizeof(mmr));
514 bfin_write16(dst, mmr);
492 return 0; 515 return 0;
493 if (IN_MEM(addr, size, COREB_L1_DATA_B_START, L1_DATA_B_LENGTH)) 516 } else if (size == 4 && ldst % 4 == 0) {
517 u32 mmr;
518 memcpy(&mmr, src, sizeof(mmr));
519 bfin_write32(dst, mmr);
494 return 0; 520 return 0;
495#endif 521 }
522 } else {
523 switch (mem_type) {
524 case BFIN_MEM_ACCESS_CORE:
525 case BFIN_MEM_ACCESS_CORE_ONLY:
526 return probe_kernel_write(dst, src, size);
527 /* XXX: should support IDMA here with SMP */
528 case BFIN_MEM_ACCESS_DMA:
529 if (dma_memcpy(dst, src, size))
530 return 0;
531 break;
532 case BFIN_MEM_ACCESS_ITEST:
533 if (isram_memcpy(dst, src, size))
534 return 0;
535 break;
536 }
496 } 537 }
497 538
498 if (IN_MEM(addr, size, L2_START, L2_LENGTH))
499 return 0;
500
501 return -EFAULT; 539 return -EFAULT;
502} 540}
503 541
@@ -509,14 +547,6 @@ int kgdb_mem2hex(char *mem, char *buf, int count)
509{ 547{
510 char *tmp; 548 char *tmp;
511 int err; 549 int err;
512 unsigned char *pch;
513 unsigned short mmr16;
514 unsigned long mmr32;
515 int cpu = raw_smp_processor_id();
516
517 err = validate_memory_access_address((unsigned long)mem, count);
518 if (err)
519 return err;
520 550
521 /* 551 /*
522 * We use the upper half of buf as an intermediate buffer for the 552 * We use the upper half of buf as an intermediate buffer for the
@@ -524,44 +554,7 @@ int kgdb_mem2hex(char *mem, char *buf, int count)
524 */ 554 */
525 tmp = buf + count; 555 tmp = buf + count;
526 556
527 if ((unsigned int)mem >= SYSMMR_BASE) { /*access MMR registers*/ 557 err = bfin_probe_kernel_read(tmp, mem, count);
528 switch (count) {
529 case 2:
530 if ((unsigned int)mem % 2 == 0) {
531 mmr16 = *(unsigned short *)mem;
532 pch = (unsigned char *)&mmr16;
533 *tmp++ = *pch++;
534 *tmp++ = *pch++;
535 tmp -= 2;
536 } else
537 err = -EFAULT;
538 break;
539 case 4:
540 if ((unsigned int)mem % 4 == 0) {
541 mmr32 = *(unsigned long *)mem;
542 pch = (unsigned char *)&mmr32;
543 *tmp++ = *pch++;
544 *tmp++ = *pch++;
545 *tmp++ = *pch++;
546 *tmp++ = *pch++;
547 tmp -= 4;
548 } else
549 err = -EFAULT;
550 break;
551 default:
552 err = -EFAULT;
553 }
554 } else if ((cpu == 0 && IN_MEM(mem, count, L1_CODE_START, L1_CODE_LENGTH))
555#ifdef CONFIG_SMP
556 || (cpu == 1 && IN_MEM(mem, count, COREB_L1_CODE_START, L1_CODE_LENGTH))
557#endif
558 ) {
559 /* access L1 instruction SRAM*/
560 if (dma_memcpy(tmp, mem, count) == NULL)
561 err = -EFAULT;
562 } else
563 err = probe_kernel_read(tmp, mem, count);
564
565 if (!err) { 558 if (!err) {
566 while (count > 0) { 559 while (count > 0) {
567 buf = pack_hex_byte(buf, *tmp); 560 buf = pack_hex_byte(buf, *tmp);
@@ -582,13 +575,8 @@ int kgdb_mem2hex(char *mem, char *buf, int count)
582 */ 575 */
583int kgdb_ebin2mem(char *buf, char *mem, int count) 576int kgdb_ebin2mem(char *buf, char *mem, int count)
584{ 577{
585 char *tmp_old; 578 char *tmp_old, *tmp_new;
586 char *tmp_new;
587 unsigned short *mmr16;
588 unsigned long *mmr32;
589 int err;
590 int size; 579 int size;
591 int cpu = raw_smp_processor_id();
592 580
593 tmp_old = tmp_new = buf; 581 tmp_old = tmp_new = buf;
594 582
@@ -601,41 +589,7 @@ int kgdb_ebin2mem(char *buf, char *mem, int count)
601 tmp_old++; 589 tmp_old++;
602 } 590 }
603 591
604 err = validate_memory_access_address((unsigned long)mem, size); 592 return bfin_probe_kernel_write(mem, buf, count);
605 if (err)
606 return err;
607
608 if ((unsigned int)mem >= SYSMMR_BASE) { /*access MMR registers*/
609 switch (size) {
610 case 2:
611 if ((unsigned int)mem % 2 == 0) {
612 mmr16 = (unsigned short *)buf;
613 *(unsigned short *)mem = *mmr16;
614 } else
615 err = -EFAULT;
616 break;
617 case 4:
618 if ((unsigned int)mem % 4 == 0) {
619 mmr32 = (unsigned long *)buf;
620 *(unsigned long *)mem = *mmr32;
621 } else
622 err = -EFAULT;
623 break;
624 default:
625 err = -EFAULT;
626 }
627 } else if ((cpu == 0 && IN_MEM(mem, count, L1_CODE_START, L1_CODE_LENGTH))
628#ifdef CONFIG_SMP
629 || (cpu == 1 && IN_MEM(mem, count, COREB_L1_CODE_START, L1_CODE_LENGTH))
630#endif
631 ) {
632 /* access L1 instruction SRAM */
633 if (dma_memcpy(mem, buf, size) == NULL)
634 err = -EFAULT;
635 } else
636 err = probe_kernel_write(mem, buf, size);
637
638 return err;
639} 593}
640 594
641/* 595/*
@@ -645,16 +599,7 @@ int kgdb_ebin2mem(char *buf, char *mem, int count)
645 */ 599 */
646int kgdb_hex2mem(char *buf, char *mem, int count) 600int kgdb_hex2mem(char *buf, char *mem, int count)
647{ 601{
648 char *tmp_raw; 602 char *tmp_raw, *tmp_hex;
649 char *tmp_hex;
650 unsigned short *mmr16;
651 unsigned long *mmr32;
652 int err;
653 int cpu = raw_smp_processor_id();
654
655 err = validate_memory_access_address((unsigned long)mem, count);
656 if (err)
657 return err;
658 603
659 /* 604 /*
660 * We use the upper half of buf as an intermediate buffer for the 605 * We use the upper half of buf as an intermediate buffer for the
@@ -669,39 +614,18 @@ int kgdb_hex2mem(char *buf, char *mem, int count)
669 *tmp_raw |= hex(*tmp_hex--) << 4; 614 *tmp_raw |= hex(*tmp_hex--) << 4;
670 } 615 }
671 616
672 if ((unsigned int)mem >= SYSMMR_BASE) { /*access MMR registers*/ 617 return bfin_probe_kernel_write(mem, tmp_raw, count);
673 switch (count) {
674 case 2:
675 if ((unsigned int)mem % 2 == 0) {
676 mmr16 = (unsigned short *)tmp_raw;
677 *(unsigned short *)mem = *mmr16;
678 } else
679 err = -EFAULT;
680 break;
681 case 4:
682 if ((unsigned int)mem % 4 == 0) {
683 mmr32 = (unsigned long *)tmp_raw;
684 *(unsigned long *)mem = *mmr32;
685 } else
686 err = -EFAULT;
687 break;
688 default:
689 err = -EFAULT;
690 }
691 } else if ((cpu == 0 && IN_MEM(mem, count, L1_CODE_START, L1_CODE_LENGTH))
692#ifdef CONFIG_SMP
693 || (cpu == 1 && IN_MEM(mem, count, COREB_L1_CODE_START, L1_CODE_LENGTH))
694#endif
695 ) {
696 /* access L1 instruction SRAM */
697 if (dma_memcpy(mem, tmp_raw, count) == NULL)
698 err = -EFAULT;
699 } else
700 err = probe_kernel_write(mem, tmp_raw, count);
701
702 return err;
703} 618}
704 619
620#define IN_MEM(addr, size, l1_addr, l1_size) \
621({ \
622 unsigned long __addr = (unsigned long)(addr); \
623 (l1_size && __addr >= l1_addr && __addr + (size) <= l1_addr + l1_size); \
624})
625#define ASYNC_BANK_SIZE \
626 (ASYNC_BANK0_SIZE + ASYNC_BANK1_SIZE + \
627 ASYNC_BANK2_SIZE + ASYNC_BANK3_SIZE)
628
705int kgdb_validate_break_address(unsigned long addr) 629int kgdb_validate_break_address(unsigned long addr)
706{ 630{
707 int cpu = raw_smp_processor_id(); 631 int cpu = raw_smp_processor_id();
@@ -724,46 +648,17 @@ int kgdb_validate_break_address(unsigned long addr)
724 648
725int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr) 649int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr)
726{ 650{
727 int err; 651 int err = bfin_probe_kernel_read(saved_instr, (char *)addr,
728 int cpu = raw_smp_processor_id(); 652 BREAK_INSTR_SIZE);
729 653 if (err)
730 if ((cpu == 0 && IN_MEM(addr, BREAK_INSTR_SIZE, L1_CODE_START, L1_CODE_LENGTH)) 654 return err;
731#ifdef CONFIG_SMP 655 return bfin_probe_kernel_write((char *)addr, arch_kgdb_ops.gdb_bpt_instr,
732 || (cpu == 1 && IN_MEM(addr, BREAK_INSTR_SIZE, COREB_L1_CODE_START, L1_CODE_LENGTH)) 656 BREAK_INSTR_SIZE);
733#endif
734 ) {
735 /* access L1 instruction SRAM */
736 if (dma_memcpy(saved_instr, (void *)addr, BREAK_INSTR_SIZE)
737 == NULL)
738 return -EFAULT;
739
740 if (dma_memcpy((void *)addr, arch_kgdb_ops.gdb_bpt_instr,
741 BREAK_INSTR_SIZE) == NULL)
742 return -EFAULT;
743
744 return 0;
745 } else {
746 err = probe_kernel_read(saved_instr, (char *)addr,
747 BREAK_INSTR_SIZE);
748 if (err)
749 return err;
750
751 return probe_kernel_write((char *)addr,
752 arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE);
753 }
754} 657}
755 658
756int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle) 659int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle)
757{ 660{
758 if (IN_MEM(addr, BREAK_INSTR_SIZE, L1_CODE_START, L1_CODE_LENGTH)) { 661 return bfin_probe_kernel_write((char *)addr, bundle, BREAK_INSTR_SIZE);
759 /* access L1 instruction SRAM */
760 if (dma_memcpy((void *)addr, bundle, BREAK_INSTR_SIZE) == NULL)
761 return -EFAULT;
762
763 return 0;
764 } else
765 return probe_kernel_write((char *)addr,
766 (char *)bundle, BREAK_INSTR_SIZE);
767} 662}
768 663
769int kgdb_arch_init(void) 664int kgdb_arch_init(void)