diff options
Diffstat (limited to 'arch/blackfin/kernel/kgdb.c')
-rw-r--r-- | arch/blackfin/kernel/kgdb.c | 297 |
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 | |||
46 | void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) | 37 | void 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 | ||
464 | static int validate_memory_access_address(unsigned long addr, int size) | 455 | static 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; | 462 | static 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 | |||
501 | static 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 | */ |
583 | int kgdb_ebin2mem(char *buf, char *mem, int count) | 576 | int 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 | */ |
646 | int kgdb_hex2mem(char *buf, char *mem, int count) | 600 | int 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 | |||
705 | int kgdb_validate_break_address(unsigned long addr) | 629 | int 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 | ||
725 | int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr) | 649 | int 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 | ||
756 | int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle) | 659 | int 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 | ||
769 | int kgdb_arch_init(void) | 664 | int kgdb_arch_init(void) |