瀏覽代碼

Add a prefetch abort handler

This patch adds a prefetch abort handler similar to the data abort one
and renames the latter for consistency. Initial implementation by Paul
Brook with some renaming by Catalin Marinas.

Signed-off-by: Paul Brook <paul@codesourcery.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Paul Brook 17 年之前
父節點
當前提交
48d7927bdf

+ 7 - 0
arch/arm/kernel/asm-offsets.c

@@ -111,5 +111,12 @@ int main(void)
   DEFINE(PROCINFO_INITFUNC,	offsetof(struct proc_info_list, __cpu_flush));
   DEFINE(PROCINFO_INITFUNC,	offsetof(struct proc_info_list, __cpu_flush));
   DEFINE(PROCINFO_MM_MMUFLAGS,	offsetof(struct proc_info_list, __cpu_mm_mmu_flags));
   DEFINE(PROCINFO_MM_MMUFLAGS,	offsetof(struct proc_info_list, __cpu_mm_mmu_flags));
   DEFINE(PROCINFO_IO_MMUFLAGS,	offsetof(struct proc_info_list, __cpu_io_mmu_flags));
   DEFINE(PROCINFO_IO_MMUFLAGS,	offsetof(struct proc_info_list, __cpu_io_mmu_flags));
+  BLANK();
+#ifdef MULTI_DABORT
+  DEFINE(PROCESSOR_DABT_FUNC,	offsetof(struct processor, _data_abort));
+#endif
+#ifdef MULTI_PABORT
+  DEFINE(PROCESSOR_PABT_FUNC,	offsetof(struct processor, _prefetch_abort));
+#endif
   return 0; 
   return 0; 
 }
 }

+ 24 - 10
arch/arm/kernel/entry-armv.S

@@ -166,12 +166,12 @@ __dabt_svc:
 	@ The abort handler must return the aborted address in r0, and
 	@ The abort handler must return the aborted address in r0, and
 	@ the fault status register in r1.  r9 must be preserved.
 	@ the fault status register in r1.  r9 must be preserved.
 	@
 	@
-#ifdef MULTI_ABORT
+#ifdef MULTI_DABORT
 	ldr	r4, .LCprocfns
 	ldr	r4, .LCprocfns
 	mov	lr, pc
 	mov	lr, pc
-	ldr	pc, [r4]
+	ldr	pc, [r4, #PROCESSOR_DABT_FUNC]
 #else
 #else
-	bl	CPU_ABORT_HANDLER
+	bl	CPU_DABORT_HANDLER
 #endif
 #endif
 
 
 	@
 	@
@@ -293,7 +293,6 @@ __pabt_svc:
 	mrs	r9, cpsr
 	mrs	r9, cpsr
 	tst	r3, #PSR_I_BIT
 	tst	r3, #PSR_I_BIT
 	biceq	r9, r9, #PSR_I_BIT
 	biceq	r9, r9, #PSR_I_BIT
-	msr	cpsr_c, r9
 
 
 	@
 	@
 	@ set args, then call main handler
 	@ set args, then call main handler
@@ -301,7 +300,15 @@ __pabt_svc:
 	@  r0 - address of faulting instruction
 	@  r0 - address of faulting instruction
 	@  r1 - pointer to registers on stack
 	@  r1 - pointer to registers on stack
 	@
 	@
-	mov	r0, r2				@ address (pc)
+#ifdef MULTI_PABORT
+	mov	r0, r2			@ pass address of aborted instruction.
+	ldr	r4, .LCprocfns
+	mov	lr, pc
+	ldr	pc, [r4, #PROCESSOR_PABT_FUNC]
+#else
+	CPU_PABORT_HANDLER(r0, r2)
+#endif
+	msr	cpsr_c, r9			@ Maybe enable interrupts
 	mov	r1, sp				@ regs
 	mov	r1, sp				@ regs
 	bl	do_PrefetchAbort		@ call abort handler
 	bl	do_PrefetchAbort		@ call abort handler
 
 
@@ -320,7 +327,7 @@ __pabt_svc:
 	.align	5
 	.align	5
 .LCcralign:
 .LCcralign:
 	.word	cr_alignment
 	.word	cr_alignment
-#ifdef MULTI_ABORT
+#ifdef MULTI_DABORT
 .LCprocfns:
 .LCprocfns:
 	.word	processor
 	.word	processor
 #endif
 #endif
@@ -404,12 +411,12 @@ __dabt_usr:
 	@ The abort handler must return the aborted address in r0, and
 	@ The abort handler must return the aborted address in r0, and
 	@ the fault status register in r1.
 	@ the fault status register in r1.
 	@
 	@
-#ifdef MULTI_ABORT
+#ifdef MULTI_DABORT
 	ldr	r4, .LCprocfns
 	ldr	r4, .LCprocfns
 	mov	lr, pc
 	mov	lr, pc
-	ldr	pc, [r4]
+	ldr	pc, [r4, #PROCESSOR_DABT_FUNC]
 #else
 #else
-	bl	CPU_ABORT_HANDLER
+	bl	CPU_DABORT_HANDLER
 #endif
 #endif
 
 
 	@
 	@
@@ -619,8 +626,15 @@ __und_usr_unknown:
 __pabt_usr:
 __pabt_usr:
 	usr_entry
 	usr_entry
 
 
+#ifdef MULTI_PABORT
+	mov	r0, r2			@ pass address of aborted instruction.
+	ldr	r4, .LCprocfns
+	mov	lr, pc
+	ldr	pc, [r4, #PROCESSOR_PABT_FUNC]
+#else
+	CPU_PABORT_HANDLER(r0, r2)
+#endif
 	enable_irq				@ Enable interrupts
 	enable_irq				@ Enable interrupts
-	mov	r0, r2				@ address (pc)
 	mov	r1, sp				@ regs
 	mov	r1, sp				@ regs
 	bl	do_PrefetchAbort		@ call abort handler
 	bl	do_PrefetchAbort		@ call abort handler
 	/* fall through */
 	/* fall through */

+ 5 - 0
arch/arm/kernel/entry-common.S

@@ -352,6 +352,11 @@ sys_mmap2:
 		b	do_mmap2
 		b	do_mmap2
 #endif
 #endif
 
 
+ENTRY(pabort_ifar)
+		mrc	p15, 0, r0, cr6, cr0, 2
+ENTRY(pabort_noifar)
+		mov	pc, lr
+
 #ifdef CONFIG_OABI_COMPAT
 #ifdef CONFIG_OABI_COMPAT
 
 
 /*
 /*

+ 23 - 0
arch/arm/mm/Kconfig

@@ -18,6 +18,7 @@ config CPU_ARM610
 	select CPU_CP15_MMU
 	select CPU_CP15_MMU
 	select CPU_COPY_V3 if MMU
 	select CPU_COPY_V3 if MMU
 	select CPU_TLB_V3 if MMU
 	select CPU_TLB_V3 if MMU
+	select CPU_PABRT_NOIFAR
 	help
 	help
 	  The ARM610 is the successor to the ARM3 processor
 	  The ARM610 is the successor to the ARM3 processor
 	  and was produced by VLSI Technology Inc.
 	  and was produced by VLSI Technology Inc.
@@ -49,6 +50,7 @@ config CPU_ARM710
 	select CPU_CP15_MMU
 	select CPU_CP15_MMU
 	select CPU_COPY_V3 if MMU
 	select CPU_COPY_V3 if MMU
 	select CPU_TLB_V3 if MMU
 	select CPU_TLB_V3 if MMU
+	select CPU_PABRT_NOIFAR
 	help
 	help
 	  A 32-bit RISC microprocessor based on the ARM7 processor core
 	  A 32-bit RISC microprocessor based on the ARM7 processor core
 	  designed by Advanced RISC Machines Ltd. The ARM710 is the
 	  designed by Advanced RISC Machines Ltd. The ARM710 is the
@@ -64,6 +66,7 @@ config CPU_ARM720T
 	default y if ARCH_CLPS711X || ARCH_L7200 || ARCH_CDB89712 || ARCH_H720X
 	default y if ARCH_CLPS711X || ARCH_L7200 || ARCH_CDB89712 || ARCH_H720X
 	select CPU_32v4T
 	select CPU_32v4T
 	select CPU_ABRT_LV4T
 	select CPU_ABRT_LV4T
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_V4
 	select CPU_CACHE_V4
 	select CPU_CACHE_VIVT
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
 	select CPU_CP15_MMU
@@ -113,6 +116,7 @@ config CPU_ARM920T
 	default y if CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_AT91RM9200
 	default y if CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_AT91RM9200
 	select CPU_32v4T
 	select CPU_32v4T
 	select CPU_ABRT_EV4T
 	select CPU_ABRT_EV4T
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_VIVT
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
 	select CPU_CP15_MMU
@@ -135,6 +139,7 @@ config CPU_ARM922T
 	default y if ARCH_LH7A40X || ARCH_KS8695
 	default y if ARCH_LH7A40X || ARCH_KS8695
 	select CPU_32v4T
 	select CPU_32v4T
 	select CPU_ABRT_EV4T
 	select CPU_ABRT_EV4T
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_VIVT
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
 	select CPU_CP15_MMU
@@ -155,6 +160,7 @@ config CPU_ARM925T
  	default y if ARCH_OMAP15XX
  	default y if ARCH_OMAP15XX
 	select CPU_32v4T
 	select CPU_32v4T
 	select CPU_ABRT_EV4T
 	select CPU_ABRT_EV4T
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_VIVT
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
 	select CPU_CP15_MMU
@@ -175,6 +181,7 @@ config CPU_ARM926T
 	default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI
 	default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI
 	select CPU_32v5
 	select CPU_32v5
 	select CPU_ABRT_EV5TJ
 	select CPU_ABRT_EV5TJ
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_VIVT
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
 	select CPU_CP15_MMU
 	select CPU_COPY_V4WB if MMU
 	select CPU_COPY_V4WB if MMU
@@ -226,6 +233,7 @@ config CPU_ARM1020
 	depends on ARCH_INTEGRATOR
 	depends on ARCH_INTEGRATOR
 	select CPU_32v5
 	select CPU_32v5
 	select CPU_ABRT_EV4T
 	select CPU_ABRT_EV4T
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_VIVT
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
 	select CPU_CP15_MMU
@@ -244,6 +252,7 @@ config CPU_ARM1020E
 	depends on ARCH_INTEGRATOR
 	depends on ARCH_INTEGRATOR
 	select CPU_32v5
 	select CPU_32v5
 	select CPU_ABRT_EV4T
 	select CPU_ABRT_EV4T
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_VIVT
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
 	select CPU_CP15_MMU
@@ -257,6 +266,7 @@ config CPU_ARM1022
 	depends on ARCH_INTEGRATOR
 	depends on ARCH_INTEGRATOR
 	select CPU_32v5
 	select CPU_32v5
 	select CPU_ABRT_EV4T
 	select CPU_ABRT_EV4T
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_VIVT
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
 	select CPU_CP15_MMU
 	select CPU_COPY_V4WB if MMU # can probably do better
 	select CPU_COPY_V4WB if MMU # can probably do better
@@ -275,6 +285,7 @@ config CPU_ARM1026
 	depends on ARCH_INTEGRATOR
 	depends on ARCH_INTEGRATOR
 	select CPU_32v5
 	select CPU_32v5
 	select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
 	select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_VIVT
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
 	select CPU_CP15_MMU
 	select CPU_COPY_V4WB if MMU # can probably do better
 	select CPU_COPY_V4WB if MMU # can probably do better
@@ -293,6 +304,7 @@ config CPU_SA110
 	select CPU_32v3 if ARCH_RPC
 	select CPU_32v3 if ARCH_RPC
 	select CPU_32v4 if !ARCH_RPC
 	select CPU_32v4 if !ARCH_RPC
 	select CPU_ABRT_EV4
 	select CPU_ABRT_EV4
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_V4WB
 	select CPU_CACHE_V4WB
 	select CPU_CACHE_VIVT
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
 	select CPU_CP15_MMU
@@ -314,6 +326,7 @@ config CPU_SA1100
 	default y
 	default y
 	select CPU_32v4
 	select CPU_32v4
 	select CPU_ABRT_EV4
 	select CPU_ABRT_EV4
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_V4WB
 	select CPU_CACHE_V4WB
 	select CPU_CACHE_VIVT
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
 	select CPU_CP15_MMU
@@ -326,6 +339,7 @@ config CPU_XSCALE
 	default y
 	default y
 	select CPU_32v5
 	select CPU_32v5
 	select CPU_ABRT_EV5T
 	select CPU_ABRT_EV5T
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_VIVT
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
 	select CPU_CP15_MMU
 	select CPU_TLB_V4WBI if MMU
 	select CPU_TLB_V4WBI if MMU
@@ -349,6 +363,7 @@ config CPU_FEROCEON
 	default y
 	default y
 	select CPU_32v5
 	select CPU_32v5
 	select CPU_ABRT_EV5T
 	select CPU_ABRT_EV5T
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_VIVT
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
 	select CPU_CP15_MMU
 	select CPU_COPY_V4WB if MMU
 	select CPU_COPY_V4WB if MMU
@@ -371,6 +386,7 @@ config CPU_V6
 	default y if ARCH_MSM7X00A
 	default y if ARCH_MSM7X00A
 	select CPU_32v6
 	select CPU_32v6
 	select CPU_ABRT_EV6
 	select CPU_ABRT_EV6
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_V6
 	select CPU_CACHE_V6
 	select CPU_CACHE_VIPT
 	select CPU_CACHE_VIPT
 	select CPU_CP15_MMU
 	select CPU_CP15_MMU
@@ -397,6 +413,7 @@ config CPU_V7
 	select CPU_32v6K
 	select CPU_32v6K
 	select CPU_32v7
 	select CPU_32v7
 	select CPU_ABRT_EV7
 	select CPU_ABRT_EV7
+	select CPU_PABRT_IFAR
 	select CPU_CACHE_V7
 	select CPU_CACHE_V7
 	select CPU_CACHE_VIPT
 	select CPU_CACHE_VIPT
 	select CPU_CP15_MMU
 	select CPU_CP15_MMU
@@ -458,6 +475,12 @@ config CPU_ABRT_EV6
 config CPU_ABRT_EV7
 config CPU_ABRT_EV7
 	bool
 	bool
 
 
+config CPU_PABRT_IFAR
+	bool
+
+config CPU_PABRT_NOIFAR
+	bool
+
 # The cache model
 # The cache model
 config CPU_CACHE_V3
 config CPU_CACHE_V3
 	bool
 	bool

+ 1 - 0
arch/arm/mm/proc-arm1020.S

@@ -478,6 +478,7 @@ arm1020_processor_functions:
 	.word	cpu_arm1020_dcache_clean_area
 	.word	cpu_arm1020_dcache_clean_area
 	.word	cpu_arm1020_switch_mm
 	.word	cpu_arm1020_switch_mm
 	.word	cpu_arm1020_set_pte_ext
 	.word	cpu_arm1020_set_pte_ext
+	.word	pabort_noifar
 	.size	arm1020_processor_functions, . - arm1020_processor_functions
 	.size	arm1020_processor_functions, . - arm1020_processor_functions
 
 
 	.section ".rodata"
 	.section ".rodata"

+ 1 - 0
arch/arm/mm/proc-arm1020e.S

@@ -459,6 +459,7 @@ arm1020e_processor_functions:
 	.word	cpu_arm1020e_dcache_clean_area
 	.word	cpu_arm1020e_dcache_clean_area
 	.word	cpu_arm1020e_switch_mm
 	.word	cpu_arm1020e_switch_mm
 	.word	cpu_arm1020e_set_pte_ext
 	.word	cpu_arm1020e_set_pte_ext
+	.word	pabort_noifar
 	.size	arm1020e_processor_functions, . - arm1020e_processor_functions
 	.size	arm1020e_processor_functions, . - arm1020e_processor_functions
 
 
 	.section ".rodata"
 	.section ".rodata"

+ 1 - 0
arch/arm/mm/proc-arm1022.S

@@ -442,6 +442,7 @@ arm1022_processor_functions:
 	.word	cpu_arm1022_dcache_clean_area
 	.word	cpu_arm1022_dcache_clean_area
 	.word	cpu_arm1022_switch_mm
 	.word	cpu_arm1022_switch_mm
 	.word	cpu_arm1022_set_pte_ext
 	.word	cpu_arm1022_set_pte_ext
+	.word	pabort_noifar
 	.size	arm1022_processor_functions, . - arm1022_processor_functions
 	.size	arm1022_processor_functions, . - arm1022_processor_functions
 
 
 	.section ".rodata"
 	.section ".rodata"

+ 1 - 0
arch/arm/mm/proc-arm1026.S

@@ -437,6 +437,7 @@ arm1026_processor_functions:
 	.word	cpu_arm1026_dcache_clean_area
 	.word	cpu_arm1026_dcache_clean_area
 	.word	cpu_arm1026_switch_mm
 	.word	cpu_arm1026_switch_mm
 	.word	cpu_arm1026_set_pte_ext
 	.word	cpu_arm1026_set_pte_ext
+	.word	pabort_noifar
 	.size	arm1026_processor_functions, . - arm1026_processor_functions
 	.size	arm1026_processor_functions, . - arm1026_processor_functions
 
 
 	.section .rodata
 	.section .rodata

+ 2 - 0
arch/arm/mm/proc-arm6_7.S

@@ -300,6 +300,7 @@ ENTRY(arm6_processor_functions)
 		.word	cpu_arm6_dcache_clean_area
 		.word	cpu_arm6_dcache_clean_area
 		.word	cpu_arm6_switch_mm
 		.word	cpu_arm6_switch_mm
 		.word	cpu_arm6_set_pte_ext
 		.word	cpu_arm6_set_pte_ext
+		.word	pabort_noifar
 		.size	arm6_processor_functions, . - arm6_processor_functions
 		.size	arm6_processor_functions, . - arm6_processor_functions
 
 
 /*
 /*
@@ -316,6 +317,7 @@ ENTRY(arm7_processor_functions)
 		.word	cpu_arm7_dcache_clean_area
 		.word	cpu_arm7_dcache_clean_area
 		.word	cpu_arm7_switch_mm
 		.word	cpu_arm7_switch_mm
 		.word	cpu_arm7_set_pte_ext
 		.word	cpu_arm7_set_pte_ext
+		.word	pabort_noifar
 		.size	arm7_processor_functions, . - arm7_processor_functions
 		.size	arm7_processor_functions, . - arm7_processor_functions
 
 
 		.section ".rodata"
 		.section ".rodata"

+ 1 - 0
arch/arm/mm/proc-arm720.S

@@ -205,6 +205,7 @@ ENTRY(arm720_processor_functions)
 		.word	cpu_arm720_dcache_clean_area
 		.word	cpu_arm720_dcache_clean_area
 		.word	cpu_arm720_switch_mm
 		.word	cpu_arm720_switch_mm
 		.word	cpu_arm720_set_pte_ext
 		.word	cpu_arm720_set_pte_ext
+		.word	pabort_noifar
 		.size	arm720_processor_functions, . - arm720_processor_functions
 		.size	arm720_processor_functions, . - arm720_processor_functions
 
 
 		.section ".rodata"
 		.section ".rodata"

+ 1 - 0
arch/arm/mm/proc-arm920.S

@@ -424,6 +424,7 @@ arm920_processor_functions:
 	.word	cpu_arm920_dcache_clean_area
 	.word	cpu_arm920_dcache_clean_area
 	.word	cpu_arm920_switch_mm
 	.word	cpu_arm920_switch_mm
 	.word	cpu_arm920_set_pte_ext
 	.word	cpu_arm920_set_pte_ext
+	.word	pabort_noifar
 	.size	arm920_processor_functions, . - arm920_processor_functions
 	.size	arm920_processor_functions, . - arm920_processor_functions
 
 
 	.section ".rodata"
 	.section ".rodata"

+ 1 - 0
arch/arm/mm/proc-arm922.S

@@ -428,6 +428,7 @@ arm922_processor_functions:
 	.word	cpu_arm922_dcache_clean_area
 	.word	cpu_arm922_dcache_clean_area
 	.word	cpu_arm922_switch_mm
 	.word	cpu_arm922_switch_mm
 	.word	cpu_arm922_set_pte_ext
 	.word	cpu_arm922_set_pte_ext
+	.word	pabort_noifar
 	.size	arm922_processor_functions, . - arm922_processor_functions
 	.size	arm922_processor_functions, . - arm922_processor_functions
 
 
 	.section ".rodata"
 	.section ".rodata"

+ 1 - 0
arch/arm/mm/proc-arm925.S

@@ -491,6 +491,7 @@ arm925_processor_functions:
 	.word	cpu_arm925_dcache_clean_area
 	.word	cpu_arm925_dcache_clean_area
 	.word	cpu_arm925_switch_mm
 	.word	cpu_arm925_switch_mm
 	.word	cpu_arm925_set_pte_ext
 	.word	cpu_arm925_set_pte_ext
+	.word	pabort_noifar
 	.size	arm925_processor_functions, . - arm925_processor_functions
 	.size	arm925_processor_functions, . - arm925_processor_functions
 
 
 	.section ".rodata"
 	.section ".rodata"

+ 1 - 0
arch/arm/mm/proc-arm926.S

@@ -444,6 +444,7 @@ arm926_processor_functions:
 	.word	cpu_arm926_dcache_clean_area
 	.word	cpu_arm926_dcache_clean_area
 	.word	cpu_arm926_switch_mm
 	.word	cpu_arm926_switch_mm
 	.word	cpu_arm926_set_pte_ext
 	.word	cpu_arm926_set_pte_ext
+	.word	pabort_noifar
 	.size	arm926_processor_functions, . - arm926_processor_functions
 	.size	arm926_processor_functions, . - arm926_processor_functions
 
 
 	.section ".rodata"
 	.section ".rodata"

+ 1 - 0
arch/arm/mm/proc-feroceon.S

@@ -430,6 +430,7 @@ feroceon_processor_functions:
 	.word	cpu_feroceon_dcache_clean_area
 	.word	cpu_feroceon_dcache_clean_area
 	.word	cpu_feroceon_switch_mm
 	.word	cpu_feroceon_switch_mm
 	.word	cpu_feroceon_set_pte_ext
 	.word	cpu_feroceon_set_pte_ext
+	.word	pabort_noifar
 	.size	feroceon_processor_functions, . - feroceon_processor_functions
 	.size	feroceon_processor_functions, . - feroceon_processor_functions
 
 
 	.section ".rodata"
 	.section ".rodata"

+ 1 - 0
arch/arm/mm/proc-sa110.S

@@ -223,6 +223,7 @@ ENTRY(sa110_processor_functions)
 	.word	cpu_sa110_dcache_clean_area
 	.word	cpu_sa110_dcache_clean_area
 	.word	cpu_sa110_switch_mm
 	.word	cpu_sa110_switch_mm
 	.word	cpu_sa110_set_pte_ext
 	.word	cpu_sa110_set_pte_ext
+	.word	pabort_noifar
 	.size	sa110_processor_functions, . - sa110_processor_functions
 	.size	sa110_processor_functions, . - sa110_processor_functions
 
 
 	.section ".rodata"
 	.section ".rodata"

+ 1 - 0
arch/arm/mm/proc-sa1100.S

@@ -238,6 +238,7 @@ ENTRY(sa1100_processor_functions)
 	.word	cpu_sa1100_dcache_clean_area
 	.word	cpu_sa1100_dcache_clean_area
 	.word	cpu_sa1100_switch_mm
 	.word	cpu_sa1100_switch_mm
 	.word	cpu_sa1100_set_pte_ext
 	.word	cpu_sa1100_set_pte_ext
+	.word	pabort_noifar
 	.size	sa1100_processor_functions, . - sa1100_processor_functions
 	.size	sa1100_processor_functions, . - sa1100_processor_functions
 
 
 	.section ".rodata"
 	.section ".rodata"

+ 1 - 0
arch/arm/mm/proc-v6.S

@@ -240,6 +240,7 @@ ENTRY(v6_processor_functions)
 	.word	cpu_v6_dcache_clean_area
 	.word	cpu_v6_dcache_clean_area
 	.word	cpu_v6_switch_mm
 	.word	cpu_v6_switch_mm
 	.word	cpu_v6_set_pte_ext
 	.word	cpu_v6_set_pte_ext
+	.word	pabort_noifar
 	.size	v6_processor_functions, . - v6_processor_functions
 	.size	v6_processor_functions, . - v6_processor_functions
 
 
 	.type	cpu_arch_name, #object
 	.type	cpu_arch_name, #object

+ 1 - 0
arch/arm/mm/proc-v7.S

@@ -212,6 +212,7 @@ ENTRY(v7_processor_functions)
 	.word	cpu_v7_dcache_clean_area
 	.word	cpu_v7_dcache_clean_area
 	.word	cpu_v7_switch_mm
 	.word	cpu_v7_switch_mm
 	.word	cpu_v7_set_pte_ext
 	.word	cpu_v7_set_pte_ext
+	.word	pabort_ifar
 	.size	v7_processor_functions, . - v7_processor_functions
 	.size	v7_processor_functions, . - v7_processor_functions
 
 
 	.type	cpu_arch_name, #object
 	.type	cpu_arch_name, #object

+ 1 - 0
arch/arm/mm/proc-xscale.S

@@ -534,6 +534,7 @@ ENTRY(xscale_processor_functions)
 	.word	cpu_xscale_dcache_clean_area
 	.word	cpu_xscale_dcache_clean_area
 	.word	cpu_xscale_switch_mm
 	.word	cpu_xscale_switch_mm
 	.word	cpu_xscale_set_pte_ext
 	.word	cpu_xscale_set_pte_ext
+	.word	pabort_noifar
 	.size	xscale_processor_functions, . - xscale_processor_functions
 	.size	xscale_processor_functions, . - xscale_processor_functions
 
 
 	.section ".rodata"
 	.section ".rodata"

+ 4 - 0
include/asm-arm/cpu-multi32.h

@@ -20,6 +20,10 @@ extern struct processor {
 	 * get data abort address/flags
 	 * get data abort address/flags
 	 */
 	 */
 	void (*_data_abort)(unsigned long pc);
 	void (*_data_abort)(unsigned long pc);
+	/*
+	 * Retrieve prefetch fault address
+	 */
+	unsigned long (*_prefetch_abort)(unsigned long lr);
 	/*
 	/*
 	 * Set up any processor specifics
 	 * Set up any processor specifics
 	 */
 	 */

+ 57 - 30
include/asm-arm/glue.h

@@ -40,83 +40,110 @@
  *	  v6_early	- ARMv6 generic early abort handler
  *	  v6_early	- ARMv6 generic early abort handler
  *	  v7_early	- ARMv7 generic early abort handler
  *	  v7_early	- ARMv7 generic early abort handler
  */
  */
-#undef CPU_ABORT_HANDLER
-#undef MULTI_ABORT
+#undef CPU_DABORT_HANDLER
+#undef MULTI_DABORT
 
 
 #if defined(CONFIG_CPU_ARM610)
 #if defined(CONFIG_CPU_ARM610)
-# ifdef CPU_ABORT_HANDLER
-#  define MULTI_ABORT 1
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
 # else
 # else
-#  define CPU_ABORT_HANDLER cpu_arm6_data_abort
+#  define CPU_DABORT_HANDLER cpu_arm6_data_abort
 # endif
 # endif
 #endif
 #endif
 
 
 #if defined(CONFIG_CPU_ARM710)
 #if defined(CONFIG_CPU_ARM710)
-# ifdef CPU_ABORT_HANDLER
-#  define MULTI_ABORT 1
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
 # else
 # else
-#  define CPU_ABORT_HANDLER cpu_arm7_data_abort
+#  define CPU_DABORT_HANDLER cpu_arm7_data_abort
 # endif
 # endif
 #endif
 #endif
 
 
 #ifdef CONFIG_CPU_ABRT_LV4T
 #ifdef CONFIG_CPU_ABRT_LV4T
-# ifdef CPU_ABORT_HANDLER
-#  define MULTI_ABORT 1
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
 # else
 # else
-#  define CPU_ABORT_HANDLER v4t_late_abort
+#  define CPU_DABORT_HANDLER v4t_late_abort
 # endif
 # endif
 #endif
 #endif
 
 
 #ifdef CONFIG_CPU_ABRT_EV4
 #ifdef CONFIG_CPU_ABRT_EV4
-# ifdef CPU_ABORT_HANDLER
-#  define MULTI_ABORT 1
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
 # else
 # else
-#  define CPU_ABORT_HANDLER v4_early_abort
+#  define CPU_DABORT_HANDLER v4_early_abort
 # endif
 # endif
 #endif
 #endif
 
 
 #ifdef CONFIG_CPU_ABRT_EV4T
 #ifdef CONFIG_CPU_ABRT_EV4T
-# ifdef CPU_ABORT_HANDLER
-#  define MULTI_ABORT 1
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
 # else
 # else
-#  define CPU_ABORT_HANDLER v4t_early_abort
+#  define CPU_DABORT_HANDLER v4t_early_abort
 # endif
 # endif
 #endif
 #endif
 
 
 #ifdef CONFIG_CPU_ABRT_EV5TJ
 #ifdef CONFIG_CPU_ABRT_EV5TJ
-# ifdef CPU_ABORT_HANDLER
-#  define MULTI_ABORT 1
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
 # else
 # else
-#  define CPU_ABORT_HANDLER v5tj_early_abort
+#  define CPU_DABORT_HANDLER v5tj_early_abort
 # endif
 # endif
 #endif
 #endif
 
 
 #ifdef CONFIG_CPU_ABRT_EV5T
 #ifdef CONFIG_CPU_ABRT_EV5T
-# ifdef CPU_ABORT_HANDLER
-#  define MULTI_ABORT 1
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
 # else
 # else
-#  define CPU_ABORT_HANDLER v5t_early_abort
+#  define CPU_DABORT_HANDLER v5t_early_abort
 # endif
 # endif
 #endif
 #endif
 
 
 #ifdef CONFIG_CPU_ABRT_EV6
 #ifdef CONFIG_CPU_ABRT_EV6
-# ifdef CPU_ABORT_HANDLER
-#  define MULTI_ABORT 1
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
 # else
 # else
-#  define CPU_ABORT_HANDLER v6_early_abort
+#  define CPU_DABORT_HANDLER v6_early_abort
 # endif
 # endif
 #endif
 #endif
 
 
 #ifdef CONFIG_CPU_ABRT_EV7
 #ifdef CONFIG_CPU_ABRT_EV7
-# ifdef CPU_ABORT_HANDLER
-#  define MULTI_ABORT 1
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
 # else
 # else
-#  define CPU_ABORT_HANDLER v7_early_abort
+#  define CPU_DABORT_HANDLER v7_early_abort
 # endif
 # endif
 #endif
 #endif
 
 
-#ifndef CPU_ABORT_HANDLER
+#ifndef CPU_DABORT_HANDLER
 #error Unknown data abort handler type
 #error Unknown data abort handler type
 #endif
 #endif
 
 
+/*
+ * Prefetch abort handler.  If the CPU has an IFAR use that, otherwise
+ * use the address of the aborted instruction
+ */
+#undef CPU_PABORT_HANDLER
+#undef MULTI_PABORT
+
+#ifdef CONFIG_CPU_PABRT_IFAR
+# ifdef CPU_PABORT_HANDLER
+#  define MULTI_PABORT 1
+# else
+#  define CPU_PABORT_HANDLER(reg, insn)	mrc p15, 0, reg, cr6, cr0, 2
+# endif
+#endif
+
+#ifdef CONFIG_CPU_PABRT_NOIFAR
+# ifdef CPU_PABORT_HANDLER
+#  define MULTI_PABORT 1
+# else
+#  define CPU_PABORT_HANDLER(reg, insn)	mov reg, insn
+# endif
+#endif
+
+#ifndef CPU_PABORT_HANDLER
+#error Unknown prefetch abort handler type
+#endif
+
 #endif
 #endif