aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/kernel/traps.c')
-rw-r--r--arch/blackfin/kernel/traps.c60
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 */
637static bool get_instruction(unsigned short *val, unsigned short *address) 638static 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/*