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 | |
| 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>
| -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 |
