aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/kernel/intvec_32.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/tile/kernel/intvec_32.S')
-rw-r--r--arch/tile/kernel/intvec_32.S101
1 files changed, 54 insertions, 47 deletions
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S
index 8f58bdff20d7..f5821626247f 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
1882: 1882:
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
1980: 1980:
@@ -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
@@ -1020,7 +1020,7 @@ STD_ENTRY(interrupt_return)
1020 1020
1021 /* Set r1 to errno if we are returning an error, otherwise zero. */ 1021 /* Set r1 to errno if we are returning an error, otherwise zero. */
1022 { 1022 {
1023 moveli r29, 1024 1023 moveli r29, 4096
1024 sub r1, zero, r0 1024 sub r1, zero, r0
1025 } 1025 }
1026 slt_u r29, r1, r29 1026 slt_u r29, r1, r29
@@ -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
@@ -1472,7 +1472,12 @@ handle_ill:
1472 lw r26, r24 1472 lw r26, r24
1473 sw r28, r26 1473 sw r28, r26
1474 1474
1475 /* Clear TIF_SINGLESTEP */ 1475 /*
1476 * Clear TIF_SINGLESTEP to prevent recursion if we execute an ill.
1477 * The normal non-arch flow redundantly clears TIF_SINGLESTEP, but we
1478 * need to clear it here and can't really impose on all other arches.
1479 * So what's another write between friends?
1480 */
1476 GET_THREAD_INFO(r0) 1481 GET_THREAD_INFO(r0)
1477 1482
1478 addi r1, r0, THREAD_INFO_FLAGS_OFFSET 1483 addi r1, r0, THREAD_INFO_FLAGS_OFFSET
@@ -1509,7 +1514,7 @@ handle_ill:
1509/* Various stub interrupt handlers and syscall handlers */ 1514/* Various stub interrupt handlers and syscall handlers */
1510 1515
1511STD_ENTRY_LOCAL(_kernel_double_fault) 1516STD_ENTRY_LOCAL(_kernel_double_fault)
1512 mfspr r1, EX_CONTEXT_1_0 1517 mfspr r1, SPR_EX_CONTEXT_K_0
1513 move r2, lr 1518 move r2, lr
1514 move r3, sp 1519 move r3, sp
1515 move r4, r52 1520 move r4, r52
@@ -1518,34 +1523,29 @@ STD_ENTRY_LOCAL(_kernel_double_fault)
1518 STD_ENDPROC(_kernel_double_fault) 1523 STD_ENDPROC(_kernel_double_fault)
1519 1524
1520STD_ENTRY_LOCAL(bad_intr) 1525STD_ENTRY_LOCAL(bad_intr)
1521 mfspr r2, EX_CONTEXT_1_0 1526 mfspr r2, SPR_EX_CONTEXT_K_0
1522 panic "Unhandled interrupt %#x: PC %#lx" 1527 panic "Unhandled interrupt %#x: PC %#lx"
1523 STD_ENDPROC(bad_intr) 1528 STD_ENDPROC(bad_intr)
1524 1529
1525/* Put address of pt_regs in reg and jump. */ 1530/* Put address of pt_regs in reg and jump. */
1526#define PTREGS_SYSCALL(x, reg) \ 1531#define PTREGS_SYSCALL(x, reg) \
1527 STD_ENTRY(x); \ 1532 STD_ENTRY(_##x); \
1528 { \ 1533 { \
1529 PTREGS_PTR(reg, PTREGS_OFFSET_BASE); \ 1534 PTREGS_PTR(reg, PTREGS_OFFSET_BASE); \
1530 j _##x \ 1535 j x \
1531 }; \ 1536 }; \
1532 STD_ENDPROC(x) 1537 STD_ENDPROC(_##x)
1533 1538
1534PTREGS_SYSCALL(sys_execve, r3) 1539PTREGS_SYSCALL(sys_execve, r3)
1535PTREGS_SYSCALL(sys_sigaltstack, r2) 1540PTREGS_SYSCALL(sys_sigaltstack, r2)
1536PTREGS_SYSCALL(sys_rt_sigreturn, r0) 1541PTREGS_SYSCALL(sys_rt_sigreturn, r0)
1542PTREGS_SYSCALL(sys_cmpxchg_badaddr, r1)
1537 1543
1538/* Save additional callee-saves to pt_regs, put address in reg and jump. */ 1544/* Save additional callee-saves to pt_regs, put address in r4 and jump. */
1539#define PTREGS_SYSCALL_ALL_REGS(x, reg) \ 1545STD_ENTRY(_sys_clone)
1540 STD_ENTRY(x); \ 1546 push_extra_callee_saves r4
1541 push_extra_callee_saves reg; \ 1547 j sys_clone
1542 j _##x; \ 1548 STD_ENDPROC(_sys_clone)
1543 STD_ENDPROC(x)
1544
1545PTREGS_SYSCALL_ALL_REGS(sys_fork, r0)
1546PTREGS_SYSCALL_ALL_REGS(sys_vfork, r0)
1547PTREGS_SYSCALL_ALL_REGS(sys_clone, r4)
1548PTREGS_SYSCALL_ALL_REGS(sys_cmpxchg_badaddr, r1)
1549 1549
1550/* 1550/*
1551 * This entrypoint is taken for the cmpxchg and atomic_update fast 1551 * This entrypoint is taken for the cmpxchg and atomic_update fast
@@ -1558,12 +1558,14 @@ PTREGS_SYSCALL_ALL_REGS(sys_cmpxchg_badaddr, r1)
1558 * to be available to it on entry. It does not modify any callee-save 1558 * to be available to it on entry. It does not modify any callee-save
1559 * registers (including "lr"). It does not check what PL it is being 1559 * registers (including "lr"). It does not check what PL it is being
1560 * called at, so you'd better not call it other than at PL0. 1560 * called at, so you'd better not call it other than at PL0.
1561 * The <atomic.h> wrapper assumes it only clobbers r20-r29, so if
1562 * it ever is necessary to use more registers, be aware.
1561 * 1563 *
1562 * It does not use the stack, but since it might be re-interrupted by 1564 * It does not use the stack, but since it might be re-interrupted by
1563 * a page fault which would assume the stack was valid, it does 1565 * a page fault which would assume the stack was valid, it does
1564 * save/restore the stack pointer and zero it out to make sure it gets reset. 1566 * save/restore the stack pointer and zero it out to make sure it gets reset.
1565 * Since we always keep interrupts disabled, the hypervisor won't 1567 * Since we always keep interrupts disabled, the hypervisor won't
1566 * clobber our EX_CONTEXT_1_x registers, so we don't save/restore them 1568 * clobber our EX_CONTEXT_K_x registers, so we don't save/restore them
1567 * (other than to advance the PC on return). 1569 * (other than to advance the PC on return).
1568 * 1570 *
1569 * We have to manually validate the user vs kernel address range 1571 * We have to manually validate the user vs kernel address range
@@ -1769,7 +1771,7 @@ ENTRY(sys_cmpxchg)
1769 /* Do slow mtspr here so the following "mf" waits less. */ 1771 /* Do slow mtspr here so the following "mf" waits less. */
1770 { 1772 {
1771 move sp, r27 1773 move sp, r27
1772 mtspr EX_CONTEXT_1_0, r28 1774 mtspr SPR_EX_CONTEXT_K_0, r28
1773 } 1775 }
1774 mf 1776 mf
1775 1777
@@ -1788,7 +1790,7 @@ ENTRY(sys_cmpxchg)
1788 } 1790 }
1789 { 1791 {
1790 move sp, r27 1792 move sp, r27
1791 mtspr EX_CONTEXT_1_0, r28 1793 mtspr SPR_EX_CONTEXT_K_0, r28
1792 } 1794 }
1793 iret 1795 iret
1794 1796
@@ -1816,7 +1818,7 @@ ENTRY(sys_cmpxchg)
1816#endif 1818#endif
1817 1819
1818 /* Issue the slow SPR here while the tns result is in flight. */ 1820 /* Issue the slow SPR here while the tns result is in flight. */
1819 mfspr r28, EX_CONTEXT_1_0 1821 mfspr r28, SPR_EX_CONTEXT_K_0
1820 1822
1821 { 1823 {
1822 addi r28, r28, 8 /* return to the instruction after the swint1 */ 1824 addi r28, r28, 8 /* return to the instruction after the swint1 */
@@ -1904,7 +1906,7 @@ ENTRY(sys_cmpxchg)
1904.Lcmpxchg64_mismatch: 1906.Lcmpxchg64_mismatch:
1905 { 1907 {
1906 move sp, r27 1908 move sp, r27
1907 mtspr EX_CONTEXT_1_0, r28 1909 mtspr SPR_EX_CONTEXT_K_0, r28
1908 } 1910 }
1909 mf 1911 mf
1910 { 1912 {
@@ -1985,8 +1987,13 @@ int_unalign:
1985 int_hand INT_PERF_COUNT, PERF_COUNT, \ 1987 int_hand INT_PERF_COUNT, PERF_COUNT, \
1986 op_handle_perf_interrupt, handle_nmi 1988 op_handle_perf_interrupt, handle_nmi
1987 int_hand INT_INTCTRL_3, INTCTRL_3, bad_intr 1989 int_hand INT_INTCTRL_3, INTCTRL_3, bad_intr
1990#if CONFIG_KERNEL_PL == 2
1991 dc_dispatch INT_INTCTRL_2, INTCTRL_2
1992 int_hand INT_INTCTRL_1, INTCTRL_1, bad_intr
1993#else
1988 int_hand INT_INTCTRL_2, INTCTRL_2, bad_intr 1994 int_hand INT_INTCTRL_2, INTCTRL_2, bad_intr
1989 dc_dispatch INT_INTCTRL_1, INTCTRL_1 1995 dc_dispatch INT_INTCTRL_1, INTCTRL_1
1996#endif
1990 int_hand INT_INTCTRL_0, INTCTRL_0, bad_intr 1997 int_hand INT_INTCTRL_0, INTCTRL_0, bad_intr
1991 int_hand INT_MESSAGE_RCV_DWNCL, MESSAGE_RCV_DWNCL, \ 1998 int_hand INT_MESSAGE_RCV_DWNCL, MESSAGE_RCV_DWNCL, \
1992 hv_message_intr, handle_interrupt_downcall 1999 hv_message_intr, handle_interrupt_downcall