Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 8 Apr 2003 01:14:58 -0700 (PDT)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 28499 for review
Message-ID:  <200304080814.h388Ew6U009052@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=28499

Change 28499 by marcel@marcel_nfs on 2003/04/08 01:14:28

	Snapshot highlights:
	o  cpu_switch() and cpu_throw() are now C functions. cpu_switch()
	   handles the high-level switching, while the low-level switching
	   is handled by swapctx(). cpu_throw() depends on restorectx().
	o  New implementation of exception_save() and exception_restore().
	   Does not have everything yet for interrupting user space. We
	   also don't use physical addressing anymore. We align the frame
	   on a 1K boundary and arrange for a well-defined failure point
	   so that we know where to jump to if we have a nested fault.
	o  We pass the address of the EPC page in ar.k3. We don't have to
	   worry about PAL clobbering the value, because we only need it
	   for syscalls, which don't use exceptions. We have to make sure
	   we restore ar.k3 when we return to user space though.
	
	There are probably a lot of loose ends...

Affected files ...

.. //depot/projects/ia64_epc/sys/conf/files.ia64#5 edit
.. //depot/projects/ia64_epc/sys/ia64/ia64/context.s#6 edit
.. //depot/projects/ia64_epc/sys/ia64/ia64/db_interface.c#3 edit
.. //depot/projects/ia64_epc/sys/ia64/ia64/exception.s#6 edit
.. //depot/projects/ia64_epc/sys/ia64/ia64/genassym.c#6 edit
.. //depot/projects/ia64_epc/sys/ia64/ia64/locore.s#5 edit
.. //depot/projects/ia64_epc/sys/ia64/ia64/machdep.c#6 edit
.. //depot/projects/ia64_epc/sys/ia64/ia64/swtch.s#3 delete
.. //depot/projects/ia64_epc/sys/ia64/ia64/syscall.s#3 edit
.. //depot/projects/ia64_epc/sys/ia64/ia64/trap.c#7 edit
.. //depot/projects/ia64_epc/sys/ia64/ia64/vm_machdep.c#4 edit
.. //depot/projects/ia64_epc/sys/ia64/include/_regset.h#5 edit
.. //depot/projects/ia64_epc/sys/ia64/include/asm.h#2 edit
.. //depot/projects/ia64_epc/sys/ia64/include/cpu.h#4 edit
.. //depot/projects/ia64_epc/sys/ia64/include/db_machdep.h#3 edit
.. //depot/projects/ia64_epc/sys/ia64/include/pcb.h#4 edit

Differences ...

==== //depot/projects/ia64_epc/sys/conf/files.ia64#5 (text+ko) ====

@@ -57,7 +57,6 @@
 ia64/ia64/support.s		standard
 ia64/ia64/ssc.c			optional	ski
 ia64/ia64/sscdisk.c		optional	ski
-ia64/ia64/swtch.s		standard
 ia64/ia64/sys_machdep.c		standard
 ia64/ia64/syscall.s		standard
 ia64/ia64/trap.c		standard

==== //depot/projects/ia64_epc/sys/ia64/ia64/context.s#6 (text+ko) ====

@@ -32,6 +32,302 @@
 	.section	.text.context, "ax"
 
 /*
+ * void restorectx(struct pcb *)
+ */
+ENTRY(restorectx, 1)
+{	.mmi
+	invala
+	mov		ar.rsc=0
+	add		r31=8,r32
+	;;
+}
+{	.mmi
+	ld8		r12=[r32]		// sp
+	ld8		r16=[r31],16		// unat (before)
+	add		r30=16,r32
+	;;
+}
+{	.mmi
+	ld8		r17=[r30],16		// rp
+	ld8		r18=[r31],16		// pr
+	add		r32=SIZEOF_SPECIAL,r32
+	;;
+}
+{	.mmi
+	ld8		r19=[r30],16		// pfs
+	ld8		r20=[r31],16		// bspstore
+	mov		rp=r17
+	;;
+}
+{	.mmi
+	loadrs
+	ld8		r21=[r30],16		// rnat
+	mov		pr=r18,0x1fffe
+	;;
+}
+{	.mmi
+	ld8		r17=[r32],8		// unat (after)
+	mov		ar.bspstore=r20
+	mov		ar.pfs=19
+	;;
+}
+{	.mmi
+	mov		ar.unat=r17
+	mov		ar.rnat=r21
+	add		r31=8,r32
+	;;
+}
+{	.mmi
+	ld8.fill	r4=[r32],16		// r4
+	ld8.fill	r5=[r31],16		// r5
+	nop		0
+	;;
+}
+{	.mmi
+	ld8.fill	r6=[r32],16		// r6
+	ld8.fill	r7=[r31],16		// r7
+	nop		1
+	;;
+}
+{	.mmi
+	mov		ar.unat=r16
+	mov		ar.rsc=3
+	nop		2
+}
+{	.mmi
+	ld8		r17=[r32],16		// b1
+	ld8		r18=[r31],16		// b2
+	nop		3
+	;;
+}
+{	.mmi
+	ld8		r19=[r32],16		// b3
+	ld8		r20=[r31],16		// b4
+	mov		b1=r17
+	;;
+}
+{	.mmi
+	ld8		r16=[r32],24		// b5
+	ld8		r17=[r31],32		// lc
+	mov		b2=r18
+	;;
+}
+{	.mmi
+	ldf.fill	f2=[r32],32
+	ldf.fill	f3=[r31],32
+	mov		b3=r19
+	;;
+}
+{	.mmi
+	ldf.fill	f4=[r32],32
+	ldf.fill	f5=[r31],32
+	mov		b4=r20
+	;;
+}
+{	.mmi
+	ldf.fill	f16=[r32],32
+	ldf.fill	f17=[r31],32
+	mov		b5=r16
+	;;
+}
+{	.mmi
+	ldf.fill	f18=[r32],32
+	ldf.fill	f19=[r31],32
+	mov		ar.lc=r17
+	;;
+}
+	ldf.fill	f20=[r32],32
+	ldf.fill	f21=[r31],32
+	;;
+	ldf.fill	f22=[r32],32
+	ldf.fill	f23=[r31],32
+	;;
+	ldf.fill	f24=[r32],32
+	ldf.fill	f25=[r31],32
+	;;
+	ldf.fill	f26=[r32],32
+	ldf.fill	f27=[r31],32
+	;;
+	ldf.fill	f28=[r32],32
+	ldf.fill	f29=[r31],32
+	;;
+{	.mmb
+	ldf.fill	f30=[r32]
+	ldf.fill	f31=[r31]
+	br.ret.sptk	rp
+	;;
+}
+END(restorectx)
+
+/*
+ * void savectx(struct pcb *)
+ * void swapctx(struct pcb *old, struct pcb *new)
+ */
+	
+ENTRY(savectx,1)
+{	.mmi
+	alloc		r16=ar.pfs,1,1,0,0
+	;;
+	add		r33=0,r0
+	nop		0
+}
+	/* FALLTHROUGH */
+
+ENTRY(swapctx, 2)
+{	.mmi
+	flushrs
+	mov		r16=ar.unat
+	add		r31=8,r32
+	;;
+}
+{	.mmi
+	st8		[r32]=sp,16		// sp
+	mov		ar.rsc=0
+	mov		r17=rp
+	;;
+}
+{	.mmi
+	st8		[r31]=r16,16		// unat (before)
+	st8		[r32]=r17,16		// rp
+	mov		r16=pr
+	;;
+}
+{	.mmi
+	st8		[r31]=r16,16		// pr
+	mov		r17=ar.bspstore
+	mov		r16=ar.pfs
+	;;
+}
+{	.mmi
+	st8		[r32]=r16,16		// pfs
+	st8		[r31]=r17,16		// bspstore
+	cmp.eq		p15,p0=0,r33
+	;;
+}
+{	.mmi
+	mov		r16=ar.rnat
+(p15)	mov		ar.rsc=3
+	add		r30=SIZEOF_SPECIAL-(6*8),r32
+	;;
+}
+{	.mmi
+	st8		[r32]=r16,SIZEOF_SPECIAL-(4*8)		// rnat
+	st8		[r31]=r0,SIZEOF_SPECIAL-(6*8)		// __spare
+	mov		r16=b1
+	;;
+}
+	/* callee_saved */
+{	.mmi
+	.mem.offset	8,0
+	st8.spill	[r31]=r4,16		// r4
+	.mem.offset	16,0
+	st8.spill	[r32]=r5,16		// r5
+	mov		r17=b2
+	;;
+}
+{	.mmi
+	.mem.offset	24,0
+	st8.spill	[r31]=r6,16		// r6
+	.mem.offset	32,0
+	st8.spill	[r32]=r7,16		// r7
+	mov		r18=b3
+	;;
+}
+{	.mmi
+	st8		[r31]=r16,16		// b1
+	mov		r16=ar.unat
+	mov		r19=b4
+	;;
+}
+{	.mmi
+	st8		[r30]=r16		// unat (after)
+	st8		[r32]=r17,16		// b2
+	mov		r16=b5
+	;;
+}
+{	.mmi
+	st8		[r31]=r18,16		// b3
+	st8		[r32]=r19,16		// b4
+	mov		r17=ar.lc
+	;;
+}
+	st8		[r31]=r16,16		// b5
+	st8		[r32]=r17,16		// lc
+	;;
+	st8		[r31]=r0,24		// __spare
+	stf.spill	[r32]=f2,32
+	;;
+	stf.spill	[r31]=f3,32
+	stf.spill	[r32]=f4,32
+	;;
+	stf.spill	[r31]=f5,32
+	stf.spill	[r32]=f16,32
+	;;
+	stf.spill	[r31]=f17,32
+	stf.spill	[r32]=f18,32
+	;;
+	stf.spill	[r31]=f19,32
+	stf.spill	[r32]=f20,32
+	;;
+	stf.spill	[r31]=f21,32
+	stf.spill	[r32]=f22,32
+	;;
+	stf.spill	[r31]=f23,32
+	stf.spill	[r32]=f24,32
+	;;
+	stf.spill	[r31]=f25,32
+	stf.spill	[r32]=f26,32
+	;;
+	stf.spill	[r31]=f27,32
+	stf.spill	[r32]=f28,32
+	;;
+	stf.spill	[r31]=f29,32
+	stf.spill	[r32]=f30
+	;;
+{	.mfb
+	stf.spill	[r31]=f31
+	nop		0
+(p15)	br.ret.sptk	rp
+	;;
+}
+{	.mfb
+	mov		r32=r33
+	nop		0
+	br.sptk		restorectx
+	;;
+}
+END(swapctx)
+
+/*
+ * fork_trampoline()
+ *
+ * Arrange for a function to be invoked neatly, after a cpu_switch().
+ *
+ * Invokes fork_exit() passing in three arguments: a callout function, an
+ * argument to the callout, and a trapframe pointer.  For child processes
+ * returning from fork(2), the argument is a pointer to the child process.
+ *
+ * The callout function is in r4, the address to return to after executing
+ * fork_exit() is in r5, and the argument is in r6.
+ */
+ENTRY(fork_trampoline, 0)
+	.prologue
+	.save	rp,r0
+	.body
+	alloc	r14=ar.pfs,0,0,3,0
+	;;
+	mov	b0=r5
+	mov	out0=r4
+	mov	out1=r6
+	add	out2=16,sp
+	;;
+	br.call.sptk.few rp=fork_exit
+	;; 
+	br.cond.sptk.many exception_restore
+	;;
+END(fork_trampoline)
+
+/*
  * _getcontext(ucontext_t *ucp)
  */
 ENTRY(_getcontext, 1)

==== //depot/projects/ia64_epc/sys/ia64/ia64/db_interface.c#3 (text+ko) ====

@@ -79,7 +79,7 @@
 #define DB_MISC_REGS	13	/* make sure this is correct */
 
 	{"pc",		(db_expr_t*) 0,				db_get_pc_reg},
-	{"ip",		(db_expr_t*) &ddb_regs.tf_special.ip,	FCN_NULL},
+	{"ip",		(db_expr_t*) &ddb_regs.tf_special.iip,	FCN_NULL},
 	{"psr",		(db_expr_t*) &ddb_regs.tf_special.psr,	FCN_NULL},
 	{"cr.isr",	(db_expr_t*) &ddb_regs.tf_special.isr,	FCN_NULL},
 	{"cr.ifa",	(db_expr_t*) &ddb_regs.tf_special.ifa,	FCN_NULL},

==== //depot/projects/ia64_epc/sys/ia64/ia64/exception.s#6 (text+ko) ====

@@ -31,12 +31,498 @@
 #include <assym.s>
 
 /*
- * ar.k7 = address of gateway page
- * ar.k6 = ksp
- * ar.k5 = kbsp
- * ar.k4 = pcpup
+ * ar.k7 = kernel memory stack
+ * ar.k6 = kernel register stack
+ * ar.k4 = PCPU data
+ */
+
+	.text
+
+/*
+ * exception_save: save interrupted state
+ *
+ * Arguments:
+ *	r16	address of bundle that contains the branch. The
+ *		return address will be the next bundle.
+ */
+ENTRY(exception_save, 0)
+{	.mii
+	mov		r17=sp
+	mov		r18=pr
+	extr.u		r31=sp,61,3
+	;;
+}
+{	.mmi
+	cmp.le		p14,p15=5,r31
+	;;
+(p15)	mov		r31=ar.k7		// kernel memory stack
+(p14)	mov		r31=sp
+	;;
+}
+{	.mmi
+	add		r30=-SIZEOF_TRAPFRAME,r31
+	;;
+	mov		r20=ar.unat
+	dep		sp=0,r30,0,10
+	;;
+}
+{	.mmi
+	mov		r21=ar.rsc
+	mov		ar.rsc=0
+	sub		r19=r31,sp
+	;;
+}
+
+	/*
+	 * 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. The registers that must
+	 * not be clobbered by the data nested TLB fault handler on top
+	 * of any interrupted state we haven't saved yet (ie almost all
+	 * of it) are: p14, p15, sp and r16-r21.
+	 */
+exception_save_restart:
+{	.mmi
+	st8		[sp]=r19		// length
+	mov		r22=cr.iip
+	add		r31=8,sp
+	;;
+}
+{	.mmi
+	st8		[r31]=r0,16		// flags
+	mov		r29=ar.bspstore
+	add		r30=16,sp
+	;;
+}
+{	.mmi
+	st8.spill	[r30]=r17,16		// sp
+	st8		[r31]=r20,16		// unat
+	mov		r27=b0
+	;;
+}
+{	.mmi
+	st8		[r30]=r27,16		// rp
+	st8		[r31]=r18,16		// pr
+	mov		r27=ar.pfs
+	;;
+}
+{	.mmb
+	st8		[r30]=r27,16		// pfs
+	st8		[r31]=r29,16		// bspstore
+	cover
+	;;
+}
+{	.mmi
+	mov		r17=ar.rnat
+	mov		r18=ar.fpsr
+	extr.u		r28=r29,61,3
+	;;
+}
+{	.mmi
+	st8		[r30]=r17,16		// rnat
+	st8		[r31]=r0,16		// __spare
+	cmp.le		p12,p13=5,r28
+	;;
+}
+{	.mmi
+	st8.spill	[r30]=r13,16		// tp
+	st8		[r31]=r21,16		// rsc
+	nop		0
+	;;
+}
+{	.mmi
+	mov		r17=cr.ipsr
+(p13)	mov		r29=ar.k6		// kernel register stack
+	nop		0
+	;;
+}
+{	.mmi
+	st8		[r30]=r18,16		// fpsr
+	st8		[r31]=r17,16		// psr
+	nop		0
+	;;
+}
+{	.mmi
+	mov		ar.bspstore=r29
+	;;
+	mov		r18=ar.bsp
+	nop		0
+	;;
+}
+{	.mmi
+	st8.spill	[r30]=gp,16		// gp
+	mov		r19=cr.ifs
+	sub		r18=r18,r29
+	;;
+}
+{	.mmi
+	st8		[r31]=r18,16		// ndirty
+	mov		r20=cr.ifa
+	nop		0
+	;;
+}
+{	.mmi
+	st8		[r30]=r19,16		// cfm
+	st8		[r31]=r22,16		// iip
+	nop		0
+	;;
+}
+{	.mmi
+	st8		[r30]=r20		// ifa
+	mov		r18=cr.isr
+	add		r29=16,r30
+	;;
+}
+{	.mmi
+	st8		[r31]=r18		// isr
+	add		r30=8,r29
+	add		r31=16,r29
+	;;
+}
+{	.mmi
+	.mem.offset	0,0
+	st8.spill	[r30]=r2,16		// r2
+	.mem.offset	8,0
+	st8.spill	[r31]=r3,16		// r3
+	add		r2=9*8,r29
+	;;
+}
+{	.mmi
+	.mem.offset	0,0
+	st8.spill	[r30]=r8,16		// r8
+	.mem.offset	8,0
+	st8.spill	[r31]=r9,16		// r9
+	add		r3=8,r2
+	;;
+}
+{	.mmi
+	.mem.offset	0,0
+	st8.spill	[r30]=r10,16		// r10
+	.mem.offset	8,0
+	st8.spill	[r31]=r11,16		// r11
+	add		r8=16,r16
+	;;
+}
+{	.mmi
+	.mem.offset	0,0
+	st8.spill	[r30]=r14		// r14
+	.mem.offset	8,0
+	st8.spill	[r31]=r15		// r15
+	mov		r9=r29
+}
+{	.mmb
+	mov		r10=ar.csd
+	mov		r11=ar.ssd
+	bsw.1
+	;;
+}
+{	.mmi
+	.mem.offset	0,0
+	st8.spill	[r2]=r16,16		// r16
+	.mem.offset	8,0
+	st8.spill	[r3]=r17,16		// r17
+	mov		r14=b6
+	;;
+}
+{	.mmi
+	.mem.offset	0,0
+	st8.spill	[r2]=r18,16		// r18
+	.mem.offset	8,0
+	st8.spill	[r3]=r19,16		// r19
+	mov		r15=b7
+	;;
+}
+{	.mmi
+	.mem.offset	0,0
+	st8.spill	[r2]=r20,16		// r20
+	.mem.offset	8,0
+	st8.spill	[r3]=r21,16		// r21
+	mov		b7=r8
+	;;
+}
+{	.mmi
+	.mem.offset	0,0
+	st8.spill	[r2]=r22,16		// r22
+	.mem.offset	8,0
+	st8.spill	[r3]=r23,16		// r23
+	;;
+}
+
+	.mem.offset	0,0
+	st8.spill	[r2]=r24,16		// r24
+	.mem.offset	8,0
+	st8.spill	[r3]=r25,16		// r25
+	;;
+	.mem.offset	0,0
+	st8.spill	[r2]=r26,16		// r26
+	.mem.offset	8,0
+	st8.spill	[r3]=r27,16		// r27
+	;;
+	.mem.offset	0,0
+	st8.spill	[r2]=r28,16		// r28
+	.mem.offset	8,0
+	st8.spill	[r3]=r29,16		// r29
+	;;
+	.mem.offset	0,0
+	st8.spill	[r2]=r30,16		// r30
+	.mem.offset	8,0
+	st8.spill	[r3]=r31,16		// r31
+	;;
+
+{	.mmi
+	st8		[r2]=r14,16		// b6
+	mov		r17=ar.unat
+	nop		0
+	;;
+}
+{	.mmi
+	st8		[r3]=r15,16		// b7
+	mov		r16=ar.ccv
+	nop		0
+	;;
+}
+{	.mmi
+	st8		[r2]=r16,16		// ccv
+	st8		[r3]=r10,16		// csd
+	nop		0
+	;;
+}
+{	.mmi
+	st8		[r2]=r11,24		// ssd
+	st8		[r9]=r17
+	nop		0
+	;;
+}
+
+	stf.spill	[r3]=f6,32		// f6
+	stf.spill	[r2]=f7,32		// f7
+	;;
+	stf.spill	[r3]=f8,32		// f8
+	stf.spill	[r2]=f9,32		// f9
+	;;
+	stf.spill	[r3]=f10,32		// f10
+	stf.spill	[r2]=f11,32		// f11
+	;;
+	stf.spill	[r3]=f12,32		// f12
+	stf.spill	[r2]=f13,32		// f13
+	;;
+	stf.spill	[r3]=f14		// f14
+	stf.spill	[r2]=f15		// f15
+	;;
+{	.mmi
+	mov		ar.rsc=3
+	mov		r13=ar.k4
+	nop		0
+	;;
+}
+{	.mlx
+	ssm		psr.ic
+	movl		gp=__gp
+	;;
+}
+{	.mfb
+	srlz.d
+	nop		0
+	br.sptk		b7
+	;;
+}
+END(exception_save)
+
+/*
+ * exception_restore:	restore interrupted state
+ *
+ * Arguments:
+ *	sp+16	trapframe pointer
  */
+ENTRY(exception_restore, 0)
+	/*
+	 * Read the length of the trapframe with interrupts enabled and
+	 * interrupt collection enabled. That way we can safely trap on
+	 * the load in case the address translation of the trapframe has
+	 * been flushed.
+	 */
+{	.mmi
+	add		sp=16,sp
+	;;
+	ld8		r9=[sp]			// length
+	add		r3=SIZEOF_TRAPFRAME-32,sp
+	;;
+}
+{	.mmi
+	rsm		psr.ic|psr.i
+	;;
+	srlz.d
+	add		r2=16,r3
+	;;
+}
+{	.mmi
+	ldf.fill	f15=[r2],-32		// f15
+	ldf.fill	f14=[r3],-32		// f14
+	add		r8=SIZEOF_SPECIAL+16,sp
+	;;
+}
+{	.mmi
+	ldf.fill	f13=[r2],-32		// f13
+	ldf.fill	f12=[r3],-32		// f12
+	add		r9=r9,sp
+	;;
+}
+
+	ldf.fill	f11=[r2],-32		// f11
+	ldf.fill	f10=[r3],-32		// f10
+	;;
+	ldf.fill	f9=[r2],-32		// f9
+	ldf.fill	f8=[r3],-32		// f8
+	;;
+	ldf.fill	f7=[r2],-24		// f7
+	ldf.fill	f6=[r3],-16		// f6
+	;;
+
+{	.mmi
+	ld8		r8=[r8]			// unat (after)
+	mov		ar.k7=r9
+	nop		0
+	;;
+}
+{	.mmi
+	ld8		r10=[r2],-16		// ssd
+	ld8		r11=[r3],-16		// csd
+	nop		0
+	;;
+}
+{	.mmi
+	mov		ar.unat=r8
+	mov		ar.ssd=r10
+	nop		0
+}
+{	.mmi
+	ld8		r14=[r2],-16		// ccv
+	ld8		r15=[r3],-16		// b7
+	nop		0
+	;;
+}
+{	.mmi
+	mov		ar.csd=r11
+	mov		ar.ccv=r14
+	mov		b7=r15
+	;;
+}
+{	.mmi
+	ld8		r8=[r2],-16		// b6
+	ld8.fill	r31=[r3],-16		// r31
+	nop		0
+	;;
+}
+{	.mmi
+	ld8.fill	r30=[r2],-16		// r30
+	ld8.fill	r29=[r3],-16		// r29
+	mov		b6=r8
+	;;
+}
+
+	ld8.fill	r28=[r2],-16		// r28
+	ld8.fill	r27=[r3],-16		// r27
+	;;
+	ld8.fill	r26=[r2],-16		// r26
+	ld8.fill	r25=[r3],-16		// r25
+	;;
+	ld8.fill	r24=[r2],-16		// r24
+	ld8.fill	r23=[r3],-16		// r23
+	;;
+	ld8.fill	r22=[r2],-16		// r22
+	ld8.fill	r21=[r3],-16		// r21
+	;;
+	ld8.fill	r20=[r2],-16		// r20
+	ld8.fill	r19=[r3],-16		// r19
+	;;
+	ld8.fill	r18=[r2],-16		// r18
+	ld8.fill	r17=[r3],-16		// r17
+	;;
+
+{	.mmb
+	ld8.fill	r16=[r2],-16		// r16
+	ld8.fill	r15=[r3],-16		// r15
+	bsw.0
+	;;
+}
+{	.mmi
+	ld8.fill	r14=[r2],-16		// r14
+	ld8.fill	r11=[r3],-16		// r11
+	add		r31=16,sp
+	;;
+}
+{	.mmi
+	ld8.fill	r10=[r2],-16		// r10
+	ld8.fill	r9=[r3],-16		// r9
+	add		r30=24,sp
+	;;
+}
+
+	ld8.fill	r8=[r2],-16		// r8
+	ld8.fill	r3=[r3]			// r3
+	;;
+	ld8.fill	r2=[r2]			// r2
+	ld8.fill	sp=[r31],16		// sp
+	;;
+	ld8		r16=[r30],16		// unat
+	ld8		r17=[r31],16		// rp
+	;;
+	ld8		r18=[r30],16		// pr
+	ld8		r19=[r31],16		// pfs
+	mov		rp=r17
+	;;
+	ld8		r20=[r30],24		// bspstore
+	ld8		r21=[r31],24		// rnat
+	;;
+	ld8.fill	r29=[r30],16		// tp
+	ld8		r22=[r31],16		// rsc
+	;;
+	ld8		r23=[r30],16		// fpsr
+	ld8		r24=[r31],16		// psr
+	;;
+	ld8.fill	r1=[r30],16		// gp
+	ld8		r25=[r31],16		// ndirty
+	;;
+	ld8		r26=[r30]		// cfm
+	ld8		r27=[r31]		// ip
+	;;
 
+	// Switch register stack
+#if 0
+	alloc		r31=ar.pfs,0,0,0,0	// discard current frame
+	shl		r30=r25,16		// value for ar.rsc
+	;;
+	mov		ar.rsc=r30		// setup for loadrs
+	;;
+	loadrs					// load user regs
+	;;
+	mov		ar.bspstore=r20
+	;;
+	mov		ar.rnat=r21
+#endif
+
+	// Don't restore r13 if returning to kernel
+
+	mov		ar.unat=r16
+	mov		ar.pfs=r19
+	mov		ar.fpsr=r23
+	mov		cr.ipsr=r24
+	mov		cr.ifs=r26
+	mov		cr.iip=r27
+	;;
+
+{	.mib
+	mov		ar.rsc=r22
+	mov		pr=r18,0x1fffe
+	rfi
+	;;
+}
+END(exception_restore)
+
 /*
  * Call exception_save_regs to preserve the interrupted state in a
  * trapframe. Note that we don't use a call instruction because we
@@ -47,12 +533,12 @@
  * resume it.
  */
 #define TRAP(_n_)				\
-1:	mov	r17=ip;;			\
-	add	r17=2f-1b,r17;			\
-	mov	r16=b6;;			\
-	mov	b6=r17;				\
-	br.sptk.few exception_save;		\
-2: (p3)	ssm	psr.i;				\
+{	.mib ;					\
+	nop		_n_ ;			\
+	mov		r16=ip ;		\
+	br.sptk.few	exception_save ;	\
+} ;						\
+(p3)	ssm	psr.i;				\
 	alloc	r15=ar.pfs,0,0,3,0;		\
 	mov	out0=_n_;			\
 	mov	out1=r14;			\
@@ -519,16 +1005,17 @@
 IVT_END(Break_Instruction)
 
 IVT_ENTRY(External_Interrupt, 0x3000)
-	mov	r16=b6			// save user's b6
-1:	mov	r17=ip;;		// construct return address
-	add	r17=2f-1b,r17;;		// for exception_save
-	mov	b6=r17
-	br.sptk.few exception_save	// 'call' exception_save
-
+{	.mib
+	nop		12
+	mov		r16=ip
+	br.sptk		exception_save
+	;;
+}
+{	.mmi
 2:	alloc	r14=ar.pfs,0,0,2,0	// make a frame for calling with
-
-	mov	out1=sp;;
-	add	sp=-16,sp;;
+	mov	out1=sp
+	add	sp=-16,sp
+}
 
 3:	mov	out0=cr.ivr		// find interrupt vector
 	;;
@@ -538,17 +1025,16 @@
 	ssm	psr.i			// re-enable interrupts
 	;;				// now that we are in-progress
 	srlz.d
+	br.call.sptk.many rp=interrupt	// call high-level handler
 	;;
-	br.call.sptk.many rp=interrupt	// call high-level handler
-
 	rsm	psr.i			// disable interrupts
 	;;
 	srlz.d
-	;;
 	mov	cr.eoi=r0		// and ack the interrupt
 	;;
 	srlz.d
 	br.sptk.few 3b			// loop for more
+	;;
 IVT_END(External_Interrupt)
 
 IVT_ENTRY(Reserved_3400, 0x3400)
@@ -770,705 +1256,3 @@
 IVT_ENTRY(Reserved_7f00, 0x7f00)
 	TRAP(67)
 IVT_END(Reserved_7f00)
-
-	.text
-
-/*
- * exception_restore:	restore interrupted state
- *
- * Arguments:
- *	sp+16	trapframe pointer
- *	r4	ar.pfs before the alloc in TRAP()
- *
- */
-ENTRY(exception_restore, 0)
-{	.mfi
-	alloc	r14=ar.pfs,0,0,1,0	// in case we call ast()
-	nop	1
-	add	r3=TF_SPECIAL_PSR+16,sp
-	;;
-}
-{	.mmi
-	ld8	r30=[r3]		// ipsr
-	;;
-	nop	2
-	extr.u	r16=r30,32,2		// extract ipsr.cpl
-	;;
-}
-{	.mfb
-	cmp.eq	p1,p2=r0,r16		// test for return to kernel mode
-	nop	3
-(p1)	br.cond.dpnt 2f			// no ast check for returns to kernel
-}
-3:
-{	.mmi
-	add	r3=PC_CURTHREAD,r13	// &curthread
-	;;
-	ld8	r3=[r3]			// curthread
-	add	r2=(TDF_ASTPENDING|TDF_NEEDRESCHED),r0
-	;;
-}
-{	.mmb
-	mov	r15=psr			// save interrupt enable status
-	nop	4
-	;;
-}
-{	.mmi
-	;;
-	rsm	psr.i			// disable interrupts
-	add	r3=TD_FLAGS,r3		// &curthread->td_flags
-	;;
-}
-{	.mmi
-	ld4	r14=[r3]		// fetch curthread->td_flags
-	;;
-	and	r14=r2,r14	    // flags & (TDF_ASTPENDING|TDF_NEEDRESCHED)
-	nop	5
-	;;
-}
-{	.mfb

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200304080814.h388Ew6U009052>