#include <asm/system.h>
#include <asm/thread_info.h>
#include <asm/unistd.h>
+#include <asm/errno.h>
#if 1
# define PSR_DEFAULT_BITS psr.ac
#endif
mov pr=r31,-1 // restore pr
rfi
-END(idirty_bit)
+END(dirty_bit)
.org ia64_ivt+0x2400
/////////////////////////////////////////////////////////////////////////////////////////
ssm psr.ic | PSR_DEFAULT_BITS
;;
srlz.i // guarantee that interruption collection is on
+ mov r3=NR_syscalls - 1
;;
(p15) ssm psr.i // restore psr.i
+ // p10==true means out registers are more than 8 or r15's Nat is true
+(p10) br.cond.spnt.many ia64_ret_from_syscall
;;
- mov r3=NR_syscalls - 1
movl r16=sys_call_table
adds r15=-1024,r15 // r15 contains the syscall number---subtract 1024
* On exit:
* - executing on bank 1 registers
* - psr.ic enabled, interrupts restored
+ * - p10: TRUE if syscall is invoked with more than 8 out
+ * registers or r15's Nat is true
* - r1: kernel's gp
* - r3: preserved (same as on entry)
+ * - r8: -EINVAL if p10 is true
* - r12: points to kernel stack
* - r13: points to current task
* - p15: TRUE if interrupts need to be re-enabled
add r17=PT(R11),r1 // initialize second base pointer
;;
alloc r19=ar.pfs,8,0,0,0 // ensure in0-in7 are writable
- st8 [r16]=r29,PT(CR_IFS)-PT(CR_IPSR) // save cr.ipsr
+ st8 [r16]=r29,PT(AR_PFS)-PT(CR_IPSR) // save cr.ipsr
tnat.nz p8,p0=in0
st8.spill [r17]=r11,PT(CR_IIP)-PT(R11) // save r11
(pKStk) mov r18=r0 // make sure r18 isn't NaT
;;
+ st8 [r16]=r26,PT(CR_IFS)-PT(AR_PFS) // save ar.pfs
st8 [r17]=r28,PT(AR_UNAT)-PT(CR_IIP) // save cr.iip
mov r28=b0 // save b0 (2 cyc)
-(p8) mov in0=-1
;;
- st8 [r16]=r0,PT(AR_PFS)-PT(CR_IFS) // clear cr.ifs
st8 [r17]=r25,PT(AR_RSC)-PT(AR_UNAT) // save ar.unat
-(p9) mov in1=-1
+ dep r19=0,r19,38,26 // clear all bits but 0..37 [I0]
+(p8) mov in0=-1
;;
- st8 [r16]=r26,PT(AR_RNAT)-PT(AR_PFS) // save ar.pfs
+ st8 [r16]=r19,PT(AR_RNAT)-PT(CR_IFS) // store ar.pfs.pfm in cr.ifs
+ extr.u r11=r19,7,7 // I0 // get sol of ar.pfs
+ and r8=0x7f,r19 // A // get sof of ar.pfs
+
st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc
- tnat.nz p10,p0=in2
+ tbit.nz p15,p0=r29,IA64_PSR_I_BIT // I0
+(p9) mov in1=-1
+ ;;
(pUStk) sub r18=r18,r22 // r18=RSE.ndirty*8
- tbit.nz p15,p0=r29,IA64_PSR_I_BIT
- tnat.nz p11,p0=in3
+ tnat.nz p10,p0=in2
+ add r11=8,r11
;;
(pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16 // skip over ar_rnat field
(pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17 // skip over ar_bspstore field
+ tnat.nz p11,p0=in3
+ ;;
(p10) mov in2=-1
-
+ tnat.nz p12,p0=in4 // [I0]
(p11) mov in3=-1
- tnat.nz p12,p0=in4
- tnat.nz p13,p0=in5
;;
(pUStk) st8 [r16]=r24,PT(PR)-PT(AR_RNAT) // save ar.rnat
(pUStk) st8 [r17]=r23,PT(B0)-PT(AR_BSPSTORE) // save ar.bspstore
;;
st8 [r16]=r31,PT(LOADRS)-PT(PR) // save predicates
st8 [r17]=r28,PT(R1)-PT(B0) // save b0
-(p12) mov in4=-1
+ tnat.nz p13,p0=in5 // [I0]
;;
st8 [r16]=r18,PT(R12)-PT(LOADRS) // save ar.rsc value for "loadrs"
st8.spill [r17]=r20,PT(R13)-PT(R1) // save original r1
-(p13) mov in5=-1
+(p12) mov in4=-1
;;
.mem.offset 0,0; st8.spill [r16]=r12,PT(AR_FPSR)-PT(R12) // save r12
.mem.offset 8,0; st8.spill [r17]=r13,PT(R15)-PT(R13) // save r13
- tnat.nz p14,p0=in6
+(p13) mov in5=-1
;;
st8 [r16]=r21,PT(R8)-PT(AR_FPSR) // save ar.fpsr
- st8.spill [r17]=r15 // save r15
- tnat.nz p8,p0=in7
+ tnat.nz p14,p0=in6
+ cmp.lt p10,p9=r11,r8 // frame size can't be more than local+8
;;
stf8 [r16]=f1 // ensure pt_regs.r8 != 0 (see handle_syscall_error)
+(p9) tnat.nz p10,p0=r15
adds r12=-16,r1 // switch to kernel memory stack (with 16 bytes of scratch)
-(p14) mov in6=-1
+
+ st8.spill [r17]=r15 // save r15
+ tnat.nz p8,p0=in7
+ nop.i 0
mov r13=r2 // establish `current'
movl r1=__gp // establish kernel global pointer
;;
+(p14) mov in6=-1
(p8) mov in7=-1
- tnat.nz p9,p0=r15
+ nop.i 0
cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
movl r17=FPSR_DEFAULT
;;
mov.m ar.fpsr=r17 // set ar.fpsr to kernel default value
-(p9) mov r15=-1
+(p10) mov r8=-EINVAL
br.ret.sptk.many b7
END(ia64_syscall_setup)