diff options
| -rw-r--r-- | arch/ia64/kernel/ivt.S | 261 |
1 files changed, 133 insertions, 128 deletions
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index 23749ed3cf08..c39627df3cde 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S | |||
| @@ -515,27 +515,6 @@ ENTRY(ikey_miss) | |||
| 515 | FAULT(6) | 515 | FAULT(6) |
| 516 | END(ikey_miss) | 516 | END(ikey_miss) |
| 517 | 517 | ||
| 518 | //----------------------------------------------------------------------------------- | ||
| 519 | // call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address) | ||
| 520 | ENTRY(page_fault) | ||
| 521 | SSM_PSR_DT_AND_SRLZ_I | ||
| 522 | ;; | ||
| 523 | SAVE_MIN_WITH_COVER | ||
| 524 | alloc r15=ar.pfs,0,0,3,0 | ||
| 525 | MOV_FROM_IFA(out0) | ||
| 526 | MOV_FROM_ISR(out1) | ||
| 527 | SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r14, r3) | ||
| 528 | adds r3=8,r2 // set up second base pointer | ||
| 529 | SSM_PSR_I(p15, p15, r14) // restore psr.i | ||
| 530 | movl r14=ia64_leave_kernel | ||
| 531 | ;; | ||
| 532 | SAVE_REST | ||
| 533 | mov rp=r14 | ||
| 534 | ;; | ||
| 535 | adds out2=16,r12 // out2 = pointer to pt_regs | ||
| 536 | br.call.sptk.many b6=ia64_do_page_fault // ignore return address | ||
| 537 | END(page_fault) | ||
| 538 | |||
| 539 | .org ia64_ivt+0x1c00 | 518 | .org ia64_ivt+0x1c00 |
| 540 | ///////////////////////////////////////////////////////////////////////////////////////// | 519 | ///////////////////////////////////////////////////////////////////////////////////////// |
| 541 | // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51) | 520 | // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51) |
| @@ -896,26 +875,8 @@ END(break_fault) | |||
| 896 | ///////////////////////////////////////////////////////////////////////////////////////// | 875 | ///////////////////////////////////////////////////////////////////////////////////////// |
| 897 | // 0x3000 Entry 12 (size 64 bundles) External Interrupt (4) | 876 | // 0x3000 Entry 12 (size 64 bundles) External Interrupt (4) |
| 898 | ENTRY(interrupt) | 877 | ENTRY(interrupt) |
| 899 | DBG_FAULT(12) | 878 | /* interrupt handler has become too big to fit this area. */ |
| 900 | mov r31=pr // prepare to save predicates | 879 | br.sptk.many __interrupt |
| 901 | ;; | ||
| 902 | SAVE_MIN_WITH_COVER // uses r31; defines r2 and r3 | ||
| 903 | SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r14) | ||
| 904 | // ensure everybody knows psr.ic is back on | ||
| 905 | adds r3=8,r2 // set up second base pointer for SAVE_REST | ||
| 906 | ;; | ||
| 907 | SAVE_REST | ||
| 908 | ;; | ||
| 909 | MCA_RECOVER_RANGE(interrupt) | ||
| 910 | alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group | ||
| 911 | MOV_FROM_IVR(out0, r8) // pass cr.ivr as first arg | ||
| 912 | add out1=16,sp // pass pointer to pt_regs as second arg | ||
| 913 | ;; | ||
| 914 | srlz.d // make sure we see the effect of cr.ivr | ||
| 915 | movl r14=ia64_leave_kernel | ||
| 916 | ;; | ||
| 917 | mov rp=r14 | ||
| 918 | br.call.sptk.many b6=ia64_handle_irq | ||
| 919 | END(interrupt) | 880 | END(interrupt) |
| 920 | 881 | ||
| 921 | .org ia64_ivt+0x3400 | 882 | .org ia64_ivt+0x3400 |
| @@ -1125,105 +1086,18 @@ END(account_sys_enter) | |||
| 1125 | DBG_FAULT(17) | 1086 | DBG_FAULT(17) |
| 1126 | FAULT(17) | 1087 | FAULT(17) |
| 1127 | 1088 | ||
| 1128 | ENTRY(non_syscall) | ||
| 1129 | mov ar.rsc=r27 // restore ar.rsc before SAVE_MIN_WITH_COVER | ||
| 1130 | ;; | ||
| 1131 | SAVE_MIN_WITH_COVER | ||
| 1132 | |||
| 1133 | // There is no particular reason for this code to be here, other than that | ||
| 1134 | // there happens to be space here that would go unused otherwise. If this | ||
| 1135 | // fault ever gets "unreserved", simply moved the following code to a more | ||
| 1136 | // suitable spot... | ||
| 1137 | |||
| 1138 | alloc r14=ar.pfs,0,0,2,0 | ||
| 1139 | MOV_FROM_IIM(out0) | ||
| 1140 | add out1=16,sp | ||
| 1141 | adds r3=8,r2 // set up second base pointer for SAVE_REST | ||
| 1142 | |||
| 1143 | SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r15, r24) | ||
| 1144 | // guarantee that interruption collection is on | ||
| 1145 | SSM_PSR_I(p15, p15, r15) // restore psr.i | ||
| 1146 | movl r15=ia64_leave_kernel | ||
| 1147 | ;; | ||
| 1148 | SAVE_REST | ||
| 1149 | mov rp=r15 | ||
| 1150 | ;; | ||
| 1151 | br.call.sptk.many b6=ia64_bad_break // avoid WAW on CFM and ignore return addr | ||
| 1152 | END(non_syscall) | ||
| 1153 | |||
| 1154 | .org ia64_ivt+0x4800 | 1089 | .org ia64_ivt+0x4800 |
| 1155 | ///////////////////////////////////////////////////////////////////////////////////////// | 1090 | ///////////////////////////////////////////////////////////////////////////////////////// |
| 1156 | // 0x4800 Entry 18 (size 64 bundles) Reserved | 1091 | // 0x4800 Entry 18 (size 64 bundles) Reserved |
| 1157 | DBG_FAULT(18) | 1092 | DBG_FAULT(18) |
| 1158 | FAULT(18) | 1093 | FAULT(18) |
| 1159 | 1094 | ||
| 1160 | /* | ||
| 1161 | * There is no particular reason for this code to be here, other than that | ||
| 1162 | * there happens to be space here that would go unused otherwise. If this | ||
| 1163 | * fault ever gets "unreserved", simply moved the following code to a more | ||
| 1164 | * suitable spot... | ||
| 1165 | */ | ||
| 1166 | |||
| 1167 | ENTRY(dispatch_unaligned_handler) | ||
| 1168 | SAVE_MIN_WITH_COVER | ||
| 1169 | ;; | ||
| 1170 | alloc r14=ar.pfs,0,0,2,0 // now it's safe (must be first in insn group!) | ||
| 1171 | MOV_FROM_IFA(out0) | ||
| 1172 | adds out1=16,sp | ||
| 1173 | |||
| 1174 | SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24) | ||
| 1175 | // guarantee that interruption collection is on | ||
| 1176 | SSM_PSR_I(p15, p15, r3) // restore psr.i | ||
| 1177 | adds r3=8,r2 // set up second base pointer | ||
| 1178 | ;; | ||
| 1179 | SAVE_REST | ||
| 1180 | movl r14=ia64_leave_kernel | ||
| 1181 | ;; | ||
| 1182 | mov rp=r14 | ||
| 1183 | br.sptk.many ia64_prepare_handle_unaligned | ||
| 1184 | END(dispatch_unaligned_handler) | ||
| 1185 | |||
| 1186 | .org ia64_ivt+0x4c00 | 1095 | .org ia64_ivt+0x4c00 |
| 1187 | ///////////////////////////////////////////////////////////////////////////////////////// | 1096 | ///////////////////////////////////////////////////////////////////////////////////////// |
| 1188 | // 0x4c00 Entry 19 (size 64 bundles) Reserved | 1097 | // 0x4c00 Entry 19 (size 64 bundles) Reserved |
| 1189 | DBG_FAULT(19) | 1098 | DBG_FAULT(19) |
| 1190 | FAULT(19) | 1099 | FAULT(19) |
| 1191 | 1100 | ||
| 1192 | /* | ||
| 1193 | * There is no particular reason for this code to be here, other than that | ||
| 1194 | * there happens to be space here that would go unused otherwise. If this | ||
| 1195 | * fault ever gets "unreserved", simply moved the following code to a more | ||
| 1196 | * suitable spot... | ||
| 1197 | */ | ||
| 1198 | |||
| 1199 | ENTRY(dispatch_to_fault_handler) | ||
| 1200 | /* | ||
| 1201 | * Input: | ||
| 1202 | * psr.ic: off | ||
| 1203 | * r19: fault vector number (e.g., 24 for General Exception) | ||
| 1204 | * r31: contains saved predicates (pr) | ||
| 1205 | */ | ||
| 1206 | SAVE_MIN_WITH_COVER_R19 | ||
| 1207 | alloc r14=ar.pfs,0,0,5,0 | ||
| 1208 | MOV_FROM_ISR(out1) | ||
| 1209 | MOV_FROM_IFA(out2) | ||
| 1210 | MOV_FROM_IIM(out3) | ||
| 1211 | MOV_FROM_ITIR(out4) | ||
| 1212 | ;; | ||
| 1213 | SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, out0) | ||
| 1214 | // guarantee that interruption collection is on | ||
| 1215 | mov out0=r15 | ||
| 1216 | ;; | ||
| 1217 | SSM_PSR_I(p15, p15, r3) // restore psr.i | ||
| 1218 | adds r3=8,r2 // set up second base pointer for SAVE_REST | ||
| 1219 | ;; | ||
| 1220 | SAVE_REST | ||
| 1221 | movl r14=ia64_leave_kernel | ||
| 1222 | ;; | ||
| 1223 | mov rp=r14 | ||
| 1224 | br.call.sptk.many b6=ia64_fault | ||
| 1225 | END(dispatch_to_fault_handler) | ||
| 1226 | |||
| 1227 | // | 1101 | // |
| 1228 | // --- End of long entries, Beginning of short entries | 1102 | // --- End of long entries, Beginning of short entries |
| 1229 | // | 1103 | // |
| @@ -1670,6 +1544,137 @@ END(ia32_interrupt) | |||
| 1670 | DBG_FAULT(67) | 1544 | DBG_FAULT(67) |
| 1671 | FAULT(67) | 1545 | FAULT(67) |
| 1672 | 1546 | ||
| 1547 | //----------------------------------------------------------------------------------- | ||
| 1548 | // call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address) | ||
| 1549 | ENTRY(page_fault) | ||
| 1550 | SSM_PSR_DT_AND_SRLZ_I | ||
| 1551 | ;; | ||
| 1552 | SAVE_MIN_WITH_COVER | ||
| 1553 | alloc r15=ar.pfs,0,0,3,0 | ||
| 1554 | MOV_FROM_IFA(out0) | ||
| 1555 | MOV_FROM_ISR(out1) | ||
| 1556 | SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r14, r3) | ||
| 1557 | adds r3=8,r2 // set up second base pointer | ||
| 1558 | SSM_PSR_I(p15, p15, r14) // restore psr.i | ||
| 1559 | movl r14=ia64_leave_kernel | ||
| 1560 | ;; | ||
| 1561 | SAVE_REST | ||
| 1562 | mov rp=r14 | ||
| 1563 | ;; | ||
| 1564 | adds out2=16,r12 // out2 = pointer to pt_regs | ||
| 1565 | br.call.sptk.many b6=ia64_do_page_fault // ignore return address | ||
| 1566 | END(page_fault) | ||
| 1567 | |||
| 1568 | ENTRY(non_syscall) | ||
| 1569 | mov ar.rsc=r27 // restore ar.rsc before SAVE_MIN_WITH_COVER | ||
| 1570 | ;; | ||
| 1571 | SAVE_MIN_WITH_COVER | ||
| 1572 | |||
| 1573 | // There is no particular reason for this code to be here, other than that | ||
| 1574 | // there happens to be space here that would go unused otherwise. If this | ||
| 1575 | // fault ever gets "unreserved", simply moved the following code to a more | ||
| 1576 | // suitable spot... | ||
| 1577 | |||
| 1578 | alloc r14=ar.pfs,0,0,2,0 | ||
| 1579 | MOV_FROM_IIM(out0) | ||
| 1580 | add out1=16,sp | ||
| 1581 | adds r3=8,r2 // set up second base pointer for SAVE_REST | ||
| 1582 | |||
| 1583 | SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r15, r24) | ||
| 1584 | // guarantee that interruption collection is on | ||
| 1585 | SSM_PSR_I(p15, p15, r15) // restore psr.i | ||
| 1586 | movl r15=ia64_leave_kernel | ||
| 1587 | ;; | ||
| 1588 | SAVE_REST | ||
| 1589 | mov rp=r15 | ||
| 1590 | ;; | ||
| 1591 | br.call.sptk.many b6=ia64_bad_break // avoid WAW on CFM and ignore return addr | ||
| 1592 | END(non_syscall) | ||
| 1593 | |||
| 1594 | ENTRY(__interrupt) | ||
| 1595 | DBG_FAULT(12) | ||
| 1596 | mov r31=pr // prepare to save predicates | ||
| 1597 | ;; | ||
| 1598 | SAVE_MIN_WITH_COVER // uses r31; defines r2 and r3 | ||
| 1599 | SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r14) | ||
| 1600 | // ensure everybody knows psr.ic is back on | ||
| 1601 | adds r3=8,r2 // set up second base pointer for SAVE_REST | ||
| 1602 | ;; | ||
| 1603 | SAVE_REST | ||
| 1604 | ;; | ||
| 1605 | MCA_RECOVER_RANGE(interrupt) | ||
| 1606 | alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group | ||
| 1607 | MOV_FROM_IVR(out0, r8) // pass cr.ivr as first arg | ||
| 1608 | add out1=16,sp // pass pointer to pt_regs as second arg | ||
| 1609 | ;; | ||
| 1610 | srlz.d // make sure we see the effect of cr.ivr | ||
| 1611 | movl r14=ia64_leave_kernel | ||
| 1612 | ;; | ||
| 1613 | mov rp=r14 | ||
| 1614 | br.call.sptk.many b6=ia64_handle_irq | ||
| 1615 | END(__interrupt) | ||
| 1616 | |||
| 1617 | /* | ||
| 1618 | * There is no particular reason for this code to be here, other than that | ||
| 1619 | * there happens to be space here that would go unused otherwise. If this | ||
| 1620 | * fault ever gets "unreserved", simply moved the following code to a more | ||
| 1621 | * suitable spot... | ||
| 1622 | */ | ||
| 1623 | |||
| 1624 | ENTRY(dispatch_unaligned_handler) | ||
| 1625 | SAVE_MIN_WITH_COVER | ||
| 1626 | ;; | ||
| 1627 | alloc r14=ar.pfs,0,0,2,0 // now it's safe (must be first in insn group!) | ||
| 1628 | MOV_FROM_IFA(out0) | ||
| 1629 | adds out1=16,sp | ||
| 1630 | |||
| 1631 | SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24) | ||
| 1632 | // guarantee that interruption collection is on | ||
| 1633 | SSM_PSR_I(p15, p15, r3) // restore psr.i | ||
| 1634 | adds r3=8,r2 // set up second base pointer | ||
| 1635 | ;; | ||
| 1636 | SAVE_REST | ||
| 1637 | movl r14=ia64_leave_kernel | ||
| 1638 | ;; | ||
| 1639 | mov rp=r14 | ||
| 1640 | br.sptk.many ia64_prepare_handle_unaligned | ||
| 1641 | END(dispatch_unaligned_handler) | ||
| 1642 | |||
| 1643 | /* | ||
| 1644 | * There is no particular reason for this code to be here, other than that | ||
| 1645 | * there happens to be space here that would go unused otherwise. If this | ||
| 1646 | * fault ever gets "unreserved", simply moved the following code to a more | ||
| 1647 | * suitable spot... | ||
| 1648 | */ | ||
| 1649 | |||
| 1650 | ENTRY(dispatch_to_fault_handler) | ||
| 1651 | /* | ||
| 1652 | * Input: | ||
| 1653 | * psr.ic: off | ||
| 1654 | * r19: fault vector number (e.g., 24 for General Exception) | ||
| 1655 | * r31: contains saved predicates (pr) | ||
| 1656 | */ | ||
| 1657 | SAVE_MIN_WITH_COVER_R19 | ||
| 1658 | alloc r14=ar.pfs,0,0,5,0 | ||
| 1659 | MOV_FROM_ISR(out1) | ||
| 1660 | MOV_FROM_IFA(out2) | ||
| 1661 | MOV_FROM_IIM(out3) | ||
| 1662 | MOV_FROM_ITIR(out4) | ||
| 1663 | ;; | ||
| 1664 | SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, out0) | ||
| 1665 | // guarantee that interruption collection is on | ||
| 1666 | mov out0=r15 | ||
| 1667 | ;; | ||
| 1668 | SSM_PSR_I(p15, p15, r3) // restore psr.i | ||
| 1669 | adds r3=8,r2 // set up second base pointer for SAVE_REST | ||
| 1670 | ;; | ||
| 1671 | SAVE_REST | ||
| 1672 | movl r14=ia64_leave_kernel | ||
| 1673 | ;; | ||
| 1674 | mov rp=r14 | ||
| 1675 | br.call.sptk.many b6=ia64_fault | ||
| 1676 | END(dispatch_to_fault_handler) | ||
| 1677 | |||
| 1673 | /* | 1678 | /* |
| 1674 | * Squatting in this space ... | 1679 | * Squatting in this space ... |
| 1675 | * | 1680 | * |
