diff options
Diffstat (limited to 'arch/tile/kernel/intvec_32.S')
-rw-r--r-- | arch/tile/kernel/intvec_32.S | 74 |
1 files changed, 20 insertions, 54 deletions
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S index 5eed4a02bf62..fffcfa6b3a62 100644 --- a/arch/tile/kernel/intvec_32.S +++ b/arch/tile/kernel/intvec_32.S | |||
@@ -32,10 +32,6 @@ | |||
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_K < 32 || INT_INTCTRL_K >= 48 | ||
36 | # error INT_INTCTRL_K coded to set high interrupt mask | ||
37 | #endif | ||
38 | |||
39 | #define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg) | 35 | #define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg) |
40 | 36 | ||
41 | #define PTREGS_OFFSET_SYSCALL PTREGS_OFFSET_REG(TREG_SYSCALL_NR) | 37 | #define PTREGS_OFFSET_SYSCALL PTREGS_OFFSET_REG(TREG_SYSCALL_NR) |
@@ -1199,46 +1195,6 @@ STD_ENTRY(interrupt_return) | |||
1199 | STD_ENDPROC(interrupt_return) | 1195 | STD_ENDPROC(interrupt_return) |
1200 | 1196 | ||
1201 | /* | 1197 | /* |
1202 | * This interrupt variant clears the INT_INTCTRL_K interrupt mask bit | ||
1203 | * before returning, so we can properly get more downcalls. | ||
1204 | */ | ||
1205 | .pushsection .text.handle_interrupt_downcall,"ax" | ||
1206 | handle_interrupt_downcall: | ||
1207 | finish_interrupt_save handle_interrupt_downcall | ||
1208 | check_single_stepping normal, .Ldispatch_downcall | ||
1209 | .Ldispatch_downcall: | ||
1210 | |||
1211 | /* Clear INTCTRL_K from the set of interrupts we ever enable. */ | ||
1212 | GET_INTERRUPTS_ENABLED_MASK_PTR(r30) | ||
1213 | { | ||
1214 | addi r30, r30, 4 | ||
1215 | movei r31, INT_MASK(INT_INTCTRL_K) | ||
1216 | } | ||
1217 | { | ||
1218 | lw r20, r30 | ||
1219 | nor r21, r31, zero | ||
1220 | } | ||
1221 | and r20, r20, r21 | ||
1222 | sw r30, r20 | ||
1223 | |||
1224 | { | ||
1225 | jalr r0 | ||
1226 | PTREGS_PTR(r0, PTREGS_OFFSET_BASE) | ||
1227 | } | ||
1228 | FEEDBACK_REENTER(handle_interrupt_downcall) | ||
1229 | |||
1230 | /* Allow INTCTRL_K to be enabled next time we enable interrupts. */ | ||
1231 | lw r20, r30 | ||
1232 | or r20, r20, r31 | ||
1233 | sw r30, r20 | ||
1234 | |||
1235 | { | ||
1236 | movei r30, 0 /* not an NMI */ | ||
1237 | j interrupt_return | ||
1238 | } | ||
1239 | STD_ENDPROC(handle_interrupt_downcall) | ||
1240 | |||
1241 | /* | ||
1242 | * Some interrupts don't check for single stepping | 1198 | * Some interrupts don't check for single stepping |
1243 | */ | 1199 | */ |
1244 | .pushsection .text.handle_interrupt_no_single_step,"ax" | 1200 | .pushsection .text.handle_interrupt_no_single_step,"ax" |
@@ -1600,7 +1556,10 @@ STD_ENTRY(_sys_clone) | |||
1600 | .align 64 | 1556 | .align 64 |
1601 | /* Align much later jump on the start of a cache line. */ | 1557 | /* Align much later jump on the start of a cache line. */ |
1602 | #if !ATOMIC_LOCKS_FOUND_VIA_TABLE() | 1558 | #if !ATOMIC_LOCKS_FOUND_VIA_TABLE() |
1603 | nop; nop | 1559 | nop |
1560 | #if PAGE_SIZE >= 0x10000 | ||
1561 | nop | ||
1562 | #endif | ||
1604 | #endif | 1563 | #endif |
1605 | ENTRY(sys_cmpxchg) | 1564 | ENTRY(sys_cmpxchg) |
1606 | 1565 | ||
@@ -1628,9 +1587,13 @@ ENTRY(sys_cmpxchg) | |||
1628 | * about aliasing among multiple mappings of the same physical page, | 1587 | * about aliasing among multiple mappings of the same physical page, |
1629 | * and we ignore the low 3 bits so we have one lock that covers | 1588 | * and we ignore the low 3 bits so we have one lock that covers |
1630 | * both a cmpxchg64() and a cmpxchg() on either its low or high word. | 1589 | * both a cmpxchg64() and a cmpxchg() on either its low or high word. |
1631 | * NOTE: this code must match __atomic_hashed_lock() in lib/atomic.c. | 1590 | * NOTE: this must match __atomic_hashed_lock() in lib/atomic_32.c. |
1632 | */ | 1591 | */ |
1633 | 1592 | ||
1593 | #if (PAGE_OFFSET & 0xffff) != 0 | ||
1594 | # error Code here assumes PAGE_OFFSET can be loaded with just hi16() | ||
1595 | #endif | ||
1596 | |||
1634 | #if ATOMIC_LOCKS_FOUND_VIA_TABLE() | 1597 | #if ATOMIC_LOCKS_FOUND_VIA_TABLE() |
1635 | { | 1598 | { |
1636 | /* Check for unaligned input. */ | 1599 | /* Check for unaligned input. */ |
@@ -1723,11 +1686,14 @@ ENTRY(sys_cmpxchg) | |||
1723 | lw r26, r0 | 1686 | lw r26, r0 |
1724 | } | 1687 | } |
1725 | { | 1688 | { |
1726 | /* atomic_locks is page aligned so this suffices to get its addr. */ | 1689 | auli r21, zero, ha16(atomic_locks) |
1727 | auli r21, zero, hi16(atomic_locks) | ||
1728 | 1690 | ||
1729 | bbns r23, .Lcmpxchg_badaddr | 1691 | bbns r23, .Lcmpxchg_badaddr |
1730 | } | 1692 | } |
1693 | #if PAGE_SIZE < 0x10000 | ||
1694 | /* atomic_locks is page-aligned so for big pages we don't need this. */ | ||
1695 | addli r21, r21, lo16(atomic_locks) | ||
1696 | #endif | ||
1731 | { | 1697 | { |
1732 | /* | 1698 | /* |
1733 | * Insert the hash bits into the page-aligned pointer. | 1699 | * Insert the hash bits into the page-aligned pointer. |
@@ -1762,7 +1728,7 @@ ENTRY(sys_cmpxchg) | |||
1762 | 1728 | ||
1763 | /* | 1729 | /* |
1764 | * Perform the actual cmpxchg or atomic_update. | 1730 | * Perform the actual cmpxchg or atomic_update. |
1765 | * Note that __futex_mark_unlocked() in uClibc relies on | 1731 | * Note that the system <arch/atomic.h> header relies on |
1766 | * atomic_update() to always perform an "mf", so don't make | 1732 | * atomic_update() to always perform an "mf", so don't make |
1767 | * it optional or conditional without modifying that code. | 1733 | * it optional or conditional without modifying that code. |
1768 | */ | 1734 | */ |
@@ -2014,17 +1980,17 @@ int_unalign: | |||
2014 | #endif | 1980 | #endif |
2015 | int_hand INT_INTCTRL_0, INTCTRL_0, bad_intr | 1981 | int_hand INT_INTCTRL_0, INTCTRL_0, bad_intr |
2016 | int_hand INT_MESSAGE_RCV_DWNCL, MESSAGE_RCV_DWNCL, \ | 1982 | int_hand INT_MESSAGE_RCV_DWNCL, MESSAGE_RCV_DWNCL, \ |
2017 | hv_message_intr, handle_interrupt_downcall | 1983 | hv_message_intr |
2018 | int_hand INT_DEV_INTR_DWNCL, DEV_INTR_DWNCL, \ | 1984 | int_hand INT_DEV_INTR_DWNCL, DEV_INTR_DWNCL, \ |
2019 | tile_dev_intr, handle_interrupt_downcall | 1985 | tile_dev_intr |
2020 | int_hand INT_I_ASID, I_ASID, bad_intr | 1986 | int_hand INT_I_ASID, I_ASID, bad_intr |
2021 | int_hand INT_D_ASID, D_ASID, bad_intr | 1987 | int_hand INT_D_ASID, D_ASID, bad_intr |
2022 | int_hand INT_DMATLB_MISS_DWNCL, DMATLB_MISS_DWNCL, \ | 1988 | int_hand INT_DMATLB_MISS_DWNCL, DMATLB_MISS_DWNCL, \ |
2023 | do_page_fault, handle_interrupt_downcall | 1989 | do_page_fault |
2024 | int_hand INT_SNITLB_MISS_DWNCL, SNITLB_MISS_DWNCL, \ | 1990 | int_hand INT_SNITLB_MISS_DWNCL, SNITLB_MISS_DWNCL, \ |
2025 | do_page_fault, handle_interrupt_downcall | 1991 | do_page_fault |
2026 | int_hand INT_DMATLB_ACCESS_DWNCL, DMATLB_ACCESS_DWNCL, \ | 1992 | int_hand INT_DMATLB_ACCESS_DWNCL, DMATLB_ACCESS_DWNCL, \ |
2027 | do_page_fault, handle_interrupt_downcall | 1993 | do_page_fault |
2028 | int_hand INT_SN_CPL, SN_CPL, bad_intr | 1994 | int_hand INT_SN_CPL, SN_CPL, bad_intr |
2029 | int_hand INT_DOUBLE_FAULT, DOUBLE_FAULT, do_trap | 1995 | int_hand INT_DOUBLE_FAULT, DOUBLE_FAULT, do_trap |
2030 | #if CHIP_HAS_AUX_PERF_COUNTERS() | 1996 | #if CHIP_HAS_AUX_PERF_COUNTERS() |