Module Name: src
Committed By: scole
Date: Sat Apr 8 17:42:47 UTC 2017
Modified Files:
src/sys/arch/ia64/ia64: exception.S
Log Message:
Updates from FreeBSD, mostly compile-tested
To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/ia64/ia64/exception.S
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/ia64/ia64/exception.S
diff -u src/sys/arch/ia64/ia64/exception.S:1.5 src/sys/arch/ia64/ia64/exception.S:1.6
--- src/sys/arch/ia64/ia64/exception.S:1.5 Sat Oct 1 15:59:27 2011
+++ src/sys/arch/ia64/ia64/exception.S Sat Apr 8 17:42:47 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: exception.S,v 1.5 2011/10/01 15:59:27 chs Exp $ */
+/* $NetBSD: exception.S,v 1.6 2017/04/08 17:42:47 scole Exp $ */
/*-
* Copyright (c) 2003,2004 Marcel Moolenaar
@@ -28,18 +28,206 @@
*/
#include <machine/asm.h>
-#include <machine/pte.h>
+/* __FBSDID("$FreeBSD: releng/10.1/sys/ia64/ia64/exception.S 268200 2014-07-02 23:47:43Z marcel $"); */
#include "assym.h"
/*
+ * Nested TLB restart tokens. These are used by the
+ * nested TLB handler for jumping back to the code
+ * where the nested TLB was caused.
+ */
+#define NTLBRT_SAVE 0x12c12c
+#define NTLBRT_RESTORE 0x12c12d
+
+/*
* ar.k7 = kernel memory stack
* ar.k6 = kernel register stack
* ar.k5 = EPC gateway page
* ar.k4 = PCPU data
*/
- .text
+ .section .ivt.data, "aw"
+
+ .align 8
+ .global ia64_kptdir
+ .size ia64_kptdir, 8
+ia64_kptdir: data8 0
+
+
+#ifdef XTRACE
+
+ .align 8
+ .global ia64_xtrace_mask
+ .size ia64_xtrace_mask, 8
+ia64_xtrace_mask: data8 0
+
+ .align 4
+ .global ia64_xtrace_enabled
+ .size ia64_xtrace_enabled, 4
+ia64_xtrace_enabled: data4 0
+
+#define XTRACE_HOOK(offset) \
+{ .mii ; \
+ nop 0 ; \
+ mov r31 = b7 ; \
+ mov r28 = pr ; \
+} ; \
+{ .mib ; \
+ nop 0 ; \
+ mov r25 = ip ; \
+ br.sptk ia64_xtrace_write ;; \
+} ; \
+{ .mii ; \
+ nop 0 ; \
+ mov b7 = r31 ; \
+ mov pr = r28, 0x1ffff ;; \
+}
+
+ .section .ivt.text, "ax"
+
+// We can only use r25, r26 & r27
+ENTRY_NOPROFILE(ia64_xtrace_write, 0)
+{ .mlx
+ add r25 = 16, r25
+ movl r26 = ia64_xtrace_enabled
+ ;;
+}
+{ .mmi
+ mov r27 = ar.k3
+ ld4 r26 = [r26]
+ mov b7 = r25
+ ;;
+}
+{ .mib
+ add r25 = -32, r25
+ cmp.eq p15,p0 = r0, r26
+(p15) br.dptk.few b7
+ ;;
+}
+{ .mib
+ nop 0
+ cmp.eq p15,p0 = r0, r27
+(p15) br.dptk.few b7
+ ;;
+}
+{ .mmi
+ st8 [r27] = r25, 8 // 0x00 IVT
+ mov r26 = ar.itc
+ nop 0
+ ;;
+}
+{ .mmi
+ st8 [r27] = r26, 8 // 0x08 ITC
+ mov r25 = cr.iip
+ nop 0
+ ;;
+}
+{ .mmi
+ st8 [r27] = r25, 8 // 0x10 IIP
+ mov r26 = cr.ifa
+ nop 0
+ ;;
+}
+{ .mmi
+ st8 [r27] = r26, 8 // 0x18 IFA
+ mov r25 = cr.isr
+ nop 0
+ ;;
+}
+{ .mmi
+ st8 [r27] = r25, 8 // 0x20 ISR
+ mov r26 = cr.ipsr
+ nop 0
+ ;;
+}
+{ .mmi
+ st8 [r27] = r26, 8 // 0x28 IPSR
+ mov r25 = cr.itir
+ nop 0
+ ;;
+}
+{ .mmi
+ st8 [r27] = r25, 8 // 0x30 ITIR
+ mov r26 = cr.iipa
+ nop 0
+ ;;
+}
+{ .mmi
+ st8 [r27] = r26, 8 // 0x38 IIPA
+ mov r25 = cr.ifs
+ nop 0
+ ;;
+}
+{ .mmi
+ st8 [r27] = r25, 8 // 0x40 IFS
+ mov r26 = cr.iim
+ nop 0
+ ;;
+}
+{ .mmi
+ st8 [r27] = r26, 8 // 0x48 IIM
+ mov r25 = cr.iha
+ nop 0
+ ;;
+}
+{ .mmi
+ st8 [r27] = r25, 8 // 0x50 IHA
+ mov r26 = ar.unat
+ nop 0
+ ;;
+}
+{ .mmi
+ st8 [r27] = r26, 8 // 0x58 UNAT
+ mov r25 = ar.rsc
+ nop 0
+ ;;
+}
+{ .mmi
+ st8 [r27] = r25, 8 // 0x60 RSC
+ mov r26 = ar.bsp
+ nop 0
+ ;;
+}
+{ .mmi
+ st8 [r27] = r26, 8 // 0x68 BSP
+ mov r25 = r13
+ nop 0
+ ;;
+}
+{ .mmi
+ st8 [r27] = r25, 8 // 0x70 PCPU/TLS
+ mov r26 = r12
+ nop 0
+ ;;
+}
+{ .mlx
+ st8 [r27] = r26, 8 // 0x78 SP
+ movl r25 = ia64_xtrace_mask
+ ;;
+}
+{ .mmi
+ ld8 r26 = [r25]
+ ;;
+ and r25 = r27, r26
+ nop 0
+ ;;
+}
+{ .mib
+ mov ar.k3 = r25
+ nop 0
+ br.sptk b7
+ ;;
+}
+END(ia64_xtrace_write)
+
+#else /* XTRACE */
+
+#define XTRACE_HOOK(offset)
+
+ .section .ivt.text, "ax"
+
+#endif /* XTRACE */
/*
* exception_save: save interrupted state
@@ -67,7 +255,7 @@ ENTRY_NOPROFILE(exception_save, 0)
;;
}
{ .mmi
- cmp.le p14,p15=5,r31
+ cmp.le p14,p15=IA64_VM_MINKERN_REGION,r31
;;
(p15) mov r23=ar.k7 // kernel memory stack
(p14) mov r23=sp
@@ -82,42 +270,57 @@ ENTRY_NOPROFILE(exception_save, 0)
}
{ .mmi
mov ar.rsc=0
- sub r19=r23,r30
- add r31=8,r30
- ;;
-}
-{ .mlx
mov r22=cr.iip
- movl r26=exception_save_restart
+ addl r29=NTLBRT_SAVE,r0 // 22-bit restart token.
;;
}
/*
- * We have a 1KB aligned trapframe, pointed to by sp. If we write
- * to the trapframe, we may trigger a data nested TLB fault. By
- * aligning the trapframe on a 1KB boundary, we guarantee that if
- * we get a data nested TLB fault, it will be on the very first
- * write. Since the data nested TLB fault does not preserve any
- * state, we have to be careful what we clobber. Consequently, we
- * have to be careful what we use here. Below a list of registers
- * that are currently alive:
+ * We have a 1KB aligned trapframe, pointed to by r30. We can't
+ * reliably write to the trapframe using virtual addressing, due
+ * to the fact that TC entries we depend on can be removed by:
+ * 1. ptc.g instructions issued by other threads/cores/CPUs, or
+ * 2. TC modifications in another thread on the same core.
+ * When our TC entry gets removed, we get nested TLB faults and
+ * since no state is saved, we can only deal with those when
+ * explicitly coded and expected.
+ * As such, we switch to physical addressing and account for the
+ * fact that the tpa instruction can cause a nested TLB fault.
+ * Since the data nested TLB fault does not preserve any state,
+ * we have to be careful what we clobber. Consequently, we have
+ * to be careful what we use here. Below a list of registers that
+ * are considered alive:
* r16,r17=arguments
* r18=pr, r19=length, r20=unat, r21=rsc, r22=iip, r23=TOS
- * r26=restart point
- * r30,r31=trapframe pointers
+ * r29=restart token
+ * r30=trapframe pointers
* p14,p15=memory stack switch
*/
exception_save_restart:
+ tpa r24=r30 // Nested TLB fault possible
+ sub r19=r23,r30
+ nop 0
+ ;;
+
+ rsm psr.dt
+ add r29=16,r19 // Clobber restart token
+ mov r30=r24
+ ;;
+ srlz.d
+ add r31=8,r24
+ ;;
+
+ // r18=pr, r19=length, r20=unat, r21=rsc, r22=iip, r23=TOS
+ // r29=delta
{ .mmi
st8 [r30]=r19,16 // length
st8 [r31]=r0,16 // flags
- add r19=16,r19
;;
}
{ .mmi
st8.spill [r30]=sp,16 // sp
st8 [r31]=r20,16 // unat
- sub sp=r23,r19
+ sub sp=r23,r29
;;
}
{ .mmi
@@ -127,6 +330,7 @@ exception_save_restart:
;;
}
// r18=pr, r19=rnat, r20=bspstore, r21=rsc, r22=iip, r23=rp
+ // r24=pfs
{ .mmi
st8 [r30]=r23,16 // rp
st8 [r31]=r18,16 // pr
@@ -149,7 +353,7 @@ exception_save_restart:
{ .mmi
st8 [r30]=r19,16 // rnat
st8 [r31]=r0,16 // __spare
- cmp.le p12,p13=5,r24
+ cmp.le p12,p13=IA64_VM_MINKERN_REGION,r24
;;
}
{ .mmi
@@ -165,7 +369,7 @@ exception_save_restart:
(p13) dep r20=r20,r21,0,9 // align dirty registers
;;
}
- // r20=bspstore, r22=iip, r23=ipsr
+ // r19=rnat, r20=bspstore, r22=iip, r23=ipsr
{ .mmi
st8 [r31]=r23,16 // psr
(p13) mov ar.bspstore=r20
@@ -173,35 +377,34 @@ exception_save_restart:
;;
}
{ .mmi
+(p13) mov ar.rnat=r19
mov r18=ar.bsp
- ;;
- mov r19=cr.ifs
- sub r18=r18,r20
+ nop 0
;;
}
{ .mmi
+ mov r19=cr.ifs
st8.spill [r30]=gp,16 // gp
- st8 [r31]=r18,16 // ndirty
- nop 0
+ sub r18=r18,r20
;;
}
- // r19=ifs, r22=iip
+ // r18=ndirty, r19=ifs, r22=iip
{ .mmi
+ st8 [r31]=r18,16 // ndirty
st8 [r30]=r19,16 // cfm
- st8 [r31]=r22,16 // iip
nop 0
;;
}
{ .mmi
- st8 [r30]=r17 // ifa
mov r18=cr.isr
+ st8 [r31]=r22,16 // iip
add r29=16,r30
;;
}
{ .mmi
- st8 [r31]=r18 // isr
- add r30=8,r29
- add r31=16,r29
+ st8 [r30]=r17,24 // ifa
+ st8 [r31]=r18,24 // isr
+ nop 0
;;
}
{ .mmi
@@ -341,11 +544,11 @@ exception_save_restart:
;;
}
{ .mlx
- ssm psr.ic|psr.dfh
+ ssm psr.dt|psr.ic|psr.dfh
movl gp=__gp
;;
}
-{ .mfb
+{ .mib
srlz.d
nop 0
br.sptk b7
@@ -366,29 +569,48 @@ ENTRY_NOPROFILE(exception_restore, 0)
nop 0
;;
}
-{ .mmi
- add r3=SIZEOF_TRAPFRAME-32,sp
- add r2=SIZEOF_TRAPFRAME-16,sp
- add r8=SIZEOF_SPECIAL+16,sp
+
+ // The next instruction can fault. Let it be...
+ tpa r9=sp
;;
-}
- // The next load can trap. Let it be...
+ rsm psr.dt|psr.ic
+ add r8=SIZEOF_SPECIAL+16,r9
+ ;;
+ srlz.d
+ add r2=SIZEOF_TRAPFRAME-16,r9
+ add r3=SIZEOF_TRAPFRAME-32,r9
+ ;;
+
+{ .mmi
ldf.fill f15=[r2],-32 // f15
ldf.fill f14=[r3],-32 // f14
+ nop 0
;;
+}
+{ .mmi
ldf.fill f13=[r2],-32 // f13
ldf.fill f12=[r3],-32 // f12
+ nop 0
;;
+}
+{ .mmi
ldf.fill f11=[r2],-32 // f11
ldf.fill f10=[r3],-32 // f10
+ nop 0
;;
+}
+{ .mmi
ldf.fill f9=[r2],-32 // f9
ldf.fill f8=[r3],-32 // f8
+ nop 0
;;
+}
+{ .mmi
ldf.fill f7=[r2],-24 // f7
ldf.fill f6=[r3],-16 // f6
+ nop 0
;;
-
+}
{ .mmi
ld8 r8=[r8] // unat (after)
;;
@@ -445,53 +667,53 @@ ENTRY_NOPROFILE(exception_restore, 0)
bsw.0
;;
}
+{ .mii
+ ld8 r16=[r9] // tf_length
+ add r31=16,r9
+ add r30=24,r9
+}
{ .mmi
ld8.fill r15=[r3],-16 // r15
ld8.fill r14=[r2],-16 // r14
- add r31=16,sp
+ nop 0
;;
}
{ .mmi
- ld8 r16=[sp] // tf_length
ld8.fill r11=[r3],-16 // r11
- add r30=24,sp
- ;;
-}
-{ .mmi
ld8.fill r10=[r2],-16 // r10
- ld8.fill r9=[r3],-16 // r9
add r16=r16,sp // ar.k7
;;
}
{ .mmi
+ ld8.fill r9=[r3],-16 // r9
ld8.fill r8=[r2],-16 // r8
- ld8.fill r3=[r3] // r3
+ nop 0
;;
}
- // We want nested TLB faults from here on...
- rsm psr.ic|psr.i
+{ .mmi
+ ld8.fill r3=[r3] // r3
ld8.fill r2=[r2] // r2
nop 0
;;
- srlz.d
- ld8.fill sp=[r31],16 // sp
- nop 0
- ;;
+}
+ ld8.fill sp=[r31],16 // sp
ld8 r17=[r30],16 // unat
- ld8 r29=[r31],16 // rp
;;
+ ld8 r29=[r31],16 // rp
ld8 r18=[r30],16 // pr
+ ;;
ld8 r28=[r31],16 // pfs
+ ld8 r20=[r30],24 // bspstore
mov rp=r29
;;
- ld8 r20=[r30],24 // bspstore
ld8 r21=[r31],24 // rnat
mov ar.pfs=r28
;;
- ld8.fill r29=[r30],16 // tp
+ ld8.fill r26=[r30],16 // tp
ld8 r22=[r31],16 // rsc
;;
+
{ .mmi
ld8 r23=[r30],16 // fpsr
ld8 r24=[r31],16 // psr
@@ -500,21 +722,21 @@ ENTRY_NOPROFILE(exception_restore, 0)
}
{ .mmi
ld8.fill r1=[r30],16 // gp
- ld8 r25=[r31],16 // ndirty
- cmp.le p14,p15=5,r28
+ ld8 r27=[r31],16 // ndirty
+ cmp.le p14,p15=IA64_VM_MINKERN_REGION,r28
;;
}
-{ .mmb
- ld8 r26=[r30] // cfm
+{ .mmi
+ ld8 r25=[r30] // cfm
ld8 r19=[r31] // ip
nop 0
;;
}
-{ .mib
+{ .mii
// Switch register stack
alloc r30=ar.pfs,0,0,0,0 // discard current frame
- shl r31=r25,16 // value for ar.rsc
- nop 0
+ shl r31=r27,16 // value for ar.rsc
+(p15) mov r13=r26
;;
}
// The loadrs can fault if the backing store is not currently
@@ -525,15 +747,21 @@ ENTRY_NOPROFILE(exception_restore, 0)
{ .mmi
mov ar.rsc=r31 // setup for loadrs
mov ar.k7=r16
-(p15) mov r13=r29
+ addl r29=NTLBRT_RESTORE,r0 // 22-bit restart token
;;
}
+
+ ssm psr.dt
+ ;;
+ srlz.d
+ mov r16 = r25
+
exception_restore_restart:
{ .mmi
mov r30=ar.bspstore
;;
loadrs // load user regs
- nop 0
+ mov r29=0 // Clobber restart token
;;
}
{ .mmi
@@ -543,21 +771,22 @@ exception_restore_restart:
dep r31=0,r31,0,13 // 8KB aligned
;;
}
-{ .mmb
+{ .mmi
+ mov cr.ifs=r16
mov ar.k6=r31
- mov ar.rnat=r21
- nop 0
+ mov pr=r18,0x1ffff
;;
}
-{ .mmb
- mov ar.unat=r17
+{ .mmi
mov cr.iip=r19
+ mov ar.unat=r17
nop 0
+ ;;
}
{ .mmi
mov cr.ipsr=r24
- mov cr.ifs=r26
- mov pr=r18,0x1fffe
+ mov ar.rnat=r21
+ nop 0
;;
}
{ .mmb
@@ -581,22 +810,22 @@ END(exception_restore)
{ .mib ; \
mov r17=_ifa_ ; \
mov r16=ip ; \
- br.sptk exception_save ; \
+ br.sptk exception_save ;; \
} ; \
{ .mmi ; \
-(p11) ssm psr.i ;; \
- alloc r15=ar.pfs,0,0,2,0 ; \
+ alloc r15=ar.pfs,0,0,2,0 ;; \
+(p11) ssm psr.i ; \
mov out0=_n_ ;; \
} ; \
-{ .mfb ; \
+{ .mib ; \
+(p11) srlz.d ; \
add out1=16,sp ; \
- nop 0 ; \
- br.call.sptk rp=_func_ ; \
+ br.call.sptk rp=_func_ ;; \
} ; \
-{ .mfb ; \
+{ .mib ; \
nop 0 ; \
nop 0 ; \
- br.sptk exception_restore ; \
+ br.sptk exception_restore ;; \
}
#define IVT_ENTRY(name, offset) \
@@ -607,7 +836,8 @@ END(exception_restore)
.unwabi @svr4, 'I'; \
.save rp, r0; \
.body; \
-ivt_##name:
+ivt_##name: \
+ XTRACE_HOOK(offset)
#define IVT_END(name) \
.endp ivt_##name
@@ -623,7 +853,7 @@ ivt_##name:
* bundles per vector and 48 slots with 16 bundles per vector.
*/
- .section .text.ivt,"ax"
+ .section .ivt, "ax"
.align 32768
.global ia64_vector_table
@@ -645,6 +875,7 @@ IVT_ENTRY(Instruction_TLB, 0x0400)
add r20=24,r18 // collision chain
;;
ld8 r21=[r21] // check VHPT tag
+ ld8 r20=[r20] // bucket head
;;
cmp.ne p15,p0=r21,r19
(p15) br.dpnt.few 1f
@@ -652,15 +883,15 @@ IVT_ENTRY(Instruction_TLB, 0x0400)
ld8 r21=[r18] // read pte
;;
itc.i r21 // insert pte
- ;;
mov pr=r17,0x1ffff
+ ;;
rfi // done
;;
-1: ld8 r20=[r20] // first entry
- ;;
- rsm psr.dt // turn off data translations
+1: rsm psr.dt // turn off data translations
+ dep r20=0,r20,61,3 // convert vhpt ptr to physical
;;
srlz.d // serialize
+ ld8 r20=[r20] // first entry
;;
2: cmp.eq p15,p0=r0,r20 // done?
(p15) br.cond.spnt.few 9f // bail if done
@@ -672,7 +903,12 @@ IVT_ENTRY(Instruction_TLB, 0x0400)
cmp.ne p15,p0=r21,r19 // compare tags
(p15) br.cond.sptk.few 3f // if not, read next in chain
;;
- ld8 r21=[r20],8 // read pte
+ ld8 r21=[r20] // read pte
+ mov r22=PTE_ACCESSED
+ ;;
+ or r21=r21,r22
+ ;;
+ st8 [r20]=r21,8
;;
ld8 r22=[r20] // read rest of pte
;;
@@ -695,17 +931,19 @@ IVT_ENTRY(Instruction_TLB, 0x0400)
st8.rel [r18]=r19 // store new tag
;;
itc.i r21 // and place in TLB
+ ssm psr.dt
;;
+ srlz.d
mov pr=r17,0x1ffff // restore predicates
rfi
-
+ ;;
3: add r20=24,r20 // next in chain
;;
ld8 r20=[r20] // read chain
- br.cond.sptk.few 2b // loop
-
-9: mov pr=r17,0x1ffff // restore predicates
- ssm psr.dt
+ br.sptk 2b // loop
+ ;;
+9: ssm psr.dt
+ mov pr=r17,0x1ffff // restore predicates
;;
srlz.d
;;
@@ -731,15 +969,15 @@ IVT_ENTRY(Data_TLB, 0x0800)
ld8 r21=[r18] // read pte
;;
itc.d r21 // insert pte
- ;;
mov pr=r17,0x1ffff
+ ;;
rfi // done
;;
-1: ld8 r20=[r20] // first entry
+1: rsm psr.dt // turn off data translations
+ dep r20=0,r20,61,3 // convert vhpt ptr to physical
;;
- rsm psr.dt // turn off data translations
- ;;
srlz.d // serialize
+ ld8 r20=[r20] // first entry
;;
2: cmp.eq p15,p0=r0,r20 // done?
(p15) br.cond.spnt.few 9f // bail if done
@@ -751,7 +989,12 @@ IVT_ENTRY(Data_TLB, 0x0800)
cmp.ne p15,p0=r21,r19 // compare tags
(p15) br.cond.sptk.few 3f // if not, read next in chain
;;
- ld8 r21=[r20],8 // read pte
+ ld8 r21=[r20] // read pte
+ mov r22=PTE_ACCESSED
+ ;;
+ or r21=r21,r22
+ ;;
+ st8 [r20]=r21,8
;;
ld8 r22=[r20] // read rest of pte
;;
@@ -774,17 +1017,19 @@ IVT_ENTRY(Data_TLB, 0x0800)
st8.rel [r18]=r19 // store new tag
;;
itc.d r21 // and place in TLB
+ ssm psr.dt
;;
+ srlz.d
mov pr=r17,0x1ffff // restore predicates
rfi
-
+ ;;
3: add r20=24,r20 // next in chain
;;
ld8 r20=[r20] // read chain
- br.cond.sptk.few 2b // loop
-
-9: mov pr=r17,0x1ffff // restore predicates
- ssm psr.dt
+ br.sptk 2b // loop
+ ;;
+9: ssm psr.dt
+ mov pr=r17,0x1ffff // restore predicates
;;
srlz.d
;;
@@ -796,24 +1041,40 @@ IVT_ENTRY(Alternate_Instruction_TLB, 0x0
mov r18=pr // save predicates
;;
extr.u r17=r16,61,3 // get region number
+ mov r19=PTE_PRESENT+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+PTE_AR_RWX
;;
- cmp.ge p13,p0=5,r17 // RR0-RR5?
- cmp.eq p15,p14=7,r17 // RR7->p15, RR6->p14
-(p13) br.spnt 9f
+ cmp.eq p13,p0=IA64_PBVM_RR,r17 // RR4?
+(p13) br.cond.sptk.few 4f
;;
-(p15) movl r17=PTE_PRESENT+PTE_MA_WB+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
- PTE_AR_RX
-(p14) movl r17=PTE_PRESENT+PTE_MA_UC+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
- PTE_AR_RX
+ cmp.ge p13,p0=5,r17 // RR0-RR5?
+ cmp.eq p14,p15=7,r17 // RR7?
+(p13) br.cond.spnt.few 9f
;;
- dep r16=0,r16,50,14 // clear bits above PPN
+(p14) add r19=PTE_MA_WB,r19
+(p15) add r19=PTE_MA_UC,r19
+ dep r17=0,r16,50,14 // clear bits above PPN
;;
- dep r16=r17,r16,0,12 // put pte bits in 0..11
+1: dep r16=r19,r17,0,12 // put pte bits in 0..11
;;
itc.i r16
mov pr=r18,0x1ffff // restore predicates
;;
rfi
+ ;;
+4:
+ add r19=PTE_MA_WB,r19
+ movl r17=IA64_PBVM_BASE
+ ;;
+ sub r17=r16,r17
+ movl r16=IA64_PBVM_PGTBL
+ ;;
+ extr.u r17=r17,IA64_PBVM_PAGE_SHIFT,61-IA64_PBVM_PAGE_SHIFT
+ ;;
+ shladd r16=r17,3,r16
+ ;;
+ ld8 r17=[r16]
+ br.sptk 1b
+ ;;
9: mov pr=r18,0x1ffff // restore predicates
CALL(trap, 3, cr.ifa)
IVT_END(Alternate_Instruction_TLB)
@@ -823,24 +1084,40 @@ IVT_ENTRY(Alternate_Data_TLB, 0x1000)
mov r18=pr // save predicates
;;
extr.u r17=r16,61,3 // get region number
+ mov r19=PTE_PRESENT+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+PTE_AR_RWX
;;
- cmp.ge p13,p0=5,r17 // RR0-RR5?
- cmp.eq p15,p14=7,r17 // RR7->p15, RR6->p14
-(p13) br.spnt 9f
+ cmp.eq p13,p0=IA64_PBVM_RR,r17 // RR4?
+(p13) br.cond.sptk.few 4f
;;
-(p15) movl r17=PTE_PRESENT+PTE_MA_WB+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
- PTE_AR_RW
-(p14) movl r17=PTE_PRESENT+PTE_MA_UC+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+ \
- PTE_AR_RW
+ cmp.ge p13,p0=5,r17 // RR0-RR5?
+ cmp.eq p14,p15=7,r17 // RR7?
+(p13) br.cond.spnt.few 9f
;;
- dep r16=0,r16,50,14 // clear bits above PPN
+(p14) add r19=PTE_MA_WB,r19
+(p15) add r19=PTE_MA_UC,r19
+ dep r17=0,r16,50,14 // clear bits above PPN
;;
- dep r16=r17,r16,0,12 // put pte bits in 0..11
+1: dep r16=r19,r17,0,12 // put pte bits in 0..11
;;
itc.d r16
mov pr=r18,0x1ffff // restore predicates
;;
rfi
+ ;;
+4:
+ add r19=PTE_MA_WB,r19
+ movl r17=IA64_PBVM_BASE
+ ;;
+ sub r17=r16,r17
+ movl r16=IA64_PBVM_PGTBL
+ ;;
+ extr.u r17=r17,IA64_PBVM_PAGE_SHIFT,61-IA64_PBVM_PAGE_SHIFT
+ ;;
+ shladd r16=r17,3,r16
+ ;;
+ ld8 r17=[r16]
+ br.sptk 1b
+ ;;
9: mov pr=r18,0x1ffff // restore predicates
CALL(trap, 4, cr.ifa)
IVT_END(Alternate_Data_TLB)
@@ -858,68 +1135,115 @@ IVT_ENTRY(Data_Nested_TLB, 0x1400)
// double nested faults. Since all virtual addresses we encounter
// here are direct mapped region 7 addresses, we have no problem
// constructing physical addresses.
-{ .mlx
- rsm psr.dt
- movl r27=ia64_kptdir
+
+{ .mmi
+ mov cr.ifa=r30
+ mov r26=rr[r30]
+ extr.u r27=r30,61,3
;;
}
{ .mii
- srlz.d
- dep r27=0,r27,61,3
- extr.u r28=r30,PAGE_SHIFT,61-PAGE_SHIFT
+ nop 0
+ dep r26=0,r26,0,2
+ cmp.eq p12,p13=7,r27
;;
}
{ .mii
- ld8 r27=[r27]
- shr.u r29=r28,PAGE_SHIFT-5 // dir index
- extr.u r28=r28,0,PAGE_SHIFT-5 // pte index
+ mov cr.itir=r26
+(p12) dep r28=0,r30,0,12
+(p13) extr.u r28=r30,3*PAGE_SHIFT-8, PAGE_SHIFT-3 // dir L0 index
+ ;;
+}
+{ .mlx
+(p12) add r28=PTE_PRESENT+PTE_ACCESSED+PTE_DIRTY+PTE_PL_KERN+PTE_AR_RWX+PTE_MA_WB,r28
+(p13) movl r27=ia64_kptdir
+ ;;
+}
+{ .mib
+(p13) ld8 r27=[r27]
+(p13) extr.u r26=r30,2*PAGE_SHIFT-5, PAGE_SHIFT-3 // dir L1 index
+(p12) br.cond.spnt.few 1f
;;
}
{ .mmi
- shladd r27=r29,3,r27
+ rsm psr.dt
;;
- mov cr.ifa=r30
+ srlz.d
dep r27=0,r27,61,3
;;
}
{ .mmi
- ld8 r27=[r27]
- mov r29=rr[r30]
- shl r28=r28,5
+ shladd r27=r28,3,r27
+ ;;
+ ld8 r27=[r27] // dir L1 page
+ extr.u r28=r30,PAGE_SHIFT,PAGE_SHIFT-5 // pte index
;;
}
{ .mii
- add r27=r27,r28 // address of pte
- dep r29=0,r29,0,2
+ shladd r27=r26,3,r27
+ shl r28=r28,5
;;
dep r27=0,r27,61,3
;;
}
-{ .mmi
- ld8 r28=[r27]
+ ld8 r27=[r27] // pte page
+ ;;
+ add r27=r28,r27
+ ;;
+ dep r27=0,r27,61,3
+ ;;
+ ld8 r28=[r27] // pte
;;
- mov cr.itir=r29
or r28=PTE_DIRTY+PTE_ACCESSED,r28
;;
-}
-{ .mlx
st8 [r27]=r28
- movl r29=exception_save_restart
;;
-}
+ ssm psr.dt
+ ;;
+1:
{ .mmi
itc.d r28
;;
- ssm psr.dt
- cmp.eq p12,p13=r26,r29
+ addl r26=NTLBRT_SAVE,r0
+ addl r27=NTLBRT_RESTORE,r0
;;
}
-{ .mbb
+{ .mmi
srlz.d
-(p12) br.sptk exception_save_restart
-(p13) br.sptk exception_restore_restart
+ cmp.eq p12,p0=r29,r26
+ cmp.eq p13,p0=r29,r27
+ ;;
+}
+{ .mbb
+ nop 0
+(p12) br.cond.sptk.few exception_save_restart
+(p13) br.cond.sptk.few exception_restore_restart
+ ;;
+}
+
+{ .mlx
+ mov r26=ar.bsp
+ movl r29=kstack
+ ;;
+}
+{ .mlx
+ mov r28=sp
+ movl r27=kstack_top
+ ;;
+}
+{ .mmi
+ add sp=-16,r27
+ ;;
+ mov r27=ar.bspstore
+ nop 0
;;
}
+ mov ar.rsc=0
+ dep r29=r27,r29,0,9
+ ;;
+ mov ar.bspstore=r29
+ ;;
+ CALL(trap, 5, r30)
IVT_END(Data_Nested_TLB)
IVT_ENTRY(Instruction_Key_Miss, 0x1800)
@@ -986,7 +1310,7 @@ IVT_ENTRY(Dirty_Bit, 0x2000)
;;
itc.d r21 // and place in TLB
ssm psr.dt
- ;;
+ ;;
srlz.d
mov pr=r17,0x1ffff // restore predicates
rfi
@@ -994,7 +1318,7 @@ IVT_ENTRY(Dirty_Bit, 0x2000)
2: add r20=24,r20 // next in chain
;;
ld8 r20=[r20] // read chain
- br.cond.sptk.few 1b // loop
+ br.sptk 1b // loop
;;
9: ssm psr.dt
mov pr=r17,0x1ffff // restore predicates
@@ -1013,11 +1337,13 @@ IVT_ENTRY(Instruction_Access_Bit, 0x2400
ttag r19=r16
add r20=24,r18 // collision chain
;;
- ld8 r20=[r20] // first entry
+ ld8 r20=[r20] // bucket head
;;
rsm psr.dt // turn off data translations
+ dep r20=0,r20,61,3 // convert vhpt ptr to physical
;;
srlz.d // serialize
+ ld8 r20=[r20] // first entry
;;
1: cmp.eq p15,p0=r0,r20 // done?
(p15) br.cond.spnt.few 9f // bail if done
@@ -1057,16 +1383,22 @@ IVT_ENTRY(Instruction_Access_Bit, 0x2400
st8.rel [r18]=r19 // store new tag
;;
itc.i r21 // and place in TLB
+ ssm psr.dt
;;
+ srlz.d
mov pr=r17,0x1ffff // restore predicates
rfi // walker will retry the access
-
+ ;;
2: add r20=24,r20 // next in chain
;;
ld8 r20=[r20] // read chain
- br.cond.sptk.few 1b // loop
-
-9: mov pr=r17,0x1ffff // restore predicates
+ br.sptk 1b // loop
+ ;;
+9: ssm psr.dt
+ mov pr=r17,0x1ffff // restore predicates
+ ;;
+ srlz.d
+ ;;
CALL(trap, 9, cr.ifa)
IVT_END(Instruction_Access_Bit)
@@ -1075,8 +1407,8 @@ IVT_ENTRY(Data_Access_Bit, 0x2800)
mov r17=pr
;;
thash r18=r16
- ttag r19=r16
;;
+ ttag r19=r16
add r20=24,r18 // collision chain
;;
ld8 r20=[r20] // bucket head
@@ -1127,16 +1459,20 @@ IVT_ENTRY(Data_Access_Bit, 0x2800)
itc.d r21 // and place in TLB
ssm psr.dt
;;
+ srlz.d
mov pr=r17,0x1ffff // restore predicates
rfi // walker will retry the access
-
+ ;;
2: add r20=24,r20 // next in chain
;;
ld8 r20=[r20] // read chain
- br.cond.sptk.few 1b // loop
-
+ br.sptk 1b // loop
+ ;;
9: ssm psr.dt
mov pr=r17,0x1ffff // restore predicates
+ ;;
+ srlz.d
+ ;;
CALL(trap, 10, cr.ifa)
IVT_END(Data_Access_Bit)
@@ -1150,17 +1486,23 @@ IVT_ENTRY(Break_Instruction, 0x2c00)
{ .mmi
alloc r15=ar.pfs,0,0,2,0
;;
- flushrs
+(p11) ssm psr.i
mov out0=11
;;
}
-{ .mib
-(p11) ssm psr.i
+{ .mmi
+ flushrs
+ ;;
+(p11) srlz.d
add out1=16,sp
+}
+{ .mib
+ nop 0
+ nop 0
br.call.sptk rp=trap
;;
}
-{ .mfb
+{ .mib
nop 0
nop 0
br.sptk exception_restore
@@ -1170,53 +1512,24 @@ IVT_END(Break_Instruction)
IVT_ENTRY(External_Interrupt, 0x3000)
{ .mib
- mov r17=cr.lid // cr.iim and cr.ifa are undefined.
+ mov r17=0
mov r16=ip
br.sptk exception_save
;;
}
- alloc r14=ar.pfs,0,0,2,0
- cmp4.eq p14,p0=0,r0
- ;;
-1:
-{ .mii
- mov out0=cr.ivr // Get interrupt vector
- add out1=16,sp
- ;;
- cmp.eq p15,p0=15,out0 // check for spurious vector number
-}
-{ .mbb
- ssm psr.i // re-enable interrupts
-(p15) br.dpnt.few 2f // if spurious, we are done
- br.call.sptk.many rp=interrupt // call high-level handler
- ;;
-}
-{ .mmi
- rsm psr.i // disable interrupts
- ;;
- srlz.d
- nop 0
-}
{ .mmi
- mov cr.eoi=r0 // ack the interrupt
- ;;
- srlz.d
+ alloc r15=ar.pfs,0,0,1,0
nop 0
-}
-{ .mfb
- cmp4.eq p14,p0=0,r8 // Return to kernel mode?
nop 0
- br.sptk 1b // loop for more
;;
}
-2:
-{ .mbb
+{ .mib
add out0=16,sp
-(p14) br.sptk exception_restore
- br.call.sptk rp=do_ast
+ nop 0
+ br.call.sptk rp=ia64_handle_intr
;;
}
-{ .mfb
+{ .mib
nop 0
nop 0
br.sptk exception_restore