diff --git a/sys/ia64/ia64/clock.c b/sys/ia64/ia64/clock.c index 2f036dae9368..9d6e927a270e 100644 --- a/sys/ia64/ia64/clock.c +++ b/sys/ia64/ia64/clock.c @@ -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 diff --git a/sys/ia64/ia64/exception.S b/sys/ia64/ia64/exception.S index 786d65879cf5..b067deaea008 100644 --- a/sys/ia64/ia64/exception.S +++ b/sys/ia64/ia64/exception.S @@ -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 diff --git a/sys/ia64/ia64/exception.s b/sys/ia64/ia64/exception.s index 786d65879cf5..b067deaea008 100644 --- a/sys/ia64/ia64/exception.s +++ b/sys/ia64/ia64/exception.s @@ -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 diff --git a/sys/ia64/ia64/genassym.c b/sys/ia64/ia64/genassym.c index c81c5bb51f86..ce3f7953967e 100644 --- a/sys/ia64/ia64/genassym.c +++ b/sys/ia64/ia64/genassym.c @@ -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)); diff --git a/sys/ia64/ia64/interrupt.c b/sys/ia64/ia64/interrupt.c index b0a52cbf2999..16fbfdbfbeaf 100644 --- a/sys/ia64/ia64/interrupt.c +++ b/sys/ia64/ia64/interrupt.c @@ -46,11 +46,11 @@ #include #include #include +#include #include #include #include -#include #ifdef EVCNT_COUNTERS struct evcnt clock_intr_evcnt; /* event counter for clock intrs. */ diff --git a/sys/ia64/ia64/locore.S b/sys/ia64/ia64/locore.S index 45d32c16b336..4b0ef2f3fa0b 100644 --- a/sys/ia64/ia64/locore.S +++ b/sys/ia64/ia64/locore.S @@ -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) diff --git a/sys/ia64/ia64/locore.s b/sys/ia64/ia64/locore.s index 45d32c16b336..4b0ef2f3fa0b 100644 --- a/sys/ia64/ia64/locore.s +++ b/sys/ia64/ia64/locore.s @@ -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) diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index 32cc8c0b797c..434f0125c993 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -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; diff --git a/sys/ia64/include/atomic.h b/sys/ia64/include/atomic.h index 59669308e0c4..c01f7d083855 100644 --- a/sys/ia64/include/atomic.h +++ b/sys/ia64/include/atomic.h @@ -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 diff --git a/sys/ia64/include/frame.h b/sys/ia64/include/frame.h index 169dba6d8b56..f827f8a3352f 100644 --- a/sys/ia64/include/frame.h +++ b/sys/ia64/include/frame.h @@ -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 diff --git a/sys/ia64/include/ia64_cpu.h b/sys/ia64/include/ia64_cpu.h index 2e10844510c5..bd9198785e58 100644 --- a/sys/ia64/include/ia64_cpu.h +++ b/sys/ia64/include/ia64_cpu.h @@ -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_ */ diff --git a/sys/ia64/include/mutex.h b/sys/ia64/include/mutex.h index e3a4a64a24a9..8c3aff4dd17e 100644 --- a/sys/ia64/include/mutex.h +++ b/sys/ia64/include/mutex.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 */ diff --git a/sys/ia64/include/signal.h b/sys/ia64/include/signal.h index 006a99bbf9a2..e1602e4ba454 100644 --- a/sys/ia64/include/signal.h +++ b/sys/ia64/include/signal.h @@ -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; diff --git a/sys/ia64/include/ucontext.h b/sys/ia64/include/ucontext.h index bb18d763c68e..e8660a5b3ae0 100644 --- a/sys/ia64/include/ucontext.h +++ b/sys/ia64/include/ucontext.h @@ -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;