diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-06-26 11:01:26 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-07-02 05:56:11 -0400 |
commit | da7404725781bc7c736e10cae5521e5604e222a5 (patch) | |
tree | e816cd79e1b09ddcbd41b7cd5b3c6c9c9bd5eb98 /arch/arm/mm/abort-lv4t.S | |
parent | 0d147db0c127c561f8f9ead9f3c1ec38f89f1040 (diff) |
ARM: entry: data abort: tail-call the main data abort handler
Tail-call the main C data abort handler code from the per-CPU helper
code. Update the comments in the code wrt the new calling and return
register state.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mm/abort-lv4t.S')
-rw-r--r-- | arch/arm/mm/abort-lv4t.S | 43 |
1 files changed, 21 insertions, 22 deletions
diff --git a/arch/arm/mm/abort-lv4t.S b/arch/arm/mm/abort-lv4t.S index d032b1f2067b..d432f31cdab5 100644 --- a/arch/arm/mm/abort-lv4t.S +++ b/arch/arm/mm/abort-lv4t.S | |||
@@ -3,7 +3,8 @@ | |||
3 | /* | 3 | /* |
4 | * Function: v4t_late_abort | 4 | * Function: v4t_late_abort |
5 | * | 5 | * |
6 | * Params : r4 = aborted context pc | 6 | * Params : r2 = pt_regs |
7 | * : r4 = aborted context pc | ||
7 | * : r5 = aborted context psr | 8 | * : r5 = aborted context psr |
8 | * | 9 | * |
9 | * Returns : r0 = address of abort | 10 | * Returns : r0 = address of abort |
@@ -47,20 +48,18 @@ ENTRY(v4t_late_abort) | |||
47 | /* 9 */ b .data_arm_ldmstm @ ldm*b rn, <rlist> | 48 | /* 9 */ b .data_arm_ldmstm @ ldm*b rn, <rlist> |
48 | /* a */ b .data_unknown | 49 | /* a */ b .data_unknown |
49 | /* b */ b .data_unknown | 50 | /* b */ b .data_unknown |
50 | /* c */ mov pc, lr @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m | 51 | /* c */ b do_DataAbort @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m |
51 | /* d */ mov pc, lr @ ldc rd, [rn, #m] | 52 | /* d */ b do_DataAbort @ ldc rd, [rn, #m] |
52 | /* e */ b .data_unknown | 53 | /* e */ b .data_unknown |
53 | /* f */ | 54 | /* f */ |
54 | .data_unknown: @ Part of jumptable | 55 | .data_unknown: @ Part of jumptable |
55 | mov r0, r4 | 56 | mov r0, r4 |
56 | mov r1, r8 | 57 | mov r1, r8 |
57 | mov r2, sp | 58 | b baddataabort |
58 | bl baddataabort | ||
59 | b ret_from_exception | ||
60 | 59 | ||
61 | .data_arm_ldmstm: | 60 | .data_arm_ldmstm: |
62 | tst r8, #1 << 21 @ check writeback bit | 61 | tst r8, #1 << 21 @ check writeback bit |
63 | moveq pc, lr @ no writeback -> no fixup | 62 | beq do_DataAbort @ no writeback -> no fixup |
64 | mov r7, #0x11 | 63 | mov r7, #0x11 |
65 | orr r7, r7, #0x1100 | 64 | orr r7, r7, #0x1100 |
66 | and r6, r8, r7 | 65 | and r6, r8, r7 |
@@ -79,11 +78,11 @@ ENTRY(v4t_late_abort) | |||
79 | subne r7, r7, r6, lsl #2 @ Undo increment | 78 | subne r7, r7, r6, lsl #2 @ Undo increment |
80 | addeq r7, r7, r6, lsl #2 @ Undo decrement | 79 | addeq r7, r7, r6, lsl #2 @ Undo decrement |
81 | str r7, [sp, r5, lsr #14] @ Put register 'Rn' | 80 | str r7, [sp, r5, lsr #14] @ Put register 'Rn' |
82 | mov pc, lr | 81 | b do_DataAbort |
83 | 82 | ||
84 | .data_arm_lateldrhpre: | 83 | .data_arm_lateldrhpre: |
85 | tst r8, #1 << 21 @ Check writeback bit | 84 | tst r8, #1 << 21 @ Check writeback bit |
86 | moveq pc, lr @ No writeback -> no fixup | 85 | beq do_DataAbort @ No writeback -> no fixup |
87 | .data_arm_lateldrhpost: | 86 | .data_arm_lateldrhpost: |
88 | and r5, r8, #0x00f @ get Rm / low nibble of immediate value | 87 | and r5, r8, #0x00f @ get Rm / low nibble of immediate value |
89 | tst r8, #1 << 22 @ if (immediate offset) | 88 | tst r8, #1 << 22 @ if (immediate offset) |
@@ -97,25 +96,25 @@ ENTRY(v4t_late_abort) | |||
97 | subne r7, r7, r6 @ Undo incrmenet | 96 | subne r7, r7, r6 @ Undo incrmenet |
98 | addeq r7, r7, r6 @ Undo decrement | 97 | addeq r7, r7, r6 @ Undo decrement |
99 | str r7, [sp, r5, lsr #14] @ Put register 'Rn' | 98 | str r7, [sp, r5, lsr #14] @ Put register 'Rn' |
100 | mov pc, lr | 99 | b do_DataAbort |
101 | 100 | ||
102 | .data_arm_lateldrpreconst: | 101 | .data_arm_lateldrpreconst: |
103 | tst r8, #1 << 21 @ check writeback bit | 102 | tst r8, #1 << 21 @ check writeback bit |
104 | moveq pc, lr @ no writeback -> no fixup | 103 | beq do_DataAbort @ no writeback -> no fixup |
105 | .data_arm_lateldrpostconst: | 104 | .data_arm_lateldrpostconst: |
106 | movs r9, r8, lsl #20 @ Get offset | 105 | movs r9, r8, lsl #20 @ Get offset |
107 | moveq pc, lr @ zero -> no fixup | 106 | beq do_DataAbort @ zero -> no fixup |
108 | and r5, r8, #15 << 16 @ Extract 'n' from instruction | 107 | and r5, r8, #15 << 16 @ Extract 'n' from instruction |
109 | ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' | 108 | ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' |
110 | tst r8, #1 << 23 @ Check U bit | 109 | tst r8, #1 << 23 @ Check U bit |
111 | subne r7, r7, r9, lsr #20 @ Undo increment | 110 | subne r7, r7, r9, lsr #20 @ Undo increment |
112 | addeq r7, r7, r9, lsr #20 @ Undo decrement | 111 | addeq r7, r7, r9, lsr #20 @ Undo decrement |
113 | str r7, [sp, r5, lsr #14] @ Put register 'Rn' | 112 | str r7, [sp, r5, lsr #14] @ Put register 'Rn' |
114 | mov pc, lr | 113 | b do_DataAbort |
115 | 114 | ||
116 | .data_arm_lateldrprereg: | 115 | .data_arm_lateldrprereg: |
117 | tst r8, #1 << 21 @ check writeback bit | 116 | tst r8, #1 << 21 @ check writeback bit |
118 | moveq pc, lr @ no writeback -> no fixup | 117 | beq do_DataAbort @ no writeback -> no fixup |
119 | .data_arm_lateldrpostreg: | 118 | .data_arm_lateldrpostreg: |
120 | and r7, r8, #15 @ Extract 'm' from instruction | 119 | and r7, r8, #15 @ Extract 'm' from instruction |
121 | ldr r6, [sp, r7, lsl #2] @ Get register 'Rm' | 120 | ldr r6, [sp, r7, lsl #2] @ Get register 'Rm' |
@@ -172,10 +171,10 @@ ENTRY(v4t_late_abort) | |||
172 | /* 3 */ b .data_unknown | 171 | /* 3 */ b .data_unknown |
173 | /* 4 */ b .data_unknown | 172 | /* 4 */ b .data_unknown |
174 | /* 5 */ b .data_thumb_reg | 173 | /* 5 */ b .data_thumb_reg |
175 | /* 6 */ mov pc, lr | 174 | /* 6 */ b do_DataAbort |
176 | /* 7 */ mov pc, lr | 175 | /* 7 */ b do_DataAbort |
177 | /* 8 */ mov pc, lr | 176 | /* 8 */ b do_DataAbort |
178 | /* 9 */ mov pc, lr | 177 | /* 9 */ b do_DataAbort |
179 | /* A */ b .data_unknown | 178 | /* A */ b .data_unknown |
180 | /* B */ b .data_thumb_pushpop | 179 | /* B */ b .data_thumb_pushpop |
181 | /* C */ b .data_thumb_ldmstm | 180 | /* C */ b .data_thumb_ldmstm |
@@ -185,10 +184,10 @@ ENTRY(v4t_late_abort) | |||
185 | 184 | ||
186 | .data_thumb_reg: | 185 | .data_thumb_reg: |
187 | tst r8, #1 << 9 | 186 | tst r8, #1 << 9 |
188 | moveq pc, lr | 187 | beq do_DataAbort |
189 | tst r8, #1 << 10 @ If 'S' (signed) bit is set | 188 | tst r8, #1 << 10 @ If 'S' (signed) bit is set |
190 | movne r1, #0 @ it must be a load instr | 189 | movne r1, #0 @ it must be a load instr |
191 | mov pc, lr | 190 | b do_DataAbort |
192 | 191 | ||
193 | .data_thumb_pushpop: | 192 | .data_thumb_pushpop: |
194 | tst r8, #1 << 10 | 193 | tst r8, #1 << 10 |
@@ -207,7 +206,7 @@ ENTRY(v4t_late_abort) | |||
207 | addeq r7, r7, r6, lsl #2 @ increment SP if PUSH | 206 | addeq r7, r7, r6, lsl #2 @ increment SP if PUSH |
208 | subne r7, r7, r6, lsl #2 @ decrement SP if POP | 207 | subne r7, r7, r6, lsl #2 @ decrement SP if POP |
209 | str r7, [sp, #13 << 2] | 208 | str r7, [sp, #13 << 2] |
210 | mov pc, lr | 209 | b do_DataAbort |
211 | 210 | ||
212 | .data_thumb_ldmstm: | 211 | .data_thumb_ldmstm: |
213 | and r6, r8, #0x55 @ hweight8(r8) | 212 | and r6, r8, #0x55 @ hweight8(r8) |
@@ -222,4 +221,4 @@ ENTRY(v4t_late_abort) | |||
222 | and r6, r6, #15 @ number of regs to transfer | 221 | and r6, r6, #15 @ number of regs to transfer |
223 | sub r7, r7, r6, lsl #2 @ always decrement | 222 | sub r7, r7, r6, lsl #2 @ always decrement |
224 | str r7, [sp, r5, lsr #6] | 223 | str r7, [sp, r5, lsr #6] |
225 | mov pc, lr | 224 | b do_DataAbort |