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 "opt_xtrace.h"
33 #include <machine/pte.h>
37 * Nested TLB restart tokens. These are used by the
38 * nested TLB handler for jumping back to the code
39 * where the nested TLB was caused.
41 #define NTLBRT_SAVE 0x12c12c
42 #define NTLBRT_RESTORE 0x12c12d
45 * ar.k7 = kernel memory stack
46 * ar.k6 = kernel register stack
47 * ar.k5 = EPC gateway page
51 #ifdef EXCEPTION_TRACING
55 xtrace: .space 1024*5*8
58 #define XTRACE(offset) \
88 cmp.eq p15,p0=r27,r28 ; \
89 addl r29=1024*5*8,r0 ;; \
90 (p15) sub r27=r28,r29 ;; \
95 mov pr=r25,0x1ffff ;; \
100 #define XTRACE(offset)
107 * exception_save: save interrupted state
110 * r16 address of bundle that contains the branch. The
111 * return address will be the next bundle.
112 * r17 the value to save as ifa in the trapframe. This
113 * normally is cr.ifa, but some interruptions set
114 * set cr.iim and not cr.ifa.
117 * p15 interrupted from user stack
118 * p14 interrupted from kernel stack
119 * p13 interrupted from user backing store
120 * p12 interrupted from kernel backing store
121 * p11 interrupts were enabled
122 * p10 interrupts were disabled
124 ENTRY_NOPROFILE(exception_save, 0)
134 (p15) mov r23=ar.k7 // kernel memory stack
140 add r30=-SIZEOF_TRAPFRAME,r23
154 addl r29=NTLBRT_SAVE,r0 // 22-bit restart token.
159 * We have a 1KB aligned trapframe, pointed to by sp. If we write
160 * to the trapframe, we may trigger a data nested TLB fault. By
161 * aligning the trapframe on a 1KB boundary, we guarantee that if
162 * we get a data nested TLB fault, it will be on the very first
163 * write. Since the data nested TLB fault does not preserve any
164 * state, we have to be careful what we clobber. Consequently, we
165 * have to be careful what we use here. Below a list of registers
166 * that are currently alive:
168 * r18=pr, r19=length, r20=unat, r21=rsc, r22=iip, r23=TOS
170 * r30,r31=trapframe pointers
171 * p14,p15=memory stack switch
174 /* PTC.G enter non-exclusive */
176 movl r25 = pmap_ptc_g_sem
181 tbit.nz p12, p0 = r26, 63
182 (p12) br.cond.spnt.few .ptc_g_0
187 cmpxchg8.rel r27 = [r25], r27, ar.ccv
189 cmp.ne p12, p0 = r26, r27
190 (p12) br.cond.spnt.few .ptc_g_0
194 exception_save_restart:
196 st8 [r30]=r19,16 // length
197 st8 [r31]=r0,16 // flags
202 st8.spill [r30]=sp,16 // sp
203 st8 [r31]=r20,16 // unat
213 // r18=pr, r19=rnat, r20=bspstore, r21=rsc, r22=iip, r23=rp
215 st8 [r30]=r23,16 // rp
216 st8 [r31]=r18,16 // pr
221 st8 [r30]=r24,16 // pfs
222 st8 [r31]=r20,16 // bspstore
232 // r18=fpsr, r19=rnat, r20=bspstore, r21=rsc, r22=iip, r23=ipsr
234 st8 [r30]=r19,16 // rnat
235 st8 [r31]=r0,16 // __spare
240 st8.spill [r30]=r13,16 // tp
241 st8 [r31]=r21,16 // rsc
242 tbit.nz p11,p10=r23,14 // p11=interrupts enabled
246 (p13) mov r21=ar.k6 // kernel register stack
248 st8 [r30]=r18,16 // fpsr
249 (p13) dep r20=r20,r21,0,9 // align dirty registers
252 // r19=rnat, r20=bspstore, r22=iip, r23=ipsr
254 st8 [r31]=r23,16 // psr
255 (p13) mov ar.bspstore=r20
260 (p13) mov ar.rnat=r19
267 st8.spill [r30]=gp,16 // gp
273 st8 [r31]=r18,16 // ndirty
274 st8 [r30]=r19,16 // cfm
280 st8 [r31]=r22,16 // iip
285 st8 [r30]=r17,24 // ifa
286 st8 [r31]=r18,24 // isr
292 st8.spill [r30]=r2,16 // r2
294 st8.spill [r31]=r3,16 // r3
300 st8.spill [r30]=r8,16 // r8
302 st8.spill [r31]=r9,16 // r9
308 st8.spill [r30]=r10,16 // r10
310 st8.spill [r31]=r11,16 // r11
316 st8.spill [r30]=r14 // r14
318 st8.spill [r31]=r15 // r15
329 st8.spill [r2]=r16,16 // r16
331 st8.spill [r3]=r17,16 // r17
337 st8.spill [r2]=r18,16 // r18
339 st8.spill [r3]=r19,16 // r19
345 st8.spill [r2]=r20,16 // r20
347 st8.spill [r3]=r21,16 // r21
353 st8.spill [r2]=r22,16 // r22
355 st8.spill [r3]=r23,16 // r23
360 st8.spill [r2]=r24,16 // r24
362 st8.spill [r3]=r25,16 // r25
365 st8.spill [r2]=r26,16 // r26
367 st8.spill [r3]=r27,16 // r27
370 st8.spill [r2]=r28,16 // r28
372 st8.spill [r3]=r29,16 // r29
375 st8.spill [r2]=r30,16 // r30
377 st8.spill [r3]=r31,16 // r31
381 st8 [r2]=r14,16 // b6
387 st8 [r3]=r15,16 // b7
393 st8 [r2]=r16,16 // ccv
394 st8 [r3]=r10,16 // csd
399 st8 [r2]=r11,24 // ssd
405 stf.spill [r3]=f6,32 // f6
406 stf.spill [r2]=f7,32 // f7
408 stf.spill [r3]=f8,32 // f8
409 stf.spill [r2]=f9,32 // f9
411 stf.spill [r3]=f10,32 // f10
412 stf.spill [r2]=f11,32 // f11
414 stf.spill [r3]=f12,32 // f12
415 stf.spill [r2]=f13,32 // f13
417 stf.spill [r3]=f14 // f14
418 stf.spill [r2]=f15 // f15
432 /* PTC.G leave non-exclusive */
434 movl r25 = pmap_ptc_g_sem
442 cmpxchg8.rel r27 = [r25], r27, ar.ccv
444 cmp.ne p12, p0 = r26, r27
445 (p12) br.cond.spnt.few .ptc_g_1
457 * exception_restore: restore interrupted state
460 * sp+16 trapframe pointer
462 ENTRY_NOPROFILE(exception_restore, 0)
465 add r3=SIZEOF_TRAPFRAME-16,sp
466 add r2=SIZEOF_TRAPFRAME,sp
471 add r8=SIZEOF_SPECIAL+32,sp
475 // The next load can trap. Let it be...
476 ldf.fill f15=[r2],-32 // f15
477 ldf.fill f14=[r3],-32 // f14
480 ldf.fill f13=[r2],-32 // f13
481 ldf.fill f12=[r3],-32 // f12
483 ldf.fill f11=[r2],-32 // f11
484 ldf.fill f10=[r3],-32 // f10
486 ldf.fill f9=[r2],-32 // f9
487 ldf.fill f8=[r3],-32 // f8
489 ldf.fill f7=[r2],-24 // f7
490 ldf.fill f6=[r3],-16 // f6
494 ld8 r8=[r8] // unat (after)
501 ld8 r10=[r2],-16 // ssd
502 ld8 r11=[r3],-16 // csd
507 ld8 r14=[r2],-16 // ccv
508 ld8 r15=[r3],-16 // b7
513 ld8 r8=[r2],-16 // b6
518 ld8.fill r31=[r3],-16 // r31
519 ld8.fill r30=[r2],-16 // r30
524 ld8.fill r29=[r3],-16 // r29
525 ld8.fill r28=[r2],-16 // r28
527 ld8.fill r27=[r3],-16 // r27
528 ld8.fill r26=[r2],-16 // r26
530 ld8.fill r25=[r3],-16 // r25
531 ld8.fill r24=[r2],-16 // r24
533 ld8.fill r23=[r3],-16 // r23
534 ld8.fill r22=[r2],-16 // r22
536 ld8.fill r21=[r3],-16 // r21
537 ld8.fill r20=[r2],-16 // r20
539 ld8.fill r19=[r3],-16 // r19
540 ld8.fill r18=[r2],-16 // r18
544 ld8.fill r17=[r3],-16 // r17
545 ld8.fill r16=[r2],-16 // r16
550 ld8.fill r15=[r3],-16 // r15
551 ld8.fill r14=[r2],-16 // r14
556 ld8 r16=[sp] // tf_length
557 ld8.fill r11=[r3],-16 // r11
562 ld8.fill r10=[r2],-16 // r10
563 ld8.fill r9=[r3],-16 // r9
564 add r16=r16,sp // ar.k7
568 ld8.fill r8=[r2],-16 // r8
569 ld8.fill r3=[r3] // r3
572 // We want nested TLB faults from here on...
574 ld8.fill r2=[r2] // r2
578 ld8.fill sp=[r31],16 // sp
582 ld8 r17=[r30],16 // unat
583 ld8 r29=[r31],16 // rp
585 ld8 r18=[r30],16 // pr
586 ld8 r28=[r31],16 // pfs
589 ld8 r20=[r30],24 // bspstore
590 ld8 r21=[r31],24 // rnat
593 ld8.fill r26=[r30],16 // tp
594 ld8 r22=[r31],16 // rsc
597 ld8 r23=[r30],16 // fpsr
598 ld8 r24=[r31],16 // psr
603 ld8.fill r1=[r30],16 // gp
604 ld8 r27=[r31],16 // ndirty
615 // Switch register stack
616 alloc r30=ar.pfs,0,0,0,0 // discard current frame
617 shl r31=r27,16 // value for ar.rsc
621 // The loadrs can fault if the backing store is not currently
622 // mapped. We assured forward progress by getting everything we
623 // need from the trapframe so that we don't care if the CPU
624 // purges that translation when it needs to insert a new one for
625 // the backing store.
627 mov ar.rsc=r31 // setup for loadrs
629 addl r29=NTLBRT_RESTORE,r0 // 22-bit restart token
632 exception_restore_restart:
636 loadrs // load user regs
644 dep r31=0,r31,0,13 // 8KB aligned
670 END(exception_restore)
673 * Call exception_save_regs to preserve the interrupted state in a
674 * trapframe. Note that we don't use a call instruction because we
675 * must be careful not to lose track of the RSE state. We then call
676 * trap() with the value of _n_ as an argument to handle the
677 * exception. We arrange for trap() to return to exception_restore
678 * which will restore the interrupted state before executing an rfi to
681 #define CALL(_func_, _n_, _ifa_) \
685 br.sptk exception_save ;; \
688 alloc r15=ar.pfs,0,0,2,0 ;; \
695 br.call.sptk rp=_func_ ;; \
700 br.sptk exception_restore ;; \
703 #define IVT_ENTRY(name, offset) \
704 .org ia64_vector_table + offset; \
705 .global ivt_##name; \
708 .unwabi @svr4, 'I'; \
714 #define IVT_END(name) \
717 #ifdef COMPAT_FREEBSD32
718 #define IA32_TRAP ia32_trap
720 #define IA32_TRAP trap
724 * The IA64 Interrupt Vector Table (IVT) contains 20 slots with 64
725 * bundles per vector and 48 slots with 16 bundles per vector.
728 .section .text.ivt,"ax"
731 .global ia64_vector_table
732 .size ia64_vector_table, 32768
735 IVT_ENTRY(VHPT_Translation, 0x0000)
736 CALL(trap, 0, cr.ifa)
737 IVT_END(VHPT_Translation)
739 IVT_ENTRY(Instruction_TLB, 0x0400)
746 add r21=16,r18 // tag
747 add r20=24,r18 // collision chain
749 ld8 r21=[r21] // check VHPT tag
750 ld8 r20=[r20] // bucket head
752 cmp.ne p15,p0=r21,r19
755 ld8 r21=[r18] // read pte
757 itc.i r21 // insert pte
762 1: rsm psr.dt // turn off data translations
763 dep r20=0,r20,61,3 // convert vhpt ptr to physical
766 ld8 r20=[r20] // first entry
768 2: cmp.eq p15,p0=r0,r20 // done?
769 (p15) br.cond.spnt.few 9f // bail if done
771 add r21=16,r20 // tag location
773 ld8 r21=[r21] // read tag
775 cmp.ne p15,p0=r21,r19 // compare tags
776 (p15) br.cond.sptk.few 3f // if not, read next in chain
778 ld8 r21=[r20] // read pte
785 ld8 r22=[r20] // read rest of pte
787 dep r18=0,r18,61,3 // convert vhpt ptr to physical
789 add r20=16,r18 // address of tag
791 ld8.acq r23=[r20] // read old tag
793 dep r23=-1,r23,63,1 // set ti bit
795 st8.rel [r20]=r23 // store old tag + ti
797 mf // make sure everyone sees
799 st8 [r18]=r21,8 // store pte
803 st8.rel [r18]=r19 // store new tag
805 itc.i r21 // and place in TLB
809 mov pr=r17,0x1ffff // restore predicates
812 3: add r20=24,r20 // next in chain
814 ld8 r20=[r20] // read chain
815 br.cond.sptk.few 2b // loop
818 mov pr=r17,0x1ffff // restore predicates
822 CALL(trap, 20, cr.ifa) // Page Not Present trap
823 IVT_END(Instruction_TLB)
825 IVT_ENTRY(Data_TLB, 0x0800)
832 add r21=16,r18 // tag
833 add r20=24,r18 // collision chain
835 ld8 r21=[r21] // check VHPT tag
836 ld8 r20=[r20] // bucket head
838 cmp.ne p15,p0=r21,r19
841 ld8 r21=[r18] // read pte
843 itc.d r21 // insert pte
848 1: rsm psr.dt // turn off data translations
849 dep r20=0,r20,61,3 // convert vhpt ptr to physical
852 ld8 r20=[r20] // first entry
854 2: cmp.eq p15,p0=r0,r20 // done?
855 (p15) br.cond.spnt.few 9f // bail if done
857 add r21=16,r20 // tag location
859 ld8 r21=[r21] // read tag
861 cmp.ne p15,p0=r21,r19 // compare tags
862 (p15) br.cond.sptk.few 3f // if not, read next in chain
864 ld8 r21=[r20] // read pte
871 ld8 r22=[r20] // read rest of pte
873 dep r18=0,r18,61,3 // convert vhpt ptr to physical
875 add r20=16,r18 // address of tag
877 ld8.acq r23=[r20] // read old tag
879 dep r23=-1,r23,63,1 // set ti bit
881 st8.rel [r20]=r23 // store old tag + ti
883 mf // make sure everyone sees
885 st8 [r18]=r21,8 // store pte
889 st8.rel [r18]=r19 // store new tag
891 itc.d r21 // and place in TLB
895 mov pr=r17,0x1ffff // restore predicates
898 3: add r20=24,r20 // next in chain
900 ld8 r20=[r20] // read chain
901 br.cond.sptk.few 2b // loop
904 mov pr=r17,0x1ffff // restore predicates
908 CALL(trap, 20, cr.ifa) // Page Not Present trap
911 IVT_ENTRY(Alternate_Instruction_TLB, 0x0c00)
912 mov r16=cr.ifa // where did it happen
913 mov r18=pr // save predicates
915 extr.u r17=r16,61,3 // get region number
917 cmp.ge p13,p0=5,r17 // RR0-RR5?
918 cmp.eq p15,p14=7,r17 // RR7->p15, RR6->p14
921 (p15) movl r17=PTE_PRESENT+PTE_MA_WB+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
923 (p14) movl r17=PTE_PRESENT+PTE_MA_UC+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
926 dep r16=0,r16,50,14 // clear bits above PPN
928 dep r16=r17,r16,0,12 // put pte bits in 0..11
931 mov pr=r18,0x1ffff // restore predicates
935 9: mov pr=r18,0x1ffff // restore predicates
936 CALL(trap, 3, cr.ifa)
937 IVT_END(Alternate_Instruction_TLB)
939 IVT_ENTRY(Alternate_Data_TLB, 0x1000)
940 mov r16=cr.ifa // where did it happen
941 mov r18=pr // save predicates
943 extr.u r17=r16,61,3 // get region number
945 cmp.ge p13,p0=5,r17 // RR0-RR5?
946 cmp.eq p15,p14=7,r17 // RR7->p15, RR6->p14
949 (p15) movl r17=PTE_PRESENT+PTE_MA_WB+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
951 (p14) movl r17=PTE_PRESENT+PTE_MA_UC+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
954 dep r16=0,r16,50,14 // clear bits above PPN
956 dep r16=r17,r16,0,12 // put pte bits in 0..11
959 mov pr=r18,0x1ffff // restore predicates
963 9: mov pr=r18,0x1ffff // restore predicates
964 CALL(trap, 4, cr.ifa)
965 IVT_END(Alternate_Data_TLB)
967 IVT_ENTRY(Data_Nested_TLB, 0x1400)
968 // See exception_save_restart and exception_restore_restart for the
969 // contexts that may cause a data nested TLB. We can only use the
970 // banked general registers and predicates, but don't use:
971 // p14 & p15 - Set in exception save
972 // r16 & r17 - Arguments to exception save
973 // r30 - Faulting address (modulo page size)
974 // We assume r30 has the virtual addresses that relate to the data
975 // nested TLB fault. The address does not have to be exact, as long
976 // as it's in the same page. We use physical addressing to avoid
977 // double nested faults. Since all virtual addresses we encounter
978 // here are direct mapped region 7 addresses, we have no problem
979 // constructing physical addresses.
989 extr.u r28=r30,3*PAGE_SHIFT-8, PAGE_SHIFT-3 // dir L0 index
992 ld8 r27=[r27] // dir L0 page
993 extr.u r26=r30,2*PAGE_SHIFT-5, PAGE_SHIFT-3 // dir L1 index
1001 ld8 r27=[r27] // dir L1 page
1002 extr.u r28=r30,PAGE_SHIFT,PAGE_SHIFT-5 // pte index
1006 shladd r27=r26,3,r27
1013 ld8 r27=[r27] // pte page
1026 ld8 r28=[r27] // pte
1029 or r28=PTE_DIRTY+PTE_ACCESSED,r28
1035 addl r26=NTLBRT_SAVE,r0
1036 addl r27=NTLBRT_RESTORE,r0
1042 cmp.eq p12,p0=r29,r26
1047 cmp.eq p13,p0=r29,r27
1048 (p12) br.sptk exception_save_restart
1054 (p13) br.sptk exception_restore_restart
1065 addl r27=KSTACK_PAGES*PAGE_SIZE-16,r0
1076 IVT_END(Data_Nested_TLB)
1078 IVT_ENTRY(Instruction_Key_Miss, 0x1800)
1079 CALL(trap, 6, cr.ifa)
1080 IVT_END(Instruction_Key_Miss)
1082 IVT_ENTRY(Data_Key_Miss, 0x1c00)
1083 CALL(trap, 7, cr.ifa)
1084 IVT_END(Data_Key_Miss)
1086 IVT_ENTRY(Dirty_Bit, 0x2000)
1093 add r20=24,r18 // collision chain
1095 ld8 r20=[r20] // bucket head
1097 rsm psr.dt // turn off data translations
1098 dep r20=0,r20,61,3 // convert vhpt ptr to physical
1101 ld8 r20=[r20] // first entry
1103 1: cmp.eq p15,p0=r0,r20 // done?
1104 (p15) br.cond.spnt.few 9f // bail if done
1106 add r21=16,r20 // tag location
1108 ld8 r21=[r21] // read tag
1110 cmp.ne p15,p0=r21,r19 // compare tags
1111 (p15) br.cond.sptk.few 2f // if not, read next in chain
1113 ld8 r21=[r20] // read pte
1114 mov r22=PTE_DIRTY+PTE_ACCESSED
1116 or r21=r22,r21 // set dirty & access bit
1118 st8 [r20]=r21,8 // store back
1120 ld8 r22=[r20] // read rest of pte
1122 dep r18=0,r18,61,3 // convert vhpt ptr to physical
1124 add r20=16,r18 // address of tag
1126 ld8.acq r23=[r20] // read old tag
1128 dep r23=-1,r23,63,1 // set ti bit
1130 st8.rel [r20]=r23 // store old tag + ti
1132 mf // make sure everyone sees
1134 st8 [r18]=r21,8 // store pte
1138 st8.rel [r18]=r19 // store new tag
1140 itc.d r21 // and place in TLB
1144 mov pr=r17,0x1ffff // restore predicates
1147 2: add r20=24,r20 // next in chain
1149 ld8 r20=[r20] // read chain
1150 br.cond.sptk.few 1b // loop
1153 mov pr=r17,0x1ffff // restore predicates
1157 CALL(trap, 8, cr.ifa) // die horribly
1160 IVT_ENTRY(Instruction_Access_Bit, 0x2400)
1167 add r20=24,r18 // collision chain
1169 ld8 r20=[r20] // bucket head
1171 rsm psr.dt // turn off data translations
1172 dep r20=0,r20,61,3 // convert vhpt ptr to physical
1175 ld8 r20=[r20] // first entry
1177 1: cmp.eq p15,p0=r0,r20 // done?
1178 (p15) br.cond.spnt.few 9f // bail if done
1180 add r21=16,r20 // tag location
1182 ld8 r21=[r21] // read tag
1184 cmp.ne p15,p0=r21,r19 // compare tags
1185 (p15) br.cond.sptk.few 2f // if not, read next in chain
1187 ld8 r21=[r20] // read pte
1188 mov r22=PTE_ACCESSED
1190 or r21=r22,r21 // set accessed bit
1192 st8 [r20]=r21,8 // store back
1194 ld8 r22=[r20] // read rest of pte
1196 dep r18=0,r18,61,3 // convert vhpt ptr to physical
1198 add r20=16,r18 // address of tag
1200 ld8.acq r23=[r20] // read old tag
1202 dep r23=-1,r23,63,1 // set ti bit
1204 st8.rel [r20]=r23 // store old tag + ti
1206 mf // make sure everyone sees
1208 st8 [r18]=r21,8 // store pte
1212 st8.rel [r18]=r19 // store new tag
1214 itc.i r21 // and place in TLB
1218 mov pr=r17,0x1ffff // restore predicates
1219 rfi // walker will retry the access
1221 2: add r20=24,r20 // next in chain
1223 ld8 r20=[r20] // read chain
1224 br.cond.sptk.few 1b // loop
1227 mov pr=r17,0x1ffff // restore predicates
1231 CALL(trap, 9, cr.ifa)
1232 IVT_END(Instruction_Access_Bit)
1234 IVT_ENTRY(Data_Access_Bit, 0x2800)
1241 add r20=24,r18 // collision chain
1243 ld8 r20=[r20] // bucket head
1245 rsm psr.dt // turn off data translations
1246 dep r20=0,r20,61,3 // convert vhpt ptr to physical
1249 ld8 r20=[r20] // first entry
1251 1: cmp.eq p15,p0=r0,r20 // done?
1252 (p15) br.cond.spnt.few 9f // bail if done
1254 add r21=16,r20 // tag location
1256 ld8 r21=[r21] // read tag
1258 cmp.ne p15,p0=r21,r19 // compare tags
1259 (p15) br.cond.sptk.few 2f // if not, read next in chain
1261 ld8 r21=[r20] // read pte
1262 mov r22=PTE_ACCESSED
1264 or r21=r22,r21 // set accessed bit
1266 st8 [r20]=r21,8 // store back
1268 ld8 r22=[r20] // read rest of pte
1270 dep r18=0,r18,61,3 // convert vhpt ptr to physical
1272 add r20=16,r18 // address of tag
1274 ld8.acq r23=[r20] // read old tag
1276 dep r23=-1,r23,63,1 // set ti bit
1278 st8.rel [r20]=r23 // store old tag + ti
1280 mf // make sure everyone sees
1282 st8 [r18]=r21,8 // store pte
1286 st8.rel [r18]=r19 // store new tag
1288 itc.d r21 // and place in TLB
1292 mov pr=r17,0x1ffff // restore predicates
1293 rfi // walker will retry the access
1295 2: add r20=24,r20 // next in chain
1297 ld8 r20=[r20] // read chain
1298 br.cond.sptk.few 1b // loop
1301 mov pr=r17,0x1ffff // restore predicates
1305 CALL(trap, 10, cr.ifa)
1306 IVT_END(Data_Access_Bit)
1308 IVT_ENTRY(Break_Instruction, 0x2c00)
1312 br.sptk exception_save
1316 alloc r15=ar.pfs,0,0,2,0
1331 br.call.sptk rp=trap
1337 br.sptk exception_restore
1340 IVT_END(Break_Instruction)
1342 IVT_ENTRY(External_Interrupt, 0x3000)
1344 mov r17=ar.itc // Put the ITC in the trapframe.
1346 br.sptk exception_save
1350 alloc r15=ar.pfs,0,0,1,0
1358 br.call.sptk rp=ia64_handle_intr
1364 br.sptk exception_restore
1367 IVT_END(External_Interrupt)
1369 IVT_ENTRY(Reserved_3400, 0x3400)
1370 CALL(trap, 13, cr.ifa)
1371 IVT_END(Reserved_3400)
1373 IVT_ENTRY(Reserved_3800, 0x3800)
1374 CALL(trap, 14, cr.ifa)
1375 IVT_END(Reserved_3800)
1377 IVT_ENTRY(Reserved_3c00, 0x3c00)
1378 CALL(trap, 15, cr.ifa)
1379 IVT_END(Reserved_3c00)
1381 IVT_ENTRY(Reserved_4000, 0x4000)
1382 CALL(trap, 16, cr.ifa)
1383 IVT_END(Reserved_4000)
1385 IVT_ENTRY(Reserved_4400, 0x4400)
1386 CALL(trap, 17, cr.ifa)
1387 IVT_END(Reserved_4400)
1389 IVT_ENTRY(Reserved_4800, 0x4800)
1390 CALL(trap, 18, cr.ifa)
1391 IVT_END(Reserved_4800)
1393 IVT_ENTRY(Reserved_4c00, 0x4c00)
1394 CALL(trap, 19, cr.ifa)
1395 IVT_END(Reserved_4c00)
1397 IVT_ENTRY(Page_Not_Present, 0x5000)
1398 CALL(trap, 20, cr.ifa)
1399 IVT_END(Page_Not_Present)
1401 IVT_ENTRY(Key_Permission, 0x5100)
1402 CALL(trap, 21, cr.ifa)
1403 IVT_END(Key_Permission)
1405 IVT_ENTRY(Instruction_Access_Rights, 0x5200)
1406 CALL(trap, 22, cr.ifa)
1407 IVT_END(Instruction_Access_Rights)
1409 IVT_ENTRY(Data_Access_Rights, 0x5300)
1410 CALL(trap, 23, cr.ifa)
1411 IVT_END(Data_Access_Rights)
1413 IVT_ENTRY(General_Exception, 0x5400)
1414 CALL(trap, 24, cr.ifa)
1415 IVT_END(General_Exception)
1417 IVT_ENTRY(Disabled_FP_Register, 0x5500)
1418 CALL(trap, 25, cr.ifa)
1419 IVT_END(Disabled_FP_Register)
1421 IVT_ENTRY(NaT_Consumption, 0x5600)
1422 CALL(trap, 26, cr.ifa)
1423 IVT_END(NaT_Consumption)
1425 IVT_ENTRY(Speculation, 0x5700)
1426 CALL(trap, 27, cr.iim)
1427 IVT_END(Speculation)
1429 IVT_ENTRY(Reserved_5800, 0x5800)
1430 CALL(trap, 28, cr.ifa)
1431 IVT_END(Reserved_5800)
1433 IVT_ENTRY(Debug, 0x5900)
1434 CALL(trap, 29, cr.ifa)
1437 IVT_ENTRY(Unaligned_Reference, 0x5a00)
1438 CALL(trap, 30, cr.ifa)
1439 IVT_END(Unaligned_Reference)
1441 IVT_ENTRY(Unsupported_Data_Reference, 0x5b00)
1442 CALL(trap, 31, cr.ifa)
1443 IVT_END(Unsupported_Data_Reference)
1445 IVT_ENTRY(Floating_Point_Fault, 0x5c00)
1446 CALL(trap, 32, cr.ifa)
1447 IVT_END(Floating_Point_Fault)
1449 IVT_ENTRY(Floating_Point_Trap, 0x5d00)
1450 CALL(trap, 33, cr.ifa)
1451 IVT_END(Floating_Point_Trap)
1453 IVT_ENTRY(Lower_Privilege_Transfer_Trap, 0x5e00)
1454 CALL(trap, 34, cr.ifa)
1455 IVT_END(Lower_Privilege_Transfer_Trap)
1457 IVT_ENTRY(Taken_Branch_Trap, 0x5f00)
1458 CALL(trap, 35, cr.ifa)
1459 IVT_END(Taken_Branch_Trap)
1461 IVT_ENTRY(Single_Step_Trap, 0x6000)
1462 CALL(trap, 36, cr.ifa)
1463 IVT_END(Single_Step_Trap)
1465 IVT_ENTRY(Reserved_6100, 0x6100)
1466 CALL(trap, 37, cr.ifa)
1467 IVT_END(Reserved_6100)
1469 IVT_ENTRY(Reserved_6200, 0x6200)
1470 CALL(trap, 38, cr.ifa)
1471 IVT_END(Reserved_6200)
1473 IVT_ENTRY(Reserved_6300, 0x6300)
1474 CALL(trap, 39, cr.ifa)
1475 IVT_END(Reserved_6300)
1477 IVT_ENTRY(Reserved_6400, 0x6400)
1478 CALL(trap, 40, cr.ifa)
1479 IVT_END(Reserved_6400)
1481 IVT_ENTRY(Reserved_6500, 0x6500)
1482 CALL(trap, 41, cr.ifa)
1483 IVT_END(Reserved_6500)
1485 IVT_ENTRY(Reserved_6600, 0x6600)
1486 CALL(trap, 42, cr.ifa)
1487 IVT_END(Reserved_6600)
1489 IVT_ENTRY(Reserved_6700, 0x6700)
1490 CALL(trap, 43, cr.ifa)
1491 IVT_END(Reserved_6700)
1493 IVT_ENTRY(Reserved_6800, 0x6800)
1494 CALL(trap, 44, cr.ifa)
1495 IVT_END(Reserved_6800)
1497 IVT_ENTRY(IA_32_Exception, 0x6900)
1498 CALL(IA32_TRAP, 45, cr.ifa)
1499 IVT_END(IA_32_Exception)
1501 IVT_ENTRY(IA_32_Intercept, 0x6a00)
1502 CALL(IA32_TRAP, 46, cr.iim)
1503 IVT_END(IA_32_Intercept)
1505 IVT_ENTRY(IA_32_Interrupt, 0x6b00)
1506 CALL(IA32_TRAP, 47, cr.ifa)
1507 IVT_END(IA_32_Interrupt)
1509 IVT_ENTRY(Reserved_6c00, 0x6c00)
1510 CALL(trap, 48, cr.ifa)
1511 IVT_END(Reserved_6c00)
1513 IVT_ENTRY(Reserved_6d00, 0x6d00)
1514 CALL(trap, 49, cr.ifa)
1515 IVT_END(Reserved_6d00)
1517 IVT_ENTRY(Reserved_6e00, 0x6e00)
1518 CALL(trap, 50, cr.ifa)
1519 IVT_END(Reserved_6e00)
1521 IVT_ENTRY(Reserved_6f00, 0x6f00)
1522 CALL(trap, 51, cr.ifa)
1523 IVT_END(Reserved_6f00)
1525 IVT_ENTRY(Reserved_7000, 0x7000)
1526 CALL(trap, 52, cr.ifa)
1527 IVT_END(Reserved_7000)
1529 IVT_ENTRY(Reserved_7100, 0x7100)
1530 CALL(trap, 53, cr.ifa)
1531 IVT_END(Reserved_7100)
1533 IVT_ENTRY(Reserved_7200, 0x7200)
1534 CALL(trap, 54, cr.ifa)
1535 IVT_END(Reserved_7200)
1537 IVT_ENTRY(Reserved_7300, 0x7300)
1538 CALL(trap, 55, cr.ifa)
1539 IVT_END(Reserved_7300)
1541 IVT_ENTRY(Reserved_7400, 0x7400)
1542 CALL(trap, 56, cr.ifa)
1543 IVT_END(Reserved_7400)
1545 IVT_ENTRY(Reserved_7500, 0x7500)
1546 CALL(trap, 57, cr.ifa)
1547 IVT_END(Reserved_7500)
1549 IVT_ENTRY(Reserved_7600, 0x7600)
1550 CALL(trap, 58, cr.ifa)
1551 IVT_END(Reserved_7600)
1553 IVT_ENTRY(Reserved_7700, 0x7700)
1554 CALL(trap, 59, cr.ifa)
1555 IVT_END(Reserved_7700)
1557 IVT_ENTRY(Reserved_7800, 0x7800)
1558 CALL(trap, 60, cr.ifa)
1559 IVT_END(Reserved_7800)
1561 IVT_ENTRY(Reserved_7900, 0x7900)
1562 CALL(trap, 61, cr.ifa)
1563 IVT_END(Reserved_7900)
1565 IVT_ENTRY(Reserved_7a00, 0x7a00)
1566 CALL(trap, 62, cr.ifa)
1567 IVT_END(Reserved_7a00)
1569 IVT_ENTRY(Reserved_7b00, 0x7b00)
1570 CALL(trap, 63, cr.ifa)
1571 IVT_END(Reserved_7b00)
1573 IVT_ENTRY(Reserved_7c00, 0x7c00)
1574 CALL(trap, 64, cr.ifa)
1575 IVT_END(Reserved_7c00)
1577 IVT_ENTRY(Reserved_7d00, 0x7d00)
1578 CALL(trap, 65, cr.ifa)
1579 IVT_END(Reserved_7d00)
1581 IVT_ENTRY(Reserved_7e00, 0x7e00)
1582 CALL(trap, 66, cr.ifa)
1583 IVT_END(Reserved_7e00)
1585 IVT_ENTRY(Reserved_7f00, 0x7f00)
1586 CALL(trap, 67, cr.ifa)
1587 IVT_END(Reserved_7f00)