Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 Apr 2003 00:21:28 -0700 (PDT)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 28909 for review
Message-ID:  <200304140721.h3E7LSQp087339@repoman.freebsd.org>

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

Change 28909 by marcel@marcel_nfs on 2003/04/14 00:20:51

	Quick and dirty implementation of swithing to kernel space. There
	are a couple of gothas:
	o  We need to make sure PSR has been sanitized before we start
	   creating the trapframe. The process may be using big-endian
	   memory accesses.
	o  It takes us a couple of instructionis to switch to kernel mode,
	   so we have a grey area in which we're not actually in kernel
	   space and not actually in process space. We need to make sure
	   exceptions in that grey area don't mess things up.
	
	More later this week...

Affected files ...

.. //depot/projects/ia64_epc/sys/ia64/ia64/syscall.s#5 edit

Differences ...

==== //depot/projects/ia64_epc/sys/ia64/ia64/syscall.s#5 (text+ko) ====

@@ -30,59 +30,46 @@
 #include <assym.s>
 
 /*
- * TEMPORARY NOTICE (ie remove when code matures or is replaced)
- * This implementation is a quick and very likely dirty way to create a
- * syscall path based on the epc instruction. The immediate reasons for
- * the implementation are:
- * 1. First release around the corner and changing the syscall interface
- *    would cause an ABI breakage. This can better be done before release
- *    than afterwards.
- * 2. Implement {set|get|swap}context syscalls when the infrastructure
- *    to reliably unwind is not yet in place. By switching the syscall
- *    interface, we created the opportunity to implement the syscalls
- *    in a way that wouldn't need the unwind infrastructure.
+ * A process performs a syscall by calling epc_syscall through the EPC
+ * gateway page. The address of the gateway page is passed to the process
+ * in ar.k3.
  *
- * A process performs a syscall by calling epc_syscall. This function
- * will reside in a special page that has all the necessary attributes
- * required for epc to increase privileges and will be mapped into the
- * process' address space at a fixed location. The epc_syscall function
- * will perform an epc and setup the necessary stack-frame on the kernel
- * stack required or at least expected when entering the kernel.
- *
- * Lightweight syscalls can be implemented by accessing kernel structures
- * or calling kernel functions without this setup.
- *
  * Syscalls don't follow the calling convention completely. The reason
  * for this is that it would create unnecessary overhead. Arguments to
  * syscalls are:
  *	r8		-	syscall number
- *	r9		-	ar.pfs
+ *	r9		-	copy of ar.pfs
  *	in0-in7		-	syscall arguments
  *	b6		-	return address
  *
  * Syscalls return:
  *	r8+r9		-	syscall return value(s)
  *	r10		-	syscall error flag
+ *
+ * The EPC gateway code prefetches the following:
+ *	r14		-	prefetched ar.k7
+ *	r15		-	prefetched ar.k6
+ *	p15		-	true for fork(2)
  */
 
 	.section	.text.gateway, "ax"
 	.align		PAGE_SIZE
 	.global		ia64_gateway_page
 ia64_gateway_page:
-{	.mfb
-	nop.m		0
-	nop.f		0
+{	.mmb
+	mov		r14=ar.k7		// Memory stack
+	mov		r15=ar.k6		// Register stack
 	epc
 	;;
 }
 {	.mlx
-	nop.m		0
-	movl		r16=epc_syscall
+	add		r30=-1,r0		// XXX
+	movl		r31=epc_syscall
 	;;
 }
 {	.mib
-	nop.m		0
-	mov		b7=r16
+	cmp.eq		p15,p0=r30,r8
+	mov		b7=r31
 	br		b7
 	;;
 }
@@ -94,174 +81,116 @@
 	.proc		epc_syscall
 	.regstk		8,0,0,0
 epc_syscall:
-	mov		r16=psr			// psr substitute
+{	.mmi
 	mov		r17=ar.rsc
-	mov		r18=sp
+	mov		r18=ar.unat
+	add		r30=-SIZEOF_TRAPFRAME,r14
 	;;
-	mov		sp=ar.k6		// Kernel SP
-	mov		r19=r0			// cr.isr substitute
+}
+{	.mmi
 	mov		ar.rsc=0
+	mov		r19=ar.fpsr
+	dep		r30=0,r30,0,10
 	;;
-	mov		r20=ar.bspstore
-	mov		r21=ar.k5		// Kernel BSP
+}
+{	.mmi
+	mov		r21=ar.bspstore
 	mov		r22=ar.rnat
-	mov		r23=ar.unat
-	mov		r24=b6			// cr.iip substitute
-	mov		r25=r9			// ar.pfs substitute
-	add		sp=-SIZEOF_TRAPFRAME,sp
+	mov		r23=r13
 	;;
-	addl		r27=FRAME_SYSCALL,r0
-	mov		r26=pr
-	add		r30=0,sp
-	add		r31=8,sp
+}
+{	.mmi
+	mov		ar.bspstore=r15
+	add		r31=8,r30
+	mov		r20=sp
 	;;
-	st8		[r30]=r27,16		// tf_flags
-	st8		[r31]=r24,16		// tf_cr_iip
-	mov		r28=b0
+}
+{	.mmi
+	mov		ar.rsc=3
+	add		sp=-16,r30
+	sub		r29=r14,r30
 	;;
-	st8		[r30]=r16,24		// tf_cr_ipsr
-	st8		[r31]=r19,24		// tf_cr_isr
-	mov		r24=b1
+}
+{	.mmi
+	st8		[r30]=r29,16		// tf_length
+	mov		r24=ar.bsp
+	add		r29=FRAME_SYSCALL,r0
 	;;
-	st8		[r30]=r26,16		// tf_pr
-	st8		[r31]=r17,24		// tf_ar_rsc
-	mov		r27=b2
+}
+{	.mmi
+	st8		[r31]=r29,16		// tf_flags
+	mov		r27=psr
+	mov		r25=b6
 	;;
-	st8		[r30]=r25,24		// tf_ar_pfs
-	mov		r16=b3
-	mov		r17=b4
+}
+{	.mmi
+	st8		[r30]=r20,16		// sp
+	st8		[r31]=r18,16		// unat
+	mov		r26=pr
 	;;
-	st8		[r31]=r20,24		// tf_ar_bspstore
-	mov		ar.bspstore=r21		// Switch to kernel BSP
-	mov		r29=b5
+}
+{	.mmi
+	st8		[r30]=r25,16		// rp
+	st8		[r31]=r26,16		// pr
+	sub		r24=r24,r15
 	;;
-	mov		r20=ar.ccv
-	mov		r21=ar.fpsr
+}
+{	.mmi
+	st8		[r30]=r9,16		// pfs
+	st8		[r31]=r21,16		// bspstore
+	nop		0
 	;;
-	st8		[r30]=r22,24		// tf_ar_rnat
-	st8		[r31]=r23,16		// tf_ar_unat
+}
+{	.mmi
+	st8		[r30]=r22,16		// rnat
+	st8		[r31]=r24,16		// __spare (=ndirty)
+	nop		0
 	;;
-	st8		[r30]=r20,32		// tf_ar_ccv
-	st8		[r31]=r21,32		// tf_ar_fpsr
+}
+{	.mmi
+	st8		[r30]=r23,16		// tp
+	st8		[r31]=r17,16		// rsc
+	nop		0
 	;;
-	st8		[r30]=r28,16		// tf_b[0]
-	st8		[r31]=r24,16		// tf_b[1]
+}
+{	.mmi
+	st8		[r30]=r19,128		// fpsr
+	st8		[r31]=r27,128		// psr
+	nop		0
 	;;
-	st8		[r30]=r27,16		// tf_b[2]
-	st8		[r31]=r16,16		// tf_b[3]
+}
+	st8		[r30]=r8,16		// syscall number (=r15)
+	st8		[r31]=r32,16		// arg0 (=r16)
 	;;
-	st8		[r30]=r17,-64		// tf_b[4]
-	st8		[r31]=r29,-64		// tf_b[5]
+	st8		[r30]=r33,16		// arg1 (=r17)
+	st8		[r31]=r34,16		// arg2 (=r18)
 	;;
-	st8		[r30]=r1,-64		// tf_r[0] (=r1=gp)
-	.mem.offset 8,0
-	st8.spill	[r31]=r4,16		// tf_r[3] (=r4)
+	st8		[r30]=r35,16		// arg3 (=r19)
+	st8		[r31]=r36,16		// arg4 (=r20)
 	;;
-	.mem.offset 0,0
-	st8.spill	[r30]=r5,16		// tf_r[4] (=r5)
-	.mem.offset 8,0
-	st8.spill	[r31]=r6,-64		// tf_r[5] (=r6)
+	st8		[r30]=r37,16		// arg5 (=r21)
+	st8		[r31]=r38,16		// arg6 (=r22)
 	;;
-	.mem.offset 0,0
-	st8.spill	[r30]=r7,-64		// tf_r[6] (=r7)
-	st8		[r31]=r18		// tf_r[11] (=r12=sp)
+	st8		[r30]=r39,8		// arg7 (=r23)
+	mov		r13=ar.k4
 	;;
-	st8		[r30]=r8		// tf_r[14] (syscall number)
-	add		sp=-(8*8),sp
+
+{	.mlx
+	alloc		r14=ar.pfs,0,0,3,0
+	movl		gp=__gp
 	;;
-	add		r31=0,sp
-	add		r30=8,sp
+}
+{	.mii
+	mov		out0=r8
+	add		out1=-(8*8),r31
+	add		out2=16,sp
 	;;
-	st8		[r31]=in0,16
-	st8		[r30]=in1,16
-	;;
-	st8		[r31]=in2,16
-	st8		[r30]=in3,16
-	;;
-	st8		[r31]=in4,16
-	st8		[r30]=in5,16
-	;;
-	st8		[r31]=in6
-	st8		[r30]=in7
-	;;
-	mov		r13=ar.k4		// PCPU
-	mov		r16=sp
-	mov		r17=ar.k5
-	cover
-	;;
-	mov		r18=ar.pfs		// cr.ifs substitute
-	mov		r19=ar.bsp
-	add		sp=-16,sp
-	;;
-	add		r20=TF_SPECIAL_PFS+(8*8),r16
-	add		r21=TF_SPECIAL_NDIRTY+(8*8),r16
-	;;
-	st8		[r20]=r18		// tf_cr_ifs
-	st8		[r21]=r19		// tf_as_bsp
-	;;
-	alloc		r14=ar.pfs,0,1,3,0
-	add		loc0=(8*8),r16
-	;;
-	mov		out0=r8			// syscall number
-	movl		gp=__gp
-	mov		out1=r16		// arguments
-	add		out2=(8*8),r16		// trapframe pointer
+}
+{	.mfb
+	ssm		psr.dfh
+	nop		0
 	br.call.sptk	rp=syscall
 	;;
-	add		r15=0,loc0
-	add		r16=SIZEOF_TRAPFRAME,loc0
-	;;
-	add		r30=0,r15	// R10
-	add		r31=0,r15	// SP
-	;;
-	alloc		r14=ar.pfs,0,0,0,0
-	mov		ar.k6=r16
-	ld8		sp=[r31],-64		// tf_r[11] (r12=sp)
-	;;
-	ld8		r10=[r30],-16		// tf_r[9] (=r10)
-	ld8		r9=[r31],-64		// tf_r[8] (=r9)
-	;;
-	ld8		r8=[r30],-64		// tf_r[7] (=r8)
-	ld8		r1=[r31],-64		// tf_r[0] (=r1=gp)
-	;;
-	ld8		r16=[r30],-32		// tf_b[0]
-	ld8		r17=[r31],-16		// tf_ar_fpsr
-	;;
-	ld8	r18=[r30],-16		// restore ar.ccv, skip to ndirty
-	ld8	r19=[r31],-16		// restore ar.unat, skip to ar.rnat
-	mov	b0=r16
-	;;
-	ld8	r20=[r30],-16		// restore ndirty, skip to ar.bspstore
-	ld8	r21=[r31],-16		// restore ar.rnat, skip to cr.ifs
-	;;
-	ld8	r16=[r30],-16		// restore ar.bspstore, skip to ar.pfs
-	mov	ar.fpsr=r17
-	shl	r20=r20,16		// value for ar.rsc
-	;;
-	ld8	r22=[r31],-16		// restore cr.ifs, skip to ar.rsc
-	mov	ar.ccv=r18
-	;;
-	ld8	r17=[r30],-16		// restore ar.pfs, skip to pr
-	mov	ar.unat=r19
-	;;
-	ld8	r18=[r31],-32		// restore ar.rsc, skip to cr.ipsr
-	mov	ar.rsc=r20		// setup for loadrs
-	;;
-	loadrs				// restore user stacked registers
-	;;
-	mov	ar.bspstore=r16		// back to user backing store
-	mov	ar.pfs=r17
-	;;
-	mov	ar.rnat=r21
-	mov	ar.rsc=r18
-	;;
-	ld8	r16=[r30],-32		// restore pr, skip to cr.iip
-	ld8	r17=[r31]		// restore cr.ipsr
-	;;
-	ld8	r18=[r30]		// restore cr.iip
-	mov	pr=r16,0x1ffff
-	;;
-	mov		b6=r18
-	br.ret.sptk	b6
-	;;
+}
+	break		0
 	.endp		epc_syscall



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