2 * Copyright (c) 2003,2004 Marcel Moolenaar
3 * Copyright (c) 2000 Doug Rabson
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <machine/asm.h>
29 __FBSDID("$FreeBSD$");
31 #include <machine/pte.h>
35 * ar.k7 = kernel memory stack
36 * ar.k6 = kernel register stack
37 * ar.k5 = EPC gateway page
44 * exception_save: save interrupted state
47 * r16 address of bundle that contains the branch. The
48 * return address will be the next bundle.
49 * r17 the value to save as ifa in the trapframe. This
50 * normally is cr.ifa, but some interruptions set
51 * set cr.iim and not cr.ifa.
54 * p15 interrupted from user stack
55 * p14 interrupted from kernel stack
56 * p13 interrupted from user backing store
57 * p12 interrupted from kernel backing store
58 * p11 interrupts were enabled
59 * p10 interrupts were disabled
61 ENTRY_NOPROFILE(exception_save, 0)
71 (p15) mov r23=ar.k7 // kernel memory stack
77 add r30=-SIZEOF_TRAPFRAME,r23
90 movl r26=exception_save_restart
95 * We have a 1KB aligned trapframe, pointed to by sp. If we write
96 * to the trapframe, we may trigger a data nested TLB fault. By
97 * aligning the trapframe on a 1KB boundary, we guarantee that if
98 * we get a data nested TLB fault, it will be on the very first
99 * write. Since the data nested TLB fault does not preserve any
100 * state, we have to be careful what we clobber. Consequently, we
101 * have to be careful what we use here. Below a list of registers
102 * that are currently alive:
104 * r18=pr, r19=length, r20=unat, r21=rsc, r22=iip, r23=TOS
106 * r30,r31=trapframe pointers
107 * p14,p15=memory stack switch
109 exception_save_restart:
111 st8 [r30]=r19,16 // length
112 st8 [r31]=r0,16 // flags
117 st8.spill [r30]=sp,16 // sp
118 st8 [r31]=r20,16 // unat
128 // r18=pr, r19=rnat, r20=bspstore, r21=rsc, r22=iip, r23=rp
130 st8 [r30]=r23,16 // rp
131 st8 [r31]=r18,16 // pr
136 st8 [r30]=r24,16 // pfs
137 st8 [r31]=r20,16 // bspstore
147 // r18=fpsr, r19=rnat, r20=bspstore, r21=rsc, r22=iip, r23=ipsr
149 st8 [r30]=r19,16 // rnat
150 st8 [r31]=r0,16 // __spare
155 st8.spill [r30]=r13,16 // tp
156 st8 [r31]=r21,16 // rsc
157 tbit.nz p11,p10=r23,14 // p11=interrupts enabled
161 (p13) mov r21=ar.k6 // kernel register stack
163 st8 [r30]=r18,16 // fpsr
164 (p13) dep r20=r20,r21,0,9 // align dirty registers
167 // r20=bspstore, r22=iip, r23=ipsr
169 st8 [r31]=r23,16 // psr
170 (p13) mov ar.bspstore=r20
182 st8.spill [r30]=gp,16 // gp
183 st8 [r31]=r18,16 // ndirty
189 st8 [r30]=r19,16 // cfm
190 st8 [r31]=r22,16 // iip
208 st8.spill [r30]=r2,16 // r2
210 st8.spill [r31]=r3,16 // r3
216 st8.spill [r30]=r8,16 // r8
218 st8.spill [r31]=r9,16 // r9
224 st8.spill [r30]=r10,16 // r10
226 st8.spill [r31]=r11,16 // r11
232 st8.spill [r30]=r14 // r14
234 st8.spill [r31]=r15 // r15
245 st8.spill [r2]=r16,16 // r16
247 st8.spill [r3]=r17,16 // r17
253 st8.spill [r2]=r18,16 // r18
255 st8.spill [r3]=r19,16 // r19
261 st8.spill [r2]=r20,16 // r20
263 st8.spill [r3]=r21,16 // r21
269 st8.spill [r2]=r22,16 // r22
271 st8.spill [r3]=r23,16 // r23
276 st8.spill [r2]=r24,16 // r24
278 st8.spill [r3]=r25,16 // r25
281 st8.spill [r2]=r26,16 // r26
283 st8.spill [r3]=r27,16 // r27
286 st8.spill [r2]=r28,16 // r28
288 st8.spill [r3]=r29,16 // r29
291 st8.spill [r2]=r30,16 // r30
293 st8.spill [r3]=r31,16 // r31
297 st8 [r2]=r14,16 // b6
303 st8 [r3]=r15,16 // b7
309 st8 [r2]=r16,16 // ccv
310 st8 [r3]=r10,16 // csd
315 st8 [r2]=r11,24 // ssd
321 stf.spill [r3]=f6,32 // f6
322 stf.spill [r2]=f7,32 // f7
324 stf.spill [r3]=f8,32 // f8
325 stf.spill [r2]=f9,32 // f9
327 stf.spill [r3]=f10,32 // f10
328 stf.spill [r2]=f11,32 // f11
330 stf.spill [r3]=f12,32 // f12
331 stf.spill [r2]=f13,32 // f13
333 stf.spill [r3]=f14 // f14
334 stf.spill [r2]=f15 // f15
356 * exception_restore: restore interrupted state
359 * sp+16 trapframe pointer
361 ENTRY_NOPROFILE(exception_restore, 0)
369 add r3=SIZEOF_TRAPFRAME-32,sp
370 add r2=SIZEOF_TRAPFRAME-16,sp
371 add r8=SIZEOF_SPECIAL+16,sp
374 // The next load can trap. Let it be...
375 ldf.fill f15=[r2],-32 // f15
376 ldf.fill f14=[r3],-32 // f14
378 ldf.fill f13=[r2],-32 // f13
379 ldf.fill f12=[r3],-32 // f12
381 ldf.fill f11=[r2],-32 // f11
382 ldf.fill f10=[r3],-32 // f10
384 ldf.fill f9=[r2],-32 // f9
385 ldf.fill f8=[r3],-32 // f8
387 ldf.fill f7=[r2],-24 // f7
388 ldf.fill f6=[r3],-16 // f6
392 ld8 r8=[r8] // unat (after)
399 ld8 r10=[r2],-16 // ssd
400 ld8 r11=[r3],-16 // csd
405 ld8 r14=[r2],-16 // ccv
406 ld8 r15=[r3],-16 // b7
411 ld8 r8=[r2],-16 // b6
416 ld8.fill r31=[r3],-16 // r31
417 ld8.fill r30=[r2],-16 // r30
422 ld8.fill r29=[r3],-16 // r29
423 ld8.fill r28=[r2],-16 // r28
425 ld8.fill r27=[r3],-16 // r27
426 ld8.fill r26=[r2],-16 // r26
428 ld8.fill r25=[r3],-16 // r25
429 ld8.fill r24=[r2],-16 // r24
431 ld8.fill r23=[r3],-16 // r23
432 ld8.fill r22=[r2],-16 // r22
434 ld8.fill r21=[r3],-16 // r21
435 ld8.fill r20=[r2],-16 // r20
437 ld8.fill r19=[r3],-16 // r19
438 ld8.fill r18=[r2],-16 // r18
442 ld8.fill r17=[r3],-16 // r17
443 ld8.fill r16=[r2],-16 // r16
448 ld8.fill r15=[r3],-16 // r15
449 ld8.fill r14=[r2],-16 // r14
454 ld8 r16=[sp] // tf_length
455 ld8.fill r11=[r3],-16 // r11
460 ld8.fill r10=[r2],-16 // r10
461 ld8.fill r9=[r3],-16 // r9
462 add r16=r16,sp // ar.k7
466 ld8.fill r8=[r2],-16 // r8
467 ld8.fill r3=[r3] // r3
470 // We want nested TLB faults from here on...
472 ld8.fill r2=[r2] // r2
476 ld8.fill sp=[r31],16 // sp
480 ld8 r17=[r30],16 // unat
481 ld8 r29=[r31],16 // rp
483 ld8 r18=[r30],16 // pr
484 ld8 r28=[r31],16 // pfs
487 ld8 r20=[r30],24 // bspstore
488 ld8 r21=[r31],24 // rnat
491 ld8.fill r29=[r30],16 // tp
492 ld8 r22=[r31],16 // rsc
495 ld8 r23=[r30],16 // fpsr
496 ld8 r24=[r31],16 // psr
501 ld8.fill r1=[r30],16 // gp
502 ld8 r25=[r31],16 // ndirty
513 // Switch register stack
514 alloc r30=ar.pfs,0,0,0,0 // discard current frame
515 shl r31=r25,16 // value for ar.rsc
519 // The loadrs can fault if the backing store is not currently
520 // mapped. We assured forward progress by getting everything we
521 // need from the trapframe so that we don't care if the CPU
522 // purges that translation when it needs to insert a new one for
523 // the backing store.
525 mov ar.rsc=r31 // setup for loadrs
530 exception_restore_restart:
534 loadrs // load user regs
542 dep r31=0,r31,0,13 // 8KB aligned
568 END(exception_restore)
571 * Call exception_save_regs to preserve the interrupted state in a
572 * trapframe. Note that we don't use a call instruction because we
573 * must be careful not to lose track of the RSE state. We then call
574 * trap() with the value of _n_ as an argument to handle the
575 * exception. We arrange for trap() to return to exception_restore
576 * which will restore the interrupted state before executing an rfi to
579 #define CALL(_func_, _n_, _ifa_) \
583 br.sptk exception_save ; \
587 alloc r15=ar.pfs,0,0,2,0 ; \
593 br.call.sptk rp=_func_ ; \
598 br.sptk exception_restore ; \
601 #define IVT_ENTRY(name, offset) \
602 .org ia64_vector_table + offset; \
603 .global ivt_##name; \
606 .unwabi @svr4, 'I'; \
611 #define IVT_END(name) \
615 #define IA32_TRAP ia32_trap
617 #define IA32_TRAP trap
621 * The IA64 Interrupt Vector Table (IVT) contains 20 slots with 64
622 * bundles per vector and 48 slots with 16 bundles per vector.
625 .section .text.ivt,"ax"
628 .global ia64_vector_table
629 .size ia64_vector_table, 32768
632 IVT_ENTRY(VHPT_Translation, 0x0000)
633 CALL(trap, 0, cr.ifa)
634 IVT_END(VHPT_Translation)
636 IVT_ENTRY(Instruction_TLB, 0x0400)
643 add r21=16,r18 // tag
644 add r20=24,r18 // collision chain
646 ld8 r21=[r21] // check VHPT tag
647 ld8 r20=[r20] // bucket head
649 cmp.ne p15,p0=r21,r19
652 ld8 r21=[r18] // read pte
654 itc.i r21 // insert pte
659 1: ld8 r20=[r20] // first entry
661 rsm psr.dt // turn off data translations
665 2: cmp.eq p15,p0=r0,r20 // done?
666 (p15) br.cond.spnt.few 9f // bail if done
668 add r21=16,r20 // tag location
670 ld8 r21=[r21] // read tag
672 cmp.ne p15,p0=r21,r19 // compare tags
673 (p15) br.cond.sptk.few 3f // if not, read next in chain
675 ld8 r21=[r20],8 // read pte
677 ld8 r22=[r20] // read rest of pte
679 dep r18=0,r18,61,3 // convert vhpt ptr to physical
681 add r20=16,r18 // address of tag
683 ld8.acq r23=[r20] // read old tag
685 dep r23=-1,r23,63,1 // set ti bit
687 st8.rel [r20]=r23 // store old tag + ti
689 mf // make sure everyone sees
691 st8 [r18]=r21,8 // store pte
695 st8.rel [r18]=r19 // store new tag
697 itc.i r21 // and place in TLB
699 mov pr=r17,0x1ffff // restore predicates
702 3: add r20=24,r20 // next in chain
704 ld8 r20=[r20] // read chain
705 br.cond.sptk.few 2b // loop
707 9: mov pr=r17,0x1ffff // restore predicates
712 CALL(trap, 20, cr.ifa) // Page Not Present trap
713 IVT_END(Instruction_TLB)
715 IVT_ENTRY(Data_TLB, 0x0800)
722 add r21=16,r18 // tag
723 add r20=24,r18 // collision chain
725 ld8 r21=[r21] // check VHPT tag
726 ld8 r20=[r20] // bucket head
728 cmp.ne p15,p0=r21,r19
731 ld8 r21=[r18] // read pte
733 itc.d r21 // insert pte
738 1: ld8 r20=[r20] // first entry
740 rsm psr.dt // turn off data translations
744 2: cmp.eq p15,p0=r0,r20 // done?
745 (p15) br.cond.spnt.few 9f // bail if done
747 add r21=16,r20 // tag location
749 ld8 r21=[r21] // read tag
751 cmp.ne p15,p0=r21,r19 // compare tags
752 (p15) br.cond.sptk.few 3f // if not, read next in chain
754 ld8 r21=[r20],8 // read pte
756 ld8 r22=[r20] // read rest of pte
758 dep r18=0,r18,61,3 // convert vhpt ptr to physical
760 add r20=16,r18 // address of tag
762 ld8.acq r23=[r20] // read old tag
764 dep r23=-1,r23,63,1 // set ti bit
766 st8.rel [r20]=r23 // store old tag + ti
768 mf // make sure everyone sees
770 st8 [r18]=r21,8 // store pte
774 st8.rel [r18]=r19 // store new tag
776 itc.d r21 // and place in TLB
778 mov pr=r17,0x1ffff // restore predicates
781 3: add r20=24,r20 // next in chain
783 ld8 r20=[r20] // read chain
784 br.cond.sptk.few 2b // loop
786 9: mov pr=r17,0x1ffff // restore predicates
791 CALL(trap, 20, cr.ifa) // Page Not Present trap
794 IVT_ENTRY(Alternate_Instruction_TLB, 0x0c00)
795 mov r16=cr.ifa // where did it happen
796 mov r18=pr // save predicates
798 extr.u r17=r16,61,3 // get region number
800 cmp.ge p13,p0=5,r17 // RR0-RR5?
801 cmp.eq p15,p14=7,r17 // RR7->p15, RR6->p14
804 (p15) movl r17=PTE_PRESENT+PTE_MA_WB+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
806 (p14) movl r17=PTE_PRESENT+PTE_MA_UC+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
809 dep r16=0,r16,50,14 // clear bits above PPN
811 dep r16=r17,r16,0,12 // put pte bits in 0..11
814 mov pr=r18,0x1ffff // restore predicates
817 9: mov pr=r18,0x1ffff // restore predicates
818 CALL(trap, 3, cr.ifa)
819 IVT_END(Alternate_Instruction_TLB)
821 IVT_ENTRY(Alternate_Data_TLB, 0x1000)
822 mov r16=cr.ifa // where did it happen
823 mov r18=pr // save predicates
825 extr.u r17=r16,61,3 // get region number
827 cmp.ge p13,p0=5,r17 // RR0-RR5?
828 cmp.eq p15,p14=7,r17 // RR7->p15, RR6->p14
831 (p15) movl r17=PTE_PRESENT+PTE_MA_WB+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
833 (p14) movl r17=PTE_PRESENT+PTE_MA_UC+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
836 dep r16=0,r16,50,14 // clear bits above PPN
838 dep r16=r17,r16,0,12 // put pte bits in 0..11
841 mov pr=r18,0x1ffff // restore predicates
844 9: mov pr=r18,0x1ffff // restore predicates
845 CALL(trap, 4, cr.ifa)
846 IVT_END(Alternate_Data_TLB)
848 IVT_ENTRY(Data_Nested_TLB, 0x1400)
849 // See exception_save_restart and exception_restore_restart for the
850 // contexts that may cause a data nested TLB. We can only use the
851 // banked general registers and predicates, but don't use:
852 // p14 & p15 - Set in exception save
853 // r16 & r17 - Arguments to exception save
854 // r30 - Faulting address (modulo page size)
855 // We assume r30 has the virtual addresses that relate to the data
856 // nested TLB fault. The address does not have to be exact, as long
857 // as it's in the same page. We use physical addressing to avoid
858 // double nested faults. Since all virtual addresses we encounter
859 // here are direct mapped region 7 addresses, we have no problem
860 // constructing physical addresses.
869 extr.u r28=r30,PAGE_SHIFT,61-PAGE_SHIFT
874 shr.u r29=r28,PAGE_SHIFT-5 // dir index
875 extr.u r28=r28,0,PAGE_SHIFT-5 // pte index
892 add r27=r27,r28 // address of pte
902 or r28=PTE_DIRTY+PTE_ACCESSED,r28
907 movl r29=exception_save_restart
914 cmp.eq p12,p13=r26,r29
919 (p12) br.sptk exception_save_restart
920 (p13) br.sptk exception_restore_restart
923 IVT_END(Data_Nested_TLB)
925 IVT_ENTRY(Instruction_Key_Miss, 0x1800)
926 CALL(trap, 6, cr.ifa)
927 IVT_END(Instruction_Key_Miss)
929 IVT_ENTRY(Data_Key_Miss, 0x1c00)
930 CALL(trap, 7, cr.ifa)
931 IVT_END(Data_Key_Miss)
933 IVT_ENTRY(Dirty_Bit, 0x2000)
940 add r20=24,r18 // collision chain
942 ld8 r20=[r20] // bucket head
944 ld8 r20=[r20] // first entry
946 rsm psr.dt // turn off data translations
950 1: cmp.eq p15,p0=r0,r20 // done?
951 (p15) br.cond.spnt.few 9f // bail if done
953 add r21=16,r20 // tag location
955 ld8 r21=[r21] // read tag
957 cmp.ne p15,p0=r21,r19 // compare tags
958 (p15) br.cond.sptk.few 2f // if not, read next in chain
960 ld8 r21=[r20] // read pte
961 mov r22=PTE_DIRTY+PTE_ACCESSED
963 or r21=r22,r21 // set dirty & access bit
965 st8 [r20]=r21,8 // store back
967 ld8 r22=[r20] // read rest of pte
969 dep r18=0,r18,61,3 // convert vhpt ptr to physical
971 add r20=16,r18 // address of tag
973 ld8.acq r23=[r20] // read old tag
975 dep r23=-1,r23,63,1 // set ti bit
977 st8.rel [r20]=r23 // store old tag + ti
979 mf // make sure everyone sees
981 st8 [r18]=r21,8 // store pte
985 st8.rel [r18]=r19 // store new tag
987 itc.d r21 // and place in TLB
989 mov pr=r17,0x1ffff // restore predicates
992 2: add r20=24,r20 // next in chain
994 ld8 r20=[r20] // read chain
995 br.cond.sptk.few 1b // loop
997 9: mov pr=r17,0x1ffff // restore predicates
998 CALL(trap, 8, cr.ifa) // die horribly
1001 IVT_ENTRY(Instruction_Access_Bit, 0x2400)
1008 add r20=24,r18 // collision chain
1010 ld8 r20=[r20] // bucket head
1012 ld8 r20=[r20] // first entry
1014 rsm psr.dt // turn off data translations
1018 1: cmp.eq p15,p0=r0,r20 // done?
1019 (p15) br.cond.spnt.few 9f // bail if done
1021 add r21=16,r20 // tag location
1023 ld8 r21=[r21] // read tag
1025 cmp.ne p15,p0=r21,r19 // compare tags
1026 (p15) br.cond.sptk.few 2f // if not, read next in chain
1028 ld8 r21=[r20] // read pte
1029 mov r22=PTE_ACCESSED
1031 or r21=r22,r21 // set accessed bit
1033 st8 [r20]=r21,8 // store back
1035 ld8 r22=[r20] // read rest of pte
1037 dep r18=0,r18,61,3 // convert vhpt ptr to physical
1039 add r20=16,r18 // address of tag
1041 ld8.acq r23=[r20] // read old tag
1043 dep r23=-1,r23,63,1 // set ti bit
1045 st8.rel [r20]=r23 // store old tag + ti
1047 mf // make sure everyone sees
1049 st8 [r18]=r21,8 // store pte
1053 st8.rel [r18]=r19 // store new tag
1055 itc.i r21 // and place in TLB
1057 mov pr=r17,0x1ffff // restore predicates
1058 rfi // walker will retry the access
1060 2: add r20=24,r20 // next in chain
1062 ld8 r20=[r20] // read chain
1063 br.cond.sptk.few 1b // loop
1065 9: mov pr=r17,0x1ffff // restore predicates
1066 CALL(trap, 9, cr.ifa)
1067 IVT_END(Instruction_Access_Bit)
1069 IVT_ENTRY(Data_Access_Bit, 0x2800)
1076 add r20=24,r18 // collision chain
1078 ld8 r20=[r20] // bucket head
1080 ld8 r20=[r20] // first entry
1082 rsm psr.dt // turn off data translations
1086 1: cmp.eq p15,p0=r0,r20 // done?
1087 (p15) br.cond.spnt.few 9f // bail if done
1089 add r21=16,r20 // tag location
1091 ld8 r21=[r21] // read tag
1093 cmp.ne p15,p0=r21,r19 // compare tags
1094 (p15) br.cond.sptk.few 2f // if not, read next in chain
1096 ld8 r21=[r20] // read pte
1097 mov r22=PTE_ACCESSED
1099 or r21=r22,r21 // set accessed bit
1101 st8 [r20]=r21,8 // store back
1103 ld8 r22=[r20] // read rest of pte
1105 dep r18=0,r18,61,3 // convert vhpt ptr to physical
1107 add r20=16,r18 // address of tag
1109 ld8.acq r23=[r20] // read old tag
1111 dep r23=-1,r23,63,1 // set ti bit
1113 st8.rel [r20]=r23 // store old tag + ti
1115 mf // make sure everyone sees
1117 st8 [r18]=r21,8 // store pte
1121 st8.rel [r18]=r19 // store new tag
1123 itc.d r21 // and place in TLB
1125 mov pr=r17,0x1ffff // restore predicates
1126 rfi // walker will retry the access
1128 2: add r20=24,r20 // next in chain
1130 ld8 r20=[r20] // read chain
1131 br.cond.sptk.few 1b // loop
1133 9: mov pr=r17,0x1ffff // restore predicates
1134 CALL(trap, 10, cr.ifa)
1135 IVT_END(Data_Access_Bit)
1137 IVT_ENTRY(Break_Instruction, 0x2c00)
1141 br.sptk exception_save
1145 alloc r15=ar.pfs,0,0,2,0
1154 br.call.sptk rp=trap
1160 br.sptk exception_restore
1163 IVT_END(Break_Instruction)
1165 IVT_ENTRY(External_Interrupt, 0x3000)
1167 mov r17=cr.lid // cr.iim and cr.ifa are undefined.
1169 br.sptk exception_save
1172 alloc r14=ar.pfs,0,0,2,0
1177 mov out0=cr.ivr // Get interrupt vector
1180 cmp.eq p15,p0=15,out0 // check for spurious vector number
1183 ssm psr.i // re-enable interrupts
1184 (p15) br.dpnt.few 2f // if spurious, we are done
1185 br.call.sptk.many rp=interrupt // call high-level handler
1189 rsm psr.i // disable interrupts
1195 mov cr.eoi=r0 // ack the interrupt
1201 cmp4.eq p14,p0=0,r8 // Return to kernel mode?
1203 br.sptk 1b // loop for more
1209 (p14) br.sptk exception_restore
1210 br.call.sptk rp=do_ast
1216 br.sptk exception_restore
1219 IVT_END(External_Interrupt)
1221 IVT_ENTRY(Reserved_3400, 0x3400)
1222 CALL(trap, 13, cr.ifa)
1223 IVT_END(Reserved_3400)
1225 IVT_ENTRY(Reserved_3800, 0x3800)
1226 CALL(trap, 14, cr.ifa)
1227 IVT_END(Reserved_3800)
1229 IVT_ENTRY(Reserved_3c00, 0x3c00)
1230 CALL(trap, 15, cr.ifa)
1231 IVT_END(Reserved_3c00)
1233 IVT_ENTRY(Reserved_4000, 0x4000)
1234 CALL(trap, 16, cr.ifa)
1235 IVT_END(Reserved_4000)
1237 IVT_ENTRY(Reserved_4400, 0x4400)
1238 CALL(trap, 17, cr.ifa)
1239 IVT_END(Reserved_4400)
1241 IVT_ENTRY(Reserved_4800, 0x4800)
1242 CALL(trap, 18, cr.ifa)
1243 IVT_END(Reserved_4800)
1245 IVT_ENTRY(Reserved_4c00, 0x4c00)
1246 CALL(trap, 19, cr.ifa)
1247 IVT_END(Reserved_4c00)
1249 IVT_ENTRY(Page_Not_Present, 0x5000)
1250 CALL(trap, 20, cr.ifa)
1251 IVT_END(Page_Not_Present)
1253 IVT_ENTRY(Key_Permission, 0x5100)
1254 CALL(trap, 21, cr.ifa)
1255 IVT_END(Key_Permission)
1257 IVT_ENTRY(Instruction_Access_Rights, 0x5200)
1258 CALL(trap, 22, cr.ifa)
1259 IVT_END(Instruction_Access_Rights)
1261 IVT_ENTRY(Data_Access_Rights, 0x5300)
1262 CALL(trap, 23, cr.ifa)
1263 IVT_END(Data_Access_Rights)
1265 IVT_ENTRY(General_Exception, 0x5400)
1266 CALL(trap, 24, cr.ifa)
1267 IVT_END(General_Exception)
1269 IVT_ENTRY(Disabled_FP_Register, 0x5500)
1270 CALL(trap, 25, cr.ifa)
1271 IVT_END(Disabled_FP_Register)
1273 IVT_ENTRY(NaT_Consumption, 0x5600)
1274 CALL(trap, 26, cr.ifa)
1275 IVT_END(NaT_Consumption)
1277 IVT_ENTRY(Speculation, 0x5700)
1278 CALL(trap, 27, cr.iim)
1279 IVT_END(Speculation)
1281 IVT_ENTRY(Reserved_5800, 0x5800)
1282 CALL(trap, 28, cr.ifa)
1283 IVT_END(Reserved_5800)
1285 IVT_ENTRY(Debug, 0x5900)
1286 CALL(trap, 29, cr.ifa)
1289 IVT_ENTRY(Unaligned_Reference, 0x5a00)
1290 CALL(trap, 30, cr.ifa)
1291 IVT_END(Unaligned_Reference)
1293 IVT_ENTRY(Unsupported_Data_Reference, 0x5b00)
1294 CALL(trap, 31, cr.ifa)
1295 IVT_END(Unsupported_Data_Reference)
1297 IVT_ENTRY(Floating_Point_Fault, 0x5c00)
1298 CALL(trap, 32, cr.ifa)
1299 IVT_END(Floating_Point_Fault)
1301 IVT_ENTRY(Floating_Point_Trap, 0x5d00)
1302 CALL(trap, 33, cr.ifa)
1303 IVT_END(Floating_Point_Trap)
1305 IVT_ENTRY(Lower_Privilege_Transfer_Trap, 0x5e00)
1306 CALL(trap, 34, cr.ifa)
1307 IVT_END(Lower_Privilege_Transfer_Trap)
1309 IVT_ENTRY(Taken_Branch_Trap, 0x5f00)
1310 CALL(trap, 35, cr.ifa)
1311 IVT_END(Taken_Branch_Trap)
1313 IVT_ENTRY(Single_Step_Trap, 0x6000)
1314 CALL(trap, 36, cr.ifa)
1315 IVT_END(Single_Step_Trap)
1317 IVT_ENTRY(Reserved_6100, 0x6100)
1318 CALL(trap, 37, cr.ifa)
1319 IVT_END(Reserved_6100)
1321 IVT_ENTRY(Reserved_6200, 0x6200)
1322 CALL(trap, 38, cr.ifa)
1323 IVT_END(Reserved_6200)
1325 IVT_ENTRY(Reserved_6300, 0x6300)
1326 CALL(trap, 39, cr.ifa)
1327 IVT_END(Reserved_6300)
1329 IVT_ENTRY(Reserved_6400, 0x6400)
1330 CALL(trap, 40, cr.ifa)
1331 IVT_END(Reserved_6400)
1333 IVT_ENTRY(Reserved_6500, 0x6500)
1334 CALL(trap, 41, cr.ifa)
1335 IVT_END(Reserved_6500)
1337 IVT_ENTRY(Reserved_6600, 0x6600)
1338 CALL(trap, 42, cr.ifa)
1339 IVT_END(Reserved_6600)
1341 IVT_ENTRY(Reserved_6700, 0x6700)
1342 CALL(trap, 43, cr.ifa)
1343 IVT_END(Reserved_6700)
1345 IVT_ENTRY(Reserved_6800, 0x6800)
1346 CALL(trap, 44, cr.ifa)
1347 IVT_END(Reserved_6800)
1349 IVT_ENTRY(IA_32_Exception, 0x6900)
1350 CALL(IA32_TRAP, 45, cr.ifa)
1351 IVT_END(IA_32_Exception)
1353 IVT_ENTRY(IA_32_Intercept, 0x6a00)
1354 CALL(IA32_TRAP, 46, cr.iim)
1355 IVT_END(IA_32_Intercept)
1357 IVT_ENTRY(IA_32_Interrupt, 0x6b00)
1358 CALL(IA32_TRAP, 47, cr.ifa)
1359 IVT_END(IA_32_Interrupt)
1361 IVT_ENTRY(Reserved_6c00, 0x6c00)
1362 CALL(trap, 48, cr.ifa)
1363 IVT_END(Reserved_6c00)
1365 IVT_ENTRY(Reserved_6d00, 0x6d00)
1366 CALL(trap, 49, cr.ifa)
1367 IVT_END(Reserved_6d00)
1369 IVT_ENTRY(Reserved_6e00, 0x6e00)
1370 CALL(trap, 50, cr.ifa)
1371 IVT_END(Reserved_6e00)
1373 IVT_ENTRY(Reserved_6f00, 0x6f00)
1374 CALL(trap, 51, cr.ifa)
1375 IVT_END(Reserved_6f00)
1377 IVT_ENTRY(Reserved_7000, 0x7000)
1378 CALL(trap, 52, cr.ifa)
1379 IVT_END(Reserved_7000)
1381 IVT_ENTRY(Reserved_7100, 0x7100)
1382 CALL(trap, 53, cr.ifa)
1383 IVT_END(Reserved_7100)
1385 IVT_ENTRY(Reserved_7200, 0x7200)
1386 CALL(trap, 54, cr.ifa)
1387 IVT_END(Reserved_7200)
1389 IVT_ENTRY(Reserved_7300, 0x7300)
1390 CALL(trap, 55, cr.ifa)
1391 IVT_END(Reserved_7300)
1393 IVT_ENTRY(Reserved_7400, 0x7400)
1394 CALL(trap, 56, cr.ifa)
1395 IVT_END(Reserved_7400)
1397 IVT_ENTRY(Reserved_7500, 0x7500)
1398 CALL(trap, 57, cr.ifa)
1399 IVT_END(Reserved_7500)
1401 IVT_ENTRY(Reserved_7600, 0x7600)
1402 CALL(trap, 58, cr.ifa)
1403 IVT_END(Reserved_7600)
1405 IVT_ENTRY(Reserved_7700, 0x7700)
1406 CALL(trap, 59, cr.ifa)
1407 IVT_END(Reserved_7700)
1409 IVT_ENTRY(Reserved_7800, 0x7800)
1410 CALL(trap, 60, cr.ifa)
1411 IVT_END(Reserved_7800)
1413 IVT_ENTRY(Reserved_7900, 0x7900)
1414 CALL(trap, 61, cr.ifa)
1415 IVT_END(Reserved_7900)
1417 IVT_ENTRY(Reserved_7a00, 0x7a00)
1418 CALL(trap, 62, cr.ifa)
1419 IVT_END(Reserved_7a00)
1421 IVT_ENTRY(Reserved_7b00, 0x7b00)
1422 CALL(trap, 63, cr.ifa)
1423 IVT_END(Reserved_7b00)
1425 IVT_ENTRY(Reserved_7c00, 0x7c00)
1426 CALL(trap, 64, cr.ifa)
1427 IVT_END(Reserved_7c00)
1429 IVT_ENTRY(Reserved_7d00, 0x7d00)
1430 CALL(trap, 65, cr.ifa)
1431 IVT_END(Reserved_7d00)
1433 IVT_ENTRY(Reserved_7e00, 0x7e00)
1434 CALL(trap, 66, cr.ifa)
1435 IVT_END(Reserved_7e00)
1437 IVT_ENTRY(Reserved_7f00, 0x7f00)
1438 CALL(trap, 67, cr.ifa)
1439 IVT_END(Reserved_7f00)