* Correct some of my misunderstandings about how best to switch to the

kernel backing store.
* Implement syscalls via break instructions.
* Fix backing store copying in cpu_fork() so that the child gets the right
  register values.

This thing is actually starting to work now. This set of changes takes me
up to the second execve (the one which runs the first shell). Next stop
single-user mode :-).
This commit is contained in:
dfr 2000-10-16 08:54:40 +00:00
parent 6409a78036
commit af713edef9
9 changed files with 525 additions and 111 deletions

View File

@ -53,13 +53,13 @@
mov b0=r17; \
br.sptk.few exception_save; \
2: (p3) ssm psr.i; \
alloc r14=ar.pfs,0,0,2,0; \
movl r15=exception_restore; \
alloc r15=ar.pfs,0,0,3,0; \
mov out0=_n_; \
mov out1=sp;; \
mov out1=r14; \
mov out2=sp;; \
add sp=-16,sp;; \
mov rp=r15; \
br.call.sptk.few b6=trap
br.call.sptk.few rp=trap; \
3: br.sptk.many exception_restore
/*
* The IA64 Interrupt Vector Table (IVT) contains 20 slots with 64
@ -507,7 +507,24 @@ ia64_vector_table:
/* 0x2c00: Break Instruction vector */
mov r16=pr // save pr for a moment
mov r17=cr.iim;; // read break value
mov r18=0x100000;; // syscall number
cmp.eq p1,p2=r18,r17;; // check for syscall
(p2) br.dpnt.few 9f
mov r17=cr.ipsr;; // check for user mode
extr.u r17=r17,32,2;;
cmp.eq p1,p2=r0,r17
(p1) br.dpnt.few 9f // trap if kernel mode
br.sptk.many do_syscall
;;
9: mov pr=r16,0x1ffff // restore pr
TRAP(11)
.align 1024
/* 0x3000: External Interrupt vector */
@ -841,7 +858,7 @@ ia64_vhpt: .quad 0
#define rR2 r23
#define rBSPSTORE r22
#define rRNAT r21
#define rBSP r27 /* overlay rPR */
#define rNDIRTY r27 /* overlay rPR */
#define rRSC r20
#define rPFS r19
#define rB0 r31 /* overlay rIIP */
@ -962,12 +979,12 @@ ENTRY(exception_restore, 0)
;;
mov b0=r16
mov ar.fpsr=r17
ld8 r18=[r1],-16 // r1=&tf_ar_bsp
ld8 r18=[r1],-16 // r1=&tf_ndirty
ld8 r19=[r2],-16 // r2=&tf_ar_rnat
;;
mov ar.ccv=r18
mov ar.unat=r19
ld8 rBSP=[r1],-16 // r1=&tf_ar_bspstore
ld8 rNDIRTY=[r1],-16 // r1=&tf_ar_bspstore
ld8 rRNAT=[r2],-16 // r2=&tf_cr_ifs
;;
ld8 rBSPSTORE=[r1],-16 // r1=&tf_cr_pfs
@ -977,9 +994,7 @@ ENTRY(exception_restore, 0)
;;
alloc r16=ar.pfs,0,0,0,0 // discard current frame
;;
sub r16=rBSP,rBSPSTORE // how many bytes to load?
;;
shl r16=r16,16 // value for ar.rsc
shl r16=rNDIRTY,16 // value for ar.rsc
;;
mov ar.rsc=r16 // setup for loadrs
;;
@ -1012,7 +1027,7 @@ ENTRY(exception_restore, 0)
;;
rfi
END(exception_restore)
END(exception_restore)
/*
@ -1023,6 +1038,7 @@ ENTRY(exception_restore, 0)
* r16 saved b0
*
* Return:
* r14 cr.iim value for break traps
* sp kernel stack pointer
* p1 true if user mode
* p2 true if kernel mode
@ -1076,18 +1092,21 @@ ENTRY(exception_save, 0)
;;
(p2) mov r16=ar.k5 // kernel backing store
mov rRNAT=ar.rnat
mov rBSP=ar.bsp
;;
(p2) mov ar.bspstore=r16 // switch bspstore
st8 [r2]=rRSC,16 // r2=&tf_cr_ifs
;;
st8 [r1]=rPFS,16 // r1=&tf_ar_bspstore
st8 [r2]=rIFS,16 // r2=&tf_ar_rnat
(p2) mov r17=ar.bsp
;;
(p2) sub r17=r17,r16 // ndirty (in bytes)
(p1) mov r17=r0
;;
st8 [r1]=rBSPSTORE,16 // r1=&tf_ar_bsp
st8 [r1]=rBSPSTORE,16 // r1=&tf_ndirty
st8 [r2]=rRNAT,16 // r2=&tf_ar_unat
;;
st8 [r1]=rBSP,16 // r1=&tf_ar_ccv
st8 [r1]=r17,16 // r1=&tf_ar_ccv
mov ar.rsc=3 // switch RSE back on
mov r16=ar.unat
;;
@ -1217,12 +1236,207 @@ ENTRY(exception_save, 0)
;;
movl r1=__gp // kernel globals
mov r13=ar.k4 // processor globals
mov r14=cr.iim // break immediate
ssm psr.ic|psr.dt // enable interrupts & translation
;;
srlz.d // serialize
br.sptk.few b0 // not br.ret - we were not br.call'ed
END(exception_save)
END(exception_save)
/*
* System call entry point (via Break Instruction vector).
*
* Arguments:
* r16 saved predicates
*/
ENTRY(do_syscall, 0)
rsm psr.dt // physical addressing for a moment
mov r17=sp;; // save user sp
srlz.d // serialize psr.dt
mov sp=ar.k6;; // switch to kernel sp
add sp=-SIZEOF_TRAPFRAME,sp;; // reserve trapframe
dep r30=0,sp,61,3;; // physical address
add r31=8,r30;; // secondary pointer
// save minimal state for syscall
mov r18=cr.iip
mov r19=cr.ipsr
mov r20=cr.isr
;;
st8 [r30]=r18,16 // save cr.iip
st8 [r31]=r19,16 // save cr.ipsr
;;
st8 [r30]=r20,16 // save cr.isr
add r31=16,r31 // skip cr.ifa
mov r18=ar.rsc
mov r19=ar.pfs
;;
st8 [r30]=r16,16 // save pr
st8 [r31]=r18,16 // save ar.rsc
mov ar.rsc=0 // turn off rse
;;
st8 [r30]=r19,16 // save ar.pfs
add r31=16,r31 // skip cr.ifs
mov r20=ar.bspstore
mov r21=ar.rnat
mov r22=ar.k5
;;
mov ar.bspstore=r22 // switch to kernel backing store
;;
mov r23=ar.bsp // calculate ndirty
;;
;;
st8 [r30]=r20,16 // save ar.bspstore
st8 [r31]=r21,16 // save ar.rnat
sub r16=r23,r22 // bytes of dirty regs
mov r18=ar.unat
;;
st8 [r30]=r16,16 // save ndirty
st8 [r31]=r18,16 // save ar.unat
mov r20=ar.ccv
mov r21=ar.fpsr
;;
st8 [r30]=r20,16 // save ar.ccv
st8 [r31]=r21,16 // save ar.fpsr
mov r16=b0
;;
st8 [r30]=r16,TF_R-TF_B+FRAME_SP*8 // save b0, r1=&tf_r[FRAME_SP]
;;
st8 [r30]=r17 // save user sp
;;
bsw.1 // switch back to bank 1
;;
mov r18=sp // trapframe pointer
;;
add sp=-(8*8),sp // reserve stack for arguments
;;
br.call.sptk.few b0=Lsaveargs // dump args
;;
mov r31=sp // point at args
mov r20=ar.bsp // record bsp before the cover
;;
cover // preserve arguments
;;
mov r22=cr.ifs // record user's CFM
add r23=TF_CR_IFS,r18
;;
ssm psr.dt|psr.ic|psr.i // safe to take interrupts again
;;
srlz.d // serialize psr.dt and psr.ic
;;
st8 [r23]=r22 // save cr.ifs
;;
mov r21=ar.bsp // r21-r20 = size of user reg frame
add r22=TF_NDIRTY,r18
;;
sub r20=r21,r20
ld8 r23=[r22]
;;
add r23=r23,r20 // adjust ndirty
;;
st8 [r22]=r23
;;
add sp=-16,sp // reserve scratch space
alloc r14=ar.pfs,0,3,3,0
mov r13=ar.k4 // processor globals
;;
mov loc0=r15 // save in case of restarts
mov loc1=r18 // save so we can restore
mov loc2=gp // save user gp
mov out0=r15 // syscall number (from user)
mov out1=r31 // arguments
mov out2=r18 // trapframe pointer
;;
movl gp=__gp // kernel globals
;;
br.call.sptk.many rp=syscall // do the work
rsm psr.dt|psr.ic // get ready to restore
;;
srlz.d // serialise psr.dt and psr.ic
dep r30=0,loc1,61,3 // physical address
mov gp=loc2 // restore user gp
;;
add r30=TF_R+FRAME_SP*8,r30 // &tf_r[FRAME_SP]
mov r15=loc0 // saved syscall number
alloc r14=ar.pfs,0,0,0,0 // discard register frame
;;
ld8 sp=[r30],-16 // restore user sp
;;
ld8 r10=[r30],-8 // ret2
;;
ld8 r9=[r30],-8 // ret1
;;
ld8 r8=[r30],-(TF_R+7*8-TF_B) // ret0
;;
ld8 r16=[r30],-16 // restore b0
;;
mov b0=r16
add r31=8,r30 // secondary pointer, &tf_fpsr
;;
ld8 r16=[r31],-16 // restore ar.fpsr
ld8 r17=[r30],-16 // restore ar.ccv
;;
ld8 r18=[r31],-16 // restore ar.unat
ld8 r19=[r30],-16 // restore ndirty
mov ar.fpsr=r16
mov ar.ccv=r17
;;
ld8 r16=[r31],-16 // restore ar.rnat
ld8 r17=[r30],-16 // restore ar.bspstore
mov ar.unat=r18
;;
shl r19=r19,16 // value for ar.rsc
;;
mov ar.rsc=r19 // setup for loadrs
;;
loadrs // restore user registers
;;
mov ar.bspstore=r17
;;
mov ar.rnat=r16
ld8 r18=[r31],-16 // restore cr.ifs
ld8 r19=[r30],-16 // restore ar.pfs
;;
ld8 r16=[r31],-32 // restore ar.rsc
ld8 r17=[r30],-32 // restore pr
mov cr.ifs=r18
mov ar.pfs=r19
;;
ld8 r18=[r31],-16 // restore cr.ipsr
ld8 r19=[r30],-16 // restore cr.iip
mov ar.rsc=r16
mov pr=r16,0x1ffff
;;
mov cr.ipsr=r18
mov cr.iip=r19
;;
rfi
// This is done as a function call to make sure that we only
// have output registers in the register frame. It also gives
// us a chance to use alloc to round up to 8 arguments for
// simplicity.
//
// We are still running in physical mode with psr.ic==0 because
// we haven't yet covered the user's register frame to get a
// value for cr.ifs
Lsaveargs:
alloc r14=ar.pfs,0,0,8,0 // round up to 8 outputs
;;
extr.u r31=sp,0,61 // physical address
;;
st8 [r31]=r32,8
st8 [r31]=r33,8
st8 [r31]=r34,8
st8 [r31]=r35,8
st8 [r31]=r36,8
st8 [r31]=r37,8
st8 [r31]=r38,8
st8 [r31]=r39
;;
br.ret.sptk.many b0
END(do_syscall)

View File

@ -53,13 +53,13 @@
mov b0=r17; \
br.sptk.few exception_save; \
2: (p3) ssm psr.i; \
alloc r14=ar.pfs,0,0,2,0; \
movl r15=exception_restore; \
alloc r15=ar.pfs,0,0,3,0; \
mov out0=_n_; \
mov out1=sp;; \
mov out1=r14; \
mov out2=sp;; \
add sp=-16,sp;; \
mov rp=r15; \
br.call.sptk.few b6=trap
br.call.sptk.few rp=trap; \
3: br.sptk.many exception_restore
/*
* The IA64 Interrupt Vector Table (IVT) contains 20 slots with 64
@ -507,7 +507,24 @@ ia64_vector_table:
/* 0x2c00: Break Instruction vector */
mov r16=pr // save pr for a moment
mov r17=cr.iim;; // read break value
mov r18=0x100000;; // syscall number
cmp.eq p1,p2=r18,r17;; // check for syscall
(p2) br.dpnt.few 9f
mov r17=cr.ipsr;; // check for user mode
extr.u r17=r17,32,2;;
cmp.eq p1,p2=r0,r17
(p1) br.dpnt.few 9f // trap if kernel mode
br.sptk.many do_syscall
;;
9: mov pr=r16,0x1ffff // restore pr
TRAP(11)
.align 1024
/* 0x3000: External Interrupt vector */
@ -841,7 +858,7 @@ ia64_vhpt: .quad 0
#define rR2 r23
#define rBSPSTORE r22
#define rRNAT r21
#define rBSP r27 /* overlay rPR */
#define rNDIRTY r27 /* overlay rPR */
#define rRSC r20
#define rPFS r19
#define rB0 r31 /* overlay rIIP */
@ -962,12 +979,12 @@ ENTRY(exception_restore, 0)
;;
mov b0=r16
mov ar.fpsr=r17
ld8 r18=[r1],-16 // r1=&tf_ar_bsp
ld8 r18=[r1],-16 // r1=&tf_ndirty
ld8 r19=[r2],-16 // r2=&tf_ar_rnat
;;
mov ar.ccv=r18
mov ar.unat=r19
ld8 rBSP=[r1],-16 // r1=&tf_ar_bspstore
ld8 rNDIRTY=[r1],-16 // r1=&tf_ar_bspstore
ld8 rRNAT=[r2],-16 // r2=&tf_cr_ifs
;;
ld8 rBSPSTORE=[r1],-16 // r1=&tf_cr_pfs
@ -977,9 +994,7 @@ ENTRY(exception_restore, 0)
;;
alloc r16=ar.pfs,0,0,0,0 // discard current frame
;;
sub r16=rBSP,rBSPSTORE // how many bytes to load?
;;
shl r16=r16,16 // value for ar.rsc
shl r16=rNDIRTY,16 // value for ar.rsc
;;
mov ar.rsc=r16 // setup for loadrs
;;
@ -1012,7 +1027,7 @@ ENTRY(exception_restore, 0)
;;
rfi
END(exception_restore)
END(exception_restore)
/*
@ -1023,6 +1038,7 @@ ENTRY(exception_restore, 0)
* r16 saved b0
*
* Return:
* r14 cr.iim value for break traps
* sp kernel stack pointer
* p1 true if user mode
* p2 true if kernel mode
@ -1076,18 +1092,21 @@ ENTRY(exception_save, 0)
;;
(p2) mov r16=ar.k5 // kernel backing store
mov rRNAT=ar.rnat
mov rBSP=ar.bsp
;;
(p2) mov ar.bspstore=r16 // switch bspstore
st8 [r2]=rRSC,16 // r2=&tf_cr_ifs
;;
st8 [r1]=rPFS,16 // r1=&tf_ar_bspstore
st8 [r2]=rIFS,16 // r2=&tf_ar_rnat
(p2) mov r17=ar.bsp
;;
(p2) sub r17=r17,r16 // ndirty (in bytes)
(p1) mov r17=r0
;;
st8 [r1]=rBSPSTORE,16 // r1=&tf_ar_bsp
st8 [r1]=rBSPSTORE,16 // r1=&tf_ndirty
st8 [r2]=rRNAT,16 // r2=&tf_ar_unat
;;
st8 [r1]=rBSP,16 // r1=&tf_ar_ccv
st8 [r1]=r17,16 // r1=&tf_ar_ccv
mov ar.rsc=3 // switch RSE back on
mov r16=ar.unat
;;
@ -1217,12 +1236,207 @@ ENTRY(exception_save, 0)
;;
movl r1=__gp // kernel globals
mov r13=ar.k4 // processor globals
mov r14=cr.iim // break immediate
ssm psr.ic|psr.dt // enable interrupts & translation
;;
srlz.d // serialize
br.sptk.few b0 // not br.ret - we were not br.call'ed
END(exception_save)
END(exception_save)
/*
* System call entry point (via Break Instruction vector).
*
* Arguments:
* r16 saved predicates
*/
ENTRY(do_syscall, 0)
rsm psr.dt // physical addressing for a moment
mov r17=sp;; // save user sp
srlz.d // serialize psr.dt
mov sp=ar.k6;; // switch to kernel sp
add sp=-SIZEOF_TRAPFRAME,sp;; // reserve trapframe
dep r30=0,sp,61,3;; // physical address
add r31=8,r30;; // secondary pointer
// save minimal state for syscall
mov r18=cr.iip
mov r19=cr.ipsr
mov r20=cr.isr
;;
st8 [r30]=r18,16 // save cr.iip
st8 [r31]=r19,16 // save cr.ipsr
;;
st8 [r30]=r20,16 // save cr.isr
add r31=16,r31 // skip cr.ifa
mov r18=ar.rsc
mov r19=ar.pfs
;;
st8 [r30]=r16,16 // save pr
st8 [r31]=r18,16 // save ar.rsc
mov ar.rsc=0 // turn off rse
;;
st8 [r30]=r19,16 // save ar.pfs
add r31=16,r31 // skip cr.ifs
mov r20=ar.bspstore
mov r21=ar.rnat
mov r22=ar.k5
;;
mov ar.bspstore=r22 // switch to kernel backing store
;;
mov r23=ar.bsp // calculate ndirty
;;
;;
st8 [r30]=r20,16 // save ar.bspstore
st8 [r31]=r21,16 // save ar.rnat
sub r16=r23,r22 // bytes of dirty regs
mov r18=ar.unat
;;
st8 [r30]=r16,16 // save ndirty
st8 [r31]=r18,16 // save ar.unat
mov r20=ar.ccv
mov r21=ar.fpsr
;;
st8 [r30]=r20,16 // save ar.ccv
st8 [r31]=r21,16 // save ar.fpsr
mov r16=b0
;;
st8 [r30]=r16,TF_R-TF_B+FRAME_SP*8 // save b0, r1=&tf_r[FRAME_SP]
;;
st8 [r30]=r17 // save user sp
;;
bsw.1 // switch back to bank 1
;;
mov r18=sp // trapframe pointer
;;
add sp=-(8*8),sp // reserve stack for arguments
;;
br.call.sptk.few b0=Lsaveargs // dump args
;;
mov r31=sp // point at args
mov r20=ar.bsp // record bsp before the cover
;;
cover // preserve arguments
;;
mov r22=cr.ifs // record user's CFM
add r23=TF_CR_IFS,r18
;;
ssm psr.dt|psr.ic|psr.i // safe to take interrupts again
;;
srlz.d // serialize psr.dt and psr.ic
;;
st8 [r23]=r22 // save cr.ifs
;;
mov r21=ar.bsp // r21-r20 = size of user reg frame
add r22=TF_NDIRTY,r18
;;
sub r20=r21,r20
ld8 r23=[r22]
;;
add r23=r23,r20 // adjust ndirty
;;
st8 [r22]=r23
;;
add sp=-16,sp // reserve scratch space
alloc r14=ar.pfs,0,3,3,0
mov r13=ar.k4 // processor globals
;;
mov loc0=r15 // save in case of restarts
mov loc1=r18 // save so we can restore
mov loc2=gp // save user gp
mov out0=r15 // syscall number (from user)
mov out1=r31 // arguments
mov out2=r18 // trapframe pointer
;;
movl gp=__gp // kernel globals
;;
br.call.sptk.many rp=syscall // do the work
rsm psr.dt|psr.ic // get ready to restore
;;
srlz.d // serialise psr.dt and psr.ic
dep r30=0,loc1,61,3 // physical address
mov gp=loc2 // restore user gp
;;
add r30=TF_R+FRAME_SP*8,r30 // &tf_r[FRAME_SP]
mov r15=loc0 // saved syscall number
alloc r14=ar.pfs,0,0,0,0 // discard register frame
;;
ld8 sp=[r30],-16 // restore user sp
;;
ld8 r10=[r30],-8 // ret2
;;
ld8 r9=[r30],-8 // ret1
;;
ld8 r8=[r30],-(TF_R+7*8-TF_B) // ret0
;;
ld8 r16=[r30],-16 // restore b0
;;
mov b0=r16
add r31=8,r30 // secondary pointer, &tf_fpsr
;;
ld8 r16=[r31],-16 // restore ar.fpsr
ld8 r17=[r30],-16 // restore ar.ccv
;;
ld8 r18=[r31],-16 // restore ar.unat
ld8 r19=[r30],-16 // restore ndirty
mov ar.fpsr=r16
mov ar.ccv=r17
;;
ld8 r16=[r31],-16 // restore ar.rnat
ld8 r17=[r30],-16 // restore ar.bspstore
mov ar.unat=r18
;;
shl r19=r19,16 // value for ar.rsc
;;
mov ar.rsc=r19 // setup for loadrs
;;
loadrs // restore user registers
;;
mov ar.bspstore=r17
;;
mov ar.rnat=r16
ld8 r18=[r31],-16 // restore cr.ifs
ld8 r19=[r30],-16 // restore ar.pfs
;;
ld8 r16=[r31],-32 // restore ar.rsc
ld8 r17=[r30],-32 // restore pr
mov cr.ifs=r18
mov ar.pfs=r19
;;
ld8 r18=[r31],-16 // restore cr.ipsr
ld8 r19=[r30],-16 // restore cr.iip
mov ar.rsc=r16
mov pr=r16,0x1ffff
;;
mov cr.ipsr=r18
mov cr.iip=r19
;;
rfi
// This is done as a function call to make sure that we only
// have output registers in the register frame. It also gives
// us a chance to use alloc to round up to 8 arguments for
// simplicity.
//
// We are still running in physical mode with psr.ic==0 because
// we haven't yet covered the user's register frame to get a
// value for cr.ifs
Lsaveargs:
alloc r14=ar.pfs,0,0,8,0 // round up to 8 outputs
;;
extr.u r31=sp,0,61 // physical address
;;
st8 [r31]=r32,8
st8 [r31]=r33,8
st8 [r31]=r34,8
st8 [r31]=r35,8
st8 [r31]=r36,8
st8 [r31]=r37,8
st8 [r31]=r38,8
st8 [r31]=r39
;;
br.ret.sptk.many b0
END(do_syscall)

View File

@ -87,6 +87,13 @@ ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS);
ASSYM(SIZEOF_USER, sizeof(struct user));
ASSYM(TF_CR_IPSR, offsetof(struct trapframe, tf_cr_ipsr));
ASSYM(TF_CR_IFS, offsetof(struct trapframe, tf_cr_ifs));
ASSYM(TF_NDIRTY, offsetof(struct trapframe, tf_ndirty));
ASSYM(TF_B, offsetof(struct trapframe, tf_b));
ASSYM(TF_R, offsetof(struct trapframe, tf_r));
ASSYM(TF_F, offsetof(struct trapframe, tf_f));
ASSYM(FRAME_SP, FRAME_SP);
ASSYM(U_PCB_R4, offsetof(struct user, u_pcb.pcb_r4));
ASSYM(U_PCB_R5, offsetof(struct user, u_pcb.pcb_r5));

View File

@ -710,9 +710,10 @@ ia64_init()
}
/*
* Force verbose mode for a while.
* Force verbose mode and single-user for a while.
*/
bootverbose = 1;
boothowto |= RB_SINGLE;
/*
* Initialize debuggers, and break into them if appropriate.
@ -800,7 +801,8 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
sf.sf_uc.uc_mcontext.mc_cfm = 0; /* XXX */
sf.sf_uc.uc_mcontext.mc_um = frame->tf_cr_ipsr & 0x1fff;
sf.sf_uc.uc_mcontext.mc_ar_rsc = frame->tf_ar_rsc;
sf.sf_uc.uc_mcontext.mc_ar_bsp = frame->tf_ar_bsp;
sf.sf_uc.uc_mcontext.mc_ar_bsp = (frame->tf_ar_bspstore
+ frame->tf_ndirty);
sf.sf_uc.uc_mcontext.mc_ar_rnat = frame->tf_ar_rnat;
sf.sf_uc.uc_mcontext.mc_ar_ccv = frame->tf_ar_ccv;
sf.sf_uc.uc_mcontext.mc_ar_unat = frame->tf_ar_unat;
@ -1048,7 +1050,7 @@ setregs(struct proc *p, u_long entry, u_long stack, u_long ps_strings)
* starts executing with an empty register stack frame.
*/
frame->tf_ar_bspstore = p->p_md.md_bspstore;
frame->tf_ar_bsp = p->p_md.md_bspstore;
frame->tf_ndirty = 0;
frame->tf_cr_ifs = (1L<<63); /* ifm=0, v=1 */
frame->tf_ar_rsc = 0xf; /* user mode rsc */
frame->tf_ar_fpsr = IA64_FPSR_DEFAULT;

View File

@ -234,9 +234,13 @@ ENTRY(cpu_switch, 0)
#endif
1:
st8 [r14]=ret0
st8 [r14]=ret0 // set r13->gd_curproc
add r15=@gprel(want_resched),gp
;;
st4 [r15]=r0 // we've rescheduled
mov ar.k7=ret0
mov r4=ret0 // save from call
;;
alloc r15=ar.pfs,0,0,1,0 // create temporary output frame
;;
mov out0=r4

View File

@ -204,7 +204,7 @@ static const char *ia64_vector_names[] = {
};
static void
printtrap(int vector, struct trapframe *framep, int isfatal, int user)
printtrap(int vector, int imm, struct trapframe *framep, int isfatal, int user)
{
printf("\n");
printf("%s %s trap:\n", isfatal? "fatal" : "handled",
@ -212,10 +212,11 @@ printtrap(int vector, struct trapframe *framep, int isfatal, int user)
printf("\n");
printf(" trap vector = 0x%x (%s)\n",
vector, ia64_vector_names[vector]);
printf(" iip = 0x%lx\n", framep->tf_cr_iip);
printf(" ipsr = 0x%lx\n", framep->tf_cr_ipsr);
printf(" isr = 0x%lx\n", framep->tf_cr_isr);
printf(" ifa = 0x%lx\n", framep->tf_cr_ifa);
printf(" cr.iip = 0x%lx\n", framep->tf_cr_iip);
printf(" cr.ipsr = 0x%lx\n", framep->tf_cr_ipsr);
printf(" cr.isr = 0x%lx\n", framep->tf_cr_isr);
printf(" cr.ifa = 0x%lx\n", framep->tf_cr_ifa);
printf(" cr.iim = 0x%x\n", imm);
printf(" curproc = %p\n", curproc);
if (curproc != NULL)
printf(" pid = %d, comm = %s\n", curproc->p_pid,
@ -231,10 +232,10 @@ printtrap(int vector, struct trapframe *framep, int isfatal, int user)
*/
/*ARGSUSED*/
void
trap(int vector, struct trapframe *framep)
trap(int vector, int imm, struct trapframe *framep)
{
register struct proc *p;
register int i;
struct proc *p;
int i;
u_int64_t ucode;
u_quad_t sticks;
int user;
@ -298,13 +299,8 @@ trap(int vector, struct trapframe *framep)
goto dopanic;
case IA64_VEC_BREAK:
/*
* This should never happen. Breaks enter the kernel
* via break().
*/
goto dopanic;
case IA64_VEC_DISABLED_FP:
/*
* on exit from the kernel, if proc == fpcurproc,
@ -456,7 +452,7 @@ trap(int vector, struct trapframe *framep)
ucode = va;
i = SIGSEGV;
#ifdef DEBUG
printtrap(vector, framep, 1, user);
printtrap(vector, imm, framep, 1, user);
#endif
break;
}
@ -466,7 +462,7 @@ trap(int vector, struct trapframe *framep)
}
#ifdef DEBUG
printtrap(vector, framep, 1, user);
printtrap(vector, imm, framep, 1, user);
#endif
trapsignal(p, i, ucode);
out:
@ -477,7 +473,7 @@ trap(int vector, struct trapframe *framep)
return;
dopanic:
printtrap(vector, framep, 1, user);
printtrap(vector, imm, framep, 1, user);
/* XXX dump registers */
@ -492,46 +488,47 @@ trap(int vector, struct trapframe *framep)
* Process a system call.
*
* System calls are strange beasts. They are passed the syscall number
* in v0, and the arguments in the registers (as normal). They return
* an error flag in a3 (if a3 != 0 on return, the syscall had an error),
* and the return value (if any) in v0.
* in r15, and the arguments in the registers (as normal). They return
* an error flag in r10 (if r10 != 0 on return, the syscall had an error),
* and the return value (if any) in r8 and r9.
*
* The assembly stub takes care of moving the call number into a register
* we can get to, and moves all of the argument registers into their places
* in the trap frame. On return, it restores the callee-saved registers,
* a3, and v0 from the frame before returning to the user process.
* we can get to, and moves all of the argument registers into a stack
* buffer. On return, it restores r8-r10 from the frame before
* returning to the user process.
*/
void
syscall(code, framep)
u_int64_t code;
struct trapframe *framep;
syscall(int code, u_int64_t *args, struct trapframe *framep)
{
struct sysent *callp;
struct proc *p;
int error = 0;
u_int64_t opc;
u_int64_t oldip, oldri;
u_quad_t sticks;
u_int64_t args[10]; /* XXX */
u_int hidden = 0, nargs;
mtx_enter(&Giant, MTX_DEF);
#if notdef /* can't happen, ever. */
if ((framep->tf_cr_ipsr & IA64_PSR_CPL) == IA64_PSR_CPL_KERN)
panic("syscall");
#endif
cnt.v_syscall++;
p = curproc;
p->p_md.md_tf = framep;
opc = framep->tf_cr_iip;
sticks = p->p_sticks;
/*
* Skip past the break instruction. Remember old address in case
* we have to restart.
*/
oldip = framep->tf_cr_iip;
oldri = framep->tf_cr_ipsr & IA64_PSR_RI;
framep->tf_cr_ipsr += IA64_PSR_RI_1;
if ((framep->tf_cr_ipsr & IA64_PSR_RI) > IA64_PSR_RI_2) {
framep->tf_cr_ipsr &= ~IA64_PSR_RI;
framep->tf_cr_iip += 16;
}
#ifdef DIAGNOSTIC
ia64_fpstate_check(p);
#endif
#if 0
if (p->p_sysent->sv_prepsyscall) {
/* (*p->p_sysent->sv_prepsyscall)(framep, args, &code, &params); */
panic("prepsyscall");
@ -544,8 +541,8 @@ syscall(code, framep)
/*
* Code is first argument, followed by actual args.
*/
code = framep->tf_regs[FRAME_A0];
hidden = 1;
code = args[0];
args++;
}
}
@ -557,33 +554,9 @@ syscall(code, framep)
else
callp = &p->p_sysent->sv_table[code];
nargs = (callp->sy_narg & SYF_ARGMASK) + hidden;
switch (nargs) {
default:
if (nargs > 10) /* XXX */
panic("syscall: too many args (%d)", nargs);
error = copyin((caddr_t)(alpha_pal_rdusp()), &args[6],
(nargs - 6) * sizeof(u_int64_t));
case 6:
args[5] = framep->tf_regs[FRAME_A5];
case 5:
args[4] = framep->tf_regs[FRAME_A4];
case 4:
args[3] = framep->tf_regs[FRAME_A3];
case 3:
args[2] = framep->tf_regs[FRAME_A2];
case 2:
args[1] = framep->tf_regs[FRAME_A1];
case 1:
args[0] = framep->tf_regs[FRAME_A0];
case 0:
break;
}
#endif
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSCALL))
ktrsyscall(p->p_tracep, code, (callp->sy_narg & SYF_ARGMASK), args + hidden);
ktrsyscall(p->p_tracep, code, (callp->sy_narg & SYF_ARGMASK), args);
#endif
if (error == 0) {
p->p_retval[0] = 0;
@ -591,7 +564,7 @@ syscall(code, framep)
STOPEVENT(p, S_SCE, (callp->sy_narg & SYF_ARGMASK));
error = (*callp->sy_call)(p, args + hidden);
error = (*callp->sy_call)(p, args);
}
@ -602,7 +575,9 @@ syscall(code, framep)
framep->tf_r[FRAME_R10] = 0;
break;
case ERESTART:
framep->tf_cr_iip = opc;
framep->tf_cr_iip = oldip;
framep->tf_cr_ipsr =
(framep->tf_cr_ipsr & ~IA64_PSR_RI) | oldri;
break;
case EJUSTRETURN:
break;

View File

@ -217,8 +217,7 @@ cpu_fork(p1, p2, flags)
* Copy enough of p1's backing store to include all
* the user's stacked regs.
*/
bcopy(p1bs, p2bs, (p1->p_md.md_tf->tf_ar_bsp
- p1->p_md.md_tf->tf_ar_bspstore));
bcopy(p1bs, p2bs, p1->p_md.md_tf->tf_ndirty);
/*
* To calculate the ar.rnat for p2, we need to decide
@ -228,9 +227,7 @@ cpu_fork(p1, p2, flags)
* that one from memory, otherwise we take p1's
* current ar.rnat.
*/
rnatloc = (u_int64_t)
(p1bs + (p1->p_md.md_tf->tf_ar_bsp
- p1->p_md.md_tf->tf_ar_bspstore));
rnatloc = (u_int64_t)p1bs + p1->p_md.md_tf->tf_ndirty;
rnatloc |= 0x1f8;
if (bspstore > rnatloc)
rnat = *(u_int64_t *) rnatloc;
@ -248,9 +245,8 @@ cpu_fork(p1, p2, flags)
* should work since the child will normally return
* straight into exception_restore.
*/
up->u_pcb.pcb_bspstore = (u_int64_t)
(p2bs + (p1->p_md.md_tf->tf_ar_bsp
- p1->p_md.md_tf->tf_ar_bspstore));
up->u_pcb.pcb_bspstore =
(u_int64_t)p2bs + p1->p_md.md_tf->tf_ndirty;
up->u_pcb.pcb_rnat = rnat;
/*
@ -306,6 +302,8 @@ cpu_exit(p)
ia64_fpstate_drop(p);
(void) splhigh();
mtx_enter(&sched_lock, MTX_SPIN);
mtx_exit(&Giant, MTX_DEF);
cnt.v_swtch++;
cpu_switch();
panic("cpu_exit");

View File

@ -163,8 +163,8 @@ void restorectx __P((struct pcb *));
void set_iointr __P((void (*)(void *, unsigned long)));
void switch_exit __P((struct proc *)); /* MAGIC */
void switch_trampoline __P((void)); /* MAGIC */
void syscall __P((u_int64_t, struct trapframe *));
void trap __P((int vector, struct trapframe *framep));
void syscall __P((int, u_int64_t *, struct trapframe *));
void trap __P((int vector, int imm, struct trapframe *framep));
#endif /* _KERNEL */

View File

@ -48,7 +48,7 @@ struct trapframe {
u_int64_t tf_cr_ifs;
u_int64_t tf_ar_bspstore;
u_int64_t tf_ar_rnat;
u_int64_t tf_ar_bsp;
u_int64_t tf_ndirty;
u_int64_t tf_ar_unat;
u_int64_t tf_ar_ccv;
u_int64_t tf_ar_fpsr;