diff options
Diffstat (limited to 'arch/arm/mm/proc-arm6_7.S')
-rw-r--r-- | arch/arm/mm/proc-arm6_7.S | 90 |
1 files changed, 44 insertions, 46 deletions
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S index 5f79dc4ce3f..50e3543d03b 100644 --- a/arch/arm/mm/proc-arm6_7.S +++ b/arch/arm/mm/proc-arm6_7.S | |||
@@ -29,19 +29,19 @@ ENTRY(cpu_arm7_dcache_clean_area) | |||
29 | /* | 29 | /* |
30 | * Function: arm6_7_data_abort () | 30 | * Function: arm6_7_data_abort () |
31 | * | 31 | * |
32 | * Params : r2 = address of aborted instruction | 32 | * Params : r2 = pt_regs |
33 | * : sp = pointer to registers | 33 | * : r4 = aborted context pc |
34 | * : r5 = aborted context psr | ||
34 | * | 35 | * |
35 | * Purpose : obtain information about current aborted instruction | 36 | * Purpose : obtain information about current aborted instruction |
36 | * | 37 | * |
37 | * Returns : r0 = address of abort | 38 | * Returns : r4-r5, r10-r11, r13 preserved |
38 | * : r1 = FSR | ||
39 | */ | 39 | */ |
40 | 40 | ||
41 | ENTRY(cpu_arm7_data_abort) | 41 | ENTRY(cpu_arm7_data_abort) |
42 | mrc p15, 0, r1, c5, c0, 0 @ get FSR | 42 | mrc p15, 0, r1, c5, c0, 0 @ get FSR |
43 | mrc p15, 0, r0, c6, c0, 0 @ get FAR | 43 | mrc p15, 0, r0, c6, c0, 0 @ get FAR |
44 | ldr r8, [r2] @ read arm instruction | 44 | ldr r8, [r4] @ read arm instruction |
45 | tst r8, #1 << 20 @ L = 0 -> write? | 45 | tst r8, #1 << 20 @ L = 0 -> write? |
46 | orreq r1, r1, #1 << 11 @ yes. | 46 | orreq r1, r1, #1 << 11 @ yes. |
47 | and r7, r8, #15 << 24 | 47 | and r7, r8, #15 << 24 |
@@ -49,7 +49,7 @@ ENTRY(cpu_arm7_data_abort) | |||
49 | nop | 49 | nop |
50 | 50 | ||
51 | /* 0 */ b .data_unknown | 51 | /* 0 */ b .data_unknown |
52 | /* 1 */ mov pc, lr @ swp | 52 | /* 1 */ b do_DataAbort @ swp |
53 | /* 2 */ b .data_unknown | 53 | /* 2 */ b .data_unknown |
54 | /* 3 */ b .data_unknown | 54 | /* 3 */ b .data_unknown |
55 | /* 4 */ b .data_arm_lateldrpostconst @ ldr rd, [rn], #m | 55 | /* 4 */ b .data_arm_lateldrpostconst @ ldr rd, [rn], #m |
@@ -60,87 +60,85 @@ ENTRY(cpu_arm7_data_abort) | |||
60 | /* 9 */ b .data_arm_ldmstm @ ldm*b rn, <rlist> | 60 | /* 9 */ b .data_arm_ldmstm @ ldm*b rn, <rlist> |
61 | /* a */ b .data_unknown | 61 | /* a */ b .data_unknown |
62 | /* b */ b .data_unknown | 62 | /* b */ b .data_unknown |
63 | /* c */ mov pc, lr @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m | 63 | /* c */ b do_DataAbort @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m |
64 | /* d */ mov pc, lr @ ldc rd, [rn, #m] | 64 | /* d */ b do_DataAbort @ ldc rd, [rn, #m] |
65 | /* e */ b .data_unknown | 65 | /* e */ b .data_unknown |
66 | /* f */ | 66 | /* f */ |
67 | .data_unknown: @ Part of jumptable | 67 | .data_unknown: @ Part of jumptable |
68 | mov r0, r2 | 68 | mov r0, r4 |
69 | mov r1, r8 | 69 | mov r1, r8 |
70 | mov r2, sp | 70 | b baddataabort |
71 | bl baddataabort | ||
72 | b ret_from_exception | ||
73 | 71 | ||
74 | ENTRY(cpu_arm6_data_abort) | 72 | ENTRY(cpu_arm6_data_abort) |
75 | mrc p15, 0, r1, c5, c0, 0 @ get FSR | 73 | mrc p15, 0, r1, c5, c0, 0 @ get FSR |
76 | mrc p15, 0, r0, c6, c0, 0 @ get FAR | 74 | mrc p15, 0, r0, c6, c0, 0 @ get FAR |
77 | ldr r8, [r2] @ read arm instruction | 75 | ldr r8, [r4] @ read arm instruction |
78 | tst r8, #1 << 20 @ L = 0 -> write? | 76 | tst r8, #1 << 20 @ L = 0 -> write? |
79 | orreq r1, r1, #1 << 11 @ yes. | 77 | orreq r1, r1, #1 << 11 @ yes. |
80 | and r7, r8, #14 << 24 | 78 | and r7, r8, #14 << 24 |
81 | teq r7, #8 << 24 @ was it ldm/stm | 79 | teq r7, #8 << 24 @ was it ldm/stm |
82 | movne pc, lr | 80 | bne do_DataAbort |
83 | 81 | ||
84 | .data_arm_ldmstm: | 82 | .data_arm_ldmstm: |
85 | tst r8, #1 << 21 @ check writeback bit | 83 | tst r8, #1 << 21 @ check writeback bit |
86 | moveq pc, lr @ no writeback -> no fixup | 84 | beq do_DataAbort @ no writeback -> no fixup |
87 | mov r7, #0x11 | 85 | mov r7, #0x11 |
88 | orr r7, r7, #0x1100 | 86 | orr r7, r7, #0x1100 |
89 | and r6, r8, r7 | 87 | and r6, r8, r7 |
90 | and r2, r8, r7, lsl #1 | 88 | and r9, r8, r7, lsl #1 |
91 | add r6, r6, r2, lsr #1 | 89 | add r6, r6, r9, lsr #1 |
92 | and r2, r8, r7, lsl #2 | 90 | and r9, r8, r7, lsl #2 |
93 | add r6, r6, r2, lsr #2 | 91 | add r6, r6, r9, lsr #2 |
94 | and r2, r8, r7, lsl #3 | 92 | and r9, r8, r7, lsl #3 |
95 | add r6, r6, r2, lsr #3 | 93 | add r6, r6, r9, lsr #3 |
96 | add r6, r6, r6, lsr #8 | 94 | add r6, r6, r6, lsr #8 |
97 | add r6, r6, r6, lsr #4 | 95 | add r6, r6, r6, lsr #4 |
98 | and r6, r6, #15 @ r6 = no. of registers to transfer. | 96 | and r6, r6, #15 @ r6 = no. of registers to transfer. |
99 | and r5, r8, #15 << 16 @ Extract 'n' from instruction | 97 | and r9, r8, #15 << 16 @ Extract 'n' from instruction |
100 | ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' | 98 | ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' |
101 | tst r8, #1 << 23 @ Check U bit | 99 | tst r8, #1 << 23 @ Check U bit |
102 | subne r7, r7, r6, lsl #2 @ Undo increment | 100 | subne r7, r7, r6, lsl #2 @ Undo increment |
103 | addeq r7, r7, r6, lsl #2 @ Undo decrement | 101 | addeq r7, r7, r6, lsl #2 @ Undo decrement |
104 | str r7, [sp, r5, lsr #14] @ Put register 'Rn' | 102 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' |
105 | mov pc, lr | 103 | b do_DataAbort |
106 | 104 | ||
107 | .data_arm_apply_r6_and_rn: | 105 | .data_arm_apply_r6_and_rn: |
108 | and r5, r8, #15 << 16 @ Extract 'n' from instruction | 106 | and r9, r8, #15 << 16 @ Extract 'n' from instruction |
109 | ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' | 107 | ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' |
110 | tst r8, #1 << 23 @ Check U bit | 108 | tst r8, #1 << 23 @ Check U bit |
111 | subne r7, r7, r6 @ Undo incrmenet | 109 | subne r7, r7, r6 @ Undo incrmenet |
112 | addeq r7, r7, r6 @ Undo decrement | 110 | addeq r7, r7, r6 @ Undo decrement |
113 | str r7, [sp, r5, lsr #14] @ Put register 'Rn' | 111 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' |
114 | mov pc, lr | 112 | b do_DataAbort |
115 | 113 | ||
116 | .data_arm_lateldrpreconst: | 114 | .data_arm_lateldrpreconst: |
117 | tst r8, #1 << 21 @ check writeback bit | 115 | tst r8, #1 << 21 @ check writeback bit |
118 | moveq pc, lr @ no writeback -> no fixup | 116 | beq do_DataAbort @ no writeback -> no fixup |
119 | .data_arm_lateldrpostconst: | 117 | .data_arm_lateldrpostconst: |
120 | movs r2, r8, lsl #20 @ Get offset | 118 | movs r6, r8, lsl #20 @ Get offset |
121 | moveq pc, lr @ zero -> no fixup | 119 | beq do_DataAbort @ zero -> no fixup |
122 | and r5, r8, #15 << 16 @ Extract 'n' from instruction | 120 | and r9, r8, #15 << 16 @ Extract 'n' from instruction |
123 | ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' | 121 | ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' |
124 | tst r8, #1 << 23 @ Check U bit | 122 | tst r8, #1 << 23 @ Check U bit |
125 | subne r7, r7, r2, lsr #20 @ Undo increment | 123 | subne r7, r7, r6, lsr #20 @ Undo increment |
126 | addeq r7, r7, r2, lsr #20 @ Undo decrement | 124 | addeq r7, r7, r6, lsr #20 @ Undo decrement |
127 | str r7, [sp, r5, lsr #14] @ Put register 'Rn' | 125 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' |
128 | mov pc, lr | 126 | b do_DataAbort |
129 | 127 | ||
130 | .data_arm_lateldrprereg: | 128 | .data_arm_lateldrprereg: |
131 | tst r8, #1 << 21 @ check writeback bit | 129 | tst r8, #1 << 21 @ check writeback bit |
132 | moveq pc, lr @ no writeback -> no fixup | 130 | beq do_DataAbort @ no writeback -> no fixup |
133 | .data_arm_lateldrpostreg: | 131 | .data_arm_lateldrpostreg: |
134 | and r7, r8, #15 @ Extract 'm' from instruction | 132 | and r7, r8, #15 @ Extract 'm' from instruction |
135 | ldr r6, [sp, r7, lsl #2] @ Get register 'Rm' | 133 | ldr r6, [r2, r7, lsl #2] @ Get register 'Rm' |
136 | mov r5, r8, lsr #7 @ get shift count | 134 | mov r9, r8, lsr #7 @ get shift count |
137 | ands r5, r5, #31 | 135 | ands r9, r9, #31 |
138 | and r7, r8, #0x70 @ get shift type | 136 | and r7, r8, #0x70 @ get shift type |
139 | orreq r7, r7, #8 @ shift count = 0 | 137 | orreq r7, r7, #8 @ shift count = 0 |
140 | add pc, pc, r7 | 138 | add pc, pc, r7 |
141 | nop | 139 | nop |
142 | 140 | ||
143 | mov r6, r6, lsl r5 @ 0: LSL #!0 | 141 | mov r6, r6, lsl r9 @ 0: LSL #!0 |
144 | b .data_arm_apply_r6_and_rn | 142 | b .data_arm_apply_r6_and_rn |
145 | b .data_arm_apply_r6_and_rn @ 1: LSL #0 | 143 | b .data_arm_apply_r6_and_rn @ 1: LSL #0 |
146 | nop | 144 | nop |
@@ -148,7 +146,7 @@ ENTRY(cpu_arm6_data_abort) | |||
148 | nop | 146 | nop |
149 | b .data_unknown @ 3: MUL? | 147 | b .data_unknown @ 3: MUL? |
150 | nop | 148 | nop |
151 | mov r6, r6, lsr r5 @ 4: LSR #!0 | 149 | mov r6, r6, lsr r9 @ 4: LSR #!0 |
152 | b .data_arm_apply_r6_and_rn | 150 | b .data_arm_apply_r6_and_rn |
153 | mov r6, r6, lsr #32 @ 5: LSR #32 | 151 | mov r6, r6, lsr #32 @ 5: LSR #32 |
154 | b .data_arm_apply_r6_and_rn | 152 | b .data_arm_apply_r6_and_rn |
@@ -156,7 +154,7 @@ ENTRY(cpu_arm6_data_abort) | |||
156 | nop | 154 | nop |
157 | b .data_unknown @ 7: MUL? | 155 | b .data_unknown @ 7: MUL? |
158 | nop | 156 | nop |
159 | mov r6, r6, asr r5 @ 8: ASR #!0 | 157 | mov r6, r6, asr r9 @ 8: ASR #!0 |
160 | b .data_arm_apply_r6_and_rn | 158 | b .data_arm_apply_r6_and_rn |
161 | mov r6, r6, asr #32 @ 9: ASR #32 | 159 | mov r6, r6, asr #32 @ 9: ASR #32 |
162 | b .data_arm_apply_r6_and_rn | 160 | b .data_arm_apply_r6_and_rn |
@@ -164,7 +162,7 @@ ENTRY(cpu_arm6_data_abort) | |||
164 | nop | 162 | nop |
165 | b .data_unknown @ B: MUL? | 163 | b .data_unknown @ B: MUL? |
166 | nop | 164 | nop |
167 | mov r6, r6, ror r5 @ C: ROR #!0 | 165 | mov r6, r6, ror r9 @ C: ROR #!0 |
168 | b .data_arm_apply_r6_and_rn | 166 | b .data_arm_apply_r6_and_rn |
169 | mov r6, r6, rrx @ D: RRX | 167 | mov r6, r6, rrx @ D: RRX |
170 | b .data_arm_apply_r6_and_rn | 168 | b .data_arm_apply_r6_and_rn |