linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] ARM: Pass IFSR register to do_PrefetchAbort()
@ 2009-09-18 13:48 Kirill A. Shutemov
  2009-09-18 11:18 ` Aaro Koskinen
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Kirill A. Shutemov @ 2009-09-18 13:48 UTC (permalink / raw)
  To: linux-arm-kernel

It needed for proper prefetch abort handling on ARMv7.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 arch/arm/include/asm/glue.h  |    4 ++--
 arch/arm/kernel/entry-armv.S |   14 ++++----------
 arch/arm/mm/Makefile         |    2 ++
 arch/arm/mm/fault.c          |    2 +-
 arch/arm/mm/pabort-ifar.S    |   18 ++++++++++++++++++
 arch/arm/mm/pabort-noifar.S  |   18 ++++++++++++++++++
 6 files changed, 45 insertions(+), 13 deletions(-)
 create mode 100644 arch/arm/mm/pabort-ifar.S
 create mode 100644 arch/arm/mm/pabort-noifar.S

diff --git a/arch/arm/include/asm/glue.h b/arch/arm/include/asm/glue.h
index a0e39d5..bc6595c 100644
--- a/arch/arm/include/asm/glue.h
+++ b/arch/arm/include/asm/glue.h
@@ -130,7 +130,7 @@
 # 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 ifar_pabort
 # endif
 #endif
 
@@ -138,7 +138,7 @@
 # ifdef CPU_PABORT_HANDLER
 #  define MULTI_PABORT 1
 # else
-#  define CPU_PABORT_HANDLER(reg, insn)	mov reg, insn
+#  define CPU_PABORT_HANDLER noifar_pabort
 # endif
 #endif
 
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 85040cf..dbb4ce7 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -291,22 +291,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.
 	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
 
 	@
@@ -666,10 +660,10 @@ __pabt_usr:
 	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
 	/* fall through */
 /*
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 480f78a..30f1708 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -78,3 +78,5 @@ obj-$(CONFIG_CACHE_FEROCEON_L2)	+= cache-feroceon-l2.o
 obj-$(CONFIG_CACHE_L2X0)	+= cache-l2x0.o
 obj-$(CONFIG_CACHE_XSC3L2)	+= cache-xsc3l2.o
 
+obj-$(CONFIG_CPU_PABRT_NOIFAR)	+= pabort-noifar.o
+obj-$(CONFIG_CPU_PABRT_IFAR)	+= pabort-ifar.o
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 22c9530..c7bbb32 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -480,7 +480,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, int ifsr, struct pt_regs *regs)
 {
 	do_translation_fault(addr, 0, regs);
 }
diff --git a/arch/arm/mm/pabort-ifar.S b/arch/arm/mm/pabort-ifar.S
new file mode 100644
index 0000000..46838ea
--- /dev/null
+++ b/arch/arm/mm/pabort-ifar.S
@@ -0,0 +1,18 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Function: ifar_pabort
+ *
+ * Returns : r0 = address of abort
+ *	   : r1 = IFSR
+ *
+ * Purpose : obtain information about current prefetch abort.
+ */
+	.align	5
+ENTRY(ifar_pabort)
+	mrc	p15, 0, r0, c6, c0, 2		@ get IFAR
+	mrc	p15, 0, r1, c5, c0, 1		@ get IFSR
+
+	mov	pc, lr
+ENDPROC(ifar_pabort)
diff --git a/arch/arm/mm/pabort-noifar.S b/arch/arm/mm/pabort-noifar.S
new file mode 100644
index 0000000..46b0daf
--- /dev/null
+++ b/arch/arm/mm/pabort-noifar.S
@@ -0,0 +1,18 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Function: noifar_pabort
+
+ * Returns : r0 = address of abort
+ *	   : r1 = 5, simulate IFSR with section translation fault status
+ *
+ * Purpose : obtain information about current prefetch abort.
+ */
+	.align	5
+ENTRY(noifar_pabort)
+	mov	r0, insn
+	mov	r1, #5		@ translation fault
+
+	mov	pc, lr
+ENDPROC(noifar_pabort)
-- 
1.6.4.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread
* [PATCH 1/2] ARM: Pass IFSR register to do_PrefetchAbort()
@ 2009-09-18 20:55 Kirill A. Shutemov
  2009-09-19 11:03 ` Russell King - ARM Linux
  0 siblings, 1 reply; 15+ messages in thread
From: Kirill A. Shutemov @ 2009-09-18 20:55 UTC (permalink / raw)
  To: linux-arm-kernel

It needed for proper prefetch abort handling on ARMv7.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 arch/arm/include/asm/glue.h    |   10 ++++++++--
 arch/arm/kernel/entry-armv.S   |   14 ++++----------
 arch/arm/kernel/entry-common.S |    8 ++++++--
 arch/arm/mm/fault.c            |    2 +-
 4 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/arch/arm/include/asm/glue.h b/arch/arm/include/asm/glue.h
index a0e39d5..5bfaf6f 100644
--- a/arch/arm/include/asm/glue.h
+++ b/arch/arm/include/asm/glue.h
@@ -130,7 +130,10 @@
 # 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(addr, ifsr, insn) \
+	mrc	p15, 0, addr, c6, c0, 2 ; \
+	mrc	p15, 0, ifsr, c5, c0, 1
+
 # endif
 #endif
 
@@ -138,7 +141,10 @@
 # ifdef CPU_PABORT_HANDLER
 #  define MULTI_PABORT 1
 # else
-#  define CPU_PABORT_HANDLER(reg, insn)	mov reg, insn
+#define __hash_5 #5
+#  define CPU_PABORT_HANDLER(addr, ifsr, insn) \
+	mov	addr, insn ; \
+	mov	ifsr, __hash_5
 # endif
 #endif
 
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 3d727a8..335ae58 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -303,22 +303,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.
 	ldr	r4, .LCprocfns
 	mov	lr, pc
 	ldr	pc, [r4, #PROCESSOR_PABT_FUNC]
 #else
-	CPU_PABORT_HANDLER(r0, r2)
+	CPU_PABORT_HANDLER(r0, r1, r2)
 #endif
 	msr	cpsr_c, r9			@ Maybe enable interrupts
-	mov	r1, sp				@ regs
+	mov	r2, sp				@ regs
 	bl	do_PrefetchAbort		@ call abort handler
 
 	@
@@ -697,10 +691,10 @@ __pabt_usr:
 	mov	lr, pc
 	ldr	pc, [r4, #PROCESSOR_PABT_FUNC]
 #else
-	CPU_PABORT_HANDLER(r0, r2)
+	CPU_PABORT_HANDLER(r0, r1, r2)
 #endif
 	enable_irq				@ Enable interrupts
-	mov	r1, sp				@ regs
+	mov	r2, sp				@ regs
 	bl	do_PrefetchAbort		@ call abort handler
  UNWIND(.fnend		)
 	/* fall through */
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 807cfeb..931ab9a 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -426,10 +426,14 @@ sys_mmap2:
 ENDPROC(sys_mmap2)
 
 ENTRY(pabort_ifar)
-		mrc	p15, 0, r0, cr6, cr0, 2
-ENTRY(pabort_noifar)
+		mrc	p15, 0, r0, c6, c0, 2		@ get IFAR
+		mrc	p15, 0, r1, c5, c0, 1		@ get IFSR
 		mov	pc, lr
 ENDPROC(pabort_ifar)
+ENTRY(pabort_noifar)
+		/* simulate IFSR with section translation fault status */
+		mov	r1, #5
+		mov	pc, lr
 ENDPROC(pabort_noifar)
 
 #ifdef CONFIG_OABI_COMPAT
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index cc8829d..5e27462 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -506,7 +506,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, int ifsr, struct pt_regs *regs)
 {
 	do_translation_fault(addr, 0, regs);
 }
-- 
1.6.4.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2009-09-21  7:06 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-18 13:48 [PATCH 1/2] ARM: Pass IFSR register to do_PrefetchAbort() Kirill A. Shutemov
2009-09-18 11:18 ` Aaro Koskinen
2009-09-18 11:36   ` Kirill A. Shutemov
     [not found] ` <alpine.DEB.1.00.0909181422370.11448@ak-desktop>
2009-09-18 11:45   ` Kirill A. Shutemov
2009-09-18 14:52     ` Aaro Koskinen
2009-09-18 15:08       ` Kirill A. Shutemov
2009-09-18 15:38         ` Catalin Marinas
2009-09-18 13:48 ` [PATCH 2/2] ARM: Proper prefetch abort handling Kirill A. Shutemov
  -- strict thread matches above, loose matches on Subject: below --
2009-09-18 20:55 [PATCH 1/2] ARM: Pass IFSR register to do_PrefetchAbort() Kirill A. Shutemov
2009-09-19 11:03 ` Russell King - ARM Linux
2009-09-20  8:15   ` Russell King - ARM Linux
2009-09-20  9:35     ` Kirill A. Shutemov
2009-09-20 12:24       ` Russell King - ARM Linux
2009-09-20 14:34         ` Kirill A. Shutemov
2009-09-21  7:06         ` Kirill A. Shutemov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).