aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mm/abort-lv4t.S34
1 files changed, 24 insertions, 10 deletions
diff --git a/arch/arm/mm/abort-lv4t.S b/arch/arm/mm/abort-lv4t.S
index 6d8e8e3365d1..4cdfab31a0b6 100644
--- a/arch/arm/mm/abort-lv4t.S
+++ b/arch/arm/mm/abort-lv4t.S
@@ -7,7 +7,7 @@
7 * : r4 = aborted context pc 7 * : r4 = aborted context pc
8 * : r5 = aborted context psr 8 * : r5 = aborted context psr
9 * 9 *
10 * Returns : r4-r5, r10-r11, r13 preserved 10 * Returns : r4-r5, r9-r11, r13 preserved
11 * 11 *
12 * Purpose : obtain information about current aborted instruction. 12 * Purpose : obtain information about current aborted instruction.
13 * Note: we read user space. This means we might cause a data 13 * Note: we read user space. This means we might cause a data
@@ -48,7 +48,10 @@ ENTRY(v4t_late_abort)
48/* c */ b do_DataAbort @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m 48/* c */ b do_DataAbort @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m
49/* d */ b do_DataAbort @ ldc rd, [rn, #m] 49/* d */ b do_DataAbort @ ldc rd, [rn, #m]
50/* e */ b .data_unknown 50/* e */ b .data_unknown
51/* f */ 51/* f */ b .data_unknown
52
53.data_unknown_r9:
54 ldr r9, [sp], #4
52.data_unknown: @ Part of jumptable 55.data_unknown: @ Part of jumptable
53 mov r0, r4 56 mov r0, r4
54 mov r1, r8 57 mov r1, r8
@@ -57,6 +60,7 @@ ENTRY(v4t_late_abort)
57.data_arm_ldmstm: 60.data_arm_ldmstm:
58 tst r8, #1 << 21 @ check writeback bit 61 tst r8, #1 << 21 @ check writeback bit
59 beq do_DataAbort @ no writeback -> no fixup 62 beq do_DataAbort @ no writeback -> no fixup
63 str r9, [sp, #-4]!
60 mov r7, #0x11 64 mov r7, #0x11
61 orr r7, r7, #0x1100 65 orr r7, r7, #0x1100
62 and r6, r8, r7 66 and r6, r8, r7
@@ -75,12 +79,14 @@ ENTRY(v4t_late_abort)
75 subne r7, r7, r6, lsl #2 @ Undo increment 79 subne r7, r7, r6, lsl #2 @ Undo increment
76 addeq r7, r7, r6, lsl #2 @ Undo decrement 80 addeq r7, r7, r6, lsl #2 @ Undo decrement
77 str r7, [r2, r9, lsr #14] @ Put register 'Rn' 81 str r7, [r2, r9, lsr #14] @ Put register 'Rn'
82 ldr r9, [sp], #4
78 b do_DataAbort 83 b do_DataAbort
79 84
80.data_arm_lateldrhpre: 85.data_arm_lateldrhpre:
81 tst r8, #1 << 21 @ Check writeback bit 86 tst r8, #1 << 21 @ Check writeback bit
82 beq do_DataAbort @ No writeback -> no fixup 87 beq do_DataAbort @ No writeback -> no fixup
83.data_arm_lateldrhpost: 88.data_arm_lateldrhpost:
89 str r9, [sp, #-4]!
84 and r9, r8, #0x00f @ get Rm / low nibble of immediate value 90 and r9, r8, #0x00f @ get Rm / low nibble of immediate value
85 tst r8, #1 << 22 @ if (immediate offset) 91 tst r8, #1 << 22 @ if (immediate offset)
86 andne r6, r8, #0xf00 @ { immediate high nibble 92 andne r6, r8, #0xf00 @ { immediate high nibble
@@ -93,6 +99,7 @@ ENTRY(v4t_late_abort)
93 subne r7, r7, r6 @ Undo incrmenet 99 subne r7, r7, r6 @ Undo incrmenet
94 addeq r7, r7, r6 @ Undo decrement 100 addeq r7, r7, r6 @ Undo decrement
95 str r7, [r2, r9, lsr #14] @ Put register 'Rn' 101 str r7, [r2, r9, lsr #14] @ Put register 'Rn'
102 ldr r9, [sp], #4
96 b do_DataAbort 103 b do_DataAbort
97 104
98.data_arm_lateldrpreconst: 105.data_arm_lateldrpreconst:
@@ -101,12 +108,14 @@ ENTRY(v4t_late_abort)
101.data_arm_lateldrpostconst: 108.data_arm_lateldrpostconst:
102 movs r6, r8, lsl #20 @ Get offset 109 movs r6, r8, lsl #20 @ Get offset
103 beq do_DataAbort @ zero -> no fixup 110 beq do_DataAbort @ zero -> no fixup
111 str r9, [sp, #-4]!
104 and r9, r8, #15 << 16 @ Extract 'n' from instruction 112 and r9, r8, #15 << 16 @ Extract 'n' from instruction
105 ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' 113 ldr r7, [r2, r9, lsr #14] @ Get register 'Rn'
106 tst r8, #1 << 23 @ Check U bit 114 tst r8, #1 << 23 @ Check U bit
107 subne r7, r7, r6, lsr #20 @ Undo increment 115 subne r7, r7, r6, lsr #20 @ Undo increment
108 addeq r7, r7, r6, lsr #20 @ Undo decrement 116 addeq r7, r7, r6, lsr #20 @ Undo decrement
109 str r7, [r2, r9, lsr #14] @ Put register 'Rn' 117 str r7, [r2, r9, lsr #14] @ Put register 'Rn'
118 ldr r9, [sp], #4
110 b do_DataAbort 119 b do_DataAbort
111 120
112.data_arm_lateldrprereg: 121.data_arm_lateldrprereg:
@@ -115,6 +124,7 @@ ENTRY(v4t_late_abort)
115.data_arm_lateldrpostreg: 124.data_arm_lateldrpostreg:
116 and r7, r8, #15 @ Extract 'm' from instruction 125 and r7, r8, #15 @ Extract 'm' from instruction
117 ldr r6, [r2, r7, lsl #2] @ Get register 'Rm' 126 ldr r6, [r2, r7, lsl #2] @ Get register 'Rm'
127 str r9, [sp, #-4]!
118 mov r9, r8, lsr #7 @ get shift count 128 mov r9, r8, lsr #7 @ get shift count
119 ands r9, r9, #31 129 ands r9, r9, #31
120 and r7, r8, #0x70 @ get shift type 130 and r7, r8, #0x70 @ get shift type
@@ -126,33 +136,33 @@ ENTRY(v4t_late_abort)
126 b .data_arm_apply_r6_and_rn 136 b .data_arm_apply_r6_and_rn
127 b .data_arm_apply_r6_and_rn @ 1: LSL #0 137 b .data_arm_apply_r6_and_rn @ 1: LSL #0
128 nop 138 nop
129 b .data_unknown @ 2: MUL? 139 b .data_unknown_r9 @ 2: MUL?
130 nop 140 nop
131 b .data_unknown @ 3: MUL? 141 b .data_unknown_r9 @ 3: MUL?
132 nop 142 nop
133 mov r6, r6, lsr r9 @ 4: LSR #!0 143 mov r6, r6, lsr r9 @ 4: LSR #!0
134 b .data_arm_apply_r6_and_rn 144 b .data_arm_apply_r6_and_rn
135 mov r6, r6, lsr #32 @ 5: LSR #32 145 mov r6, r6, lsr #32 @ 5: LSR #32
136 b .data_arm_apply_r6_and_rn 146 b .data_arm_apply_r6_and_rn
137 b .data_unknown @ 6: MUL? 147 b .data_unknown_r9 @ 6: MUL?
138 nop 148 nop
139 b .data_unknown @ 7: MUL? 149 b .data_unknown_r9 @ 7: MUL?
140 nop 150 nop
141 mov r6, r6, asr r9 @ 8: ASR #!0 151 mov r6, r6, asr r9 @ 8: ASR #!0
142 b .data_arm_apply_r6_and_rn 152 b .data_arm_apply_r6_and_rn
143 mov r6, r6, asr #32 @ 9: ASR #32 153 mov r6, r6, asr #32 @ 9: ASR #32
144 b .data_arm_apply_r6_and_rn 154 b .data_arm_apply_r6_and_rn
145 b .data_unknown @ A: MUL? 155 b .data_unknown_r9 @ A: MUL?
146 nop 156 nop
147 b .data_unknown @ B: MUL? 157 b .data_unknown_r9 @ B: MUL?
148 nop 158 nop
149 mov r6, r6, ror r9 @ C: ROR #!0 159 mov r6, r6, ror r9 @ C: ROR #!0
150 b .data_arm_apply_r6_and_rn 160 b .data_arm_apply_r6_and_rn
151 mov r6, r6, rrx @ D: RRX 161 mov r6, r6, rrx @ D: RRX
152 b .data_arm_apply_r6_and_rn 162 b .data_arm_apply_r6_and_rn
153 b .data_unknown @ E: MUL? 163 b .data_unknown_r9 @ E: MUL?
154 nop 164 nop
155 b .data_unknown @ F: MUL? 165 b .data_unknown_r9 @ F: MUL?
156 166
157.data_thumb_abort: 167.data_thumb_abort:
158 ldrh r8, [r4] @ read instruction 168 ldrh r8, [r4] @ read instruction
@@ -190,6 +200,7 @@ ENTRY(v4t_late_abort)
190.data_thumb_pushpop: 200.data_thumb_pushpop:
191 tst r8, #1 << 10 201 tst r8, #1 << 10
192 beq .data_unknown 202 beq .data_unknown
203 str r9, [sp, #-4]!
193 and r6, r8, #0x55 @ hweight8(r8) + R bit 204 and r6, r8, #0x55 @ hweight8(r8) + R bit
194 and r9, r8, #0xaa 205 and r9, r8, #0xaa
195 add r6, r6, r9, lsr #1 206 add r6, r6, r9, lsr #1
@@ -204,9 +215,11 @@ ENTRY(v4t_late_abort)
204 addeq r7, r7, r6, lsl #2 @ increment SP if PUSH 215 addeq r7, r7, r6, lsl #2 @ increment SP if PUSH
205 subne r7, r7, r6, lsl #2 @ decrement SP if POP 216 subne r7, r7, r6, lsl #2 @ decrement SP if POP
206 str r7, [r2, #13 << 2] 217 str r7, [r2, #13 << 2]
218 ldr r9, [sp], #4
207 b do_DataAbort 219 b do_DataAbort
208 220
209.data_thumb_ldmstm: 221.data_thumb_ldmstm:
222 str r9, [sp, #-4]!
210 and r6, r8, #0x55 @ hweight8(r8) 223 and r6, r8, #0x55 @ hweight8(r8)
211 and r9, r8, #0xaa 224 and r9, r8, #0xaa
212 add r6, r6, r9, lsr #1 225 add r6, r6, r9, lsr #1
@@ -219,4 +232,5 @@ ENTRY(v4t_late_abort)
219 and r6, r6, #15 @ number of regs to transfer 232 and r6, r6, #15 @ number of regs to transfer
220 sub r7, r7, r6, lsl #2 @ always decrement 233 sub r7, r7, r6, lsl #2 @ always decrement
221 str r7, [r2, r9, lsr #6] 234 str r7, [r2, r9, lsr #6]
235 ldr r9, [sp], #4
222 b do_DataAbort 236 b do_DataAbort