1
2#include <linux/linkage.h>
3#include <asm/assembler.h>
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18ENTRY(v4t_late_abort)
19 tst r5,
20#ifdef CONFIG_CPU_CP15_MMU
21 mrc p15, 0, r1, c5, c0, 0 @ get FSR
22 mrc p15, 0, r0, c6, c0, 0 @ get FAR
23 bic r1, r1,
24#else
25 mov r0,
26 mov r1,
27#endif
28 bne .data_thumb_abort
29 ldr r8, [r4] @ read arm instruction
30 uaccess_disable ip @ disable userspace access
31 tst r8,
32 orreq r1, r1,
33 and r7, r8,
34 add pc, pc, r7, lsr
35 nop
36
37 b .data_arm_lateldrhpost @ ldrh rd, [rn],
38 b .data_arm_lateldrhpre @ ldrh rd, [rn,
39 b .data_unknown
40 b .data_unknown
41 b .data_arm_lateldrpostconst @ ldr rd, [rn],
42 b .data_arm_lateldrpreconst @ ldr rd, [rn,
43 b .data_arm_lateldrpostreg @ ldr rd, [rn], rm
44 b .data_arm_lateldrprereg @ ldr rd, [rn, rm]
45 b .data_arm_ldmstm @ ldm*a rn, <rlist>
46 b .data_arm_ldmstm @ ldm*b rn, <rlist>
47 b .data_unknown
48 b .data_unknown
49 b do_DataAbort @ ldc rd, [rn],
50 b do_DataAbort @ ldc rd, [rn,
51 b .data_unknown
52 b .data_unknown
53
54.data_unknown_r9:
55 ldr r9, [sp],
56.data_unknown: @ Part of jumptable
57 mov r0, r4
58 mov r1, r8
59 b baddataabort
60
61.data_arm_ldmstm:
62 tst r8,
63 beq do_DataAbort @ no writeback -> no fixup
64 str r9, [sp,
65 mov r7,
66 orr r7, r7,
67 and r6, r8, r7
68 and r9, r8, r7, lsl
69 add r6, r6, r9, lsr
70 and r9, r8, r7, lsl
71 add r6, r6, r9, lsr
72 and r9, r8, r7, lsl
73 add r6, r6, r9, lsr
74 add r6, r6, r6, lsr
75 add r6, r6, r6, lsr
76 and r6, r6,
77 and r9, r8,
78 ldr r7, [r2, r9, lsr
79 tst r8,
80 subne r7, r7, r6, lsl
81 addeq r7, r7, r6, lsl
82 str r7, [r2, r9, lsr
83 ldr r9, [sp],
84 b do_DataAbort
85
86.data_arm_lateldrhpre:
87 tst r8,
88 beq do_DataAbort @ No writeback -> no fixup
89.data_arm_lateldrhpost:
90 str r9, [sp,
91 and r9, r8,
92 tst r8,
93 andne r6, r8,
94 orrne r6, r9, r6, lsr
95 ldreq r6, [r2, r9, lsl
96.data_arm_apply_r6_and_rn:
97 and r9, r8,
98 ldr r7, [r2, r9, lsr
99 tst r8,
100 subne r7, r7, r6 @ Undo incrmenet
101 addeq r7, r7, r6 @ Undo decrement
102 str r7, [r2, r9, lsr
103 ldr r9, [sp],
104 b do_DataAbort
105
106.data_arm_lateldrpreconst:
107 tst r8,
108 beq do_DataAbort @ no writeback -> no fixup
109.data_arm_lateldrpostconst:
110 movs r6, r8, lsl
111 beq do_DataAbort @ zero -> no fixup
112 str r9, [sp,
113 and r9, r8,
114 ldr r7, [r2, r9, lsr
115 tst r8,
116 subne r7, r7, r6, lsr
117 addeq r7, r7, r6, lsr
118 str r7, [r2, r9, lsr
119 ldr r9, [sp],
120 b do_DataAbort
121
122.data_arm_lateldrprereg:
123 tst r8,
124 beq do_DataAbort @ no writeback -> no fixup
125.data_arm_lateldrpostreg:
126 and r7, r8,
127 ldr r6, [r2, r7, lsl
128 str r9, [sp,
129 mov r9, r8, lsr
130 ands r9, r9,
131 and r7, r8,
132 orreq r7, r7,
133 add pc, pc, r7
134 nop
135
136 mov r6, r6, lsl r9 @ 0: LSL
137 b .data_arm_apply_r6_and_rn
138 b .data_arm_apply_r6_and_rn @ 1: LSL
139 nop
140 b .data_unknown_r9 @ 2: MUL?
141 nop
142 b .data_unknown_r9 @ 3: MUL?
143 nop
144 mov r6, r6, lsr r9 @ 4: LSR
145 b .data_arm_apply_r6_and_rn
146 mov r6, r6, lsr
147 b .data_arm_apply_r6_and_rn
148 b .data_unknown_r9 @ 6: MUL?
149 nop
150 b .data_unknown_r9 @ 7: MUL?
151 nop
152 mov r6, r6, asr r9 @ 8: ASR
153 b .data_arm_apply_r6_and_rn
154 mov r6, r6, asr
155 b .data_arm_apply_r6_and_rn
156 b .data_unknown_r9 @ A: MUL?
157 nop
158 b .data_unknown_r9 @ B: MUL?
159 nop
160 mov r6, r6, ror r9 @ C: ROR
161 b .data_arm_apply_r6_and_rn
162 mov r6, r6, rrx @ D: RRX
163 b .data_arm_apply_r6_and_rn
164 b .data_unknown_r9 @ E: MUL?
165 nop
166 b .data_unknown_r9 @ F: MUL?
167
168.data_thumb_abort:
169 ldrh r8, [r4] @ read instruction
170 uaccess_disable ip @ disable userspace access
171 tst r8,
172 orreq r1, r1,
173 and r7, r8,
174 add pc, pc, r7, lsr
175 nop
176
177 b .data_unknown
178 b .data_unknown
179 b .data_unknown
180 b .data_unknown
181 b .data_unknown
182 b .data_thumb_reg
183 b do_DataAbort
184 b do_DataAbort
185 b do_DataAbort
186 b do_DataAbort
187 b .data_unknown
188 b .data_thumb_pushpop
189 b .data_thumb_ldmstm
190 b .data_unknown
191 b .data_unknown
192 b .data_unknown
193
194.data_thumb_reg:
195 tst r8,
196 beq do_DataAbort
197 tst r8,
198 movne r1,
199 b do_DataAbort
200
201.data_thumb_pushpop:
202 tst r8,
203 beq .data_unknown
204 str r9, [sp,
205 and r6, r8,
206 and r9, r8,
207 add r6, r6, r9, lsr
208 and r9, r6,
209 and r6, r6,
210 add r6, r6, r9, lsr
211 movs r7, r8, lsr
212 adc r6, r6, r6, lsr
213 and r6, r6,
214 ldr r7, [r2,
215 tst r8,
216 addeq r7, r7, r6, lsl
217 subne r7, r7, r6, lsl
218 str r7, [r2,
219 ldr r9, [sp],
220 b do_DataAbort
221
222.data_thumb_ldmstm:
223 str r9, [sp,
224 and r6, r8,
225 and r9, r8,
226 add r6, r6, r9, lsr
227 and r9, r6,
228 and r6, r6,
229 add r6, r6, r9, lsr
230 add r6, r6, r6, lsr
231 and r9, r8,
232 ldr r7, [r2, r9, lsr
233 and r6, r6,
234 sub r7, r7, r6, lsl
235 str r7, [r2, r9, lsr
236 ldr r9, [sp],
237 b do_DataAbort
238