diff options
| -rw-r--r-- | arch/xtensa/kernel/entry.S | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index de1dfa18d0a1..21dbe6bdb8ed 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S | |||
| @@ -1122,7 +1122,7 @@ ENDPROC(fast_syscall_spill_registers) | |||
| 1122 | * a3: exctable, original value in excsave1 | 1122 | * a3: exctable, original value in excsave1 |
| 1123 | */ | 1123 | */ |
| 1124 | 1124 | ||
| 1125 | fast_syscall_spill_registers_fixup: | 1125 | ENTRY(fast_syscall_spill_registers_fixup) |
| 1126 | 1126 | ||
| 1127 | rsr a2, windowbase # get current windowbase (a2 is saved) | 1127 | rsr a2, windowbase # get current windowbase (a2 is saved) |
| 1128 | xsr a0, depc # restore depc and a0 | 1128 | xsr a0, depc # restore depc and a0 |
| @@ -1134,22 +1134,26 @@ fast_syscall_spill_registers_fixup: | |||
| 1134 | */ | 1134 | */ |
| 1135 | 1135 | ||
| 1136 | xsr a3, excsave1 # get spill-mask | 1136 | xsr a3, excsave1 # get spill-mask |
| 1137 | slli a2, a3, 1 # shift left by one | 1137 | slli a3, a3, 1 # shift left by one |
| 1138 | 1138 | ||
| 1139 | slli a3, a2, 32-WSBITS | 1139 | slli a2, a3, 32-WSBITS |
| 1140 | src a2, a2, a3 # a1 = xxwww1yyxxxwww1yy...... | 1140 | src a2, a3, a2 # a2 = xxwww1yyxxxwww1yy...... |
| 1141 | wsr a2, windowstart # set corrected windowstart | 1141 | wsr a2, windowstart # set corrected windowstart |
| 1142 | 1142 | ||
| 1143 | rsr a3, excsave1 | 1143 | srli a3, a3, 1 |
| 1144 | l32i a2, a3, EXC_TABLE_DOUBLE_SAVE # restore a2 | 1144 | rsr a2, excsave1 |
| 1145 | l32i a3, a3, EXC_TABLE_PARAM # original WB (in user task) | 1145 | l32i a2, a2, EXC_TABLE_DOUBLE_SAVE # restore a2 |
| 1146 | xsr a2, excsave1 | ||
| 1147 | s32i a3, a2, EXC_TABLE_DOUBLE_SAVE # save a3 | ||
| 1148 | l32i a3, a2, EXC_TABLE_PARAM # original WB (in user task) | ||
| 1149 | xsr a2, excsave1 | ||
| 1146 | 1150 | ||
| 1147 | /* Return to the original (user task) WINDOWBASE. | 1151 | /* Return to the original (user task) WINDOWBASE. |
| 1148 | * We leave the following frame behind: | 1152 | * We leave the following frame behind: |
| 1149 | * a0, a1, a2 same | 1153 | * a0, a1, a2 same |
| 1150 | * a3: trashed (saved in excsave_1) | 1154 | * a3: trashed (saved in EXC_TABLE_DOUBLE_SAVE) |
| 1151 | * depc: depc (we have to return to that address) | 1155 | * depc: depc (we have to return to that address) |
| 1152 | * excsave_1: a3 | 1156 | * excsave_1: exctable |
| 1153 | */ | 1157 | */ |
| 1154 | 1158 | ||
| 1155 | wsr a3, windowbase | 1159 | wsr a3, windowbase |
| @@ -1159,9 +1163,9 @@ fast_syscall_spill_registers_fixup: | |||
| 1159 | * a0: return address | 1163 | * a0: return address |
| 1160 | * a1: used, stack pointer | 1164 | * a1: used, stack pointer |
| 1161 | * a2: kernel stack pointer | 1165 | * a2: kernel stack pointer |
| 1162 | * a3: available, saved in EXCSAVE_1 | 1166 | * a3: available |
| 1163 | * depc: exception address | 1167 | * depc: exception address |
| 1164 | * excsave: a3 | 1168 | * excsave: exctable |
| 1165 | * Note: This frame might be the same as above. | 1169 | * Note: This frame might be the same as above. |
| 1166 | */ | 1170 | */ |
| 1167 | 1171 | ||
| @@ -1181,9 +1185,12 @@ fast_syscall_spill_registers_fixup: | |||
| 1181 | rsr a0, exccause | 1185 | rsr a0, exccause |
| 1182 | addx4 a0, a0, a3 # find entry in table | 1186 | addx4 a0, a0, a3 # find entry in table |
| 1183 | l32i a0, a0, EXC_TABLE_FAST_USER # load handler | 1187 | l32i a0, a0, EXC_TABLE_FAST_USER # load handler |
| 1188 | l32i a3, a3, EXC_TABLE_DOUBLE_SAVE | ||
| 1184 | jx a0 | 1189 | jx a0 |
| 1185 | 1190 | ||
| 1186 | fast_syscall_spill_registers_fixup_return: | 1191 | ENDPROC(fast_syscall_spill_registers_fixup) |
| 1192 | |||
| 1193 | ENTRY(fast_syscall_spill_registers_fixup_return) | ||
| 1187 | 1194 | ||
| 1188 | /* When we return here, all registers have been restored (a2: DEPC) */ | 1195 | /* When we return here, all registers have been restored (a2: DEPC) */ |
| 1189 | 1196 | ||
| @@ -1191,13 +1198,13 @@ fast_syscall_spill_registers_fixup_return: | |||
| 1191 | 1198 | ||
| 1192 | /* Restore fixup handler. */ | 1199 | /* Restore fixup handler. */ |
| 1193 | 1200 | ||
| 1194 | xsr a3, excsave1 | 1201 | rsr a2, excsave1 |
| 1195 | movi a2, fast_syscall_spill_registers_fixup | 1202 | s32i a3, a2, EXC_TABLE_DOUBLE_SAVE |
| 1196 | s32i a2, a3, EXC_TABLE_FIXUP | 1203 | movi a3, fast_syscall_spill_registers_fixup |
| 1197 | s32i a0, a3, EXC_TABLE_DOUBLE_SAVE | 1204 | s32i a3, a2, EXC_TABLE_FIXUP |
| 1198 | rsr a2, windowbase | 1205 | rsr a3, windowbase |
| 1199 | s32i a2, a3, EXC_TABLE_PARAM | 1206 | s32i a3, a2, EXC_TABLE_PARAM |
| 1200 | l32i a2, a3, EXC_TABLE_KSTK | 1207 | l32i a2, a2, EXC_TABLE_KSTK |
| 1201 | 1208 | ||
| 1202 | /* Load WB at the time the exception occurred. */ | 1209 | /* Load WB at the time the exception occurred. */ |
| 1203 | 1210 | ||
| @@ -1206,8 +1213,12 @@ fast_syscall_spill_registers_fixup_return: | |||
| 1206 | wsr a3, windowbase | 1213 | wsr a3, windowbase |
| 1207 | rsync | 1214 | rsync |
| 1208 | 1215 | ||
| 1216 | rsr a3, excsave1 | ||
| 1217 | l32i a3, a3, EXC_TABLE_DOUBLE_SAVE | ||
| 1218 | |||
| 1209 | rfde | 1219 | rfde |
| 1210 | 1220 | ||
| 1221 | ENDPROC(fast_syscall_spill_registers_fixup_return) | ||
| 1211 | 1222 | ||
| 1212 | /* | 1223 | /* |
| 1213 | * spill all registers. | 1224 | * spill all registers. |
