* Various fixes to breakage introduced by the atomic and mutex reorgs.
* Fixes to the signal delivery code. Not quite right yet. I would have preferred to wait until I have signal delivery actually working but the current kernel in CVS doesn't build.
This commit is contained in:
parent
245824f1cf
commit
ce97a5fc4e
@ -133,6 +133,11 @@ clockattach(device_t dev)
|
||||
#ifdef EVCNT_COUNTERS
|
||||
evcnt_attach(dev, "intr", &clock_intr_evcnt);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get the clock started.
|
||||
*/
|
||||
CLOCK_INIT(clockdev);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -157,9 +162,6 @@ cpu_initclocks()
|
||||
{
|
||||
u_int32_t freq;
|
||||
|
||||
if (clockdev == NULL)
|
||||
panic("cpu_initclocks: no clock attached");
|
||||
|
||||
/*
|
||||
* We use cr.itc and cr.itm to implement a 1024hz clock.
|
||||
*/
|
||||
@ -190,11 +192,6 @@ cpu_initclocks()
|
||||
tc_init(&ia64_timecounter);
|
||||
|
||||
stathz = 128;
|
||||
|
||||
/*
|
||||
* Get the clock started.
|
||||
*/
|
||||
CLOCK_INIT(clockdev);
|
||||
}
|
||||
|
||||
static u_int32_t
|
||||
|
@ -905,8 +905,8 @@ ENTRY(exception_restore, 0)
|
||||
ldf.fill f9=[r1],-32 // r1=&tf_f[FRAME_F7]
|
||||
ldf.fill f8=[r2],-32 // r2=&tf_f[FRAME_F6]
|
||||
;;
|
||||
ldf.fill f7=[r1],-32 // r1=&tf_r[FRAME_R31]
|
||||
ldf.fill f6=[r2],-24 // r2=&tf_r[FRAME_R30]
|
||||
ldf.fill f7=[r1],-24 // r1=&tf_r[FRAME_R31]
|
||||
ldf.fill f6=[r2],-16 // r2=&tf_r[FRAME_R30]
|
||||
;;
|
||||
ld8.fill r31=[r1],-16 // r1=&tf_r[FRAME_R29]
|
||||
ld8.fill r30=[r2],-16 // r2=&tf_r[FRAME_R28]
|
||||
@ -1068,9 +1068,10 @@ ENTRY(exception_save, 0)
|
||||
mov rR1=r1
|
||||
mov rR2=r2
|
||||
;;
|
||||
dep r1=0,sp,61,3 // r1=&tf_cr_iip
|
||||
dep r1=0,sp,61,3 // r1=&tf_flags
|
||||
;;
|
||||
add r2=8,r1 // r2=&tf_cr_ipsr
|
||||
add r2=16,r1 // r2=&tf_cr_ipsr
|
||||
st8 [r1]=r0,8 // zero flags, r1=&tf_cr_iip
|
||||
;;
|
||||
st8 [r1]=rIIP,16 // r1=&tf_cr_isr
|
||||
st8 [r2]=rIPSR,16 // r2=&tf_cr_ifa
|
||||
@ -1215,9 +1216,9 @@ ENTRY(exception_save, 0)
|
||||
st8.spill [r1]=r29,16 // r1=&tf_r[FRAME_R31]
|
||||
;;
|
||||
.mem.offset 8,0
|
||||
st8.spill [r2]=r30,24 // r2=&tf_f[FRAME_F6]
|
||||
st8.spill [r2]=r30,16 // r2=&tf_f[FRAME_F6]
|
||||
.mem.offset 0,0
|
||||
st8.spill [r1]=r31,32 // r1=&tf_f[FRAME_F7]
|
||||
st8.spill [r1]=r31,24 // r1=&tf_f[FRAME_F7]
|
||||
;;
|
||||
stf.spill [r2]=f6,32 // r2=&tf_f[FRAME_F8]
|
||||
stf.spill [r1]=f7,32 // r1=&tf_f[FRAME_F9]
|
||||
@ -1258,12 +1259,15 @@ ENTRY(do_syscall, 0)
|
||||
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
|
||||
add r31=16,r30;; // secondary pointer
|
||||
|
||||
// save minimal state for syscall
|
||||
mov r18=cr.iip
|
||||
mov r19=cr.ipsr
|
||||
mov r20=cr.isr
|
||||
mov r21=FRAME_SYSCALL
|
||||
;;
|
||||
st8 [r30]=r21,8
|
||||
;;
|
||||
st8 [r30]=r18,16 // save cr.iip
|
||||
st8 [r31]=r19,16 // save cr.ipsr
|
||||
@ -1302,8 +1306,16 @@ ENTRY(do_syscall, 0)
|
||||
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]=r16,TF_R-TF_B+FRAME_R4*8 // save b0, r1=&tf_r[FRAME_SP]
|
||||
;;
|
||||
st8.spill [r30]=r4,8 // save r4
|
||||
;;
|
||||
st8.spill [r30]=r5,8 // save r5
|
||||
;;
|
||||
st8.spill [r30]=r6,8 // save r6
|
||||
;;
|
||||
st8.spill [r30]=r7,(FRAME_SP-FRAME_R7)*8 // save r7
|
||||
;;
|
||||
st8 [r30]=r17 // save user sp
|
||||
;;
|
||||
bsw.1 // switch back to bank 1
|
||||
@ -1353,9 +1365,10 @@ ENTRY(do_syscall, 0)
|
||||
;;
|
||||
br.call.sptk.many rp=syscall // do the work
|
||||
|
||||
cmp.eq p6,p0=59,loc0 // do a full restore for execve
|
||||
ld8 r14=[loc1] // check tf_flags
|
||||
;;
|
||||
(p6) add sp=-16,loc1
|
||||
tbit.z p6,p0=r14,0 // check FRAME_SYSCALL bit
|
||||
(p6) add sp=-16,loc1 // do a full restore if clear
|
||||
(p6) br.dpnt.many exception_restore
|
||||
|
||||
rsm psr.dt|psr.ic|psr.i // get ready to restore
|
||||
|
@ -905,8 +905,8 @@ ENTRY(exception_restore, 0)
|
||||
ldf.fill f9=[r1],-32 // r1=&tf_f[FRAME_F7]
|
||||
ldf.fill f8=[r2],-32 // r2=&tf_f[FRAME_F6]
|
||||
;;
|
||||
ldf.fill f7=[r1],-32 // r1=&tf_r[FRAME_R31]
|
||||
ldf.fill f6=[r2],-24 // r2=&tf_r[FRAME_R30]
|
||||
ldf.fill f7=[r1],-24 // r1=&tf_r[FRAME_R31]
|
||||
ldf.fill f6=[r2],-16 // r2=&tf_r[FRAME_R30]
|
||||
;;
|
||||
ld8.fill r31=[r1],-16 // r1=&tf_r[FRAME_R29]
|
||||
ld8.fill r30=[r2],-16 // r2=&tf_r[FRAME_R28]
|
||||
@ -1068,9 +1068,10 @@ ENTRY(exception_save, 0)
|
||||
mov rR1=r1
|
||||
mov rR2=r2
|
||||
;;
|
||||
dep r1=0,sp,61,3 // r1=&tf_cr_iip
|
||||
dep r1=0,sp,61,3 // r1=&tf_flags
|
||||
;;
|
||||
add r2=8,r1 // r2=&tf_cr_ipsr
|
||||
add r2=16,r1 // r2=&tf_cr_ipsr
|
||||
st8 [r1]=r0,8 // zero flags, r1=&tf_cr_iip
|
||||
;;
|
||||
st8 [r1]=rIIP,16 // r1=&tf_cr_isr
|
||||
st8 [r2]=rIPSR,16 // r2=&tf_cr_ifa
|
||||
@ -1215,9 +1216,9 @@ ENTRY(exception_save, 0)
|
||||
st8.spill [r1]=r29,16 // r1=&tf_r[FRAME_R31]
|
||||
;;
|
||||
.mem.offset 8,0
|
||||
st8.spill [r2]=r30,24 // r2=&tf_f[FRAME_F6]
|
||||
st8.spill [r2]=r30,16 // r2=&tf_f[FRAME_F6]
|
||||
.mem.offset 0,0
|
||||
st8.spill [r1]=r31,32 // r1=&tf_f[FRAME_F7]
|
||||
st8.spill [r1]=r31,24 // r1=&tf_f[FRAME_F7]
|
||||
;;
|
||||
stf.spill [r2]=f6,32 // r2=&tf_f[FRAME_F8]
|
||||
stf.spill [r1]=f7,32 // r1=&tf_f[FRAME_F9]
|
||||
@ -1258,12 +1259,15 @@ ENTRY(do_syscall, 0)
|
||||
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
|
||||
add r31=16,r30;; // secondary pointer
|
||||
|
||||
// save minimal state for syscall
|
||||
mov r18=cr.iip
|
||||
mov r19=cr.ipsr
|
||||
mov r20=cr.isr
|
||||
mov r21=FRAME_SYSCALL
|
||||
;;
|
||||
st8 [r30]=r21,8
|
||||
;;
|
||||
st8 [r30]=r18,16 // save cr.iip
|
||||
st8 [r31]=r19,16 // save cr.ipsr
|
||||
@ -1302,8 +1306,16 @@ ENTRY(do_syscall, 0)
|
||||
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]=r16,TF_R-TF_B+FRAME_R4*8 // save b0, r1=&tf_r[FRAME_SP]
|
||||
;;
|
||||
st8.spill [r30]=r4,8 // save r4
|
||||
;;
|
||||
st8.spill [r30]=r5,8 // save r5
|
||||
;;
|
||||
st8.spill [r30]=r6,8 // save r6
|
||||
;;
|
||||
st8.spill [r30]=r7,(FRAME_SP-FRAME_R7)*8 // save r7
|
||||
;;
|
||||
st8 [r30]=r17 // save user sp
|
||||
;;
|
||||
bsw.1 // switch back to bank 1
|
||||
@ -1353,9 +1365,10 @@ ENTRY(do_syscall, 0)
|
||||
;;
|
||||
br.call.sptk.many rp=syscall // do the work
|
||||
|
||||
cmp.eq p6,p0=59,loc0 // do a full restore for execve
|
||||
ld8 r14=[loc1] // check tf_flags
|
||||
;;
|
||||
(p6) add sp=-16,loc1
|
||||
tbit.z p6,p0=r14,0 // check FRAME_SYSCALL bit
|
||||
(p6) add sp=-16,loc1 // do a full restore if clear
|
||||
(p6) br.dpnt.many exception_restore
|
||||
|
||||
rsm psr.dt|psr.ic|psr.i // get ready to restore
|
||||
|
@ -86,6 +86,8 @@ ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS);
|
||||
|
||||
ASSYM(SIZEOF_USER, sizeof(struct user));
|
||||
|
||||
ASSYM(FRAME_SYSCALL, FRAME_SYSCALL);
|
||||
|
||||
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));
|
||||
@ -93,6 +95,10 @@ 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_R4, FRAME_R4);
|
||||
ASSYM(FRAME_R5, FRAME_R5);
|
||||
ASSYM(FRAME_R6, FRAME_R6);
|
||||
ASSYM(FRAME_R7, FRAME_R7);
|
||||
ASSYM(FRAME_SP, FRAME_SP);
|
||||
|
||||
ASSYM(U_PCB_R4, offsetof(struct user, u_pcb.pcb_r4));
|
||||
|
@ -46,11 +46,11 @@
|
||||
#include <sys/bus.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/ktr.h>
|
||||
#include <sys/mutex.h>
|
||||
|
||||
#include <machine/reg.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/intr.h>
|
||||
#include <machine/mutex.h>
|
||||
|
||||
#ifdef EVCNT_COUNTERS
|
||||
struct evcnt clock_intr_evcnt; /* event counter for clock intrs. */
|
||||
|
@ -136,7 +136,7 @@ ENTRY(sigcode,0)
|
||||
mov r9=ar.bsp // save ar.bsp
|
||||
;;
|
||||
st8 [r8]=r9
|
||||
cmp.eq p1,p0=r0,r18 // check for new bs
|
||||
cmp.eq p1,p2=r0,r18 // check for new bs
|
||||
(p1) br.cond.sptk.few 1f // branch if not switching
|
||||
flushrs // flush out to old bs
|
||||
mov ar.rsc=0 // switch off RSE
|
||||
@ -151,8 +151,9 @@ ENTRY(sigcode,0)
|
||||
;;
|
||||
1: mov out1=r15 // siginfo
|
||||
mov out2=r16 // ucontext
|
||||
mov r4=r17 // save ucontext pointer from call
|
||||
mov r4=r16 // save from call
|
||||
br.call.sptk.few rp=b6 // call the signal handler
|
||||
;;
|
||||
(p1) br.cond.sptk.few 2f // note: p1 is preserved
|
||||
flushrs
|
||||
mov ar.rsc=0
|
||||
@ -168,8 +169,10 @@ ENTRY(sigcode,0)
|
||||
;;
|
||||
mov ar.rnat=r9
|
||||
mov ar.rsc=15
|
||||
2:
|
||||
CALLSYS_NOERROR(sigreturn) // and call sigreturn() with it.
|
||||
|
||||
2: alloc r14=ar.pfs,0,0,0,0 // no frame for sigreturn
|
||||
CALLSYS_NOERROR(sigreturn) // call sigreturn()
|
||||
alloc r14=ar.pfs,0,0,1,0 ;;
|
||||
mov out0=ret0 // if that failed, get error code
|
||||
CALLSYS_NOERROR(exit) // and call exit() with it.
|
||||
XENTRY(esigcode)
|
||||
|
@ -136,7 +136,7 @@ ENTRY(sigcode,0)
|
||||
mov r9=ar.bsp // save ar.bsp
|
||||
;;
|
||||
st8 [r8]=r9
|
||||
cmp.eq p1,p0=r0,r18 // check for new bs
|
||||
cmp.eq p1,p2=r0,r18 // check for new bs
|
||||
(p1) br.cond.sptk.few 1f // branch if not switching
|
||||
flushrs // flush out to old bs
|
||||
mov ar.rsc=0 // switch off RSE
|
||||
@ -151,8 +151,9 @@ ENTRY(sigcode,0)
|
||||
;;
|
||||
1: mov out1=r15 // siginfo
|
||||
mov out2=r16 // ucontext
|
||||
mov r4=r17 // save ucontext pointer from call
|
||||
mov r4=r16 // save from call
|
||||
br.call.sptk.few rp=b6 // call the signal handler
|
||||
;;
|
||||
(p1) br.cond.sptk.few 2f // note: p1 is preserved
|
||||
flushrs
|
||||
mov ar.rsc=0
|
||||
@ -168,8 +169,10 @@ ENTRY(sigcode,0)
|
||||
;;
|
||||
mov ar.rnat=r9
|
||||
mov ar.rsc=15
|
||||
2:
|
||||
CALLSYS_NOERROR(sigreturn) // and call sigreturn() with it.
|
||||
|
||||
2: alloc r14=ar.pfs,0,0,0,0 // no frame for sigreturn
|
||||
CALLSYS_NOERROR(sigreturn) // call sigreturn()
|
||||
alloc r14=ar.pfs,0,0,1,0 ;;
|
||||
mov out0=ret0 // if that failed, get error code
|
||||
CALLSYS_NOERROR(exit) // and call exit() with it.
|
||||
XENTRY(esigcode)
|
||||
|
@ -788,20 +788,26 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
oonstack = (p->p_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
|
||||
rndfsize = ((sizeof(sf) + 15) / 16) * 16;
|
||||
|
||||
/*
|
||||
* Make sure that we restore the entire trapframe after a
|
||||
* signal.
|
||||
*/
|
||||
frame->tf_flags &= ~FRAME_SYSCALL;
|
||||
|
||||
/* save user context */
|
||||
bzero(&sf, sizeof(struct sigframe));
|
||||
sf.sf_uc.uc_sigmask = *mask;
|
||||
sf.sf_uc.uc_stack = p->p_sigstk;
|
||||
sf.sf_uc.uc_mcontext.mc_flags = IA64_MC_FLAG_ONSTACK;
|
||||
|
||||
sf.sf_uc.uc_mcontext.mc_nat = 0; /* XXX */
|
||||
sf.sf_uc.uc_mcontext.mc_nat = 0; /* XXX */
|
||||
sf.sf_uc.uc_mcontext.mc_sp = frame->tf_r[FRAME_SP];
|
||||
sf.sf_uc.uc_mcontext.mc_ip = frame->tf_cr_iip;
|
||||
sf.sf_uc.uc_mcontext.mc_cfm = 0; /* XXX */
|
||||
sf.sf_uc.uc_mcontext.mc_ip = (frame->tf_cr_iip
|
||||
| ((frame->tf_cr_ipsr >> 41) & 3));
|
||||
sf.sf_uc.uc_mcontext.mc_cfm = frame->tf_cr_ifs & ~(1<<31);
|
||||
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_bspstore
|
||||
+ frame->tf_ndirty);
|
||||
sf.sf_uc.uc_mcontext.mc_ar_bsp = frame->tf_ar_bspstore;
|
||||
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;
|
||||
@ -812,8 +818,9 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
bcopy(&frame->tf_b[0],
|
||||
&sf.sf_uc.uc_mcontext.mc_br[0],
|
||||
8 * sizeof(unsigned long));
|
||||
sf.sf_uc.uc_mcontext.mc_gr[0] = 0;
|
||||
bcopy(&frame->tf_r[0],
|
||||
&sf.sf_uc.uc_mcontext.mc_gr[0],
|
||||
&sf.sf_uc.uc_mcontext.mc_gr[1],
|
||||
31 * sizeof(unsigned long));
|
||||
|
||||
/* XXX mc_fr[] */
|
||||
@ -831,6 +838,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
sfp = (struct sigframe *)((caddr_t)p->p_sigstk.ss_sp +
|
||||
p->p_sigstk.ss_size - rndfsize);
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
sf.sf_uc.uc_mcontext.mc_onstack |= 1;
|
||||
} else
|
||||
sfp = (struct sigframe *)(frame->tf_r[FRAME_SP] - rndfsize);
|
||||
|
||||
@ -868,12 +876,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
sf.sf_uc.uc_mcontext.mc_fp_control = p->p_addr->u_pcb.pcb_fp_control;
|
||||
#endif
|
||||
|
||||
#ifdef COMPAT_OSF1
|
||||
/*
|
||||
* XXX Create an OSF/1-style sigcontext and associated goo.
|
||||
*/
|
||||
#endif
|
||||
|
||||
/*
|
||||
* copy the frame out to userland.
|
||||
*/
|
||||
@ -887,10 +889,11 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
/*
|
||||
* Set up the registers to return to sigcode.
|
||||
*/
|
||||
frame->tf_cr_ipsr &= ~IA64_PSR_RI;
|
||||
frame->tf_cr_iip = PS_STRINGS - (esigcode - sigcode);
|
||||
frame->tf_r[FRAME_R1] = sig;
|
||||
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
|
||||
frame->tf_r[FRAME_R2] = (u_int64_t)&(sfp->sf_si);
|
||||
frame->tf_r[FRAME_R15] = (u_int64_t)&(sfp->sf_si);
|
||||
|
||||
/* Fill in POSIX parts */
|
||||
sf.sf_si.si_signo = sig;
|
||||
@ -898,12 +901,14 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
sf.sf_si.si_addr = (void*)frame->tf_cr_ifa;
|
||||
}
|
||||
else
|
||||
frame->tf_r[FRAME_R2] = code;
|
||||
frame->tf_r[FRAME_R15] = code;
|
||||
|
||||
frame->tf_r[FRAME_R3] = (u_int64_t)&(sfp->sf_uc);
|
||||
frame->tf_r[FRAME_R4] = (u_int64_t)catcher;
|
||||
frame->tf_r[FRAME_R5] = sbs;
|
||||
frame->tf_r[FRAME_SP] = (u_int64_t)sfp - 16;
|
||||
frame->tf_r[FRAME_R14] = sig;
|
||||
frame->tf_r[FRAME_R15] = (u_int64_t) &sfp->sf_si;
|
||||
frame->tf_r[FRAME_R16] = (u_int64_t) &sfp->sf_uc;
|
||||
frame->tf_r[FRAME_R17] = (u_int64_t)catcher;
|
||||
frame->tf_r[FRAME_R18] = sbs;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (sigdebug & SDB_FOLLOW)
|
||||
@ -949,10 +954,10 @@ sigreturn(struct proc *p,
|
||||
ucontext_t *sigcntxp;
|
||||
} */ *uap)
|
||||
{
|
||||
#if 0
|
||||
ucontext_t uc, *ucp;
|
||||
struct pcb *pcb;
|
||||
unsigned long val;
|
||||
struct trapframe *frame = p->p_md.md_tf;
|
||||
struct __mcontext *mcp;
|
||||
|
||||
ucp = uap->sigcntxp;
|
||||
pcb = &p->p_addr->u_pcb;
|
||||
@ -964,19 +969,45 @@ sigreturn(struct proc *p,
|
||||
|
||||
/*
|
||||
* Fetch the entire context structure at once for speed.
|
||||
* We don't use a normal argument to simplify RSE handling.
|
||||
*/
|
||||
if (copyin((caddr_t)ucp, (caddr_t)&uc, sizeof(ucontext_t)))
|
||||
if (copyin((caddr_t)frame->tf_r[FRAME_R4],
|
||||
(caddr_t)&uc, sizeof(ucontext_t)))
|
||||
return (EFAULT);
|
||||
|
||||
/*
|
||||
* Restore the user-supplied information
|
||||
*/
|
||||
set_regs(p, (struct reg *)uc.uc_mcontext.mc_regs);
|
||||
val = (uc.uc_mcontext.mc_regs[R_PS] | IA64_PSL_USERSET) &
|
||||
~IA64_PSL_USERCLR;
|
||||
p->p_md.md_tf->tf_regs[FRAME_PS] = val;
|
||||
p->p_md.md_tf->tf_regs[FRAME_PC] = uc.uc_mcontext.mc_regs[R_PC];
|
||||
ia64_pal_wrusp(uc.uc_mcontext.mc_regs[R_SP]);
|
||||
mcp = &uc.uc_mcontext;
|
||||
bcopy(&mcp->mc_br[0], &frame->tf_b[0], 8*sizeof(u_int64_t));
|
||||
bcopy(&mcp->mc_gr[1], &frame->tf_r[0], 31*sizeof(u_int64_t));
|
||||
/* XXX mc_fr */
|
||||
|
||||
frame->tf_flags &= ~FRAME_SYSCALL;
|
||||
frame->tf_cr_iip = mcp->mc_ip & ~15;
|
||||
frame->tf_cr_ipsr &= ~IA64_PSR_RI;
|
||||
switch (mcp->mc_ip & 15) {
|
||||
case 1:
|
||||
frame->tf_cr_ipsr |= IA64_PSR_RI_1;
|
||||
break;
|
||||
case 2:
|
||||
frame->tf_cr_ipsr |= IA64_PSR_RI_2;
|
||||
break;
|
||||
}
|
||||
frame->tf_cr_ipsr = ((frame->tf_cr_ipsr & ~0x1fff)
|
||||
| (mcp->mc_um & 0x1fff));
|
||||
frame->tf_pr = mcp->mc_pr;
|
||||
frame->tf_ar_rsc = (mcp->mc_ar_rsc & 3) | 12; /* user, loadrs=0 */
|
||||
frame->tf_ar_pfs = mcp->mc_ar_pfs;
|
||||
frame->tf_cr_ifs = mcp->mc_cfm | (1UL<<63);
|
||||
frame->tf_ar_bspstore = mcp->mc_ar_bsp;
|
||||
frame->tf_ar_rnat = mcp->mc_ar_rnat;
|
||||
frame->tf_ndirty = 0; /* assumes flushrs in sigcode */
|
||||
frame->tf_ar_unat = mcp->mc_ar_unat;
|
||||
frame->tf_ar_ccv = mcp->mc_ar_ccv;
|
||||
frame->tf_ar_fpsr = mcp->mc_ar_fpsr;
|
||||
|
||||
frame->tf_r[FRAME_SP] = mcp->mc_sp;
|
||||
|
||||
if (uc.uc_mcontext.mc_onstack & 1)
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
@ -988,14 +1019,16 @@ sigreturn(struct proc *p,
|
||||
|
||||
/* XXX ksc.sc_ownedfp ? */
|
||||
ia64_fpstate_drop(p);
|
||||
#if 0
|
||||
bcopy((struct fpreg *)uc.uc_mcontext.mc_fpregs,
|
||||
&p->p_addr->u_pcb.pcb_fp, sizeof(struct fpreg));
|
||||
p->p_addr->u_pcb.pcb_fp_control = uc.uc_mcontext.mc_fp_control;
|
||||
p->p_addr->u_pcb.pcb_fp_control =
|
||||
uc.uc_mcontext.mc_fp_control;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
if (sigdebug & SDB_FOLLOW)
|
||||
printf("sigreturn(%d): returns\n", p->p_pid);
|
||||
#endif
|
||||
#endif
|
||||
return (EJUSTRETURN);
|
||||
}
|
||||
@ -1030,6 +1063,12 @@ setregs(struct proc *p, u_long entry, u_long stack, u_long ps_strings)
|
||||
|
||||
frame = p->p_md.md_tf;
|
||||
|
||||
/*
|
||||
* Make sure that we restore the entire trapframe after an
|
||||
* execve.
|
||||
*/
|
||||
frame->tf_flags &= ~FRAME_SYSCALL;
|
||||
|
||||
bzero(frame->tf_r, sizeof(frame->tf_r));
|
||||
bzero(frame->tf_f, sizeof(frame->tf_f));
|
||||
frame->tf_cr_iip = entry;
|
||||
|
@ -84,11 +84,11 @@ ia64_cmpxchg_rel_64(volatile u_int64_t* p, u_int64_t cmpval, u_int64_t newval)
|
||||
static __inline u_int##width##_t \
|
||||
ia64_ld_acq_##width(volatile u_int##width##_t* p) \
|
||||
{ \
|
||||
u_int##width_t v; \
|
||||
u_int##width##_t v; \
|
||||
\
|
||||
__asm __volatile ("ld" size ".acq %0=%1" \
|
||||
: "r" (v) \
|
||||
: "=m" (*p) \
|
||||
: "=r" (v) \
|
||||
: "m" (*p) \
|
||||
: "memory"); \
|
||||
return (v); \
|
||||
} \
|
||||
@ -96,11 +96,11 @@ ia64_ld_acq_##width(volatile u_int##width##_t* p) \
|
||||
static __inline u_int##width##_t \
|
||||
atomic_load_acq_##width(volatile u_int##width##_t* p) \
|
||||
{ \
|
||||
u_int##width_t v; \
|
||||
u_int##width##_t v; \
|
||||
\
|
||||
__asm __volatile ("ld" size ".acq %0=%1" \
|
||||
: "r" (v) \
|
||||
: "=m" (*p) \
|
||||
: "=r" (v) \
|
||||
: "m" (*p) \
|
||||
: "memory"); \
|
||||
return (v); \
|
||||
} \
|
||||
@ -108,11 +108,11 @@ atomic_load_acq_##width(volatile u_int##width##_t* p) \
|
||||
static __inline u_int##width##_t \
|
||||
atomic_load_acq_##type(volatile u_int##width##_t* p) \
|
||||
{ \
|
||||
u_int##width_t v; \
|
||||
u_int##width##_t v; \
|
||||
\
|
||||
__asm __volatile ("ld" size ".acq %0=%1" \
|
||||
: "r" (v) \
|
||||
: "=m" (*p) \
|
||||
: "=r" (v) \
|
||||
: "m" (*p) \
|
||||
: "memory"); \
|
||||
return (v); \
|
||||
} \
|
||||
@ -266,6 +266,18 @@ IA64_ATOMIC(8, u_int64_t, subtract, 64, -)
|
||||
#define atomic_add_rel_long atomic_add_rel_64
|
||||
#define atomic_subtract_rel_long atomic_subtract_rel_64
|
||||
|
||||
static __inline void
|
||||
atomic_set_ptr(volatile void *p, u_int64_t v)
|
||||
{
|
||||
atomic_set_64((volatile u_int64_t *) p, v);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
atomic_clear_ptr(volatile void *p, u_int64_t v)
|
||||
{
|
||||
atomic_clear_64((volatile u_int64_t *) p, v);
|
||||
}
|
||||
|
||||
/*
|
||||
* Atomically compare the value stored at *p with cmpval and if the
|
||||
* two values are equal, update the value of *p with newval. Returns
|
||||
|
@ -33,11 +33,11 @@
|
||||
|
||||
/*
|
||||
* Software trap, exception, and syscall frame.
|
||||
*
|
||||
* This is loosely based on the Linux pt_regs structure. When I
|
||||
* understand things better, I might change it.
|
||||
*/
|
||||
struct trapframe {
|
||||
u_int64_t tf_flags;
|
||||
#define FRAME_SYSCALL 1 /* syscalls use a partial trapframe */
|
||||
|
||||
u_int64_t tf_cr_iip;
|
||||
u_int64_t tf_cr_ipsr;
|
||||
u_int64_t tf_cr_isr;
|
||||
@ -91,8 +91,6 @@ struct trapframe {
|
||||
#define FRAME_R30 29
|
||||
#define FRAME_R31 30
|
||||
|
||||
u_int64_t tf_pad1;
|
||||
|
||||
/*
|
||||
* We rely on the compiler to save/restore f2-f5 and
|
||||
* f16-f31. We also tell the compiler to avoid f32-f127
|
||||
|
@ -136,6 +136,8 @@
|
||||
#define IA64_PHYS_TO_RR6(x) ((x) | IA64_RR_BASE(6))
|
||||
#define IA64_PHYS_TO_RR7(x) ((x) | IA64_RR_BASE(7))
|
||||
|
||||
#ifndef LOCORE
|
||||
|
||||
/*
|
||||
* Various special ia64 instructions.
|
||||
*/
|
||||
@ -427,5 +429,7 @@ ia64_set_rr(u_int64_t rrbase, u_int64_t v)
|
||||
__asm __volatile("mov rr[%0]=%1" :: "r"(rrbase), "r"(v) : "memory");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _MACHINE_IA64_CPU_H_ */
|
||||
|
||||
|
@ -46,7 +46,7 @@
|
||||
#ifdef _KERN_MUTEX_C_
|
||||
char STR_IEN[] = "psr.i";
|
||||
char STR_IDIS[] = "!psr.i";
|
||||
char STR_SIEN[] = "mpp->mtx_saveintr & PSR_I";
|
||||
char STR_SIEN[] = "mpp->mtx_saveintr & IA64_PSR_I";
|
||||
#else /* _KERN_MUTEX_C_ */
|
||||
extern char STR_IEN[];
|
||||
extern char STR_IDIS[];
|
||||
@ -57,9 +57,9 @@ extern char STR_SIEN[];
|
||||
|
||||
#define ASS_IEN MPASS2((save_intr() & IA64_PSR_I), STR_IEN)
|
||||
#define ASS_IDIS MPASS2(!(save_intr() & IA64_PSR_I), STR_IDIS)
|
||||
#define ASS_SIEN(mpp) MPASS2((mpp)->mtx_saveintr & IA64_PSR_I), STR_SIEN)
|
||||
#define ASS_SIEN(mpp) MPASS2(((mpp)->mtx_saveintr & IA64_PSR_I), STR_SIEN)
|
||||
|
||||
#define mtx_legal2block() ((save_intr() & IA64_PSL_I)
|
||||
#define mtx_legal2block() ((save_intr() & IA64_PSR_I)
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
@ -63,7 +63,8 @@ struct osigcontext {};
|
||||
* mcontext_t. Keep them in sync!
|
||||
*/
|
||||
struct sigcontext {
|
||||
sigset_t sc_mask; /* signal mask to restore */
|
||||
sigset_t sc_mask; /* signal mask to restore */
|
||||
unsigned long sc_onstack;
|
||||
unsigned long sc_flags;
|
||||
unsigned long sc_nat;
|
||||
unsigned long sc_sp;
|
||||
|
@ -41,10 +41,8 @@ typedef struct __mcontext {
|
||||
* of struct sigcontext. That way we can support
|
||||
* struct sigcontext and ucontext_t at the same
|
||||
* time.
|
||||
*
|
||||
* We use the same layout as Linux/ia64 to make emulation
|
||||
* easier.
|
||||
*/
|
||||
long mc_onstack; /* XXX - sigcontext compat. */
|
||||
unsigned long mc_flags;
|
||||
unsigned long mc_nat;
|
||||
unsigned long mc_sp;
|
||||
|
Loading…
Reference in New Issue
Block a user