ARM: 5727/1: Pass IFSR register to do_PrefetchAbort()

Instruction fault status register, IFSR, was introduced on ARMv6 to
provide status information about the last insturction fault. It
needed for proper prefetch abort handling.

Now we have three prefetch abort model:

  * legacy - for CPUs before ARMv6. They doesn't provide neither
    IFSR nor IFAR. We simulate IFSR with section translation fault
    status for them to generalize code;
  * ARMv6 - provides IFSR, but not IFAR;
  * ARMv7 - provides both IFSR and IFAR.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
Kirill A. Shutemov 2009-09-25 13:39:47 +01:00 committed by Russell King
parent 6806bfe18f
commit 4fb2847437
33 changed files with 144 additions and 78 deletions

View file

@ -120,25 +120,39 @@
#endif
/*
* Prefetch abort handler. If the CPU has an IFAR use that, otherwise
* use the address of the aborted instruction
* Prefetch Abort Model
* ================
*
* We have the following to choose from:
* legacy - no IFSR, no IFAR
* v6 - ARMv6: IFSR, no IFAR
* v7 - ARMv7: IFSR and IFAR
*/
#undef CPU_PABORT_HANDLER
#undef MULTI_PABORT
#ifdef CONFIG_CPU_PABRT_IFAR
#ifdef CONFIG_CPU_PABRT_LEGACY
# ifdef CPU_PABORT_HANDLER
# define MULTI_PABORT 1
# else
# define CPU_PABORT_HANDLER(reg, insn) mrc p15, 0, reg, cr6, cr0, 2
# define CPU_PABORT_HANDLER legacy_pabort
# endif
#endif
#ifdef CONFIG_CPU_PABRT_NOIFAR
#ifdef CONFIG_CPU_PABRT_V6
# ifdef CPU_PABORT_HANDLER
# define MULTI_PABORT 1
# else
# define CPU_PABORT_HANDLER(reg, insn) mov reg, insn
# define CPU_PABORT_HANDLER v6_pabort
# endif
#endif
#ifdef CONFIG_CPU_PABRT_V7
# ifdef CPU_PABORT_HANDLER
# define MULTI_PABORT 1
# else
# define CPU_PABORT_HANDLER v7_pabort
# endif
#endif

View file

@ -311,22 +311,16 @@ __pabt_svc:
tst r3, #PSR_I_BIT
biceq r9, r9, #PSR_I_BIT
@
@ set args, then call main handler
@
@ r0 - address of faulting instruction
@ r1 - pointer to registers on stack
@
#ifdef MULTI_PABORT
mov r0, r2 @ pass address of aborted instruction.
#ifdef MULTI_PABORT
ldr r4, .LCprocfns
mov lr, pc
ldr pc, [r4, #PROCESSOR_PABT_FUNC]
#else
CPU_PABORT_HANDLER(r0, r2)
bl CPU_PABORT_HANDLER
#endif
msr cpsr_c, r9 @ Maybe enable interrupts
mov r1, sp @ regs
mov r2, sp @ regs
bl do_PrefetchAbort @ call abort handler
@
@ -701,16 +695,16 @@ ENDPROC(__und_usr_unknown)
__pabt_usr:
usr_entry
#ifdef MULTI_PABORT
mov r0, r2 @ pass address of aborted instruction.
#ifdef MULTI_PABORT
ldr r4, .LCprocfns
mov lr, pc
ldr pc, [r4, #PROCESSOR_PABT_FUNC]
#else
CPU_PABORT_HANDLER(r0, r2)
bl CPU_PABORT_HANDLER
#endif
enable_irq @ Enable interrupts
mov r1, sp @ regs
mov r2, sp @ regs
bl do_PrefetchAbort @ call abort handler
UNWIND(.fnend )
/* fall through */

View file

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

View file

@ -17,7 +17,7 @@ config CPU_ARM610
select CPU_CP15_MMU
select CPU_COPY_V3 if MMU
select CPU_TLB_V3 if MMU
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
help
The ARM610 is the successor to the ARM3 processor
and was produced by VLSI Technology Inc.
@ -31,7 +31,7 @@ config CPU_ARM7TDMI
depends on !MMU
select CPU_32v4T
select CPU_ABRT_LV4T
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_V4
help
A 32-bit RISC microprocessor based on the ARM7 processor core
@ -49,7 +49,7 @@ config CPU_ARM710
select CPU_CP15_MMU
select CPU_COPY_V3 if MMU
select CPU_TLB_V3 if MMU
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
help
A 32-bit RISC microprocessor based on the ARM7 processor core
designed by Advanced RISC Machines Ltd. The ARM710 is the
@ -64,7 +64,7 @@ config CPU_ARM720T
bool "Support ARM720T processor" if ARCH_INTEGRATOR
select CPU_32v4T
select CPU_ABRT_LV4T
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_V4
select CPU_CACHE_VIVT
select CPU_CP15_MMU
@ -83,7 +83,7 @@ config CPU_ARM740T
depends on !MMU
select CPU_32v4T
select CPU_ABRT_LV4T
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_V3 # although the core is v4t
select CPU_CP15_MPU
help
@ -100,7 +100,7 @@ config CPU_ARM9TDMI
depends on !MMU
select CPU_32v4T
select CPU_ABRT_NOMMU
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_V4
help
A 32-bit RISC microprocessor based on the ARM9 processor core
@ -114,7 +114,7 @@ config CPU_ARM920T
bool "Support ARM920T processor" if ARCH_INTEGRATOR
select CPU_32v4T
select CPU_ABRT_EV4T
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_CP15_MMU
@ -135,7 +135,7 @@ config CPU_ARM922T
bool "Support ARM922T processor" if ARCH_INTEGRATOR
select CPU_32v4T
select CPU_ABRT_EV4T
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_CP15_MMU
@ -154,7 +154,7 @@ config CPU_ARM925T
bool "Support ARM925T processor" if ARCH_OMAP1
select CPU_32v4T
select CPU_ABRT_EV4T
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_CP15_MMU
@ -173,7 +173,7 @@ config CPU_ARM926T
bool "Support ARM926T processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB
select CPU_32v5
select CPU_ABRT_EV5TJ
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU
@ -191,7 +191,7 @@ config CPU_FA526
bool
select CPU_32v4
select CPU_ABRT_EV4
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_CACHE_FA
@ -210,7 +210,7 @@ config CPU_ARM940T
depends on !MMU
select CPU_32v4T
select CPU_ABRT_NOMMU
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MPU
help
@ -228,7 +228,7 @@ config CPU_ARM946E
depends on !MMU
select CPU_32v5
select CPU_ABRT_NOMMU
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MPU
help
@ -244,7 +244,7 @@ config CPU_ARM1020
bool "Support ARM1020T (rev 0) processor" if ARCH_INTEGRATOR
select CPU_32v5
select CPU_ABRT_EV4T
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_CP15_MMU
@ -262,7 +262,7 @@ config CPU_ARM1020E
bool "Support ARM1020E processor" if ARCH_INTEGRATOR
select CPU_32v5
select CPU_ABRT_EV4T
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_CP15_MMU
@ -275,7 +275,7 @@ config CPU_ARM1022
bool "Support ARM1022E processor" if ARCH_INTEGRATOR
select CPU_32v5
select CPU_ABRT_EV4T
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU # can probably do better
@ -293,7 +293,7 @@ config CPU_ARM1026
bool "Support ARM1026EJ-S processor" if ARCH_INTEGRATOR
select CPU_32v5
select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU # can probably do better
@ -311,7 +311,7 @@ config CPU_SA110
select CPU_32v3 if ARCH_RPC
select CPU_32v4 if !ARCH_RPC
select CPU_ABRT_EV4
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_V4WB
select CPU_CACHE_VIVT
select CPU_CP15_MMU
@ -331,7 +331,7 @@ config CPU_SA1100
bool
select CPU_32v4
select CPU_ABRT_EV4
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_V4WB
select CPU_CACHE_VIVT
select CPU_CP15_MMU
@ -342,7 +342,7 @@ config CPU_XSCALE
bool
select CPU_32v5
select CPU_ABRT_EV5T
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_TLB_V4WBI if MMU
@ -352,7 +352,7 @@ config CPU_XSC3
bool
select CPU_32v5
select CPU_ABRT_EV5T
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_TLB_V4WBI if MMU
@ -363,7 +363,7 @@ config CPU_MOHAWK
bool
select CPU_32v5
select CPU_ABRT_EV5T
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_TLB_V4WBI if MMU
@ -374,7 +374,7 @@ config CPU_FEROCEON
bool
select CPU_32v5
select CPU_ABRT_EV5T
select CPU_PABRT_NOIFAR
select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_COPY_FEROCEON if MMU
@ -394,7 +394,7 @@ config CPU_V6
bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX
select CPU_32v6
select CPU_ABRT_EV6
select CPU_PABRT_NOIFAR
select CPU_PABRT_V6
select CPU_CACHE_V6
select CPU_CACHE_VIPT
select CPU_CP15_MMU
@ -420,7 +420,7 @@ config CPU_V7
select CPU_32v6K
select CPU_32v7
select CPU_ABRT_EV7
select CPU_PABRT_IFAR
select CPU_PABRT_V7
select CPU_CACHE_V7
select CPU_CACHE_VIPT
select CPU_CP15_MMU
@ -482,10 +482,13 @@ config CPU_ABRT_EV6
config CPU_ABRT_EV7
bool
config CPU_PABRT_IFAR
config CPU_PABRT_LEGACY
bool
config CPU_PABRT_NOIFAR
config CPU_PABRT_V6
bool
config CPU_PABRT_V7
bool
# The cache model

View file

@ -27,6 +27,10 @@ obj-$(CONFIG_CPU_ABRT_EV5TJ) += abort-ev5tj.o
obj-$(CONFIG_CPU_ABRT_EV6) += abort-ev6.o
obj-$(CONFIG_CPU_ABRT_EV7) += abort-ev7.o
obj-$(CONFIG_CPU_PABRT_LEGACY) += pabort-legacy.o
obj-$(CONFIG_CPU_PABRT_V6) += pabort-v6.o
obj-$(CONFIG_CPU_PABRT_V7) += pabort-v7.o
obj-$(CONFIG_CPU_CACHE_V3) += cache-v3.o
obj-$(CONFIG_CPU_CACHE_V4) += cache-v4.o
obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o

View file

@ -520,7 +520,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
}
asmlinkage void __exception
do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
{
do_translation_fault(addr, FSR_LNX_PF, regs);
}

View file

@ -0,0 +1,19 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
/*
* Function: legacy_pabort
*
* Params : r0 = address of aborted instruction
*
* Returns : r0 = address of abort
* : r1 = Simulated IFSR with section translation fault status
*
* Purpose : obtain information about current prefetch abort.
*/
.align 5
ENTRY(legacy_pabort)
mov r1, #5
mov pc, lr
ENDPROC(legacy_pabort)

19
arch/arm/mm/pabort-v6.S Normal file
View file

@ -0,0 +1,19 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
/*
* Function: v6_pabort
*
* Params : r0 = address of aborted instruction
*
* Returns : r0 = address of abort
* : r1 = IFSR
*
* Purpose : obtain information about current prefetch abort.
*/
.align 5
ENTRY(v6_pabort)
mrc p15, 0, r1, c5, c0, 1 @ get IFSR
mov pc, lr
ENDPROC(v6_pabort)

20
arch/arm/mm/pabort-v7.S Normal file
View file

@ -0,0 +1,20 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
/*
* Function: v6_pabort
*
* Params : r0 = address of aborted instruction
*
* Returns : r0 = address of abort
* : r1 = IFSR
*
* Purpose : obtain information about current prefetch abort.
*/
.align 5
ENTRY(v7_pabort)
mrc p15, 0, r0, c6, c0, 2 @ get IFAR
mrc p15, 0, r1, c5, c0, 1 @ get IFSR
mov pc, lr
ENDPROC(v7_pabort)

View file

@ -449,7 +449,7 @@ arm1020_crval:
.type arm1020_processor_functions, #object
arm1020_processor_functions:
.word v4t_early_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_arm1020_proc_init
.word cpu_arm1020_proc_fin
.word cpu_arm1020_reset

View file

@ -430,7 +430,7 @@ arm1020e_crval:
.type arm1020e_processor_functions, #object
arm1020e_processor_functions:
.word v4t_early_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_arm1020e_proc_init
.word cpu_arm1020e_proc_fin
.word cpu_arm1020e_reset

View file

@ -413,7 +413,7 @@ arm1022_crval:
.type arm1022_processor_functions, #object
arm1022_processor_functions:
.word v4t_early_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_arm1022_proc_init
.word cpu_arm1022_proc_fin
.word cpu_arm1022_reset

View file

@ -408,7 +408,7 @@ arm1026_crval:
.type arm1026_processor_functions, #object
arm1026_processor_functions:
.word v5t_early_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_arm1026_proc_init
.word cpu_arm1026_proc_fin
.word cpu_arm1026_reset

View file

@ -278,7 +278,7 @@ __arm7_setup: mov r0, #0
.type arm6_processor_functions, #object
ENTRY(arm6_processor_functions)
.word cpu_arm6_data_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_arm6_proc_init
.word cpu_arm6_proc_fin
.word cpu_arm6_reset
@ -295,7 +295,7 @@ ENTRY(arm6_processor_functions)
.type arm7_processor_functions, #object
ENTRY(arm7_processor_functions)
.word cpu_arm7_data_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_arm7_proc_init
.word cpu_arm7_proc_fin
.word cpu_arm7_reset

View file

@ -181,7 +181,7 @@ arm720_crval:
.type arm720_processor_functions, #object
ENTRY(arm720_processor_functions)
.word v4t_late_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_arm720_proc_init
.word cpu_arm720_proc_fin
.word cpu_arm720_reset

View file

@ -126,7 +126,7 @@ __arm740_setup:
.type arm740_processor_functions, #object
ENTRY(arm740_processor_functions)
.word v4t_late_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_arm740_proc_init
.word cpu_arm740_proc_fin
.word cpu_arm740_reset

View file

@ -64,7 +64,7 @@ __arm7tdmi_setup:
.type arm7tdmi_processor_functions, #object
ENTRY(arm7tdmi_processor_functions)
.word v4t_late_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_arm7tdmi_proc_init
.word cpu_arm7tdmi_proc_fin
.word cpu_arm7tdmi_reset

View file

@ -395,7 +395,7 @@ arm920_crval:
.type arm920_processor_functions, #object
arm920_processor_functions:
.word v4t_early_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_arm920_proc_init
.word cpu_arm920_proc_fin
.word cpu_arm920_reset

View file

@ -399,7 +399,7 @@ arm922_crval:
.type arm922_processor_functions, #object
arm922_processor_functions:
.word v4t_early_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_arm922_proc_init
.word cpu_arm922_proc_fin
.word cpu_arm922_reset

View file

@ -462,7 +462,7 @@ arm925_crval:
.type arm925_processor_functions, #object
arm925_processor_functions:
.word v4t_early_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_arm925_proc_init
.word cpu_arm925_proc_fin
.word cpu_arm925_reset

View file

@ -415,7 +415,7 @@ arm926_crval:
.type arm926_processor_functions, #object
arm926_processor_functions:
.word v5tj_early_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_arm926_proc_init
.word cpu_arm926_proc_fin
.word cpu_arm926_reset

View file

@ -322,7 +322,7 @@ __arm940_setup:
.type arm940_processor_functions, #object
ENTRY(arm940_processor_functions)
.word nommu_early_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_arm940_proc_init
.word cpu_arm940_proc_fin
.word cpu_arm940_reset

View file

@ -377,7 +377,7 @@ __arm946_setup:
.type arm946_processor_functions, #object
ENTRY(arm946_processor_functions)
.word nommu_early_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_arm946_proc_init
.word cpu_arm946_proc_fin
.word cpu_arm946_reset

View file

@ -64,7 +64,7 @@ __arm9tdmi_setup:
.type arm9tdmi_processor_functions, #object
ENTRY(arm9tdmi_processor_functions)
.word nommu_early_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_arm9tdmi_proc_init
.word cpu_arm9tdmi_proc_fin
.word cpu_arm9tdmi_reset

View file

@ -191,7 +191,7 @@ fa526_cr1_set:
.type fa526_processor_functions, #object
fa526_processor_functions:
.word v4_early_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_fa526_proc_init
.word cpu_fa526_proc_fin
.word cpu_fa526_reset

View file

@ -499,7 +499,7 @@ feroceon_crval:
.type feroceon_processor_functions, #object
feroceon_processor_functions:
.word v5t_early_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_feroceon_proc_init
.word cpu_feroceon_proc_fin
.word cpu_feroceon_reset

View file

@ -359,7 +359,7 @@ mohawk_crval:
.type mohawk_processor_functions, #object
mohawk_processor_functions:
.word v5t_early_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_mohawk_proc_init
.word cpu_mohawk_proc_fin
.word cpu_mohawk_reset

View file

@ -199,7 +199,7 @@ sa110_crval:
.type sa110_processor_functions, #object
ENTRY(sa110_processor_functions)
.word v4_early_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_sa110_proc_init
.word cpu_sa110_proc_fin
.word cpu_sa110_reset

View file

@ -214,7 +214,7 @@ sa1100_crval:
.type sa1100_processor_functions, #object
ENTRY(sa1100_processor_functions)
.word v4_early_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_sa1100_proc_init
.word cpu_sa1100_proc_fin
.word cpu_sa1100_reset

View file

@ -191,7 +191,7 @@ v6_crval:
.type v6_processor_functions, #object
ENTRY(v6_processor_functions)
.word v6_early_abort
.word pabort_noifar
.word v6_pabort
.word cpu_v6_proc_init
.word cpu_v6_proc_fin
.word cpu_v6_reset

View file

@ -295,7 +295,7 @@ __v7_setup_stack:
.type v7_processor_functions, #object
ENTRY(v7_processor_functions)
.word v7_early_abort
.word pabort_ifar
.word v7_pabort
.word cpu_v7_proc_init
.word cpu_v7_proc_fin
.word cpu_v7_reset

View file

@ -428,7 +428,7 @@ xsc3_crval:
.type xsc3_processor_functions, #object
ENTRY(xsc3_processor_functions)
.word v5t_early_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_xsc3_proc_init
.word cpu_xsc3_proc_fin
.word cpu_xsc3_reset

View file

@ -511,7 +511,7 @@ xscale_crval:
.type xscale_processor_functions, #object
ENTRY(xscale_processor_functions)
.word v5t_early_abort
.word pabort_noifar
.word legacy_pabort
.word cpu_xscale_proc_init
.word cpu_xscale_proc_fin
.word cpu_xscale_reset