diff options
Diffstat (limited to 'arch/blackfin/kernel/traps.c')
-rw-r--r-- | arch/blackfin/kernel/traps.c | 60 |
1 files changed, 17 insertions, 43 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index d279552fe9b0..8eeb457ce5d5 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <asm/traps.h> | 37 | #include <asm/traps.h> |
38 | #include <asm/cacheflush.h> | 38 | #include <asm/cacheflush.h> |
39 | #include <asm/cplb.h> | 39 | #include <asm/cplb.h> |
40 | #include <asm/dma.h> | ||
40 | #include <asm/blackfin.h> | 41 | #include <asm/blackfin.h> |
41 | #include <asm/irq_handler.h> | 42 | #include <asm/irq_handler.h> |
42 | #include <linux/irq.h> | 43 | #include <linux/irq.h> |
@@ -636,57 +637,30 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
636 | */ | 637 | */ |
637 | static bool get_instruction(unsigned short *val, unsigned short *address) | 638 | static bool get_instruction(unsigned short *val, unsigned short *address) |
638 | { | 639 | { |
639 | 640 | unsigned long addr = (unsigned long)address; | |
640 | unsigned long addr; | ||
641 | |||
642 | addr = (unsigned long)address; | ||
643 | 641 | ||
644 | /* Check for odd addresses */ | 642 | /* Check for odd addresses */ |
645 | if (addr & 0x1) | 643 | if (addr & 0x1) |
646 | return false; | 644 | return false; |
647 | 645 | ||
648 | /* Check that things do not wrap around */ | 646 | /* MMR region will never have instructions */ |
649 | if (addr > (addr + 2)) | 647 | if (addr >= SYSMMR_BASE) |
650 | return false; | 648 | return false; |
651 | 649 | ||
652 | /* | 650 | switch (bfin_mem_access_type(addr, 2)) { |
653 | * Since we are in exception context, we need to do a little address checking | 651 | case BFIN_MEM_ACCESS_CORE: |
654 | * We need to make sure we are only accessing valid memory, and | 652 | case BFIN_MEM_ACCESS_CORE_ONLY: |
655 | * we don't read something in the async space that can hang forever | 653 | *val = *address; |
656 | */ | 654 | return true; |
657 | if ((addr >= FIXED_CODE_START && (addr + 2) <= physical_mem_end) || | 655 | case BFIN_MEM_ACCESS_DMA: |
658 | #if L2_LENGTH != 0 | 656 | dma_memcpy(val, address, 2); |
659 | (addr >= L2_START && (addr + 2) <= (L2_START + L2_LENGTH)) || | 657 | return true; |
660 | #endif | 658 | case BFIN_MEM_ACCESS_ITEST: |
661 | (addr >= BOOT_ROM_START && (addr + 2) <= (BOOT_ROM_START + BOOT_ROM_LENGTH)) || | 659 | isram_memcpy(val, address, 2); |
662 | #if L1_DATA_A_LENGTH != 0 | 660 | return true; |
663 | (addr >= L1_DATA_A_START && (addr + 2) <= (L1_DATA_A_START + L1_DATA_A_LENGTH)) || | 661 | default: /* invalid access */ |
664 | #endif | 662 | return false; |
665 | #if L1_DATA_B_LENGTH != 0 | ||
666 | (addr >= L1_DATA_B_START && (addr + 2) <= (L1_DATA_B_START + L1_DATA_B_LENGTH)) || | ||
667 | #endif | ||
668 | (addr >= L1_SCRATCH_START && (addr + 2) <= (L1_SCRATCH_START + L1_SCRATCH_LENGTH)) || | ||
669 | (!(bfin_read_EBIU_AMBCTL0() & B0RDYEN) && | ||
670 | addr >= ASYNC_BANK0_BASE && (addr + 2) <= (ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE)) || | ||
671 | (!(bfin_read_EBIU_AMBCTL0() & B1RDYEN) && | ||
672 | addr >= ASYNC_BANK1_BASE && (addr + 2) <= (ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE)) || | ||
673 | (!(bfin_read_EBIU_AMBCTL1() & B2RDYEN) && | ||
674 | addr >= ASYNC_BANK2_BASE && (addr + 2) <= (ASYNC_BANK2_BASE + ASYNC_BANK1_SIZE)) || | ||
675 | (!(bfin_read_EBIU_AMBCTL1() & B3RDYEN) && | ||
676 | addr >= ASYNC_BANK3_BASE && (addr + 2) <= (ASYNC_BANK3_BASE + ASYNC_BANK1_SIZE))) { | ||
677 | *val = *address; | ||
678 | return true; | ||
679 | } | 663 | } |
680 | |||
681 | #if L1_CODE_LENGTH != 0 | ||
682 | if (addr >= L1_CODE_START && (addr + 2) <= (L1_CODE_START + L1_CODE_LENGTH)) { | ||
683 | isram_memcpy(val, address, 2); | ||
684 | return true; | ||
685 | } | ||
686 | #endif | ||
687 | |||
688 | |||
689 | return false; | ||
690 | } | 664 | } |
691 | 665 | ||
692 | /* | 666 | /* |