~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to arch/tile/kernel/intvec_32.S

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
# error "No support for kernel preemption currently"
33
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
35
#define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg)
40
36
 
41
37
#define PTREGS_OFFSET_SYSCALL PTREGS_OFFSET_REG(TREG_SYSCALL_NR)
855
851
        /* Check to see if there is any work to do before returning to user. */
856
852
        {
857
853
         addi   r29, r32, THREAD_INFO_FLAGS_OFFSET
858
 
         moveli r28, lo16(_TIF_ALLWORK_MASK)
 
854
         moveli r1, lo16(_TIF_ALLWORK_MASK)
859
855
        }
860
856
        {
861
857
         lw     r29, r29
862
 
         auli   r28, r28, ha16(_TIF_ALLWORK_MASK)
863
 
        }
864
 
        and     r28, r29, r28
865
 
        bnz     r28, .Lwork_pending
 
858
         auli   r1, r1, ha16(_TIF_ALLWORK_MASK)
 
859
        }
 
860
        and     r1, r29, r1
 
861
        bzt     r1, .Lrestore_all
 
862
 
 
863
        /*
 
864
         * Make sure we have all the registers saved for signal
 
865
         * handling or single-step.  Call out to C code to figure out
 
866
         * exactly what we need to do for each flag bit, then if
 
867
         * necessary, reload the flags and recheck.
 
868
         */
 
869
        push_extra_callee_saves r0
 
870
        {
 
871
         PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
 
872
         jal    do_work_pending
 
873
        }
 
874
        bnz     r0, .Lresume_userspace
866
875
 
867
876
        /*
868
877
         * In the NMI case we
1103
1112
        pop_reg r50
1104
1113
        pop_reg r51, sp, PTREGS_OFFSET_REG(29) - PTREGS_OFFSET_REG(51)
1105
1114
        j .Lcontinue_restore_regs
1106
 
 
1107
 
.Lwork_pending:
1108
 
        /* Mask the reschedule flag */
1109
 
        andi    r28, r29, _TIF_NEED_RESCHED
1110
 
 
1111
 
        {
1112
 
         /*
1113
 
          * If the NEED_RESCHED flag is called, we call schedule(), which
1114
 
          * may drop this context right here and go do something else.
1115
 
          * On return, jump back to .Lresume_userspace and recheck.
1116
 
          */
1117
 
         bz     r28, .Lasync_tlb
1118
 
 
1119
 
         /* Mask the async-tlb flag */
1120
 
         andi   r28, r29, _TIF_ASYNC_TLB
1121
 
        }
1122
 
 
1123
 
        jal     schedule
1124
 
        FEEDBACK_REENTER(interrupt_return)
1125
 
 
1126
 
        /* Reload the flags and check again */
1127
 
        j       .Lresume_userspace
1128
 
 
1129
 
.Lasync_tlb:
1130
 
        {
1131
 
         bz     r28, .Lneed_sigpending
1132
 
 
1133
 
         /* Mask the sigpending flag */
1134
 
         andi   r28, r29, _TIF_SIGPENDING
1135
 
        }
1136
 
 
1137
 
        PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
1138
 
        jal     do_async_page_fault
1139
 
        FEEDBACK_REENTER(interrupt_return)
1140
 
 
1141
 
        /*
1142
 
         * Go restart the "resume userspace" process.  We may have
1143
 
         * fired a signal, and we need to disable interrupts again.
1144
 
         */
1145
 
        j       .Lresume_userspace
1146
 
 
1147
 
.Lneed_sigpending:
1148
 
        /*
1149
 
         * At this point we are either doing signal handling or single-step,
1150
 
         * so either way make sure we have all the registers saved.
1151
 
         */
1152
 
        push_extra_callee_saves r0
1153
 
 
1154
 
        {
1155
 
         /* If no signal pending, skip to singlestep check */
1156
 
         bz     r28, .Lneed_singlestep
1157
 
 
1158
 
         /* Mask the singlestep flag */
1159
 
         andi   r28, r29, _TIF_SINGLESTEP
1160
 
        }
1161
 
 
1162
 
        jal     do_signal
1163
 
        FEEDBACK_REENTER(interrupt_return)
1164
 
 
1165
 
        /* Reload the flags and check again */
1166
 
        j       .Lresume_userspace
1167
 
 
1168
 
.Lneed_singlestep:
1169
 
        {
1170
 
         /* Get a pointer to the EX1 field */
1171
 
         PTREGS_PTR(r29, PTREGS_OFFSET_EX1)
1172
 
 
1173
 
         /* If we get here, our bit must be set. */
1174
 
         bz     r28, .Lwork_confusion
1175
 
        }
1176
 
        /* If we are in priv mode, don't single step */
1177
 
        lw      r28, r29
1178
 
        andi    r28, r28, SPR_EX_CONTEXT_1_1__PL_MASK  /* mask off ICS */
1179
 
        bnz     r28, .Lrestore_all
1180
 
 
1181
 
        /* Allow interrupts within the single step code */
1182
 
        TRACE_IRQS_ON  /* Note: clobbers registers r0-r29 */
1183
 
        IRQ_ENABLE(r20, r21)
1184
 
 
1185
 
        /* try to single-step the current instruction */
1186
 
        PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
1187
 
        jal     single_step_once
1188
 
        FEEDBACK_REENTER(interrupt_return)
1189
 
 
1190
 
        /* Re-disable interrupts.  TRACE_IRQS_OFF in .Lrestore_all. */
1191
 
        IRQ_DISABLE(r20,r21)
1192
 
 
1193
 
        j       .Lrestore_all
1194
 
 
1195
 
.Lwork_confusion:
1196
 
        move    r0, r28
1197
 
        panic   "thread_info allwork flags unhandled on userspace resume: %#x"
1198
 
 
1199
1115
        STD_ENDPROC(interrupt_return)
1200
1116
 
1201
1117
        /*
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
1118
         * Some interrupts don't check for single stepping
1243
1119
         */
1244
1120
        .pushsection .text.handle_interrupt_no_single_step,"ax"
1594
1470
 * We place it in the __HEAD section to ensure it is relatively
1595
1471
 * near to the intvec_SWINT_1 code (reachable by a conditional branch).
1596
1472
 *
1597
 
 * Must match register usage in do_page_fault().
 
1473
 * Our use of ATOMIC_LOCK_REG here must match do_page_fault_ics().
 
1474
 *
 
1475
 * As we do in lib/atomic_asm_32.S, we bypass a store if the value we
 
1476
 * would store is the same as the value we just loaded.
1598
1477
 */
1599
1478
        __HEAD
1600
1479
        .align 64
1601
1480
        /* Align much later jump on the start of a cache line. */
1602
1481
#if !ATOMIC_LOCKS_FOUND_VIA_TABLE()
1603
 
        nop; nop
 
1482
        nop
 
1483
#if PAGE_SIZE >= 0x10000
 
1484
        nop
 
1485
#endif
1604
1486
#endif
1605
1487
ENTRY(sys_cmpxchg)
1606
1488
 
1628
1510
         * about aliasing among multiple mappings of the same physical page,
1629
1511
         * and we ignore the low 3 bits so we have one lock that covers
1630
1512
         * 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.
 
1513
         * NOTE: this must match __atomic_hashed_lock() in lib/atomic_32.c.
1632
1514
         */
1633
1515
 
 
1516
#if (PAGE_OFFSET & 0xffff) != 0
 
1517
# error Code here assumes PAGE_OFFSET can be loaded with just hi16()
 
1518
#endif
 
1519
 
1634
1520
#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
1635
1521
        {
1636
1522
         /* Check for unaligned input. */
1648
1534
        {
1649
1535
         shri   r20, r25, 32 - ATOMIC_HASH_L1_SHIFT
1650
1536
         slt_u  r23, r0, r23
1651
 
 
1652
 
         /*
1653
 
          * Ensure that the TLB is loaded before we take out the lock.
1654
 
          * On TILEPro, this will start fetching the value all the way
1655
 
          * into our L1 as well (and if it gets modified before we
1656
 
          * grab the lock, it will be invalidated from our cache
1657
 
          * before we reload it).  On tile64, we'll start fetching it
1658
 
          * into our L1 if we're the home, and if we're not, we'll
1659
 
          * still at least start fetching it into the home's L2.
1660
 
          */
1661
 
         lw     r26, r0
 
1537
         lw     r26, r0  /* see comment in the "#else" for the "lw r26". */
1662
1538
        }
1663
1539
        {
1664
1540
         s2a    r21, r20, r21
1674
1550
         bbs    r23, .Lcmpxchg64
1675
1551
         andi   r23, r0, 7       /* Precompute alignment for cmpxchg64. */
1676
1552
        }
1677
 
 
1678
1553
        {
1679
 
         /*
1680
 
          * We very carefully align the code that actually runs with
1681
 
          * the lock held (nine bundles) so that we know it is all in
1682
 
          * the icache when we start.  This instruction (the jump) is
1683
 
          * at the start of the first cache line, address zero mod 64;
1684
 
          * we jump to somewhere in the second cache line to issue the
1685
 
          * tns, then jump back to finish up.
1686
 
          */
1687
1554
         s2a    ATOMIC_LOCK_REG_NAME, r25, r21
1688
 
         j      .Lcmpxchg32_tns
 
1555
         j      .Lcmpxchg32_tns   /* see comment in the #else for the jump. */
1689
1556
        }
1690
1557
 
1691
1558
#else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
1723
1590
         lw     r26, r0
1724
1591
        }
1725
1592
        {
1726
 
         /* atomic_locks is page aligned so this suffices to get its addr. */
1727
 
         auli   r21, zero, hi16(atomic_locks)
 
1593
         auli   r21, zero, ha16(atomic_locks)
1728
1594
 
1729
1595
         bbns   r23, .Lcmpxchg_badaddr
1730
1596
        }
 
1597
#if PAGE_SIZE < 0x10000
 
1598
        /* atomic_locks is page-aligned so for big pages we don't need this. */
 
1599
        addli   r21, r21, lo16(atomic_locks)
 
1600
#endif
1731
1601
        {
1732
1602
         /*
1733
1603
          * Insert the hash bits into the page-aligned pointer.
1747
1617
        {
1748
1618
         /*
1749
1619
          * We very carefully align the code that actually runs with
1750
 
          * the lock held (nine bundles) so that we know it is all in
 
1620
          * the lock held (twelve bundles) so that we know it is all in
1751
1621
          * the icache when we start.  This instruction (the jump) is
1752
1622
          * at the start of the first cache line, address zero mod 64;
1753
 
          * we jump to somewhere in the second cache line to issue the
1754
 
          * tns, then jump back to finish up.
 
1623
          * we jump to the very end of the second cache line to get that
 
1624
          * line loaded in the icache, then fall through to issue the tns
 
1625
          * in the third cache line, at which point it's all cached.
 
1626
          * Note that is for performance, not correctness.
1755
1627
          */
1756
1628
         j      .Lcmpxchg32_tns
1757
1629
        }
1758
1630
 
1759
1631
#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
1760
1632
 
1761
 
        ENTRY(__sys_cmpxchg_grab_lock)
 
1633
/* Symbol for do_page_fault_ics() to use to compare against the PC. */
 
1634
.global __sys_cmpxchg_grab_lock
 
1635
__sys_cmpxchg_grab_lock:
1762
1636
 
1763
1637
        /*
1764
1638
         * Perform the actual cmpxchg or atomic_update.
1765
 
         * Note that __futex_mark_unlocked() in uClibc relies on
1766
 
         * atomic_update() to always perform an "mf", so don't make
1767
 
         * it optional or conditional without modifying that code.
1768
1639
         */
1769
1640
.Ldo_cmpxchg32:
1770
1641
        {
1782
1653
        }
1783
1654
        {
1784
1655
         mvnz   r24, r23, r25    /* Use atomic_update value if appropriate. */
1785
 
         bbns   r22, .Lcmpxchg32_mismatch
 
1656
         bbns   r22, .Lcmpxchg32_nostore
1786
1657
        }
 
1658
        seq     r22, r24, r21    /* Are we storing the value we loaded? */
 
1659
        bbs     r22, .Lcmpxchg32_nostore
1787
1660
        sw      r0, r24
1788
1661
 
 
1662
        /* The following instruction is the start of the second cache line. */
1789
1663
        /* Do slow mtspr here so the following "mf" waits less. */
1790
1664
        {
1791
1665
         move   sp, r27
1793
1667
        }
1794
1668
        mf
1795
1669
 
1796
 
        /* The following instruction is the start of the second cache line. */
1797
1670
        {
1798
1671
         move   r0, r21
1799
1672
         sw     ATOMIC_LOCK_REG_NAME, zero
1801
1674
        iret
1802
1675
 
1803
1676
        /* Duplicated code here in the case where we don't overlap "mf" */
1804
 
.Lcmpxchg32_mismatch:
 
1677
.Lcmpxchg32_nostore:
1805
1678
        {
1806
1679
         move   r0, r21
1807
1680
         sw     ATOMIC_LOCK_REG_NAME, zero
1817
1690
         * and for 64-bit cmpxchg.  We provide it as a macro and put
1818
1691
         * it into both versions.  We can't share the code literally
1819
1692
         * since it depends on having the right branch-back address.
1820
 
         * Note that the first few instructions should share the cache
1821
 
         * line with the second half of the actual locked code.
1822
1693
         */
1823
1694
        .macro  cmpxchg_lock, bitwidth
1824
1695
 
1844
1715
        }
1845
1716
        /*
1846
1717
         * The preceding instruction is the last thing that must be
1847
 
         * on the second cache line.
 
1718
         * hot in the icache before we do the "tns" above.
1848
1719
         */
1849
1720
 
1850
1721
#ifdef CONFIG_SMP
1875
1746
        .endm
1876
1747
 
1877
1748
.Lcmpxchg32_tns:
 
1749
        /*
 
1750
         * This is the last instruction on the second cache line.
 
1751
         * The nop here loads the second line, then we fall through
 
1752
         * to the tns to load the third line before we take the lock.
 
1753
         */
 
1754
        nop
1878
1755
        cmpxchg_lock 32
1879
1756
 
1880
1757
        /*
2014
1891
#endif
2015
1892
        int_hand     INT_INTCTRL_0, INTCTRL_0, bad_intr
2016
1893
        int_hand     INT_MESSAGE_RCV_DWNCL, MESSAGE_RCV_DWNCL, \
2017
 
                     hv_message_intr, handle_interrupt_downcall
 
1894
                     hv_message_intr
2018
1895
        int_hand     INT_DEV_INTR_DWNCL, DEV_INTR_DWNCL, \
2019
 
                     tile_dev_intr, handle_interrupt_downcall
 
1896
                     tile_dev_intr
2020
1897
        int_hand     INT_I_ASID, I_ASID, bad_intr
2021
1898
        int_hand     INT_D_ASID, D_ASID, bad_intr
2022
1899
        int_hand     INT_DMATLB_MISS_DWNCL, DMATLB_MISS_DWNCL, \
2023
 
                     do_page_fault, handle_interrupt_downcall
 
1900
                     do_page_fault
2024
1901
        int_hand     INT_SNITLB_MISS_DWNCL, SNITLB_MISS_DWNCL, \
2025
 
                     do_page_fault, handle_interrupt_downcall
 
1902
                     do_page_fault
2026
1903
        int_hand     INT_DMATLB_ACCESS_DWNCL, DMATLB_ACCESS_DWNCL, \
2027
 
                     do_page_fault, handle_interrupt_downcall
 
1904
                     do_page_fault
2028
1905
        int_hand     INT_SN_CPL, SN_CPL, bad_intr
2029
1906
        int_hand     INT_DOUBLE_FAULT, DOUBLE_FAULT, do_trap
2030
1907
#if CHIP_HAS_AUX_PERF_COUNTERS()