Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 17 Apr 2003 00:32:11 -0700 (PDT)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 29108 for review
Message-ID:  <200304170732.h3H7WBoJ073808@repoman.freebsd.org>

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

Change 29108 by marcel@marcel_nfs on 2003/04/17 00:32:02

	Finish the rudimenary EPC syscall code. Of course this is
	still missing the signal handling, but at least it gets us
	to the first fork(2). This is the point I needed to get to
	so that I can finish fork_trampoline (I now have a quick
	and dirty version that only works for the very first process
	(ie init).
	
	Change the syscall stub to use ar.k5 instead of ar.k3.
	
	Also: we didn't save the frame marker and return pointer
	of the function calling a syscall stub and thus got lost
	in the forest that is code on our way back. To keep the
	stubs small (but mostly generatable) we save the frame
	marker and return pointer of the function calling a
	syscall stub in registers and pass them on to the EPC
	syscall code. There we restore them for the process.
	Note that this is caused by the requirement to use a
	call to go to the EPC gateway page, because we need to
	lower the privilege level on our way back. This can only
	be done by a return. Otherwise I would have avoided the
	call so that we would not clobber the frame marker and
	return pointer.
	
	Oh, and we now use spills to store the syscall argument
	in memory. The reasoning is this: We don't know how many
	arguments a syscall has, but we know that 8 is the max.
	Hence, we may be reading garbage, including NaTs. If we
	don't spill, we could therefore get a NaT consumption fault.
	and since we're already in kernel mode, this is bad. By
	spilling we basicly ignore the NaT bits (if any).

Affected files ...

.. //depot/projects/ia64_epc/sys/ia64/ia64/syscall.s#6 edit
.. //depot/projects/ia64_epc/sys/ia64/include/asm.h#3 edit

Differences ...

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

@@ -30,26 +30,32 @@
 #include <assym.s>
 
 /*
- * 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 performing an indirect call to the
+ * address stored in ar.k5. The contents ar.pfs and rp should be saved
+ * prior to the syscall in r9 and r10 respectively. The kernel will
+ * restore these values on return. The value of gp is preserved across
+ * the call.
+ * The address in ar.k5 is the start of the EPC gateway page. The code
+ * in the gateway page is primarily responsible for increasing the
+ * privilege level, but will also make sure we have a reliable psr.
  *
- * Syscalls don't follow the calling convention completely. The reason
- * for this is that it would create unnecessary overhead. Arguments to
- * syscalls are:
+ * A process defines:
  *	r8		-	syscall number
  *	r9		-	copy of ar.pfs
+ *	r10		-	copy of rp
  *	in0-in7		-	syscall arguments
- *	b6		-	return address
  *
- * Syscalls return:
+ * A syscall returns:
  *	r8+r9		-	syscall return value(s)
  *	r10		-	syscall error flag
+ *	ar.pfs		-	restored from r9
+ *	rp		-	restored from r10
+ *	gp		-	preserved
  *
- * The EPC gateway code prefetches the following:
- *	r14		-	prefetched ar.k7
- *	r15		-	prefetched ar.k6
- *	p15		-	true for fork(2)
+ * The EPC defines:
+ *	r11		-	copy of psr.l
+ *	r14		-	Kernel memory stack
+ *	r15		-	Kernel register stack
  */
 
 	.section	.text.gateway, "ax"
@@ -63,16 +69,29 @@
 	;;
 }
 {	.mlx
-	add		r30=-1,r0		// XXX
+	mov		r11=psr
 	movl		r31=epc_syscall
 	;;
 }
 {	.mib
-	cmp.eq		p15,p0=r30,r8
+	rum		psr.be
 	mov		b7=r31
 	br		b7
 	;;
 }
+gw_ret:
+{	.mmi
+	mov		ar.rnat=r22
+	mov		ar.rsc=r24
+	mov		ar.pfs=r28
+}
+{	.mib
+	mov		ar.fpsr=r25
+	mov		b0=r29
+	br.sptk		b6
+	;;
+}
+
 	.align		PAGE_SIZE
 
 
@@ -82,99 +101,139 @@
 	.regstk		8,0,0,0
 epc_syscall:
 {	.mmi
-	mov		r17=ar.rsc
-	mov		r18=ar.unat
+	mov		r16=ar.rsc
+	mov		ar.rsc=0
+	mov		r17=r13
+	;;
+}
+{	.mmi
+	mov		r18=ar.bspstore
+	mov		r19=ar.rnat
 	add		r30=-SIZEOF_TRAPFRAME,r14
 	;;
 }
 {	.mmi
-	mov		ar.rsc=0
-	mov		r19=ar.fpsr
+	mov		ar.bspstore=r15
+	mov		r13=ar.k4
 	dep		r30=0,r30,0,10
 	;;
 }
-{	.mmi
-	mov		r21=ar.bspstore
-	mov		r22=ar.rnat
-	mov		r23=r13
+{	.mii
+	mov		r20=sp
+	add		r31=8,r30
+	add		sp=-16,r30
 	;;
 }
 {	.mmi
-	mov		ar.bspstore=r15
-	add		r31=8,r30
-	mov		r20=sp
+	mov		r21=ar.unat
+	mov		r22=ar.fpsr
+	sub		r29=r14,r30
 	;;
 }
 {	.mmi
+	mov		r23=ar.bsp
 	mov		ar.rsc=3
-	add		sp=-16,r30
-	sub		r29=r14,r30
+	add		r28=FRAME_SYSCALL,r0
 	;;
 }
 {	.mmi
 	st8		[r30]=r29,16		// tf_length
-	mov		r24=ar.bsp
-	add		r29=FRAME_SYSCALL,r0
+	st8		[r31]=r28,16		// tf_flags
+	mov		r24=rp
+	;;
+}
+{	.mmi
+	st8		[r30]=r20,16		// sp
+	st8		[r31]=r21,16		// unat
+	mov		r25=pr
+	;;
+}
+{	.mmi
+	st8		[r30]=r24,16		// rp (syscall stub)
+	st8		[r31]=r25,16		// pr
+	mov		r26=ar.pfs
 	;;
 }
 {	.mmi
-	st8		[r31]=r29,16		// tf_flags
-	mov		r27=psr
-	mov		r25=b6
+	st8		[r30]=r26,16		// pfs (syscall stub)
+	st8		[r31]=r18,16		// bspstore
+	sub		r27=r23,r15
 	;;
 }
 {	.mmi
-	st8		[r30]=r20,16		// sp
-	st8		[r31]=r18,16		// unat
-	mov		r26=pr
+	st8		[r30]=r19,16		// rnat
+	st8		[r31]=r0,16		// __spare
+	nop		0
 	;;
 }
 {	.mmi
-	st8		[r30]=r25,16		// rp
-	st8		[r31]=r26,16		// pr
-	sub		r24=r24,r15
+	st8		[r30]=r17,16		// tp
+	st8		[r31]=r16,16		// rsc
+	nop		0
 	;;
 }
 {	.mmi
-	st8		[r30]=r9,16		// pfs
-	st8		[r31]=r21,16		// bspstore
+	st8		[r30]=r22,16		// fpsr
+	st8		[r31]=r11,16		// psr
 	nop		0
 	;;
 }
 {	.mmi
-	st8		[r30]=r22,16		// rnat
-	st8		[r31]=r24,16		// __spare (=ndirty)
+	st8		[r30]=r1,16		// gp
+	st8		[r31]=r27,16		// ndirty
 	nop		0
 	;;
 }
 {	.mmi
-	st8		[r30]=r23,16		// tp
-	st8		[r31]=r17,16		// rsc
+	st8		[r30]=r9,16		// pfs (syscall caller)
+	st8		[r31]=r10,16		// rp (syscall caller)
 	nop		0
 	;;
 }
 {	.mmi
-	st8		[r30]=r19,128		// fpsr
-	st8		[r31]=r27,128		// psr
+	st8		[r30]=r0,80		// ifa
+	st8		[r31]=r0,80		// isr
 	nop		0
 	;;
 }
+{	.mmi
 	st8		[r30]=r8,16		// syscall number (=r15)
-	st8		[r31]=r32,16		// arg0 (=r16)
+	.mem.offset	0,0
+	st8.spill	[r31]=r32,16		// arg0 (=r16)
+	nop		0
 	;;
-	st8		[r30]=r33,16		// arg1 (=r17)
-	st8		[r31]=r34,16		// arg2 (=r18)
+}
+{	.mmi
+	.mem.offset	8,0
+	st8.spill	[r30]=r33,16		// arg1 (=r17)
+	.mem.offset	16,0
+	st8.spill	[r31]=r34,16		// arg2 (=r18)
+	nop		0
 	;;
-	st8		[r30]=r35,16		// arg3 (=r19)
-	st8		[r31]=r36,16		// arg4 (=r20)
+}
+{	.mmi
+	.mem.offset	24,0
+	st8.spill	[r30]=r35,16		// arg3 (=r19)
+	.mem.offset	32,0
+	st8.spill	[r31]=r36,16		// arg4 (=r20)
+	nop		0
 	;;
-	st8		[r30]=r37,16		// arg5 (=r21)
-	st8		[r31]=r38,16		// arg6 (=r22)
+}
+{	.mmi
+	.mem.offset	40,0
+	st8.spill	[r30]=r37,16		// arg5 (=r21)
+	.mem.offset	48,0
+	st8.spill	[r31]=r38,16		// arg6 (=r22)
+	nop		0
 	;;
-	st8		[r30]=r39,8		// arg7 (=r23)
-	mov		r13=ar.k4
+}
+{	.mmi
+	.mem.offset	56,0
+	st8.spill	[r30]=r39,8		// arg7 (=r23)
+	ssm		psr.dfh|psr.ac
+	nop		0
 	;;
-
+}
 {	.mlx
 	alloc		r14=ar.pfs,0,0,3,0
 	movl		gp=__gp
@@ -187,10 +246,109 @@
 	;;
 }
 {	.mfb
-	ssm		psr.dfh
+	srlz.d
 	nop		0
 	br.call.sptk	rp=syscall
 	;;
 }
-	break		0
+
+	.global		syscall_return
+	.type		syscall_return, @function
+syscall_return:
+{	.mmi
+	alloc		r31=ar.pfs,0,0,0,0
+	add		r14=32,sp
+	add		r15=16,sp
+	;;
+}
+{	.mmi
+	ld8		r31=[r15],24		// tf_length
+	ld8		r16=[r14],16		// sp
+	add		sp=16,sp
+	;;
+}
+{	.mmi
+	ld8		r17=[r15],16		// unat (before)
+	ld8		r18=[r14],16		// rp (syscall stub)
+	add		r31=r31,sp
+	;;
+}
+{	.mmi
+	ld8		r19=[r15],16		// pr
+	ld8		r20=[r14],16		// pfs (syscall stub)
+	mov		sp=r16
+	;;
+}
+{	.mmi
+	ld8		r21=[r15],24		// bspstore
+	ld8		r22=[r14],24		// rnat
+	mov		b6=r18
+	;;
+}
+{	.mmi
+	ld8		r23=[r15],16		// tp
+	ld8		r24=[r14],16		// rsc
+	mov		pr=r19,0x1fffe
+	;;
+}
+{	.mmi
+	ld8		r25=[r15],16		// fpsr
+	ld8		r26=[r14],16		// psr
+	mov		ar.pfs=r20
+	;;
+}
+{	.mmi
+	ld8		gp=[r15],16		// gp
+	ld8		r27=[r14],16		// ndirty
+	nop		0
+	;;
+}
+{	.mmi
+	ld8		r28=[r15],56		// pfs (syscall caller)
+	ld8		r29=[r14],56		// rp (syscall caller)
+	shl		r27=r27,16
+	;;
+}
+{	.mmi
+	ld8		r8=[r15],16		// r8
+	mov		ar.rsc=r27
+	nop		0
+	;;
+}
+{	.mmi
+	ld8		r9=[r14]		// r9
+	ld8		r10=[r15]		// r10
+	nop		0
+	;;
+}
+{	.mmi
+	loadrs
+	mov		ar.k7=r31
+	dep		r26=-1,r26,19,1		// Set psr.dfh
+	;;
+}
+{	.mmi
+	mov		r31=ar.bspstore
+	mov		ar.bspstore=r21
+	mov		r13=r23
+	;;
+}
+{	.mmi
+	mov		r14=ar.k5
+	mov		ar.k6=r31
+	nop		0
+	;;
+}
+{	.mmi
+	mov		psr.l=r26
+	mov		ar.unat=r17
+	add		r14=gw_ret-ia64_gateway_page,r14
+	;;
+}
+{	.mib
+	srlz.d
+	mov		b7=r14
+	br.ret.sptk	b7
+	;;
+}
 	.endp		epc_syscall

==== //depot/projects/ia64_epc/sys/ia64/include/asm.h#3 (text+ko) ====

@@ -164,11 +164,12 @@
 #define	EPC_CALLSYS_NOERROR(name)				\
 {	.mmi ;							\
 	alloc		r9 = ar.pfs, 0, 0, 8, 0 ;		\
-	mov		r14 = ar.k3 ;; }			\
+	mov		r31 = ar.k5 ;				\
+	mov		r10 = b0 ;; }				\
 {	.mib ;							\
 	mov		r8 = SYSCALLNUM(name) ;			\
-	mov		b7 = r14 ; 				\
-	br.call.sptk	b6 = b7 }
+	mov		b7 = r31 ; 				\
+	br.call.sptk	b0 = b7 ;; }
 
 
 /*



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