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>