diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2010-10-14 16:23:03 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2010-10-15 15:38:09 -0400 |
commit | a78c942df64ef4cf495fd4d8715e48501bd7f8a4 (patch) | |
tree | fe44212d36e6ca23dbe9f2c633824389216a3d1d /arch/tile/kernel/intvec_32.S | |
parent | bf65e440e8248f22b2eacf8d47961bb9d52260f7 (diff) |
arch/tile: parameterize system PLs to support KVM port
While not a port to KVM (yet), this change modifies the kernel
to be able to build either at PL1 or at PL2 with a suitable
config switch. Pushing up this change avoids handling branch
merge issues going forward with the KVM work.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile/kernel/intvec_32.S')
-rw-r--r-- | arch/tile/kernel/intvec_32.S | 67 |
1 files changed, 36 insertions, 31 deletions
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S index f87c5c044d6b..206dc7e1fe36 100644 --- a/arch/tile/kernel/intvec_32.S +++ b/arch/tile/kernel/intvec_32.S | |||
@@ -32,8 +32,8 @@ | |||
32 | # error "No support for kernel preemption currently" | 32 | # error "No support for kernel preemption currently" |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | #if INT_INTCTRL_1 < 32 || INT_INTCTRL_1 >= 48 | 35 | #if INT_INTCTRL_K < 32 || INT_INTCTRL_K >= 48 |
36 | # error INT_INTCTRL_1 coded to set high interrupt mask | 36 | # error INT_INTCTRL_K coded to set high interrupt mask |
37 | #endif | 37 | #endif |
38 | 38 | ||
39 | #define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg) | 39 | #define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg) |
@@ -132,8 +132,8 @@ intvec_\vecname: | |||
132 | 132 | ||
133 | /* Temporarily save a register so we have somewhere to work. */ | 133 | /* Temporarily save a register so we have somewhere to work. */ |
134 | 134 | ||
135 | mtspr SYSTEM_SAVE_1_1, r0 | 135 | mtspr SPR_SYSTEM_SAVE_K_1, r0 |
136 | mfspr r0, EX_CONTEXT_1_1 | 136 | mfspr r0, SPR_EX_CONTEXT_K_1 |
137 | 137 | ||
138 | /* The cmpxchg code clears sp to force us to reset it here on fault. */ | 138 | /* The cmpxchg code clears sp to force us to reset it here on fault. */ |
139 | { | 139 | { |
@@ -167,18 +167,18 @@ intvec_\vecname: | |||
167 | * The page_fault handler may be downcalled directly by the | 167 | * The page_fault handler may be downcalled directly by the |
168 | * hypervisor even when Linux is running and has ICS set. | 168 | * hypervisor even when Linux is running and has ICS set. |
169 | * | 169 | * |
170 | * In this case the contents of EX_CONTEXT_1_1 reflect the | 170 | * In this case the contents of EX_CONTEXT_K_1 reflect the |
171 | * previous fault and can't be relied on to choose whether or | 171 | * previous fault and can't be relied on to choose whether or |
172 | * not to reinitialize the stack pointer. So we add a test | 172 | * not to reinitialize the stack pointer. So we add a test |
173 | * to see whether SYSTEM_SAVE_1_2 has the high bit set, | 173 | * to see whether SYSTEM_SAVE_K_2 has the high bit set, |
174 | * and if so we don't reinitialize sp, since we must be coming | 174 | * and if so we don't reinitialize sp, since we must be coming |
175 | * from Linux. (In fact the precise case is !(val & ~1), | 175 | * from Linux. (In fact the precise case is !(val & ~1), |
176 | * but any Linux PC has to have the high bit set.) | 176 | * but any Linux PC has to have the high bit set.) |
177 | * | 177 | * |
178 | * Note that the hypervisor *always* sets SYSTEM_SAVE_1_2 for | 178 | * Note that the hypervisor *always* sets SYSTEM_SAVE_K_2 for |
179 | * any path that turns into a downcall to one of our TLB handlers. | 179 | * any path that turns into a downcall to one of our TLB handlers. |
180 | */ | 180 | */ |
181 | mfspr r0, SYSTEM_SAVE_1_2 | 181 | mfspr r0, SPR_SYSTEM_SAVE_K_2 |
182 | { | 182 | { |
183 | blz r0, 0f /* high bit in S_S_1_2 is for a PC to use */ | 183 | blz r0, 0f /* high bit in S_S_1_2 is for a PC to use */ |
184 | move r0, sp | 184 | move r0, sp |
@@ -187,12 +187,12 @@ intvec_\vecname: | |||
187 | 187 | ||
188 | 2: | 188 | 2: |
189 | /* | 189 | /* |
190 | * SYSTEM_SAVE_1_0 holds the cpu number in the low bits, and | 190 | * SYSTEM_SAVE_K_0 holds the cpu number in the low bits, and |
191 | * the current stack top in the higher bits. So we recover | 191 | * the current stack top in the higher bits. So we recover |
192 | * our stack top by just masking off the low bits, then | 192 | * our stack top by just masking off the low bits, then |
193 | * point sp at the top aligned address on the actual stack page. | 193 | * point sp at the top aligned address on the actual stack page. |
194 | */ | 194 | */ |
195 | mfspr r0, SYSTEM_SAVE_1_0 | 195 | mfspr r0, SPR_SYSTEM_SAVE_K_0 |
196 | mm r0, r0, zero, LOG2_THREAD_SIZE, 31 | 196 | mm r0, r0, zero, LOG2_THREAD_SIZE, 31 |
197 | 197 | ||
198 | 0: | 198 | 0: |
@@ -254,7 +254,7 @@ intvec_\vecname: | |||
254 | sw sp, r3 | 254 | sw sp, r3 |
255 | addli sp, sp, PTREGS_OFFSET_PC - PTREGS_OFFSET_REG(3) | 255 | addli sp, sp, PTREGS_OFFSET_PC - PTREGS_OFFSET_REG(3) |
256 | } | 256 | } |
257 | mfspr r0, EX_CONTEXT_1_0 | 257 | mfspr r0, SPR_EX_CONTEXT_K_0 |
258 | .ifc \processing,handle_syscall | 258 | .ifc \processing,handle_syscall |
259 | /* | 259 | /* |
260 | * Bump the saved PC by one bundle so that when we return, we won't | 260 | * Bump the saved PC by one bundle so that when we return, we won't |
@@ -267,7 +267,7 @@ intvec_\vecname: | |||
267 | sw sp, r0 | 267 | sw sp, r0 |
268 | addli sp, sp, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC | 268 | addli sp, sp, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC |
269 | } | 269 | } |
270 | mfspr r0, EX_CONTEXT_1_1 | 270 | mfspr r0, SPR_EX_CONTEXT_K_1 |
271 | { | 271 | { |
272 | sw sp, r0 | 272 | sw sp, r0 |
273 | addi sp, sp, PTREGS_OFFSET_FAULTNUM - PTREGS_OFFSET_EX1 | 273 | addi sp, sp, PTREGS_OFFSET_FAULTNUM - PTREGS_OFFSET_EX1 |
@@ -289,7 +289,7 @@ intvec_\vecname: | |||
289 | .endif | 289 | .endif |
290 | addli sp, sp, PTREGS_OFFSET_REG(0) - PTREGS_OFFSET_FAULTNUM | 290 | addli sp, sp, PTREGS_OFFSET_REG(0) - PTREGS_OFFSET_FAULTNUM |
291 | } | 291 | } |
292 | mfspr r0, SYSTEM_SAVE_1_1 /* Original r0 */ | 292 | mfspr r0, SPR_SYSTEM_SAVE_K_1 /* Original r0 */ |
293 | { | 293 | { |
294 | sw sp, r0 | 294 | sw sp, r0 |
295 | addi sp, sp, -PTREGS_OFFSET_REG(0) - 4 | 295 | addi sp, sp, -PTREGS_OFFSET_REG(0) - 4 |
@@ -309,12 +309,12 @@ intvec_\vecname: | |||
309 | * See discussion below at "finish_interrupt_save". | 309 | * See discussion below at "finish_interrupt_save". |
310 | */ | 310 | */ |
311 | .ifc \c_routine, do_page_fault | 311 | .ifc \c_routine, do_page_fault |
312 | mfspr r2, SYSTEM_SAVE_1_3 /* address of page fault */ | 312 | mfspr r2, SPR_SYSTEM_SAVE_K_3 /* address of page fault */ |
313 | mfspr r3, SYSTEM_SAVE_1_2 /* info about page fault */ | 313 | mfspr r3, SPR_SYSTEM_SAVE_K_2 /* info about page fault */ |
314 | .else | 314 | .else |
315 | .ifc \vecnum, INT_DOUBLE_FAULT | 315 | .ifc \vecnum, INT_DOUBLE_FAULT |
316 | { | 316 | { |
317 | mfspr r2, SYSTEM_SAVE_1_2 /* double fault info from HV */ | 317 | mfspr r2, SPR_SYSTEM_SAVE_K_2 /* double fault info from HV */ |
318 | movei r3, 0 | 318 | movei r3, 0 |
319 | } | 319 | } |
320 | .else | 320 | .else |
@@ -467,7 +467,7 @@ intvec_\vecname: | |||
467 | /* Load tp with our per-cpu offset. */ | 467 | /* Load tp with our per-cpu offset. */ |
468 | #ifdef CONFIG_SMP | 468 | #ifdef CONFIG_SMP |
469 | { | 469 | { |
470 | mfspr r20, SYSTEM_SAVE_1_0 | 470 | mfspr r20, SPR_SYSTEM_SAVE_K_0 |
471 | moveli r21, lo16(__per_cpu_offset) | 471 | moveli r21, lo16(__per_cpu_offset) |
472 | } | 472 | } |
473 | { | 473 | { |
@@ -487,7 +487,7 @@ intvec_\vecname: | |||
487 | * We load flags in r32 here so we can jump to .Lrestore_regs | 487 | * We load flags in r32 here so we can jump to .Lrestore_regs |
488 | * directly after do_page_fault_ics() if necessary. | 488 | * directly after do_page_fault_ics() if necessary. |
489 | */ | 489 | */ |
490 | mfspr r32, EX_CONTEXT_1_1 | 490 | mfspr r32, SPR_EX_CONTEXT_K_1 |
491 | { | 491 | { |
492 | andi r32, r32, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ | 492 | andi r32, r32, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ |
493 | PTREGS_PTR(r21, PTREGS_OFFSET_FLAGS) | 493 | PTREGS_PTR(r21, PTREGS_OFFSET_FLAGS) |
@@ -957,11 +957,11 @@ STD_ENTRY(interrupt_return) | |||
957 | pop_reg_zero r21, r3, sp, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC | 957 | pop_reg_zero r21, r3, sp, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC |
958 | pop_reg_zero lr, r4, sp, PTREGS_OFFSET_REG(52) - PTREGS_OFFSET_EX1 | 958 | pop_reg_zero lr, r4, sp, PTREGS_OFFSET_REG(52) - PTREGS_OFFSET_EX1 |
959 | { | 959 | { |
960 | mtspr EX_CONTEXT_1_0, r21 | 960 | mtspr SPR_EX_CONTEXT_K_0, r21 |
961 | move r5, zero | 961 | move r5, zero |
962 | } | 962 | } |
963 | { | 963 | { |
964 | mtspr EX_CONTEXT_1_1, lr | 964 | mtspr SPR_EX_CONTEXT_K_1, lr |
965 | andi lr, lr, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ | 965 | andi lr, lr, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ |
966 | } | 966 | } |
967 | 967 | ||
@@ -1199,7 +1199,7 @@ STD_ENTRY(interrupt_return) | |||
1199 | STD_ENDPROC(interrupt_return) | 1199 | STD_ENDPROC(interrupt_return) |
1200 | 1200 | ||
1201 | /* | 1201 | /* |
1202 | * This interrupt variant clears the INT_INTCTRL_1 interrupt mask bit | 1202 | * This interrupt variant clears the INT_INTCTRL_K interrupt mask bit |
1203 | * before returning, so we can properly get more downcalls. | 1203 | * before returning, so we can properly get more downcalls. |
1204 | */ | 1204 | */ |
1205 | .pushsection .text.handle_interrupt_downcall,"ax" | 1205 | .pushsection .text.handle_interrupt_downcall,"ax" |
@@ -1208,11 +1208,11 @@ handle_interrupt_downcall: | |||
1208 | check_single_stepping normal, .Ldispatch_downcall | 1208 | check_single_stepping normal, .Ldispatch_downcall |
1209 | .Ldispatch_downcall: | 1209 | .Ldispatch_downcall: |
1210 | 1210 | ||
1211 | /* Clear INTCTRL_1 from the set of interrupts we ever enable. */ | 1211 | /* Clear INTCTRL_K from the set of interrupts we ever enable. */ |
1212 | GET_INTERRUPTS_ENABLED_MASK_PTR(r30) | 1212 | GET_INTERRUPTS_ENABLED_MASK_PTR(r30) |
1213 | { | 1213 | { |
1214 | addi r30, r30, 4 | 1214 | addi r30, r30, 4 |
1215 | movei r31, INT_MASK(INT_INTCTRL_1) | 1215 | movei r31, INT_MASK(INT_INTCTRL_K) |
1216 | } | 1216 | } |
1217 | { | 1217 | { |
1218 | lw r20, r30 | 1218 | lw r20, r30 |
@@ -1227,7 +1227,7 @@ handle_interrupt_downcall: | |||
1227 | } | 1227 | } |
1228 | FEEDBACK_REENTER(handle_interrupt_downcall) | 1228 | FEEDBACK_REENTER(handle_interrupt_downcall) |
1229 | 1229 | ||
1230 | /* Allow INTCTRL_1 to be enabled next time we enable interrupts. */ | 1230 | /* Allow INTCTRL_K to be enabled next time we enable interrupts. */ |
1231 | lw r20, r30 | 1231 | lw r20, r30 |
1232 | or r20, r20, r31 | 1232 | or r20, r20, r31 |
1233 | sw r30, r20 | 1233 | sw r30, r20 |
@@ -1509,7 +1509,7 @@ handle_ill: | |||
1509 | /* Various stub interrupt handlers and syscall handlers */ | 1509 | /* Various stub interrupt handlers and syscall handlers */ |
1510 | 1510 | ||
1511 | STD_ENTRY_LOCAL(_kernel_double_fault) | 1511 | STD_ENTRY_LOCAL(_kernel_double_fault) |
1512 | mfspr r1, EX_CONTEXT_1_0 | 1512 | mfspr r1, SPR_EX_CONTEXT_K_0 |
1513 | move r2, lr | 1513 | move r2, lr |
1514 | move r3, sp | 1514 | move r3, sp |
1515 | move r4, r52 | 1515 | move r4, r52 |
@@ -1518,7 +1518,7 @@ STD_ENTRY_LOCAL(_kernel_double_fault) | |||
1518 | STD_ENDPROC(_kernel_double_fault) | 1518 | STD_ENDPROC(_kernel_double_fault) |
1519 | 1519 | ||
1520 | STD_ENTRY_LOCAL(bad_intr) | 1520 | STD_ENTRY_LOCAL(bad_intr) |
1521 | mfspr r2, EX_CONTEXT_1_0 | 1521 | mfspr r2, SPR_EX_CONTEXT_K_0 |
1522 | panic "Unhandled interrupt %#x: PC %#lx" | 1522 | panic "Unhandled interrupt %#x: PC %#lx" |
1523 | STD_ENDPROC(bad_intr) | 1523 | STD_ENDPROC(bad_intr) |
1524 | 1524 | ||
@@ -1560,7 +1560,7 @@ STD_ENTRY(_sys_clone) | |||
1560 | * a page fault which would assume the stack was valid, it does | 1560 | * a page fault which would assume the stack was valid, it does |
1561 | * save/restore the stack pointer and zero it out to make sure it gets reset. | 1561 | * save/restore the stack pointer and zero it out to make sure it gets reset. |
1562 | * Since we always keep interrupts disabled, the hypervisor won't | 1562 | * Since we always keep interrupts disabled, the hypervisor won't |
1563 | * clobber our EX_CONTEXT_1_x registers, so we don't save/restore them | 1563 | * clobber our EX_CONTEXT_K_x registers, so we don't save/restore them |
1564 | * (other than to advance the PC on return). | 1564 | * (other than to advance the PC on return). |
1565 | * | 1565 | * |
1566 | * We have to manually validate the user vs kernel address range | 1566 | * We have to manually validate the user vs kernel address range |
@@ -1766,7 +1766,7 @@ ENTRY(sys_cmpxchg) | |||
1766 | /* Do slow mtspr here so the following "mf" waits less. */ | 1766 | /* Do slow mtspr here so the following "mf" waits less. */ |
1767 | { | 1767 | { |
1768 | move sp, r27 | 1768 | move sp, r27 |
1769 | mtspr EX_CONTEXT_1_0, r28 | 1769 | mtspr SPR_EX_CONTEXT_K_0, r28 |
1770 | } | 1770 | } |
1771 | mf | 1771 | mf |
1772 | 1772 | ||
@@ -1785,7 +1785,7 @@ ENTRY(sys_cmpxchg) | |||
1785 | } | 1785 | } |
1786 | { | 1786 | { |
1787 | move sp, r27 | 1787 | move sp, r27 |
1788 | mtspr EX_CONTEXT_1_0, r28 | 1788 | mtspr SPR_EX_CONTEXT_K_0, r28 |
1789 | } | 1789 | } |
1790 | iret | 1790 | iret |
1791 | 1791 | ||
@@ -1813,7 +1813,7 @@ ENTRY(sys_cmpxchg) | |||
1813 | #endif | 1813 | #endif |
1814 | 1814 | ||
1815 | /* Issue the slow SPR here while the tns result is in flight. */ | 1815 | /* Issue the slow SPR here while the tns result is in flight. */ |
1816 | mfspr r28, EX_CONTEXT_1_0 | 1816 | mfspr r28, SPR_EX_CONTEXT_K_0 |
1817 | 1817 | ||
1818 | { | 1818 | { |
1819 | addi r28, r28, 8 /* return to the instruction after the swint1 */ | 1819 | addi r28, r28, 8 /* return to the instruction after the swint1 */ |
@@ -1901,7 +1901,7 @@ ENTRY(sys_cmpxchg) | |||
1901 | .Lcmpxchg64_mismatch: | 1901 | .Lcmpxchg64_mismatch: |
1902 | { | 1902 | { |
1903 | move sp, r27 | 1903 | move sp, r27 |
1904 | mtspr EX_CONTEXT_1_0, r28 | 1904 | mtspr SPR_EX_CONTEXT_K_0, r28 |
1905 | } | 1905 | } |
1906 | mf | 1906 | mf |
1907 | { | 1907 | { |
@@ -1982,8 +1982,13 @@ int_unalign: | |||
1982 | int_hand INT_PERF_COUNT, PERF_COUNT, \ | 1982 | int_hand INT_PERF_COUNT, PERF_COUNT, \ |
1983 | op_handle_perf_interrupt, handle_nmi | 1983 | op_handle_perf_interrupt, handle_nmi |
1984 | int_hand INT_INTCTRL_3, INTCTRL_3, bad_intr | 1984 | int_hand INT_INTCTRL_3, INTCTRL_3, bad_intr |
1985 | #if CONFIG_KERNEL_PL == 2 | ||
1986 | dc_dispatch INT_INTCTRL_2, INTCTRL_2 | ||
1987 | int_hand INT_INTCTRL_1, INTCTRL_1, bad_intr | ||
1988 | #else | ||
1985 | int_hand INT_INTCTRL_2, INTCTRL_2, bad_intr | 1989 | int_hand INT_INTCTRL_2, INTCTRL_2, bad_intr |
1986 | dc_dispatch INT_INTCTRL_1, INTCTRL_1 | 1990 | dc_dispatch INT_INTCTRL_1, INTCTRL_1 |
1991 | #endif | ||
1987 | int_hand INT_INTCTRL_0, INTCTRL_0, bad_intr | 1992 | int_hand INT_INTCTRL_0, INTCTRL_0, bad_intr |
1988 | int_hand INT_MESSAGE_RCV_DWNCL, MESSAGE_RCV_DWNCL, \ | 1993 | int_hand INT_MESSAGE_RCV_DWNCL, MESSAGE_RCV_DWNCL, \ |
1989 | hv_message_intr, handle_interrupt_downcall | 1994 | hv_message_intr, handle_interrupt_downcall |