From owner-p4-projects@FreeBSD.ORG Thu Apr 17 00:32:14 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id C30FC37B404; Thu, 17 Apr 2003 00:32:13 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6FA9037B405 for ; Thu, 17 Apr 2003 00:32:13 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 840A243FBF for ; Thu, 17 Apr 2003 00:32:12 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h3H7WC0U073811 for ; Thu, 17 Apr 2003 00:32:12 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h3H7WBoJ073808 for perforce@freebsd.org; Thu, 17 Apr 2003 00:32:11 -0700 (PDT) Date: Thu, 17 Apr 2003 00:32:11 -0700 (PDT) Message-Id: <200304170732.h3H7WBoJ073808@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to marcel@freebsd.org using -f From: Marcel Moolenaar To: Perforce Change Reviews Subject: PERFORCE change 29108 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 17 Apr 2003 07:32:15 -0000 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 /* - * 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 ;; } /*