ChangeSet 1.2181.28.5, 2005/03/27 18:48:13+01:00, [EMAIL PROTECTED](none)
[ARM PATCH] 2576/1: Fix LDRD and LDRSB (Thumb) abort handling
Patch from Deepak Saxena
The ARM LDRD (v5+) and Thumb LDRSB instructions use bit 20/11
(ARM/Thumb)
differently than every other instruction, so it is set to 0 (write) even
though the instructions are read instructions. This means that during an
abort the instructions will be treated as a write and the handler will
raise a signal from unwriteable locations if they fault. We have to
specifically check for these instructions from the abort handlers to
treat them properly. EABI toolchains emit LDRD instructions and even
those not using EABI might have handcoded ASM that uses these
instructions.
This patch creates an abort-macro.S file that is included by the
abort-ev* files that need the special cases and changes those
handlers to use the macros. ARMv6 does not need the special case
handling as the HW takes care of setting the FSR bit appropriately.
Signed-off-by: Deepak Saxena
Signed-off-by: Russell King
abort-ev4t.S | 5 ++---
abort-ev5t.S | 6 +++---
abort-ev5tj.S | 6 +++---
abort-macro.S | 42 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 50 insertions(+), 9 deletions(-)
diff -Nru a/arch/arm/mm/abort-ev4t.S b/arch/arm/mm/abort-ev4t.S
--- a/arch/arm/mm/abort-ev4t.S 2005-03-28 23:12:57 -08:00
+++ b/arch/arm/mm/abort-ev4t.S 2005-03-28 23:12:57 -08:00
@@ -1,5 +1,6 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include "abort-macro.S"
/*
* Function: v4t_early_abort
*
@@ -21,11 +22,9 @@
ENTRY(v4t_early_abort)
mrc p15, 0, r1, c5, c0, 0 @ get FSR
mrc p15, 0, r0, c6, c0, 0 @ get FAR
- tst r3, #PSR_T_BIT
- ldrneh r3, [r2] @ read aborted thumb instruction
+ do_thumb_abort
ldreq r3, [r2] @ read aborted ARM instruction
bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
- movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit
20
tst r3, #1 << 20 @ check write
orreq r1, r1, #1 << 11
mov pc, lr
diff -Nru a/arch/arm/mm/abort-ev5t.S b/arch/arm/mm/abort-ev5t.S
--- a/arch/arm/mm/abort-ev5t.S 2005-03-28 23:12:57 -08:00
+++ b/arch/arm/mm/abort-ev5t.S 2005-03-28 23:12:57 -08:00
@@ -1,5 +1,6 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include "abort-macro.S"
/*
* Function: v5t_early_abort
*
@@ -21,11 +22,10 @@
ENTRY(v5t_early_abort)
mrc p15, 0, r1, c5, c0, 0 @ get FSR
mrc p15, 0, r0, c6, c0, 0 @ get FAR
- tst r3, #PSR_T_BIT
- ldrneh r3, [r2] @ read aborted thumb instruction
+ do_thumb_abort
ldreq r3, [r2] @ read aborted ARM instruction
bic r1, r1, #1 << 11 @ clear bits 11 of FSR
- movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit
20
+ do_ldrd_abort
tst r3, #1 << 20 @ check write
orreq r1, r1, #1 << 11
mov pc, lr
diff -Nru a/arch/arm/mm/abort-ev5tj.S b/arch/arm/mm/abort-ev5tj.S
--- a/arch/arm/mm/abort-ev5tj.S 2005-03-28 23:12:57 -08:00
+++ b/arch/arm/mm/abort-ev5tj.S 2005-03-28 23:12:57 -08:00
@@ -1,5 +1,6 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include "abort-macro.S"
/*
* Function: v5tj_early_abort
*
@@ -24,10 +25,9 @@
bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
tst r3, #PSR_J_BIT @ Java?
movne pc, lr
- tst r3, #PSR_T_BIT @ Thumb?
- ldrneh r3, [r2] @ read aborted thumb instruction
+ do_thumb_abort
ldreq r3, [r2] @ read aborted ARM instruction
- movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit
20
+ do_ldrd_abort
tst r3, #1 << 20 @ L = 0 -> write
orreq r1, r1, #1 << 11 @ yes.
mov pc, lr
diff -Nru a/arch/arm/mm/abort-macro.S b/arch/arm/mm/abort-macro.S
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/arch/arm/mm/abort-macro.S 2005-03-28 23:12:57 -08:00
@@ -0,0 +1,42 @@
+/*
+ * The ARM LDRD and Thumb LDRSB instructions use bit 20/11 (ARM/Thumb)
+ * differently than every other instruction, so it is set to 0 (write)
+ * even though the instructions are read instructions. This means that
+ * during an abort the instructions will be treated as a write and the
+ * handler will raise a signal from unwriteable locations if they
+ * fault. We have to specifically check for these instructions
+ * from the abort handlers to treat them properly.
+ *
+ */
+
+ .macro do_thumb_abort
+ tst r3, #PSR_T_BIT
+ beq not_thumb
+ ldrh r3, [r2] @ Read aborted Thumb instruction
+ and r3, r3, # 0xfe00 @ Mask opcode field
+ cmp r3, # 0x5600 @ Is it ldrsb?
+ orreq r3, r3, #1 << 11 @ Set L-bit if yes
+ tst r3, #1 << 11 @ L = 0 -> write
+ orreq r1, r1, #1 << 11 @ yes.
+ mov pc, lr
+not_thumb:
+ .endm
+
+/*
+ * We check for the following insturction encoding for LDRD.
+ *
+ * [27:25] == 0
+ * [7:4] == 1101
+ * [20] == 0
+ */
+ .macro do_ldrd_abort
+ tst r3, #0x0e000000 @ [27:25] == 0
+ bne not_ldrd
+ and r2, r3, #0x000000f0 @ [7:4] == 1101
+ cmp r2, #0x000000d0
+ bne not_ldrd
+ tst r3, #1 << 20 @ [20] == 0
+ moveq pc, lr
+not_ldrd:
+ .endm
+
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html