summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2000-10-24 19:54:38 +0000
committerdfr <dfr@FreeBSD.org>2000-10-24 19:54:38 +0000
commita0ecb2ad9b9f4c0d17044a3d795112743988eebd (patch)
tree4bd222fde6b5f4a386d863fe92ed0f556be4f965 /sys/ia64
parent3738b3e38b5e5f713950b10c7fb33b33b2197382 (diff)
downloadFreeBSD-src-a0ecb2ad9b9f4c0d17044a3d795112743988eebd.zip
FreeBSD-src-a0ecb2ad9b9f4c0d17044a3d795112743988eebd.tar.gz
* 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.
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia64/clock.c13
-rw-r--r--sys/ia64/ia64/exception.S33
-rw-r--r--sys/ia64/ia64/exception.s33
-rw-r--r--sys/ia64/ia64/genassym.c6
-rw-r--r--sys/ia64/ia64/interrupt.c2
-rw-r--r--sys/ia64/ia64/locore.S11
-rw-r--r--sys/ia64/ia64/locore.s11
-rw-r--r--sys/ia64/ia64/machdep.c95
-rw-r--r--sys/ia64/include/atomic.h30
-rw-r--r--sys/ia64/include/frame.h8
-rw-r--r--sys/ia64/include/ia64_cpu.h4
-rw-r--r--sys/ia64/include/mutex.h6
-rw-r--r--sys/ia64/include/signal.h3
-rw-r--r--sys/ia64/include/ucontext.h4
14 files changed, 173 insertions, 86 deletions
diff --git a/sys/ia64/ia64/clock.c b/sys/ia64/ia64/clock.c
index 2f036da..9d6e927 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 786d658..b067dea 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 786d658..b067dea 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 c81c5bb..ce3f795 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 b0a52cb..16fbfdb 100644
--- a/sys/ia64/ia64/interrupt.c
+++ b/sys/ia64/ia64/interrupt.c
@@ -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. */
diff --git a/sys/ia64/ia64/locore.S b/sys/ia64/ia64/locore.S
index 45d32c1..4b0ef2f 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 45d32c1..4b0ef2f 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 32cc8c0..434f012 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,15 +1019,17 @@ 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 5966930..c01f7d0 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 169dba6..f827f8a 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 2e10844..bd91987 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 e3a4a64..8c3aff4 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 006a99b..e1602e4 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 bb18d76..e8660a5 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;
OpenPOWER on IntegriCloud