diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-06-27 07:27:47 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-07-02 05:56:12 -0400 |
commit | 40f0b90a2f16f433f9afbfef4b7c312efb54e933 (patch) | |
tree | 70f9ba82308817eabc79f915babd33862d716506 /arch | |
parent | 108f6af0a82cf3b61f3ac6728e2241805a935b64 (diff) |
ARM: entry: data abort: ensure r5 is preserved by abort functions
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mm/abort-lv4t.S | 48 | ||||
-rw-r--r-- | arch/arm/mm/proc-arm6_7.S | 33 |
2 files changed, 38 insertions, 43 deletions
diff --git a/arch/arm/mm/abort-lv4t.S b/arch/arm/mm/abort-lv4t.S index 54b6d279371a..f3982580c273 100644 --- a/arch/arm/mm/abort-lv4t.S +++ b/arch/arm/mm/abort-lv4t.S | |||
@@ -7,11 +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 : r0 = address of abort | 10 | * Returns : r4-r5, r10-r11, r13 preserved |
11 | * : r1 = FSR, bit 11 = write | ||
12 | * : r2-r8 = corrupted | ||
13 | * : r9 = preserved | ||
14 | * : sp = pointer to registers | ||
15 | * | 11 | * |
16 | * Purpose : obtain information about current aborted instruction. | 12 | * Purpose : obtain information about current aborted instruction. |
17 | * 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 |
@@ -72,30 +68,30 @@ ENTRY(v4t_late_abort) | |||
72 | add r6, r6, r6, lsr #8 | 68 | add r6, r6, r6, lsr #8 |
73 | add r6, r6, r6, lsr #4 | 69 | add r6, r6, r6, lsr #4 |
74 | and r6, r6, #15 @ r6 = no. of registers to transfer. | 70 | and r6, r6, #15 @ r6 = no. of registers to transfer. |
75 | and r5, r8, #15 << 16 @ Extract 'n' from instruction | 71 | and r9, r8, #15 << 16 @ Extract 'n' from instruction |
76 | ldr r7, [r2, r5, lsr #14] @ Get register 'Rn' | 72 | ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' |
77 | tst r8, #1 << 23 @ Check U bit | 73 | tst r8, #1 << 23 @ Check U bit |
78 | subne r7, r7, r6, lsl #2 @ Undo increment | 74 | subne r7, r7, r6, lsl #2 @ Undo increment |
79 | addeq r7, r7, r6, lsl #2 @ Undo decrement | 75 | addeq r7, r7, r6, lsl #2 @ Undo decrement |
80 | str r7, [r2, r5, lsr #14] @ Put register 'Rn' | 76 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' |
81 | b do_DataAbort | 77 | b do_DataAbort |
82 | 78 | ||
83 | .data_arm_lateldrhpre: | 79 | .data_arm_lateldrhpre: |
84 | tst r8, #1 << 21 @ Check writeback bit | 80 | tst r8, #1 << 21 @ Check writeback bit |
85 | beq do_DataAbort @ No writeback -> no fixup | 81 | beq do_DataAbort @ No writeback -> no fixup |
86 | .data_arm_lateldrhpost: | 82 | .data_arm_lateldrhpost: |
87 | and r5, r8, #0x00f @ get Rm / low nibble of immediate value | 83 | and r9, r8, #0x00f @ get Rm / low nibble of immediate value |
88 | tst r8, #1 << 22 @ if (immediate offset) | 84 | tst r8, #1 << 22 @ if (immediate offset) |
89 | andne r6, r8, #0xf00 @ { immediate high nibble | 85 | andne r6, r8, #0xf00 @ { immediate high nibble |
90 | orrne r6, r5, r6, lsr #4 @ combine nibbles } else | 86 | orrne r6, r9, r6, lsr #4 @ combine nibbles } else |
91 | ldreq r6, [r2, r5, lsl #2] @ { load Rm value } | 87 | ldreq r6, [r2, r9, lsl #2] @ { load Rm value } |
92 | .data_arm_apply_r6_and_rn: | 88 | .data_arm_apply_r6_and_rn: |
93 | and r5, r8, #15 << 16 @ Extract 'n' from instruction | 89 | and r9, r8, #15 << 16 @ Extract 'n' from instruction |
94 | ldr r7, [r2, r5, lsr #14] @ Get register 'Rn' | 90 | ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' |
95 | tst r8, #1 << 23 @ Check U bit | 91 | tst r8, #1 << 23 @ Check U bit |
96 | subne r7, r7, r6 @ Undo incrmenet | 92 | subne r7, r7, r6 @ Undo incrmenet |
97 | addeq r7, r7, r6 @ Undo decrement | 93 | addeq r7, r7, r6 @ Undo decrement |
98 | str r7, [r2, r5, lsr #14] @ Put register 'Rn' | 94 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' |
99 | b do_DataAbort | 95 | b do_DataAbort |
100 | 96 | ||
101 | .data_arm_lateldrpreconst: | 97 | .data_arm_lateldrpreconst: |
@@ -104,12 +100,12 @@ ENTRY(v4t_late_abort) | |||
104 | .data_arm_lateldrpostconst: | 100 | .data_arm_lateldrpostconst: |
105 | movs r6, r8, lsl #20 @ Get offset | 101 | movs r6, r8, lsl #20 @ Get offset |
106 | beq do_DataAbort @ zero -> no fixup | 102 | beq do_DataAbort @ zero -> no fixup |
107 | and r5, r8, #15 << 16 @ Extract 'n' from instruction | 103 | and r9, r8, #15 << 16 @ Extract 'n' from instruction |
108 | ldr r7, [r2, r5, lsr #14] @ Get register 'Rn' | 104 | ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' |
109 | tst r8, #1 << 23 @ Check U bit | 105 | tst r8, #1 << 23 @ Check U bit |
110 | subne r7, r7, r6, lsr #20 @ Undo increment | 106 | subne r7, r7, r6, lsr #20 @ Undo increment |
111 | addeq r7, r7, r6, lsr #20 @ Undo decrement | 107 | addeq r7, r7, r6, lsr #20 @ Undo decrement |
112 | str r7, [r2, r5, lsr #14] @ Put register 'Rn' | 108 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' |
113 | b do_DataAbort | 109 | b do_DataAbort |
114 | 110 | ||
115 | .data_arm_lateldrprereg: | 111 | .data_arm_lateldrprereg: |
@@ -118,14 +114,14 @@ ENTRY(v4t_late_abort) | |||
118 | .data_arm_lateldrpostreg: | 114 | .data_arm_lateldrpostreg: |
119 | and r7, r8, #15 @ Extract 'm' from instruction | 115 | and r7, r8, #15 @ Extract 'm' from instruction |
120 | ldr r6, [r2, r7, lsl #2] @ Get register 'Rm' | 116 | ldr r6, [r2, r7, lsl #2] @ Get register 'Rm' |
121 | mov r5, r8, lsr #7 @ get shift count | 117 | mov r9, r8, lsr #7 @ get shift count |
122 | ands r5, r5, #31 | 118 | ands r9, r9, #31 |
123 | and r7, r8, #0x70 @ get shift type | 119 | and r7, r8, #0x70 @ get shift type |
124 | orreq r7, r7, #8 @ shift count = 0 | 120 | orreq r7, r7, #8 @ shift count = 0 |
125 | add pc, pc, r7 | 121 | add pc, pc, r7 |
126 | nop | 122 | nop |
127 | 123 | ||
128 | mov r6, r6, lsl r5 @ 0: LSL #!0 | 124 | mov r6, r6, lsl r9 @ 0: LSL #!0 |
129 | b .data_arm_apply_r6_and_rn | 125 | b .data_arm_apply_r6_and_rn |
130 | b .data_arm_apply_r6_and_rn @ 1: LSL #0 | 126 | b .data_arm_apply_r6_and_rn @ 1: LSL #0 |
131 | nop | 127 | nop |
@@ -133,7 +129,7 @@ ENTRY(v4t_late_abort) | |||
133 | nop | 129 | nop |
134 | b .data_unknown @ 3: MUL? | 130 | b .data_unknown @ 3: MUL? |
135 | nop | 131 | nop |
136 | mov r6, r6, lsr r5 @ 4: LSR #!0 | 132 | mov r6, r6, lsr r9 @ 4: LSR #!0 |
137 | b .data_arm_apply_r6_and_rn | 133 | b .data_arm_apply_r6_and_rn |
138 | mov r6, r6, lsr #32 @ 5: LSR #32 | 134 | mov r6, r6, lsr #32 @ 5: LSR #32 |
139 | b .data_arm_apply_r6_and_rn | 135 | b .data_arm_apply_r6_and_rn |
@@ -141,7 +137,7 @@ ENTRY(v4t_late_abort) | |||
141 | nop | 137 | nop |
142 | b .data_unknown @ 7: MUL? | 138 | b .data_unknown @ 7: MUL? |
143 | nop | 139 | nop |
144 | mov r6, r6, asr r5 @ 8: ASR #!0 | 140 | mov r6, r6, asr r9 @ 8: ASR #!0 |
145 | b .data_arm_apply_r6_and_rn | 141 | b .data_arm_apply_r6_and_rn |
146 | mov r6, r6, asr #32 @ 9: ASR #32 | 142 | mov r6, r6, asr #32 @ 9: ASR #32 |
147 | b .data_arm_apply_r6_and_rn | 143 | b .data_arm_apply_r6_and_rn |
@@ -149,7 +145,7 @@ ENTRY(v4t_late_abort) | |||
149 | nop | 145 | nop |
150 | b .data_unknown @ B: MUL? | 146 | b .data_unknown @ B: MUL? |
151 | nop | 147 | nop |
152 | mov r6, r6, ror r5 @ C: ROR #!0 | 148 | mov r6, r6, ror r9 @ C: ROR #!0 |
153 | b .data_arm_apply_r6_and_rn | 149 | b .data_arm_apply_r6_and_rn |
154 | mov r6, r6, rrx @ D: RRX | 150 | mov r6, r6, rrx @ D: RRX |
155 | b .data_arm_apply_r6_and_rn | 151 | b .data_arm_apply_r6_and_rn |
@@ -216,9 +212,9 @@ ENTRY(v4t_late_abort) | |||
216 | and r6, r6, #0x33 | 212 | and r6, r6, #0x33 |
217 | add r6, r6, r9, lsr #2 | 213 | add r6, r6, r9, lsr #2 |
218 | add r6, r6, r6, lsr #4 | 214 | add r6, r6, r6, lsr #4 |
219 | and r5, r8, #7 << 8 | 215 | and r9, r8, #7 << 8 |
220 | ldr r7, [r2, r5, lsr #6] | 216 | ldr r7, [r2, r9, lsr #6] |
221 | and r6, r6, #15 @ number of regs to transfer | 217 | and r6, r6, #15 @ number of regs to transfer |
222 | sub r7, r7, r6, lsl #2 @ always decrement | 218 | sub r7, r7, r6, lsl #2 @ always decrement |
223 | str r7, [r2, r5, lsr #6] | 219 | str r7, [r2, r9, lsr #6] |
224 | b do_DataAbort | 220 | b do_DataAbort |
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S index 4d963114c66b..50e3543d03bf 100644 --- a/arch/arm/mm/proc-arm6_7.S +++ b/arch/arm/mm/proc-arm6_7.S | |||
@@ -35,8 +35,7 @@ ENTRY(cpu_arm7_dcache_clean_area) | |||
35 | * | 35 | * |
36 | * Purpose : obtain information about current aborted instruction | 36 | * Purpose : obtain information about current aborted instruction |
37 | * | 37 | * |
38 | * Returns : r0 = address of abort | 38 | * Returns : r4-r5, r10-r11, r13 preserved |
39 | * : r1 = FSR | ||
40 | */ | 39 | */ |
41 | 40 | ||
42 | ENTRY(cpu_arm7_data_abort) | 41 | ENTRY(cpu_arm7_data_abort) |
@@ -95,21 +94,21 @@ ENTRY(cpu_arm6_data_abort) | |||
95 | add r6, r6, r6, lsr #8 | 94 | add r6, r6, r6, lsr #8 |
96 | add r6, r6, r6, lsr #4 | 95 | add r6, r6, r6, lsr #4 |
97 | and r6, r6, #15 @ r6 = no. of registers to transfer. | 96 | and r6, r6, #15 @ r6 = no. of registers to transfer. |
98 | and r5, r8, #15 << 16 @ Extract 'n' from instruction | 97 | and r9, r8, #15 << 16 @ Extract 'n' from instruction |
99 | ldr r7, [r2, r5, lsr #14] @ Get register 'Rn' | 98 | ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' |
100 | tst r8, #1 << 23 @ Check U bit | 99 | tst r8, #1 << 23 @ Check U bit |
101 | subne r7, r7, r6, lsl #2 @ Undo increment | 100 | subne r7, r7, r6, lsl #2 @ Undo increment |
102 | addeq r7, r7, r6, lsl #2 @ Undo decrement | 101 | addeq r7, r7, r6, lsl #2 @ Undo decrement |
103 | str r7, [r2, r5, lsr #14] @ Put register 'Rn' | 102 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' |
104 | b do_DataAbort | 103 | b do_DataAbort |
105 | 104 | ||
106 | .data_arm_apply_r6_and_rn: | 105 | .data_arm_apply_r6_and_rn: |
107 | and r5, r8, #15 << 16 @ Extract 'n' from instruction | 106 | and r9, r8, #15 << 16 @ Extract 'n' from instruction |
108 | ldr r7, [r2, r5, lsr #14] @ Get register 'Rn' | 107 | ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' |
109 | tst r8, #1 << 23 @ Check U bit | 108 | tst r8, #1 << 23 @ Check U bit |
110 | subne r7, r7, r6 @ Undo incrmenet | 109 | subne r7, r7, r6 @ Undo incrmenet |
111 | addeq r7, r7, r6 @ Undo decrement | 110 | addeq r7, r7, r6 @ Undo decrement |
112 | str r7, [r2, r5, lsr #14] @ Put register 'Rn' | 111 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' |
113 | b do_DataAbort | 112 | b do_DataAbort |
114 | 113 | ||
115 | .data_arm_lateldrpreconst: | 114 | .data_arm_lateldrpreconst: |
@@ -118,12 +117,12 @@ ENTRY(cpu_arm6_data_abort) | |||
118 | .data_arm_lateldrpostconst: | 117 | .data_arm_lateldrpostconst: |
119 | movs r6, r8, lsl #20 @ Get offset | 118 | movs r6, r8, lsl #20 @ Get offset |
120 | beq do_DataAbort @ zero -> no fixup | 119 | beq do_DataAbort @ zero -> no fixup |
121 | and r5, r8, #15 << 16 @ Extract 'n' from instruction | 120 | and r9, r8, #15 << 16 @ Extract 'n' from instruction |
122 | ldr r7, [r2, r5, lsr #14] @ Get register 'Rn' | 121 | ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' |
123 | tst r8, #1 << 23 @ Check U bit | 122 | tst r8, #1 << 23 @ Check U bit |
124 | subne r7, r7, r6, lsr #20 @ Undo increment | 123 | subne r7, r7, r6, lsr #20 @ Undo increment |
125 | addeq r7, r7, r6, lsr #20 @ Undo decrement | 124 | addeq r7, r7, r6, lsr #20 @ Undo decrement |
126 | str r7, [r2, r5, lsr #14] @ Put register 'Rn' | 125 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' |
127 | b do_DataAbort | 126 | b do_DataAbort |
128 | 127 | ||
129 | .data_arm_lateldrprereg: | 128 | .data_arm_lateldrprereg: |
@@ -132,14 +131,14 @@ ENTRY(cpu_arm6_data_abort) | |||
132 | .data_arm_lateldrpostreg: | 131 | .data_arm_lateldrpostreg: |
133 | and r7, r8, #15 @ Extract 'm' from instruction | 132 | and r7, r8, #15 @ Extract 'm' from instruction |
134 | ldr r6, [r2, r7, lsl #2] @ Get register 'Rm' | 133 | ldr r6, [r2, r7, lsl #2] @ Get register 'Rm' |
135 | mov r5, r8, lsr #7 @ get shift count | 134 | mov r9, r8, lsr #7 @ get shift count |
136 | ands r5, r5, #31 | 135 | ands r9, r9, #31 |
137 | and r7, r8, #0x70 @ get shift type | 136 | and r7, r8, #0x70 @ get shift type |
138 | orreq r7, r7, #8 @ shift count = 0 | 137 | orreq r7, r7, #8 @ shift count = 0 |
139 | add pc, pc, r7 | 138 | add pc, pc, r7 |
140 | nop | 139 | nop |
141 | 140 | ||
142 | mov r6, r6, lsl r5 @ 0: LSL #!0 | 141 | mov r6, r6, lsl r9 @ 0: LSL #!0 |
143 | b .data_arm_apply_r6_and_rn | 142 | b .data_arm_apply_r6_and_rn |
144 | b .data_arm_apply_r6_and_rn @ 1: LSL #0 | 143 | b .data_arm_apply_r6_and_rn @ 1: LSL #0 |
145 | nop | 144 | nop |
@@ -147,7 +146,7 @@ ENTRY(cpu_arm6_data_abort) | |||
147 | nop | 146 | nop |
148 | b .data_unknown @ 3: MUL? | 147 | b .data_unknown @ 3: MUL? |
149 | nop | 148 | nop |
150 | mov r6, r6, lsr r5 @ 4: LSR #!0 | 149 | mov r6, r6, lsr r9 @ 4: LSR #!0 |
151 | b .data_arm_apply_r6_and_rn | 150 | b .data_arm_apply_r6_and_rn |
152 | mov r6, r6, lsr #32 @ 5: LSR #32 | 151 | mov r6, r6, lsr #32 @ 5: LSR #32 |
153 | b .data_arm_apply_r6_and_rn | 152 | b .data_arm_apply_r6_and_rn |
@@ -155,7 +154,7 @@ ENTRY(cpu_arm6_data_abort) | |||
155 | nop | 154 | nop |
156 | b .data_unknown @ 7: MUL? | 155 | b .data_unknown @ 7: MUL? |
157 | nop | 156 | nop |
158 | mov r6, r6, asr r5 @ 8: ASR #!0 | 157 | mov r6, r6, asr r9 @ 8: ASR #!0 |
159 | b .data_arm_apply_r6_and_rn | 158 | b .data_arm_apply_r6_and_rn |
160 | mov r6, r6, asr #32 @ 9: ASR #32 | 159 | mov r6, r6, asr #32 @ 9: ASR #32 |
161 | b .data_arm_apply_r6_and_rn | 160 | b .data_arm_apply_r6_and_rn |
@@ -163,7 +162,7 @@ ENTRY(cpu_arm6_data_abort) | |||
163 | nop | 162 | nop |
164 | b .data_unknown @ B: MUL? | 163 | b .data_unknown @ B: MUL? |
165 | nop | 164 | nop |
166 | mov r6, r6, ror r5 @ C: ROR #!0 | 165 | mov r6, r6, ror r9 @ C: ROR #!0 |
167 | b .data_arm_apply_r6_and_rn | 166 | b .data_arm_apply_r6_and_rn |
168 | mov r6, r6, rrx @ D: RRX | 167 | mov r6, r6, rrx @ D: RRX |
169 | b .data_arm_apply_r6_and_rn | 168 | b .data_arm_apply_r6_and_rn |