diff options
Diffstat (limited to 'arch/ia64')
-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 | * |