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

Reply via email to