Merge the nathanw_sa branch.

This commit is contained in:
thorpej 2003-01-18 06:23:28 +00:00
parent 71b2230367
commit f91b0bb3f2
45 changed files with 968 additions and 391 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.c,v 1.16 2003/01/06 20:30:33 wiz Exp $ */
/* $NetBSD: pmap.c,v 1.17 2003/01/18 06:23:30 thorpej Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@ -1127,23 +1127,23 @@ pmap_page_protect(struct vm_page *pg, vm_prot_t prot)
* is the current process, load the new MMU context.
*/
void
pmap_activate(struct proc *p)
pmap_activate(struct lwp *l)
{
#if 0
struct pcb *pcb = &p->p_addr->u_pcb;
pmap_t pmap = p->p_vmspace->vm_map.pmap;
struct pcb *pcb = &l->l_proc->p_addr->u_pcb;
pmap_t pmap = l->l_proc->p_vmspace->vm_map.pmap;
/*
* XXX Normally performed in cpu_fork().
*/
printf("pmap_activate(%p), pmap=%p\n",p,pmap);
printf("pmap_activate(%p), pmap=%p\n",l,pmap);
if (pcb->pcb_pm != pmap) {
pcb->pcb_pm = pmap;
(void) pmap_extract(pmap_kernel(), (vaddr_t)pcb->pcb_pm,
(paddr_t *)&pcb->pcb_pmreal);
}
if (p == curproc) {
if (l == curlwp) {
/* Store pointer to new current pmap. */
curpm = pcb->pcb_pmreal;
}
@ -1154,7 +1154,7 @@ pmap_activate(struct proc *p)
* Deactivate the specified process's address space.
*/
void
pmap_deactivate(struct proc *p)
pmap_deactivate(struct lwp *l)
{
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.9 2002/11/25 05:11:32 thorpej Exp $ */
/* $NetBSD: trap.c,v 1.10 2003/01/18 06:23:31 thorpej Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@ -81,6 +81,9 @@
#ifdef KTRACE
#include <sys/ktrace.h>
#endif
#include <sys/pool.h>
#include <sys/sa.h>
#include <sys/savar.h>
#ifdef SYSTRACE
#include <sys/systrace.h>
#endif
@ -112,7 +115,7 @@ volatile int astpending;
volatile int want_resched;
#endif
static int fix_unaligned __P((struct proc *p, struct trapframe *frame));
static int fix_unaligned __P((struct lwp *l, struct trapframe *frame));
void trap __P((struct trapframe *)); /* Called from locore / trap_subr */
int setfault __P((faultbuf)); /* defined in locore.S */
@ -132,11 +135,12 @@ int trapdebug = /* TDB_ALL */ 0;
void
trap(struct trapframe *frame)
{
struct proc *p = curproc;
struct lwp *l = curlwp;
struct proc *p = l ? l->l_proc : NULL;
int type = frame->exc;
int ftype, rv;
KASSERT(p == 0 || (p->p_stat == SONPROC));
KASSERT(l == 0 || (l->l_stat == LSONPROC));
if (frame->srr1 & PSL_PR)
type |= EXC_USER;
@ -157,10 +161,10 @@ printf("debug reg is %x srr2 %x srr3 %x\n", rv, srr2, srr3);
* DEBUG intr -- probably single-step.
*/
case EXC_TRC|EXC_USER:
KERNEL_PROC_LOCK(p);
KERNEL_PROC_LOCK(l);
frame->srr1 &= ~PSL_SE;
trapsignal(p, SIGTRAP, EXC_TRC);
KERNEL_PROC_UNLOCK(p);
trapsignal(l, SIGTRAP, EXC_TRC);
KERNEL_PROC_UNLOCK(l);
break;
/* If we could not find and install appropriate TLB entry, fall through */
@ -190,7 +194,7 @@ frame->srr0, (ftype&VM_PROT_WRITE) ? "write" : "read", (void *)va, frame->esr));
KERNEL_UNLOCK();
if (rv == 0)
goto done;
if ((fb = p->p_addr->u_pcb.pcb_onfault) != NULL) {
if ((fb = l->l_addr->u_pcb.pcb_onfault) != NULL) {
frame->pid = KERNEL_PID;
frame->srr0 = (*fb)[0];
frame->srr1 |= PSL_IR; /* Re-enable IMMU */
@ -208,50 +212,50 @@ frame->srr0, (ftype&VM_PROT_WRITE) ? "write" : "read", (void *)va, frame->esr));
case EXC_DSI|EXC_USER:
/* FALLTHROUGH */
case EXC_DTMISS|EXC_USER:
KERNEL_PROC_LOCK(p);
KERNEL_PROC_LOCK(l);
if (frame->esr & (ESR_DST|ESR_DIZ))
ftype = VM_PROT_WRITE;
DBPRINTF(TDB_ALL, ("trap(EXC_DSI|EXC_USER) at %x %s fault on %x %x\n",
frame->srr0, (ftype&VM_PROT_WRITE) ? "write" : "read", frame->dear, frame->esr));
KASSERT(p == curproc && (p->p_stat == SONPROC));
KASSERT(l == curlwp && (l->l_stat == LSONPROC));
rv = uvm_fault(&p->p_vmspace->vm_map,
trunc_page(frame->dear), 0, ftype);
if (rv == 0) {
KERNEL_PROC_UNLOCK(p);
KERNEL_PROC_UNLOCK(l);
break;
}
if (rv == ENOMEM) {
printf("UVM: pid %d (%s), uid %d killed: "
printf("UVM: pid %d (%s) lid %d, uid %d killed: "
"out of swap\n",
p->p_pid, p->p_comm,
p->p_pid, p->p_comm, l->l_lid,
p->p_cred && p->p_ucred ?
p->p_ucred->cr_uid : -1);
trapsignal(p, SIGKILL, EXC_DSI);
trapsignal(l, SIGKILL, EXC_DSI);
} else {
trapsignal(p, SIGSEGV, EXC_DSI);
trapsignal(l, SIGSEGV, EXC_DSI);
}
KERNEL_PROC_UNLOCK(p);
KERNEL_PROC_UNLOCK(l);
break;
case EXC_ITMISS|EXC_USER:
case EXC_ISI|EXC_USER:
KERNEL_PROC_LOCK(p);
KERNEL_PROC_LOCK(l);
ftype = VM_PROT_READ | VM_PROT_EXECUTE;
DBPRINTF(TDB_ALL, ("trap(EXC_ISI|EXC_USER) at %x %s fault on %x tf %p\n",
frame->srr0, (ftype&VM_PROT_WRITE) ? "write" : "read", frame->srr0, frame));
rv = uvm_fault(&p->p_vmspace->vm_map, trunc_page(frame->srr0), 0, ftype);
if (rv == 0) {
KERNEL_PROC_UNLOCK(p);
KERNEL_PROC_UNLOCK(l);
break;
}
trapsignal(p, SIGSEGV, EXC_ISI);
KERNEL_PROC_UNLOCK(p);
trapsignal(l, SIGSEGV, EXC_ISI);
KERNEL_PROC_UNLOCK(l);
break;
case EXC_AST|EXC_USER:
astpending = 0; /* we are about to do it */
KERNEL_PROC_LOCK(p);
KERNEL_PROC_LOCK(l);
uvmexp.softs++;
if (p->p_flag & P_OWEUPC) {
p->p_flag &= ~P_OWEUPC;
@ -259,18 +263,18 @@ frame->srr0, (ftype&VM_PROT_WRITE) ? "write" : "read", frame->srr0, frame));
}
/* Check whether we are being preempted. */
if (want_resched)
preempt(NULL);
KERNEL_PROC_UNLOCK(p);
preempt(0);
KERNEL_PROC_UNLOCK(l);
break;
case EXC_ALI|EXC_USER:
KERNEL_PROC_LOCK(p);
if (fix_unaligned(p, frame) != 0)
trapsignal(p, SIGBUS, EXC_ALI);
KERNEL_PROC_LOCK(l);
if (fix_unaligned(l, frame) != 0)
trapsignal(l, SIGBUS, EXC_ALI);
else
frame->srr0 += 4;
KERNEL_PROC_UNLOCK(p);
KERNEL_PROC_UNLOCK(l);
break;
case EXC_PGM|EXC_USER:
@ -280,17 +284,17 @@ frame->srr0, (ftype&VM_PROT_WRITE) ? "write" : "read", frame->srr0, frame));
* let's try to see if it's FPU and can be emulated.
*/
uvmexp.traps ++;
if (!(p->p_addr->u_pcb.pcb_flags & PCB_FPU)) {
memset(&p->p_addr->u_pcb.pcb_fpu, 0,
sizeof p->p_addr->u_pcb.pcb_fpu);
p->p_addr->u_pcb.pcb_flags |= PCB_FPU;
if (!(l->l_addr->u_pcb.pcb_flags & PCB_FPU)) {
memset(&l->l_addr->u_pcb.pcb_fpu, 0,
sizeof l->l_addr->u_pcb.pcb_fpu);
l->l_addr->u_pcb.pcb_flags |= PCB_FPU;
}
if ((rv = fpu_emulate(frame,
(struct fpreg *)&p->p_addr->u_pcb.pcb_fpu))) {
KERNEL_PROC_LOCK(p);
trapsignal(p, rv, EXC_PGM);
KERNEL_PROC_UNLOCK(p);
(struct fpreg *)&l->l_addr->u_pcb.pcb_fpu))) {
KERNEL_PROC_LOCK(l);
trapsignal(l, rv, EXC_PGM);
KERNEL_PROC_UNLOCK(l);
}
break;
@ -298,7 +302,7 @@ frame->srr0, (ftype&VM_PROT_WRITE) ? "write" : "read", frame->srr0, frame));
{
faultbuf *fb;
if ((fb = p->p_addr->u_pcb.pcb_onfault) != NULL) {
if ((fb = l->l_addr->u_pcb.pcb_onfault) != NULL) {
frame->pid = KERNEL_PID;
frame->srr0 = (*fb)[0];
frame->srr1 |= PSL_IR; /* Re-enable IMMU */
@ -330,11 +334,19 @@ brain_damage:
{
int sig;
while ((sig = CURSIG(p)) != 0)
while ((sig = CURSIG(l)) != 0)
postsig(sig);
}
curcpu()->ci_schedstate.spc_curpriority = p->p_priority = p->p_usrpri;
/* Invoke per-process kernel-exit handling, if any */
if (p->p_userret)
(p->p_userret)(l, p->p_userret_arg);
/* Invoke any pending upcalls */
while (l->l_flag & L_SA_UPCALL)
sa_upcall_userret(l);
curcpu()->ci_schedstate.spc_curpriority = l->l_priority = l->l_usrpri;
done:
return;
}
@ -431,20 +443,23 @@ bigcopyin(const void *udaddr, void *kaddr, size_t len)
{
const char *up;
char *kp = kaddr;
struct proc *p = curproc;
struct lwp *l = curlwp;
struct proc *p;
int error;
if (!p) {
if (!l) {
return EFAULT;
}
p = l->l_proc;
/*
* Stolen from physio():
*/
PHOLD(p);
PHOLD(l);
error = uvm_vslock(p, (caddr_t)udaddr, len, VM_PROT_READ);
if (error) {
PRELE(p);
PRELE(l);
return EFAULT;
}
up = (char *)vmaprange(p, (vaddr_t)udaddr, len, VM_PROT_READ);
@ -452,7 +467,7 @@ bigcopyin(const void *udaddr, void *kaddr, size_t len)
memcpy(kp, up, len);
vunmaprange((vaddr_t)up, len);
uvm_vsunlock(p, (caddr_t)udaddr, len);
PRELE(p);
PRELE(l);
return 0;
}
@ -508,20 +523,23 @@ bigcopyout(const void *kaddr, void *udaddr, size_t len)
{
char *up;
const char *kp = (char *)kaddr;
struct proc *p = curproc;
struct lwp *l = curlwp;
struct proc *p;
int error;
if (!p) {
if (!l) {
return EFAULT;
}
p = l->l_proc;
/*
* Stolen from physio():
*/
PHOLD(p);
PHOLD(l);
error = uvm_vslock(p, udaddr, len, VM_PROT_WRITE);
if (error) {
PRELE(p);
PRELE(l);
return EFAULT;
}
up = (char *)vmaprange(p, (vaddr_t)udaddr, len,
@ -530,7 +548,7 @@ bigcopyout(const void *kaddr, void *udaddr, size_t len)
memcpy(up, kp, len);
vunmaprange((vaddr_t)up, len);
uvm_vsunlock(p, udaddr, len);
PRELE(p);
PRELE(l);
return 0;
}
@ -620,8 +638,54 @@ badaddr_read(void *addr, size_t size, int *rptr)
*/
static int
fix_unaligned(struct proc *p, struct trapframe *frame)
fix_unaligned(struct lwp *l, struct trapframe *frame)
{
return -1;
}
/*
* Start a new LWP
*/
void
startlwp(arg)
void *arg;
{
int err;
ucontext_t *uc = arg;
struct lwp *l = curlwp;
err = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
#if DIAGNOSTIC
if (err) {
printf("Error %d from cpu_setmcontext.", err);
}
#endif
pool_put(&lwp_uc_pool, uc);
upcallret(l);
}
/*
* XXX This is a terrible name.
*/
void
upcallret(l)
struct lwp *l;
{
int sig;
/* Take pending signals. */
while ((sig = CURSIG(l)) != 0)
postsig(sig);
/* Invoke per-process kernel-exit handling, if any */
if (l->l_proc->p_userret)
(l->l_proc->p_userret)(l, l->l_proc->p_userret_arg);
/* Invoke any pending upcalls */
while (l->l_flag & L_SA_UPCALL)
sa_upcall_userret(l);
curcpu()->ci_schedstate.spc_curpriority = l->l_priority = l->l_usrpri;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap_subr.S,v 1.5 2002/08/02 03:46:42 chs Exp $ */
/* $NetBSD: trap_subr.S,v 1.6 2003/01/18 06:23:31 thorpej Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@ -373,8 +373,9 @@ s_sctrap:
wrteei 1 /* Enable interrupts */
/* Call the appropriate syscall handler: */
addi 3,1,8
lis 4,_C_LABEL(curproc)@ha
lwz 4,_C_LABEL(curproc)@l(4)
lis 4,_C_LABEL(curlwp)@ha
lwz 4,_C_LABEL(curlwp)@l(4)
lwz 4,L_PROC@l(4)
lwz 4,P_MD_SYSCALL@l(4)
mtctr 4
bctrl

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.28 2002/11/26 23:30:22 lukem Exp $
# $NetBSD: Makefile,v 1.29 2003/01/18 06:23:29 thorpej Exp $
INCSDIR= /usr/include/powerpc
@ -13,7 +13,7 @@ INCS= ansi.h aout_machdep.h asm.h atomic.h \
ipkdb.h \
kcore.h \
limits.h lock.h \
math.h \
math.h mcontext.h \
param.h pcb.h pio.h pmap.h pmc.h proc.h profile.h psl.h pte.h ptrace.h \
reg.h reloc.h \
setjmp.h signal.h stdarg.h \

View File

@ -1,4 +1,4 @@
/* $NetBSD: altivec.h,v 1.5 2002/11/03 22:36:22 matt Exp $ */
/* $NetBSD: altivec.h,v 1.6 2003/01/18 06:23:29 thorpej Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@ -45,9 +45,9 @@
#ifdef _KERNEL
void enable_vec(void);
void save_vec_cpu(void);
void save_vec_proc(struct proc *);
void save_vec_lwp(struct lwp *);
#ifdef MULTIPROCESSOR
void mp_save_vec_proc(struct proc *);
void mp_save_vec_lwp(struct lwp *);
#endif
void init_vec(void);
void vzeropage(paddr_t);

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.22 2002/11/25 01:31:12 thorpej Exp $ */
/* $NetBSD: cpu.h,v 1.23 2003/01/18 06:23:29 thorpej Exp $ */
/*
* Copyright (C) 1999 Wolfgang Solfrank.
@ -66,12 +66,12 @@ struct cpu_info {
u_long ci_simple_locks; /* # of simple locks held */
#endif
struct device *ci_dev; /* device of corresponding cpu */
struct proc *ci_curproc; /* current owner of the processor */
struct lwp *ci_curlwp; /* current owner of the processor */
struct pcb *ci_curpcb;
struct pmap *ci_curpm;
struct proc *ci_fpuproc;
struct proc *ci_vecproc;
struct lwp *ci_fpulwp;
struct lwp *ci_veclwp;
struct pcb *ci_idle_pcb; /* PA of our idle pcb */
int ci_cpuid;
@ -132,7 +132,7 @@ void cpu_boot_secondary_processors(void);
extern struct cpu_info cpu_info[];
#define CPU_IS_PRIMARY(ci) ((ci)->ci_cpuid == 0)
#define curproc curcpu()->ci_curproc
#define curlwp curcpu()->ci_curlwp
#define curpcb curcpu()->ci_curpcb
#define curpm curcpu()->ci_curpm
#define want_resched curcpu()->ci_want_resched
@ -213,10 +213,11 @@ mfpvr(void)
#define CLKF_PC(frame) ((frame)->srr0)
#define CLKF_INTR(frame) ((frame)->depth > 0)
#define PROC_PC(p) (trapframe(p)->srr0)
#define LWP_PC(l) (trapframe(l)->srr0)
#define cpu_swapout(p)
#define cpu_wait(p)
#define cpu_proc_fork(p1, p2)
extern int powersave;
extern int cpu_timebase;

View File

@ -1,4 +1,4 @@
/* $NetBSD: fpu.h,v 1.8 2002/11/03 22:36:22 matt Exp $ */
/* $NetBSD: fpu.h,v 1.9 2003/01/18 06:23:29 thorpej Exp $ */
/*-
* Copyright (C) 1996 Wolfgang Solfrank.
@ -78,9 +78,9 @@
void enable_fpu(void);
void save_fpu_cpu(void);
void save_fpu_proc(struct proc *);
void save_fpu_lwp(struct lwp *);
#ifdef MULTIPROCESSOR
void mp_save_fpu_proc(struct proc *);
void mp_save_fpu_lwp(struct lwp *);
#endif
#endif /* PPC_HAVE_FPU */
#endif /* _KERNEL */

View File

@ -1,4 +1,4 @@
/* $NetBSD: frame.h,v 1.8 2002/11/03 22:36:22 matt Exp $ */
/* $NetBSD: frame.h,v 1.9 2003/01/18 06:23:29 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -62,7 +62,7 @@ struct trapframe {
* This is to ensure alignment of the stackpointer
*/
#define FRAMELEN roundup(sizeof(struct trapframe) + 8, 16)
#define trapframe(p) ((struct trapframe *)((char *)(p)->p_addr + USPACE - FRAMELEN + 8))
#define trapframe(l) ((struct trapframe *)((char *)(l)->l_addr + USPACE - FRAMELEN + 8))
struct switchframe {
register_t sp;
@ -90,6 +90,11 @@ struct callframe {
register_t r31;
};
struct saframe {
register_t r1; /* stack pointer */
register_t lr; /* Callee lr save area */
register_t fill[2]; /* Pad to multiple of 16 bytes */
};
#define IFRAMELEN roundup(sizeof(struct intrframe), 16)
struct intrframe {

View File

@ -0,0 +1,126 @@
/* $NetBSD: mcontext.h,v 1.2 2003/01/18 06:23:28 thorpej Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Klaus Klein.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _POWERPC_MCONTEXT_H_
#define _POWERPC_MCONTEXT_H_
/*
* Layout of mcontext_t based on the System V Application Binary Interface,
* Edition 4.1, PowerPC Processor ABI Supplement - September 1995, and
* extended for the AltiVec Register File. Note that due to the increased
* alignment requirements of the latter, the offset of mcontext_t within
* an ucontext_t is different from System V.
*/
#define _NGREG 39 /* GR0-31, CR, LR, SRR0, SRR1, CTR, XER, MQ */
typedef int __greg_t;
typedef __greg_t __gregset_t[_NGREG];
struct __gregs {
__greg_t __r_r0; /* GR0-31 */
__greg_t __r_r1;
__greg_t __r_r2;
__greg_t __r_r3;
__greg_t __r_r4;
__greg_t __r_r5;
__greg_t __r_r6;
__greg_t __r_r7;
__greg_t __r_r8;
__greg_t __r_r9;
__greg_t __r_r10;
__greg_t __r_r11;
__greg_t __r_r12;
__greg_t __r_r13;
__greg_t __r_r14;
__greg_t __r_r15;
__greg_t __r_r16;
__greg_t __r_r17;
__greg_t __r_r18;
__greg_t __r_r19;
__greg_t __r_r20;
__greg_t __r_r21;
__greg_t __r_r22;
__greg_t __r_r23;
__greg_t __r_r24;
__greg_t __r_r25;
__greg_t __r_r26;
__greg_t __r_r27;
__greg_t __r_r28;
__greg_t __r_r29;
__greg_t __r_r30;
__greg_t __r_r31;
__greg_t __r_cr; /* Condition Register */
__greg_t __r_lr; /* Link Register */
__greg_t __r_pc; /* PC (copy of SRR0) */
__greg_t __r_msr; /* MSR (copy of SRR1) */
__greg_t __r_ctr; /* Count Register */
__greg_t __r_xer; /* Integer Exception Register */
__greg_t __r_mq; /* MQ Register (POWER only) */
};
typedef struct {
double __fpu_regs[32]; /* FP0-31 */
unsigned int __fpu_fpscr; /* FP Status and Control Register */
unsigned int __fpu_valid; /* Set together with _UC_FPU */
} __fpregset_t;
#define _NVR 32 /* Number of Vector registers */
typedef struct {
union __vr {
unsigned char __vr8[16];
unsigned short __vr16[8];
unsigned int __vr32[4];
} __vrs[_NVR] __attribute__((__aligned__(16)));
unsigned int __vscr; /* VSCR */
unsigned int __vrsave; /* VRSAVE */
} __vrf_t;
typedef struct {
__gregset_t __gregs; /* General Purpose Register set */
__fpregset_t __fpregs; /* Floating Point Register set */
__vrf_t __vrf; /* Vector Register File */
} mcontext_t;
/* Machine-dependent uc_flags */
#define _UC_POWERPC_VEC 0x00010000 /* Vector Register File valid */
#define _UC_MACHINE_SP(uc) ((uc)->uc_mcontext.__gregs[1])
#endif /* !_POWERPC_MCONTEXT_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: proc.h,v 1.3 2002/07/05 18:45:21 matt Exp $ */
/* $NetBSD: proc.h,v 1.4 2003/01/18 06:23:29 thorpej Exp $ */
/*-
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -36,12 +36,16 @@
/*
* Machine-dependent part of the proc structure
*/
struct trapframe;
struct mdproc {
void (*md_syscall)(struct trapframe *);
struct mdlwp {
int md_flags;
};
#define MDP_USEDFP 0x0001 /* this process has used the FPU */
#define MDP_USEDVEC 0x0002 /* this process has used AltiVec */
struct trapframe;
struct mdproc {
void (*md_syscall)(struct trapframe *);
};
#ifdef _KERNEL

View File

@ -1,4 +1,4 @@
/* $NetBSD: signal.h,v 1.6 2002/11/03 22:36:23 matt Exp $ */
/* $NetBSD: signal.h,v 1.7 2003/01/18 06:23:29 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -54,6 +54,41 @@ struct sigcontext {
sigset_t sc_mask; /* saved signal mask (new style) */
};
/*
* The following macros are used to convert from a ucontext to sigcontext,
* and vice-versa. This is for building a sigcontext to deliver to old-style
* signal handlers, and converting back (in the event the handler modifies
* the context).
*/
#define _MCONTEXT_TO_SIGCONTEXT(uc, sc) \
do { \
memcpy((sc)->sc_frame.fixreg, &(uc)->uc_mcontext.__gregs.__r_r0,\
sizeof((sc)->sc_frame.fixreg)); \
(sc)->sc_frame.lr = (uc)->uc_mcontext.__gregs.__r_lr; \
(sc)->sc_frame.cr = (uc)->uc_mcontext.__gregs.__r_cr; \
(sc)->sc_frame.xer = (uc)->uc_mcontext.__gregs.__r_xer; \
(sc)->sc_frame.ctr = (uc)->uc_mcontext.__gregs.__r_ctr; \
(sc)->sc_frame.srr0 = (uc)->uc_mcontext.__gregs.__r_pc; \
(sc)->sc_frame.srr1 = (uc)->uc_mcontext.__gregs.__r_msr; \
(sc)->sc_frame.dar = 0; \
(sc)->sc_frame.dsisr = 0; \
(sc)->sc_frame.exc = 0; \
(sc)->sc_frame.vrsave = (uc)->uc_mcontext.__vrf.__vrsave; \
} while (/*CONSTCOND*/0)
#define _SIGCONTEXT_TO_MCONTEXT(sc, uc) \
do { \
memcpy(&(uc)->uc_mcontext.__gregs.__r_r0, (sc)->sc_frame.fixreg,\
sizeof((sc)->sc_frame.fixreg)); \
(uc)->uc_mcontext.__gregs.__r_lr = (sc)->sc_frame.lr; \
(uc)->uc_mcontext.__gregs.__r_cr = (sc)->sc_frame.cr; \
(uc)->uc_mcontext.__gregs.__r_xer = (sc)->sc_frame.xer; \
(uc)->uc_mcontext.__gregs.__r_ctr = (sc)->sc_frame.ctr; \
(uc)->uc_mcontext.__gregs.__r_pc = (sc)->sc_frame.srr0; \
(uc)->uc_mcontext.__gregs.__r_msr = (sc)->sc_frame.srr1; \
(uc)->uc_mcontext.__vrf.__vrsave = (sc)->sc_frame.vrsave; \
} while (/*CONSTCOND*/0)
struct sigframe {
struct sigcontext sf_sc;
};

View File

@ -1,4 +1,4 @@
/* $NetBSD: userret.h,v 1.3 2002/08/08 01:27:35 chs Exp $ */
/* $NetBSD: userret.h,v 1.4 2003/01/18 06:23:30 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -40,18 +40,26 @@
* trap and syscall.
*/
static __inline void
userret(struct proc *p, struct trapframe *frame)
userret(struct lwp *l, struct trapframe *frame)
{
struct cpu_info *ci = curcpu();
struct pcb *pcb;
int sig;
/* Take pending signals. */
while ((sig = CURSIG(p)) != 0) {
while ((sig = CURSIG(l)) != 0) {
postsig(sig);
}
pcb = &p->p_addr->u_pcb;
/* Invoke per-process kernel-exit handling, if any */
if (l->l_proc->p_userret)
(l->l_proc->p_userret)(l, l->l_proc->p_userret_arg);
/* Invoke any pending upcalls */
while (l->l_flag & L_SA_UPCALL)
sa_upcall_userret(l);
pcb = &l->l_addr->u_pcb;
/*
* If someone stole the fp or vector unit while we were away,
@ -59,13 +67,13 @@ userret(struct proc *p, struct trapframe *frame)
*/
#ifdef PPC_HAVE_FPU
if ((pcb->pcb_flags & PCB_FPU) &&
(p != ci->ci_fpuproc || pcb->pcb_fpcpu != ci)) {
(l != ci->ci_fpulwp || pcb->pcb_fpcpu != ci)) {
frame->srr1 &= ~PSL_FP;
}
#endif
#ifdef ALTIVEC
if ((pcb->pcb_flags & PCB_ALTIVEC) &&
(p != ci->ci_vecproc || pcb->pcb_veccpu != ci)) {
(l != ci->ci_veclwp || pcb->pcb_veccpu != ci)) {
frame->srr1 &= ~PSL_VEC;
}
@ -74,10 +82,10 @@ userret(struct proc *p, struct trapframe *frame)
* cpu, we need to stop any data streams that are active (since
* it will be a different address space).
*/
if (ci->ci_vecproc != NULL && ci->ci_vecproc != p) {
if (ci->ci_veclwp != NULL && ci->ci_veclwp != l) {
__asm __volatile("dssall;sync");
}
#endif
ci->ci_schedstate.spc_curpriority = p->p_priority = p->p_usrpri;
ci->ci_schedstate.spc_curpriority = l->l_priority = l->l_usrpri;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: altivec.c,v 1.6 2002/07/28 07:07:45 chs Exp $ */
/* $NetBSD: altivec.c,v 1.7 2003/01/18 06:23:31 thorpej Exp $ */
/*
* Copyright (C) 1996 Wolfgang Solfrank.
@ -32,6 +32,7 @@
*/
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/sa.h>
#include <sys/systm.h>
#include <sys/user.h>
#include <sys/malloc.h>
@ -47,9 +48,9 @@ void
enable_vec()
{
struct cpu_info *ci = curcpu();
struct proc *p = curproc;
struct pcb *pcb = &p->p_addr->u_pcb;
struct trapframe *tf = trapframe(p);
struct lwp *l = curlwp;
struct pcb *pcb = &l->l_addr->u_pcb;
struct trapframe *tf = trapframe(l);
struct vreg *vr = pcb->pcb_vr;
int msr, scratch;
@ -82,10 +83,10 @@ enable_vec()
msr = mfmsr();
mtmsr((msr & ~PSL_EE) | PSL_VEC);
__asm __volatile ("isync");
if (ci->ci_vecproc) {
if (ci->ci_veclwp) {
save_vec_cpu();
}
KASSERT(curcpu()->ci_vecproc == NULL);
KASSERT(curcpu()->ci_veclwp == NULL);
/*
* Restore VSCR by first loading it into a vector and then into VSCR.
@ -122,7 +123,7 @@ enable_vec()
* Record the new ownership of the AltiVec unit.
*/
tf->srr1 |= PSL_VEC;
curcpu()->ci_vecproc = p;
curcpu()->ci_veclwp = l;
pcb->pcb_veccpu = curcpu();
__asm __volatile ("sync");
@ -136,7 +137,7 @@ void
save_vec_cpu(void)
{
struct cpu_info *ci = curcpu();
struct proc *p;
struct lwp *l;
struct pcb *pcb;
struct vreg *vr;
struct trapframe *tf;
@ -148,13 +149,13 @@ save_vec_cpu(void)
msr = mfmsr();
mtmsr((msr & ~PSL_EE) | PSL_VEC);
__asm __volatile ("isync");
p = ci->ci_vecproc;
if (p == NULL) {
l = ci->ci_veclwp;
if (l == NULL) {
goto out;
}
pcb = &p->p_addr->u_pcb;
pcb = &l->l_addr->u_pcb;
vr = pcb->pcb_vr;
tf = trapframe(p);
tf = trapframe(l);
#define STVX(n,vr) __asm /*__volatile*/("stvx %2,%0,%1" \
:: "r"(vr), "r"(offsetof(struct vreg, vreg[n])), "n"(n));
@ -190,7 +191,7 @@ save_vec_cpu(void)
*/
tf->srr1 &= ~PSL_VEC;
pcb->pcb_veccpu = NULL;
ci->ci_vecproc = NULL;
ci->ci_veclwp = NULL;
__asm __volatile ("dssall; sync");
out:
@ -208,10 +209,10 @@ save_vec_cpu(void)
* this function).
*/
void
save_vec_proc(p)
struct proc *p;
save_vec_lwp(l)
struct lwp *l;
{
struct pcb *pcb = &p->p_addr->u_pcb;
struct pcb *pcb = &l->l_addr->u_pcb;
struct cpu_info *ci = curcpu();
/*
@ -227,7 +228,7 @@ save_vec_proc(p)
* state.
*/
if (p == ci->ci_vecproc) {
if (l == ci->ci_veclwp) {
save_vec_cpu();
return;
}
@ -238,7 +239,7 @@ save_vec_proc(p)
* It must be on another CPU, flush it from there.
*/
mp_save_vec_proc(p);
mp_save_vec_lwp(l);
#endif
}

View File

@ -1,4 +1,4 @@
# $NetBSD: genassym.cf,v 1.6 2002/08/02 03:46:44 chs Exp $
# $NetBSD: genassym.cf,v 1.7 2003/01/18 06:23:31 thorpej Exp $
#
# Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -106,18 +106,19 @@ define PM_SR offsetof(struct pmap, pm_sr[0])
define PM_USRSR offsetof(struct pmap, pm_sr[USER_SR])
define PM_KERNELSR offsetof(struct pmap, pm_sr[KERNEL_SR])
define P_FORW offsetof(struct proc, p_forw)
define P_BACK offsetof(struct proc, p_back)
define P_ADDR offsetof(struct proc, p_addr)
define P_STAT offsetof(struct proc, p_stat)
define P_CPU offsetof(struct proc, p_cpu)
define L_FORW offsetof(struct lwp, l_forw)
define L_BACK offsetof(struct lwp, l_back)
define L_ADDR offsetof(struct lwp, l_addr)
define L_STAT offsetof(struct lwp, l_stat)
define L_CPU offsetof(struct lwp, l_cpu)
define L_PRIORITY offsetof(struct lwp, l_priority)
define L_PROC offsetof(struct lwp, l_proc)
define LSONPROC LSONPROC
define P_MD_SYSCALL offsetof(struct proc, p_md.md_syscall)
define SONPROC SONPROC
define CI_SIZE sizeof(struct cpu_info)
define CI_CURPROC offsetof(struct cpu_info, ci_curproc)
define CI_CURLWP offsetof(struct cpu_info, ci_curlwp)
define CI_CURPCB offsetof(struct cpu_info, ci_curpcb)
define CI_CURPM offsetof(struct cpu_info, ci_curpm)
define CI_IDLE_PCB offsetof(struct cpu_info, ci_idle_pcb)

View File

@ -1,4 +1,4 @@
/* $NetBSD: mpc6xx_machdep.c,v 1.9 2002/10/10 22:37:51 matt Exp $ */
/* $NetBSD: mpc6xx_machdep.c,v 1.10 2003/01/18 06:23:31 thorpej Exp $ */
/*
* Copyright (C) 2002 Matt Thomas
@ -48,6 +48,7 @@
#include <sys/msgbuf.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/sa.h>
#include <sys/syscallargs.h>
#include <sys/syslog.h>
#include <sys/systm.h>
@ -133,9 +134,9 @@ mpc6xx_init(void (*handler)(void))
/*
* Initialize proc0 and current pcb and pmap pointers.
*/
proc0.p_cpu = ci;
proc0.p_addr = proc0paddr;
memset(proc0.p_addr, 0, sizeof *proc0.p_addr);
lwp0.l_cpu = ci;
lwp0.l_addr = proc0paddr;
memset(lwp0.l_addr, 0, sizeof *lwp0.l_addr);
curpcb = &proc0paddr->u_pcb;
curpm = curpcb->pcb_pmreal = curpcb->pcb_pm = pmap_kernel();

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.c,v 1.62 2002/10/22 04:34:13 chs Exp $ */
/* $NetBSD: pmap.c,v 1.63 2003/01/18 06:23:32 thorpej Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
@ -2033,13 +2033,13 @@ pmap_page_protect(struct vm_page *pg, vm_prot_t prot)
* is the current process, load the new MMU context.
*/
void
pmap_activate(struct proc *p)
pmap_activate(struct lwp *l)
{
struct pcb *pcb = &p->p_addr->u_pcb;
pmap_t pmap = p->p_vmspace->vm_map.pmap;
struct pcb *pcb = &l->l_addr->u_pcb;
pmap_t pmap = l->l_proc->p_vmspace->vm_map.pmap;
DPRINTFN(ACTIVATE,
("pmap_activate: proc %p (curproc %p)\n", p, curproc));
("pmap_activate: lwp %p (curlwp %p)\n", l, curlwp));
/*
* XXX Normally performed in cpu_fork().
@ -2053,7 +2053,7 @@ pmap_activate(struct proc *p)
* In theory, the SR registers need only be valid on return
* to user space wait to do them there.
*/
if (p == curproc) {
if (l == curlwp) {
/* Store pointer to new current pmap. */
curpm = pmap;
}
@ -2063,7 +2063,7 @@ pmap_activate(struct proc *p)
* Deactivate the specified process's address space.
*/
void
pmap_deactivate(struct proc *p)
pmap_deactivate(struct lwp *l)
{
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: Locore.c,v 1.4 2000/06/08 06:48:45 kleink Exp $ */
/* $NetBSD: Locore.c,v 1.5 2003/01/18 06:23:32 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -46,23 +46,23 @@
* Calls should be made at splstatclock(), and p->p_stat should be SRUN.
*/
void
setrunqueue(p)
struct proc *p;
setrunqueue(l)
struct lwp *l;
{
struct prochd *q;
struct proc *oldlast;
int which = p->p_priority >> 2;
struct lwp *oldlast;
int which = l->l_priority >> 2;
#ifdef DIAGNOSTIC
if (p->p_back)
if (l->l_back)
panic("setrunqueue");
#endif
q = &sched_qs[which];
sched_whichqs |= 0x80000000 >> which;
p->p_forw = (struct proc *)q;
p->p_back = oldlast = q->ph_rlink;
q->ph_rlink = p;
oldlast->p_forw = p;
l->l_forw = (struct lwp *)q;
l->l_back = oldlast = q->ph_rlink;
q->ph_rlink = l;
oldlast->l_forw = l;
}
/*
@ -71,20 +71,20 @@ setrunqueue(p)
* Calls should be made at splstatclock().
*/
void
remrunqueue(p)
struct proc *p;
remrunqueue(l)
struct lwp *l;
{
int which = p->p_priority >> 2;
int which = l->l_priority >> 2;
struct prochd *q;
#ifdef DIAGNOSTIC
if (!(sched_whichqs & (0x80000000 >> which)))
panic("remrunqueue");
#endif
p->p_forw->p_back = p->p_back;
p->p_back->p_forw = p->p_forw;
p->p_back = NULL;
l->l_forw->l_back = l->l_back;
l->l_back->l_forw = l->l_forw;
l->l_back = NULL;
q = &sched_qs[which];
if (q->ph_link == (struct proc *)q)
if (q->ph_link == (struct lwp *)q)
sched_whichqs &= ~(0x80000000 >> which);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: compat_13_machdep.c,v 1.4 2002/09/25 22:21:18 thorpej Exp $ */
/* $NetBSD: compat_13_machdep.c,v 1.5 2003/01/18 06:23:32 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -38,17 +38,19 @@
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/mount.h>
#include <sys/sa.h>
#include <sys/syscallargs.h>
int
compat_13_sys_sigreturn(p, v, retval)
struct proc *p;
compat_13_sys_sigreturn(l, v, retval)
struct lwp *l;
void *v;
register_t *retval;
{
struct compat_13_sys_sigreturn_args /* {
syscallarg(struct sigcontext13 *) sigcntxp;
} */ *uap = v;
struct proc *p = l->l_proc;
struct sigcontext13 sc;
struct trapframe *tf;
int error;
@ -63,7 +65,7 @@ compat_13_sys_sigreturn(p, v, retval)
return (error);
/* Restore the register context. */
tf = trapframe(p);
tf = trapframe(l);
if ((sc.sc_frame.srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC))
return (EINVAL);
*tf = sc.sc_frame;

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_trace.c,v 1.22 2002/11/25 01:33:51 thorpej Exp $ */
/* $NetBSD: db_trace.c,v 1.23 2003/01/18 06:23:33 thorpej Exp $ */
/* $OpenBSD: db_trace.c,v 1.3 1997/03/21 02:10:48 niklas Exp $ */
/*
@ -133,6 +133,7 @@ db_stack_trace_print(addr, have_addr, count, modif, pr)
if (have_addr) {
if (trace_thread) {
struct proc *p;
struct lwp *l;
struct user *u;
(*pr)("trace: pid %d ", (int)addr);
@ -141,11 +142,12 @@ db_stack_trace_print(addr, have_addr, count, modif, pr)
(*pr)("not found\n");
return;
}
if (!(p->p_flag&P_INMEM)) {
l = proc_representative_lwp(p); /* XXX NJWLWP */
if ((l->l_flag & L_INMEM) == 0) {
(*pr)("swapped out\n");
return;
}
u = p->p_addr;
u = l->l_addr;
frame = (db_addr_t)u->u_pcb.pcb_sp;
(*pr)("at %p\n", frame);
} else

View File

@ -1,4 +1,4 @@
/* $NetBSD: fpu.c,v 1.7 2002/07/28 07:07:45 chs Exp $ */
/* $NetBSD: fpu.c,v 1.8 2003/01/18 06:23:33 thorpej Exp $ */
/*
* Copyright (C) 1996 Wolfgang Solfrank.
@ -45,9 +45,9 @@ void
enable_fpu(void)
{
struct cpu_info *ci = curcpu();
struct proc *p = curproc;
struct pcb *pcb = &p->p_addr->u_pcb;
struct trapframe *tf = trapframe(p);
struct lwp *l = curlwp;
struct pcb *pcb = &l->l_addr->u_pcb;
struct trapframe *tf = trapframe(l);
int msr;
KASSERT(pcb->pcb_fpcpu == NULL);
@ -58,10 +58,10 @@ enable_fpu(void)
msr = mfmsr();
mtmsr((msr & ~PSL_EE) | PSL_FP);
asm volatile ("isync");
if (ci->ci_fpuproc) {
if (ci->ci_fpulwp) {
save_fpu_cpu();
}
KASSERT(ci->ci_fpuproc == NULL);
KASSERT(ci->ci_fpulwp == NULL);
asm volatile ("lfd 0,0(%0); mtfsf 0xff,0" :: "b"(&pcb->pcb_fpu.fpscr));
asm ("lfd 0,0(%0);"
"lfd 1,8(%0);"
@ -97,7 +97,7 @@ enable_fpu(void)
"lfd 31,248(%0)" :: "b"(&pcb->pcb_fpu.fpr[0]));
asm volatile ("isync");
tf->srr1 |= PSL_FP;
ci->ci_fpuproc = p;
ci->ci_fpulwp = l;
pcb->pcb_fpcpu = ci;
asm volatile ("sync");
mtmsr(msr);
@ -110,18 +110,18 @@ void
save_fpu_cpu(void)
{
struct cpu_info *ci = curcpu();
struct proc *p;
struct lwp *l;
struct pcb *pcb;
int msr;
msr = mfmsr();
mtmsr((msr & ~PSL_EE) | PSL_FP);
__asm __volatile ("isync");
p = ci->ci_fpuproc;
if (p == NULL) {
l = ci->ci_fpulwp;
if (l == NULL) {
goto out;
}
pcb = &p->p_addr->u_pcb;
pcb = &l->l_addr->u_pcb;
asm ("stfd 0,0(%0);"
"stfd 1,8(%0);"
"stfd 2,16(%0);"
@ -157,7 +157,7 @@ save_fpu_cpu(void)
asm volatile ("mffs 0; stfd 0,0(%0)" :: "b"(&pcb->pcb_fpu.fpscr));
asm volatile ("sync");
pcb->pcb_fpcpu = NULL;
ci->ci_fpuproc = NULL;
ci->ci_fpulwp = NULL;
ci->ci_ev_fpusw.ev_count++;
asm volatile ("sync");
out:
@ -171,10 +171,10 @@ save_fpu_cpu(void)
* this function).
*/
void
save_fpu_proc(p)
struct proc *p;
save_fpu_lwp(l)
struct lwp *l;
{
struct pcb *pcb = &p->p_addr->u_pcb;
struct pcb *pcb = &l->l_addr->u_pcb;
struct cpu_info *ci = curcpu();
/*
@ -190,7 +190,7 @@ save_fpu_proc(p)
* state.
*/
if (p == ci->ci_fpuproc) {
if (l == ci->ci_fpulwp) {
save_fpu_cpu();
return;
}
@ -201,6 +201,6 @@ save_fpu_proc(p)
* It must be on another CPU, flush it from there.
*/
mp_save_fpu_proc(p);
mp_save_fpu_lwp(l);
#endif
}

View File

@ -1,4 +1,4 @@
# $NetBSD: genassym.cf,v 1.3 2002/05/19 18:56:55 augustss Exp $
# $NetBSD: genassym.cf,v 1.4 2003/01/18 06:23:33 thorpej Exp $
#
# Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -65,9 +65,12 @@ define PCB_FAULT offsetof(struct pcb, pcb_onfault)
define PM_USRSR offsetof(struct pmap, pm_sr[USER_SR])
define PM_KERNELSR offsetof(struct pmap, pm_sr[KERNEL_SR])
define P_FORW offsetof(struct proc, p_forw)
define P_BACK offsetof(struct proc, p_back)
define P_ADDR offsetof(struct proc, p_addr)
define L_FORW offsetof(struct lwp, l_forw)
define L_BACK offsetof(struct lwp, l_back)
define L_ADDR offsetof(struct lwp, l_addr)
define L_CPU offsetof(struct lwp, l_cpu)
define L_STAT offsetof(struct lwp, l_stat)
define L_PRIORITY offsetof(struct lwp, l_priority)
define SPLX offsetof(struct machvec, splx)

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_trap.c,v 1.1 2001/06/18 02:04:43 christos Exp $ */
/* $NetBSD: linux_trap.c,v 1.2 2003/01/18 06:23:33 thorpej Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -48,6 +48,6 @@
#include <compat/linux/common/linux_exec.h>
void
linux_trapsignal(struct proc *p, int signo, u_long type) {
trapsignal(p, signo, type);
linux_trapsignal(struct lwp *l, int signo, u_long type) {
trapsignal(l, signo, type);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore_subr.S,v 1.6 2002/12/19 19:37:26 thorpej Exp $ */
/* $NetBSD: locore_subr.S,v 1.7 2003/01/18 06:23:33 thorpej Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@ -80,6 +80,7 @@ GLOBAL(powersave)
.long -1
.text
.align 2
/*
* No processes are runnable, so loop waiting for one.
* Separate label here for accounting purposes.
@ -135,9 +136,10 @@ ASENTRY(Idle)
b _ASM_LABEL(Idle)
/*
* switchexit gets called from cpu_exit to complete the exit procedure.
* switch_exit(struct lwp *l, void (*exit)(struct lwp *))
* switch_exit gets called from cpu_exit to complete the exit procedure.
*/
ENTRY(switchexit)
ENTRY(switch_exit)
/* First switch to the idle pcb/kernel stack */
#if defined(MULTIPROCESSOR)
GET_CPUINFO(7)
@ -149,12 +151,16 @@ ENTRY(switchexit)
lis 7,_C_LABEL(curpcb)@ha
stw 6,_C_LABEL(curpcb)@l(7)
#endif
addi 1,6,USPACE-16 /* 16 bytes are reserved at stack top */
/*
* Adjust the stack to provide space for the callee to save LR.
*/
addi 1,6,USPACE-16
/*
* Schedule the vmspace and stack to be freed (the proc arg is
* already in r3).
* already in r3). Function to call is in r4.
*/
bl _C_LABEL(exit2)
mtctr 4
bctrl
#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
bl _C_LABEL(sched_lock_idle)
@ -164,7 +170,7 @@ ENTRY(switchexit)
li 3,0 /* indicate exited process */
/*
* void cpu_switch(struct proc *p)
* void cpu_switch(struct lwp *l)
* Find a runnable process and switch to it.
*/
ENTRY_NOPROFILE(cpu_switch)
@ -186,7 +192,7 @@ ENTRY_NOPROFILE(cpu_switch)
mr 12,2 /* save r2 */
stwu 1,-SFRAMELEN(1) /* still running on old stack */
stmw 10,8(1)
lwz 3,P_ADDR(30)
lwz 3,L_ADDR(30)
stw 1,PCB_SP(3) /* save SP */
lwz 6,CI_IDLE_PCB(7)
@ -194,15 +200,15 @@ ENTRY_NOPROFILE(cpu_switch)
1:
xor 31,31,31
stw 31,CI_CURPROC(7) /* Zero to not accumulate cpu time */
stw 31,CI_CURLWP(7) /* Zero to not accumulate cpu time */
lwz 31,CI_CURPCB(7)
lwz 3,CI_CPL(7)
stw 3,PCB_SPL(31) /* save spl */
#else
lis 3,_C_LABEL(curproc)@ha
lis 3,_C_LABEL(curlwp)@ha
xor 31,31,31
stw 31,_C_LABEL(curproc)@l(3) /* Zero to not accumulate cpu time */
stw 31,_C_LABEL(curlwp)@l(3) /* Zero to not accumulate cpu time */
lis 3,_C_LABEL(curpcb)@ha
lwz 31,_C_LABEL(curpcb)@l(3)
#endif
@ -246,10 +252,10 @@ ENTRY_NOPROFILE(cpu_switch)
slwi 3,10,3
add 3,3,4 /* select queue */
lwz 31,P_FORW(3) /* unlink first proc from queue */
lwz 4,P_FORW(31)
stw 4,P_FORW(3)
stw 3,P_BACK(4)
lwz 31,L_FORW(3) /* unlink first proc from queue */
lwz 4,L_FORW(31)
stw 4,L_FORW(3)
stw 3,L_BACK(4)
cmpl 0,3,4 /* queue empty? */
bne 1f
@ -259,6 +265,7 @@ ENTRY_NOPROFILE(cpu_switch)
andc 9,9,3
stw 9,_C_LABEL(sched_whichqs)@l(8) /* mark it empty */
switch_common:
1:
/* just did this resched thing */
xor 3,3,3
@ -270,31 +277,36 @@ ENTRY_NOPROFILE(cpu_switch)
stw 3,_C_LABEL(want_resched)@l(4)
#endif
stw 3,P_BACK(31) /* probably superfluous */
stw 3,L_BACK(31) /* probably superfluous */
#if defined(MULTIPROCESSOR)
GET_CPUINFO(4)
stw 4,P_CPU(31) /* p->p_cpu = curcpu() */
stw 4,L_CPU(31) /* l->l_cpu = curcpu() */
#else
lis 4,_C_LABEL(cpu_info_store)@ha
addi 4,4,_C_LABEL(cpu_info_store)@l
stw 4,L_CPU(31) /* l->l_cpu = &cpu_info_store */
#endif
/* Process now running on a processor. */
li 3,SONPROC /* p->p_stat = SONPROC */
stb 3,P_STAT(31)
li 3,LSONPROC /* l->l_stat = LSONPROC */
stw 3,L_STAT(31)
/* record new process */
#if defined(MULTIPROCESSOR)
stw 31,CI_CURPROC(4)
stw 31,CI_CURLWP(4)
#else
lis 4,_C_LABEL(curproc)@ha
stw 31,_C_LABEL(curproc)@l(4)
lis 4,_C_LABEL(curlwp)@ha
stw 31,_C_LABEL(curlwp)@l(4)
#endif
lwz 4,P_ADDR(31)
lwz 4,L_ADDR(31)
#if !defined(MULTIPROCESSOR) /* XXX */
cmpl 0,31,30 /* is it the same process? */
xor 3,3,3 /* if it is the same lwp, return 0 */
cmpl 0,31,30 /* is it the same lwp? */
beq switch_return
or. 30,30,30 /* old process was exiting? */
or. 30,30,30 /* old lwp was exiting? */
beq switch_exited
#if defined(PPC_IBM4XX)
@ -306,7 +318,7 @@ ENTRY_NOPROFILE(cpu_switch)
mr 12,2 /* save r2 */
stwu 1,-SFRAMELEN(1) /* still running on old stack */
stmw 10,8(1)
lwz 3,P_ADDR(30)
lwz 3,L_ADDR(30)
stw 1,PCB_SP(3) /* save SP */
switch_exited:
@ -348,7 +360,10 @@ switch_exited:
isync
#endif
li 3,1 /* switched lwps */
switch_return:
mr 30,3 /* save return value */
#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
/* Unlock the sched_lock, but leave interrupts off, for now. */
bl _C_LABEL(sched_unlock_idle)
@ -362,7 +377,6 @@ switch_return:
mtmsr 3
#endif
mr 30,7 /* save proc pointer */
lwz 3,PCB_SPL(4)
bl _C_LABEL(lcsplx)
@ -373,16 +387,14 @@ switch_return:
lwz 4,PM_CTX(3)
cmpwi 4,0
# mtspr SPR_SPR0,4 /* Always keep the current ctx here */
mr 3,30
mr 3,30 /* restore return value */
bne 1f
bl _C_LABEL(ctx_alloc)
mr 3,30 /* get curproc for special fork
returns */
mr 3,30 /* restore return value */
b 0b /* reload */
1:
#else /* PPC_MPC6XX */
mr 3,30 /* get curproc for special fork
returns */
mr 3,30 /* restore return value */
#endif
lwz 31,12(1)
@ -392,6 +404,92 @@ switch_return:
mtlr 0
blr
/*
* void
* cpu_switchto(struct lwp *current, struct lwp *new)
* Variant of cpu_switch, but instead of picking a new LWP from the run
* queue, switch to the indicated new LWP.
* r3 - current LWP
* r4 - LWP to switch to
*/
ENTRY(cpu_switchto)
mflr 0 /* save lr */
stw 0,4(1)
stwu 1,-16(1)
stw 31,12(1)
stw 30,8(1)
stwu 1,-16(1)
stw 29,8(1)
mr 30,3 /* r30 = curlwp */
mr 29,4 /* r29 = newlwp */
#if defined(MULTIPROCESSOR)
/* Switch to the idle PCB unless we're already running on it. */
GET_CPUINFO(7)
cmpwi 30,0 /* old process was exiting? */
beq 1f
mfsr 10,USER_SR /* save USER_SR for copyin/copyout */
mfcr 11 /* save cr */
mr 12,2 /* save r2 */
stwu 1,-SFRAMELEN(1) /* still running on old stack */
stmw 10,8(1)
lwz 3,L_ADDR(30)
stw 1,PCB_SP(3) /* save SP */
lwz 6,CI_IDLE_PCB(7)
addi 1,6,USPACE-16 /* 16 bytes are reserved at stack top */
1:
xor 31,31,31
stw 31,CI_CURLWP(7) /* Zero to not accumulate cpu time */
lwz 31,CI_CURPCB(7)
lwz 3,CI_CPL(7)
stw 3,PCB_SPL(31) /* save spl */
#else
lis 3,_C_LABEL(curlwp)@ha
xor 31,31,31
stw 31,_C_LABEL(curlwp)@l(3) /* Zero to not accumulate cpu time */
lis 3,_C_LABEL(curpcb)@ha
lwz 31,_C_LABEL(curpcb)@l(3)
#endif
#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
/* Release the sched_lock before processing interrupts. */
bl _C_LABEL(sched_unlock_idle)
#endif
xor 3,3,3
bl _C_LABEL(lcsplx)
#if !defined(MULTIPROCESSOR)
stw 3,PCB_SPL(31) /* save spl */
#endif
/* Lock the scheduler. */
#if defined(PPC_IBM4XX)
wrteei 0 /* disable interrupts while
manipulating runque */
#else /* PPC_MPC6XX */
mfmsr 3
andi. 3,3,~PSL_EE@l /* disable interrupts while
manipulating runque */
mtmsr 3
isync
#endif
#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
bl _C_LABEL(sched_lock_idle)
#endif
/* Make stack normal, r31 newlwp, r30 oldlwp */
mr 31,29
lwz 29,8(1)
addi 1,1,16
b switch_common
/* NOTREACHED */
/*
* Child comes here at the end of a fork.
* Return to userspace via the trap return path.

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.c,v 1.50 2002/10/10 22:37:51 matt Exp $ */
/* $NetBSD: pmap.c,v 1.51 2003/01/18 06:23:33 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -1489,11 +1489,11 @@ next:
* is the current process, load the new MMU context.
*/
void
pmap_activate(p)
struct proc *p;
pmap_activate(l)
struct lwp *l;
{
struct pcb *pcb = &p->p_addr->u_pcb;
pmap_t pmap = p->p_vmspace->vm_map.pmap, rpm;
struct pcb *pcb = &l->l_addr->u_pcb;
pmap_t pmap = l->l_proc->p_vmspace->vm_map.pmap, rpm;
int psl, i, seg;
/*
@ -1505,7 +1505,7 @@ pmap_activate(p)
(paddr_t *)&pcb->pcb_pmreal);
}
if (p == curproc) {
if (l == curlwp) {
/* Disable interrupts while switching. */
__asm __volatile("mfmsr %0" : "=r"(psl) :);
psl &= ~PSL_EE;
@ -1538,8 +1538,8 @@ pmap_activate(p)
* Deactivate the specified process's address space.
*/
void
pmap_deactivate(p)
struct proc *p;
pmap_deactivate(l)
struct lwp *l;
{
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: powerpc_machdep.c,v 1.14 2002/09/06 13:18:43 gehenna Exp $ */
/* $NetBSD: powerpc_machdep.c,v 1.15 2003/01/18 06:23:34 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -37,7 +37,13 @@
#include <sys/conf.h>
#include <sys/disklabel.h>
#include <sys/exec.h>
#include <sys/pool.h>
#include <sys/proc.h>
#include <sys/sa.h>
#include <sys/savar.h>
#include <sys/signal.h>
#include <sys/sysctl.h>
#include <sys/ucontext.h>
#include <sys/user.h>
int cpu_timebase;
@ -46,16 +52,19 @@ int cpu_printfataltraps;
extern int powersave;
#endif
extern struct pool siginfo_pool;
/*
* Set set up registers on exec.
*/
void
setregs(p, pack, stack)
struct proc *p;
setregs(l, pack, stack)
struct lwp *l;
struct exec_package *pack;
u_long stack;
{
struct trapframe *tf = trapframe(p);
struct proc *p = l->l_proc;
struct trapframe *tf = trapframe(l);
struct ps_strings arginfo;
memset(tf, 0, sizeof *tf);
@ -93,7 +102,7 @@ setregs(p, pack, stack)
#ifdef ALTIVEC
tf->vrsave = 0;
#endif
p->p_addr->u_pcb.pcb_flags = 0;
l->l_addr->u_pcb.pcb_flags = 0;
}
/*
@ -191,3 +200,25 @@ cpu_dumpconf()
if (dumplo < nblks - ctod(dumpsize))
dumplo = nblks - ctod(dumpsize);
}
void
cpu_upcall(struct lwp *l, int type, int nevents, int ninterrupted, void *sas, void *ap, void *sp, sa_upcall_t upcall)
{
struct trapframe *tf;
tf = trapframe(l);
/*
* Build context to run handler in.
*/
tf->fixreg[1] = (int)((struct saframe *)sp - 1);
tf->lr = 0;
tf->fixreg[3] = (int)type;
tf->fixreg[4] = (int)sas;
tf->fixreg[5] = (int)nevents;
tf->fixreg[6] = (int)ninterrupted;
tf->fixreg[7] = (int)ap;
tf->srr0 = (int)upcall;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: process_machdep.c,v 1.9 2002/07/28 07:07:45 chs Exp $ */
/* $NetBSD: process_machdep.c,v 1.10 2003/01/18 06:23:34 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -42,11 +42,11 @@
#include <machine/reg.h>
int
process_read_regs(p, regs)
struct proc *p;
process_read_regs(l, regs)
struct lwp *l;
struct reg *regs;
{
struct trapframe *tf = trapframe(p);
struct trapframe *tf = trapframe(l);
memcpy(regs->fixreg, tf->fixreg, sizeof(regs->fixreg));
regs->lr = tf->lr;
@ -59,11 +59,11 @@ process_read_regs(p, regs)
}
int
process_write_regs(p, regs)
struct proc *p;
process_write_regs(l, regs)
struct lwp *l;
struct reg *regs;
{
struct trapframe *tf = trapframe(p);
struct trapframe *tf = trapframe(l);
memcpy(tf->fixreg, regs->fixreg, sizeof(regs->fixreg));
tf->lr = regs->lr;
@ -76,11 +76,11 @@ process_write_regs(p, regs)
}
int
process_read_fpregs(p, regs)
struct proc *p;
process_read_fpregs(l, regs)
struct lwp *l;
struct fpreg *regs;
{
struct pcb *pcb = &p->p_addr->u_pcb;
struct pcb *pcb = &l->l_addr->u_pcb;
/* Is the process using the fpu? */
if ((pcb->pcb_flags & PCB_FPU) == 0) {
@ -89,7 +89,7 @@ process_read_fpregs(p, regs)
}
#ifdef PPC_HAVE_FPU
save_fpu_proc(p);
save_fpu_lwp(l);
#endif
memcpy(regs, &pcb->pcb_fpu, sizeof (struct fpreg));
@ -97,14 +97,14 @@ process_read_fpregs(p, regs)
}
int
process_write_fpregs(p, regs)
struct proc *p;
process_write_fpregs(l, regs)
struct lwp *l;
struct fpreg *regs;
{
struct pcb *pcb = &p->p_addr->u_pcb;
struct pcb *pcb = &l->l_addr->u_pcb;
#ifdef PPC_HAVE_FPU
save_fpu_proc(p);
save_fpu_lwp(l);
#endif
memcpy(&pcb->pcb_fpu, regs, sizeof(struct fpreg));
@ -119,22 +119,22 @@ process_write_fpregs(p, regs)
* Set the process's program counter.
*/
int
process_set_pc(p, addr)
struct proc *p;
process_set_pc(l, addr)
struct lwp *l;
caddr_t addr;
{
struct trapframe *tf = trapframe(p);
struct trapframe *tf = trapframe(l);
tf->srr0 = (int)addr;
return 0;
}
int
process_sstep(p, sstep)
struct proc *p;
process_sstep(l, sstep)
struct lwp *l;
int sstep;
{
struct trapframe *tf = trapframe(p);
struct trapframe *tf = trapframe(l);
if (sstep)
tf->srr1 |= PSL_SE;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sig_machdep.c,v 1.7 2002/07/04 23:32:06 thorpej Exp $ */
/* $NetBSD: sig_machdep.c,v 1.8 2003/01/18 06:23:34 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -32,14 +32,20 @@
*/
#include "opt_compat_netbsd.h"
#include "opt_ppcarch.h"
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/proc.h>
#include <sys/sa.h>
#include <sys/savar.h>
#include <sys/syscallargs.h>
#include <sys/systm.h>
#include <sys/ucontext.h>
#include <sys/user.h>
#include <machine/fpu.h>
/*
* Send a signal to process.
*/
@ -49,14 +55,15 @@ sendsig(sig, mask, code)
sigset_t *mask;
u_long code;
{
struct proc *p = curproc;
struct lwp *l = curlwp;
struct proc *p = l->l_proc;
struct sigacts *ps = p->p_sigacts;
struct trapframe *tf;
struct sigframe *fp, frame;
int onstack;
sig_t catcher = SIGACTION(p, sig).sa_handler;
tf = trapframe(p);
tf = trapframe(l);
/* Do we need to jump onto the signal stack? */
onstack =
@ -95,7 +102,7 @@ sendsig(sig, mask, code)
* Process has trashed its stack; give it an illegal
* instructoin to halt it in its tracks.
*/
sigexit(p, SIGILL);
sigexit(l, SIGILL);
/* NOTREACHED */
}
@ -126,7 +133,7 @@ sendsig(sig, mask, code)
default:
/* Don't know what trampoline version; kill it. */
sigexit(p, SIGILL);
sigexit(l, SIGILL);
}
/* Remember that we're now on the signal stack. */
@ -138,14 +145,15 @@ sendsig(sig, mask, code)
* System call to cleanup state after a signal handler returns.
*/
int
sys___sigreturn14(p, v, retval)
struct proc *p;
sys___sigreturn14(l, v, retval)
struct lwp *l;
void *v;
register_t *retval;
{
struct sys___sigreturn14_args /* {
syscallarg(struct sigcontext *) sigcntxp;
} */ *uap = v;
struct proc *p = l->l_proc;
struct sigcontext sc;
struct trapframe *tf;
int error;
@ -159,7 +167,7 @@ sys___sigreturn14(p, v, retval)
return (error);
/* Restore the register context. */
tf = trapframe(p);
tf = trapframe(l);
if ((sc.sc_frame.srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC))
return (EINVAL);
*tf = sc.sc_frame;
@ -175,3 +183,88 @@ sys___sigreturn14(p, v, retval)
return (EJUSTRETURN);
}
void
cpu_getmcontext(l, mcp, flagp)
struct lwp *l;
mcontext_t *mcp;
unsigned int *flagp;
{
const struct trapframe *tf = trapframe(l);
struct __gregs *gr = (struct __gregs *)mcp->__gregs;
#ifdef PPC_HAVE_FPU
struct pcb *pcb = &l->l_addr->u_pcb;
#endif
/* Save GPR context. */
(void)memcpy(gr, &tf->fixreg, 32 * sizeof (gr->__r_r0)); /* GR0-31 */
gr->__r_cr = tf->cr;
gr->__r_lr = tf->lr;
gr->__r_pc = tf->srr0;
gr->__r_msr = tf->srr1;
gr->__r_ctr = tf->ctr;
gr->__r_xer = tf->xer;
gr->__r_mq = 0; /* For now. */
*flagp |= _UC_CPU;
#ifdef PPC_HAVE_FPU
/* Save FPR context, if any. */
if ((pcb->pcb_flags & PCB_FPU) != 0) {
/* If we're the FPU owner, dump its context to the PCB first. */
if (pcb->pcb_fpcpu)
save_fpu_lwp(l);
(void)memcpy(mcp->__fpregs.__fpu_regs, pcb->pcb_fpu.fpr,
sizeof (mcp->__fpregs.__fpu_regs));
mcp->__fpregs.__fpu_fpscr =
((int *)&pcb->pcb_fpu.fpscr)[_QUAD_LOWWORD];
mcp->__fpregs.__fpu_valid = 1;
*flagp |= _UC_FPU;
} else
#endif
mcp->__fpregs.__fpu_valid = 0;
/* No AltiVec support, for now. */
memset(&mcp->__vrf, 0, sizeof (mcp->__vrf));
}
int
cpu_setmcontext(l, mcp, flags)
struct lwp *l;
const mcontext_t *mcp;
unsigned int flags;
{
struct trapframe *tf = trapframe(l);
struct __gregs *gr = (struct __gregs *)mcp->__gregs;
#ifdef PPC_HAVE_FPU
struct pcb *pcb = &l->l_addr->u_pcb;
#endif
/* Restore GPR context, if any. */
if (flags & _UC_CPU) {
if ((gr->__r_msr & PSL_USERSTATIC) !=
(tf->srr1 & PSL_USERSTATIC))
return (EINVAL);
(void)memcpy(&tf->fixreg, gr, 32 * sizeof (gr->__r_r0));
tf->cr = gr->__r_cr;
tf->lr = gr->__r_lr;
tf->srr0 = gr->__r_pc;
tf->srr1 = gr->__r_msr;
tf->ctr = gr->__r_ctr;
tf->xer = gr->__r_xer;
/* unused = gr->__r_mq; */
}
#ifdef PPC_HAVE_FPU
/* Restore FPR context, if any. */
if ((flags & _UC_FPU) && mcp->__fpregs.__fpu_valid != 0) {
/* XXX we don't need to save the state, just to drop it */
save_fpu_lwp(l);
(void)memcpy(&pcb->pcb_fpu.fpr, &mcp->__fpregs.__fpu_regs,
sizeof (pcb->pcb_fpu.fpr));
pcb->pcb_fpu.fpscr = *(double *)&mcp->__fpregs.__fpu_fpscr;
}
#endif
return (0);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: sys_machdep.c,v 1.3 2000/06/09 14:08:45 kleink Exp $ */
/* $NetBSD: sys_machdep.c,v 1.4 2003/01/18 06:23:34 thorpej Exp $ */
/*
* Copyright (C) 1996 Wolfgang Solfrank.
@ -34,11 +34,12 @@
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/sa.h>
#include <sys/syscallargs.h>
int
sys_sysarch(p, v, retval)
struct proc *p;
sys_sysarch(l, v, retval)
struct lwp *l;
void *v;
register_t *retval;
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: syscall.c,v 1.17 2002/12/21 16:23:56 manu Exp $ */
/* $NetBSD: syscall.c,v 1.18 2003/01/18 06:23:34 thorpej Exp $ */
/*
* Copyright (C) 2002 Matt Thomas
@ -42,6 +42,8 @@
#include <sys/reboot.h>
#include <sys/systm.h>
#include <sys/user.h>
#include <sys/sa.h>
#include <sys/savar.h>
#ifdef KTRACE
#include <sys/ktrace.h>
#endif
@ -65,31 +67,34 @@
#define EMULNAME(x) (x)
#define EMULNAMEU(x) (x)
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.17 2002/12/21 16:23:56 manu Exp $");
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.18 2003/01/18 06:23:34 thorpej Exp $");
void
child_return(void *arg)
{
struct proc * const p = arg;
struct trapframe * const tf = trapframe(p);
struct lwp * const l = arg;
#ifdef KTRACE
struct proc * const p = l->l_proc;
#endif
struct trapframe * const tf = trapframe(l);
KERNEL_PROC_UNLOCK(p);
KERNEL_PROC_UNLOCK(l);
tf->fixreg[FIRSTARG] = 0;
tf->fixreg[FIRSTARG + 1] = 1;
tf->cr &= ~0x10000000;
tf->srr1 &= ~(PSL_FP|PSL_VEC); /* Disable FP & AltiVec, as we can't
be them. */
p->p_addr->u_pcb.pcb_fpcpu = NULL;
l->l_addr->u_pcb.pcb_fpcpu = NULL;
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSRET)) {
KERNEL_PROC_LOCK(p);
KERNEL_PROC_LOCK(l);
ktrsysret(p, SYS_fork, 0, 0);
KERNEL_PROC_UNLOCK(p);
KERNEL_PROC_UNLOCK(l);
}
#endif
/* Profiling? XXX */
curcpu()->ci_schedstate.spc_curpriority = p->p_priority;
curcpu()->ci_schedstate.spc_curpriority = l->l_priority;
}
#endif
@ -98,7 +103,8 @@ static void EMULNAME(syscall_plain)(struct trapframe *);
void
EMULNAME(syscall_plain)(struct trapframe *frame)
{
struct proc *p = curproc;
struct lwp *l = curlwp;
struct proc *p = l->l_proc;
const struct sysent *callp;
size_t argsize;
register_t code;
@ -145,11 +151,11 @@ EMULNAME(syscall_plain)(struct trapframe *frame)
if (argsize > n * sizeof(register_t)) {
memcpy(args, params, n * sizeof(register_t));
KERNEL_PROC_LOCK(p);
KERNEL_PROC_LOCK(l);
error = copyin(MOREARGS(frame->fixreg[1]),
args + n,
argsize - n * sizeof(register_t));
KERNEL_PROC_UNLOCK(p);
KERNEL_PROC_UNLOCK(l);
if (error)
goto syscall_bad;
params = args;
@ -159,13 +165,13 @@ EMULNAME(syscall_plain)(struct trapframe *frame)
rval[1] = 0;
if ((callp->sy_flags & SYCALL_MPSAFE) == 0) {
KERNEL_PROC_LOCK(p);
KERNEL_PROC_LOCK(l);
}
error = (*callp->sy_call)(p, params, rval);
error = (*callp->sy_call)(l, params, rval);
if ((callp->sy_flags & SYCALL_MPSAFE) == 0) {
KERNEL_PROC_UNLOCK(p);
KERNEL_PROC_UNLOCK(l);
}
switch (error) {
@ -200,7 +206,7 @@ syscall_bad:
frame->cr |= 0x10000000;
break;
}
userret(p, frame);
userret(l, frame);
}
#if defined(KTRACE) || defined(SYSTRACE)
@ -209,7 +215,8 @@ static void EMULNAME(syscall_fancy)(struct trapframe *);
void
EMULNAME(syscall_fancy)(struct trapframe *frame)
{
struct proc *p = curproc;
struct lwp *l = curlwp;
struct proc *p = l->l_proc;
const struct sysent *callp;
size_t argsize;
register_t code;
@ -219,7 +226,7 @@ EMULNAME(syscall_fancy)(struct trapframe *frame)
int error;
int n;
KERNEL_PROC_LOCK(p);
KERNEL_PROC_LOCK(l);
curcpu()->ci_ev_scalls.ev_count++;
code = frame->fixreg[0];
@ -268,14 +275,14 @@ EMULNAME(syscall_fancy)(struct trapframe *frame)
params = args;
}
if ((error = trace_enter(p, code, realcode,
if ((error = trace_enter(l, code, realcode,
callp - code, params, rval)) != 0)
goto syscall_bad;
rval[0] = 0;
rval[1] = 0;
error = (*callp->sy_call)(p, params, rval);
error = (*callp->sy_call)(l, params, rval);
switch (error) {
case 0:
frame->fixreg[FIRSTARG] = rval[0];
@ -308,9 +315,9 @@ syscall_bad:
frame->cr |= 0x10000000;
break;
}
KERNEL_PROC_UNLOCK(p);
trace_exit(p, realcode, params, rval, error);
userret(p, frame);
KERNEL_PROC_UNLOCK(l);
trace_exit(l, realcode, params, rval, error);
userret(l, frame);
}
#endif /* KTRACE || SYSTRACE */
@ -333,4 +340,3 @@ EMULNAME(syscall_intern)(struct proc *p)
#endif
p->p_md.md_syscall = EMULNAME(syscall_plain);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.74 2002/11/25 02:07:37 thorpej Exp $ */
/* $NetBSD: trap.c,v 1.75 2003/01/18 06:23:35 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -36,8 +36,11 @@
#include "opt_multiprocessor.h"
#include <sys/param.h>
#include <sys/pool.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/sa.h>
#include <sys/savar.h>
#include <sys/systm.h>
#include <sys/user.h>
@ -62,7 +65,7 @@ volatile int astpending;
volatile int want_resched;
#endif
static int fix_unaligned __P((struct proc *p, struct trapframe *frame));
static int fix_unaligned __P((struct lwp *l, struct trapframe *frame));
static inline void setusr __P((int));
void trap __P((struct trapframe *)); /* Called from locore / trap_subr */
@ -75,7 +78,8 @@ void
trap(struct trapframe *frame)
{
struct cpu_info * const ci = curcpu();
struct proc *p = curproc;
struct lwp *l = curlwp;
struct proc *p = l ? l->l_proc : NULL;
struct pcb *pcb = curpcb;
struct vm_map *map;
int type = frame->exc;
@ -98,10 +102,10 @@ trap(struct trapframe *frame)
case EXC_RUNMODETRC|EXC_USER:
/* FALLTHROUGH */
case EXC_TRC|EXC_USER:
KERNEL_PROC_LOCK(p);
KERNEL_PROC_LOCK(l);
frame->srr1 &= ~PSL_SE;
trapsignal(p, SIGTRAP, EXC_TRC);
KERNEL_PROC_UNLOCK(p);
trapsignal(l, SIGTRAP, EXC_TRC);
KERNEL_PROC_UNLOCK(l);
break;
case EXC_DSI: {
faultbuf *fb;
@ -133,13 +137,13 @@ trap(struct trapframe *frame)
va &= ADDR_PIDX | ADDR_POFF;
va |= user_sr << ADDR_SR_SHFT;
map = &p->p_vmspace->vm_map;
/* KERNEL_PROC_LOCK(p); */
/* KERNEL_PROC_LOCK(l); */
if ((frame->dsisr & DSISR_NOTFOUND) &&
vm_map_pmap(map)->pm_evictions > 0 &&
pmap_pte_spill(vm_map_pmap(map),
trunc_page(va))) {
/* KERNEL_PROC_UNLOCK(p); */
/* KERNEL_PROC_UNLOCK(l); */
KERNEL_UNLOCK();
return;
}
@ -159,7 +163,7 @@ trap(struct trapframe *frame)
*/
if (rv == 0)
uvm_grow(p, trunc_page(va));
/* KERNEL_PROC_UNLOCK(p); */
/* KERNEL_PROC_UNLOCK(l); */
}
KERNEL_UNLOCK();
if (rv == 0)
@ -189,7 +193,7 @@ trap(struct trapframe *frame)
goto brain_damage2;
}
case EXC_DSI|EXC_USER:
KERNEL_PROC_LOCK(p);
KERNEL_PROC_LOCK(l);
ci->ci_ev_udsi.ev_count++;
if (frame->dsisr & DSISR_STORE)
ftype = VM_PROT_WRITE;
@ -204,7 +208,7 @@ trap(struct trapframe *frame)
if ((frame->dsisr & DSISR_NOTFOUND) &&
vm_map_pmap(map)->pm_evictions > 0 &&
pmap_pte_spill(vm_map_pmap(map), trunc_page(frame->dar))) {
KERNEL_PROC_UNLOCK(p);
KERNEL_PROC_UNLOCK(l);
break;
}
@ -214,7 +218,7 @@ trap(struct trapframe *frame)
* Record any stack growth...
*/
uvm_grow(p, trunc_page(frame->dar));
KERNEL_PROC_UNLOCK(p);
KERNEL_PROC_UNLOCK(l);
break;
}
ci->ci_ev_udsi_fatal.ev_count++;
@ -226,16 +230,16 @@ trap(struct trapframe *frame)
frame->dar, frame->srr0, frame->dsisr, rv);
}
if (rv == ENOMEM) {
printf("UVM: pid %d (%s), uid %d killed: "
printf("UVM: pid %d (%s) lid %d, uid %d killed: "
"out of swap\n",
p->p_pid, p->p_comm,
p->p_pid, p->p_comm, l->l_lid,
p->p_cred && p->p_ucred ?
p->p_ucred->cr_uid : -1);
trapsignal(p, SIGKILL, EXC_DSI);
trapsignal(l, SIGKILL, EXC_DSI);
} else {
trapsignal(p, SIGSEGV, EXC_DSI);
trapsignal(l, SIGSEGV, EXC_DSI);
}
KERNEL_PROC_UNLOCK(p);
KERNEL_PROC_UNLOCK(l);
break;
case EXC_ISI:
@ -244,7 +248,7 @@ trap(struct trapframe *frame)
goto brain_damage2;
case EXC_ISI|EXC_USER:
KERNEL_PROC_LOCK(p);
KERNEL_PROC_LOCK(l);
ci->ci_ev_isi.ev_count++;
/*
* Try to spill an evicted pte into the page table
@ -255,37 +259,37 @@ trap(struct trapframe *frame)
if ((frame->srr1 & DSISR_NOTFOUND) &&
vm_map_pmap(map)->pm_evictions > 0 &&
pmap_pte_spill(vm_map_pmap(map), trunc_page(frame->srr0))) {
KERNEL_PROC_UNLOCK(p);
KERNEL_PROC_UNLOCK(l);
break;
}
ftype = VM_PROT_READ | VM_PROT_EXECUTE;
rv = uvm_fault(map, trunc_page(frame->srr0), 0, ftype);
if (rv == 0) {
KERNEL_PROC_UNLOCK(p);
KERNEL_PROC_UNLOCK(l);
break;
}
ci->ci_ev_isi_fatal.ev_count++;
if (cpu_printfataltraps) {
printf("trap: pid %d (%s): user ISI trap @ %#x "
"(SSR1=%#x)\n",
p->p_pid, p->p_comm, frame->srr0, frame->srr1);
printf("trap: pid %d (%s) lid %d: user ISI trap @ %#x "
"(SSR1=%#x)\n", p->p_pid, p->p_comm, l->l_lid,
frame->srr0, frame->srr1);
}
trapsignal(p, SIGSEGV, EXC_ISI);
KERNEL_PROC_UNLOCK(p);
trapsignal(l, SIGSEGV, EXC_ISI);
KERNEL_PROC_UNLOCK(l);
break;
case EXC_FPU|EXC_USER:
ci->ci_ev_fpu.ev_count++;
if (pcb->pcb_fpcpu) {
save_fpu_proc(p);
save_fpu_lwp(l);
}
enable_fpu();
break;
case EXC_AST|EXC_USER:
astpending = 0; /* we are about to do it */
KERNEL_PROC_LOCK(p);
KERNEL_PROC_LOCK(l);
uvmexp.softs++;
if (p->p_flag & P_OWEUPC) {
p->p_flag &= ~P_OWEUPC;
@ -293,25 +297,25 @@ trap(struct trapframe *frame)
}
/* Check whether we are being preempted. */
if (want_resched)
preempt(NULL);
KERNEL_PROC_UNLOCK(p);
preempt(0);
KERNEL_PROC_UNLOCK(l);
break;
case EXC_ALI|EXC_USER:
KERNEL_PROC_LOCK(p);
KERNEL_PROC_LOCK(l);
ci->ci_ev_ali.ev_count++;
if (fix_unaligned(p, frame) != 0) {
if (fix_unaligned(l, frame) != 0) {
ci->ci_ev_ali_fatal.ev_count++;
if (cpu_printfataltraps) {
printf("trap: pid %d (%s): user ALI @ %#x "
printf("trap: pid %d.%d (%s): user ALI @ %#x "
"by %#x (DSISR %#x)\n",
p->p_pid, p->p_comm,
p->p_pid, l->l_lid, p->p_comm,
frame->dar, frame->srr0, frame->dsisr);
}
trapsignal(p, SIGBUS, EXC_ALI);
trapsignal(l, SIGBUS, EXC_ALI);
} else
frame->srr0 += 4;
KERNEL_PROC_UNLOCK(p);
KERNEL_PROC_UNLOCK(l);
break;
case EXC_PERF|EXC_USER:
@ -320,44 +324,44 @@ trap(struct trapframe *frame)
ci->ci_ev_vec.ev_count++;
#ifdef ALTIVEC
if (pcb->pcb_veccpu)
save_vec_proc(p);
save_vec_lwp(l);
enable_vec();
break;
#else
KERNEL_PROC_LOCK(p);
KERNEL_PROC_LOCK(l);
if (cpu_printfataltraps) {
printf("trap: pid %d (%s): user VEC trap @ %#x "
"(SSR1=%#x)\n",
p->p_pid, p->p_comm, frame->srr0, frame->srr1);
}
trapsignal(p, SIGILL, EXC_PGM);
KERNEL_PROC_UNLOCK(p);
trapsignal(l, SIGILL, EXC_PGM);
KERNEL_PROC_UNLOCK(l);
break;
#endif
case EXC_MCHK|EXC_USER:
ci->ci_ev_umchk.ev_count++;
KERNEL_PROC_LOCK(p);
KERNEL_PROC_LOCK(l);
if (cpu_printfataltraps) {
printf("trap: pid %d (%s): user MCHK trap @ %#x "
"(SSR1=%#x)\n",
p->p_pid, p->p_comm, frame->srr0, frame->srr1);
}
trapsignal(p, SIGBUS, EXC_PGM);
KERNEL_PROC_UNLOCK(p);
trapsignal(l, SIGBUS, EXC_PGM);
KERNEL_PROC_UNLOCK(l);
case EXC_PGM|EXC_USER:
ci->ci_ev_pgm.ev_count++;
KERNEL_PROC_LOCK(p);
KERNEL_PROC_LOCK(l);
if (cpu_printfataltraps) {
printf("trap: pid %d (%s): user PGM trap @ %#x "
"(SSR1=%#x)\n",
p->p_pid, p->p_comm, frame->srr0, frame->srr1);
printf("trap: pid %d (%s) lid %d: user PGM trap @ %#x "
"(SSR1=%#x)\n", p->p_pid, p->p_comm, l->l_lid,
frame->srr0, frame->srr1);
}
if (frame->srr1 & 0x00020000) /* Bit 14 is set if trap */
trapsignal(p, SIGTRAP, EXC_PGM);
trapsignal(l, SIGTRAP, EXC_PGM);
else
trapsignal(p, SIGILL, EXC_PGM);
KERNEL_PROC_UNLOCK(p);
trapsignal(l, SIGILL, EXC_PGM);
KERNEL_PROC_UNLOCK(l);
break;
case EXC_MCHK: {
@ -392,7 +396,7 @@ brain_damage2:
#endif
panic("trap");
}
userret(p, frame);
userret(l, frame);
}
static inline void
@ -560,8 +564,8 @@ badaddr_read(addr, size, rptr)
*/
static int
fix_unaligned(p, frame)
struct proc *p;
fix_unaligned(l, frame)
struct lwp *l;
struct trapframe *frame;
{
int indicator = EXC_ALI_OPCODE_INDICATOR(frame->dsisr);
@ -598,7 +602,7 @@ fix_unaligned(p, frame)
* the PCB.
*/
save_fpu_proc(p);
save_fpu_lwp(l);
enable_fpu();
save_fpu_cpu();
if (indicator == EXC_ALI_LFD) {
@ -709,3 +713,36 @@ copyoutstr(kaddr, udaddr, len, done)
}
return rv;
}
/*
* Start a new LWP
*/
void
startlwp(arg)
void *arg;
{
int err;
ucontext_t *uc = arg;
struct lwp *l = curlwp;
err = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
#if DIAGNOSTIC
if (err) {
printf("Error %d from cpu_setmcontext.", err);
}
#endif
pool_put(&lwp_uc_pool, uc);
upcallret((void *) l);
}
/*
* XXX This is a terrible name.
*/
void
upcallret(struct lwp *l)
{
struct trapframe *frame = trapframe(l);
userret(l, frame);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap_subr.S,v 1.29 2002/10/10 22:37:52 matt Exp $ */
/* $NetBSD: trap_subr.S,v 1.30 2003/01/18 06:23:35 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -725,8 +725,9 @@ s_sctrap:
isync
addi 3,1,8
/* Call the appropriate syscall handler: */
lis 4,_C_LABEL(curproc)@ha
lwz 4,_C_LABEL(curproc)@l(4)
lis 4,_C_LABEL(curlwp)@ha
lwz 4,_C_LABEL(curlwp)@l(4)
lwz 4,L_PROC@l(4)
lwz 4,P_MD_SYSCALL@l(4)
mtctr 4
bctrl

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap_subr_mp.S,v 1.8 2002/10/10 22:44:21 matt Exp $ */
/* $NetBSD: trap_subr_mp.S,v 1.9 2003/01/18 06:23:35 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -685,7 +685,8 @@ s_sctrap:
addi 3,1,8
/* Call the appropriate syscall handler: */
GET_CPUINFO(4)
lwz 4,CI_CURPROC(4)
lwz 4,CI_CURLWP(4)
lwz 4,L_PROC(4)
lwz 4,P_MD_SYSCALL(4)
mtctr 4
bctrl

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.43 2002/08/11 02:17:30 matt Exp $ */
/* $NetBSD: vm_machdep.c,v 1.44 2003/01/18 06:23:36 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -57,16 +57,16 @@ void vunmaprange(vaddr_t, vsize_t);
#endif
/*
* Finish a fork operation, with process p2 nearly set up.
* Finish a fork operation, with execution context l2 nearly set up.
* Copy and update the pcb and trap frame, making the child ready to run.
*
* Rig the child's kernel stack so that it will start out in
* fork_trampoline() and call child_return() with p2 as an
* fork_trampoline() and call child_return() with l2 as an
* argument. This causes the newly-created child process to go
* directly to user level with an apparent return value of 0 from
* fork(), while the parent process returns normally.
*
* p1 is the process being forked; if p1 == &proc0, we are creating
* l1 is the execution context being forked; if l1 == &lwp0, we are creating
* a kernel thread, and the return path and argument are specified with
* `func' and `arg'.
*
@ -75,8 +75,8 @@ void vunmaprange(vaddr_t, vsize_t);
* accordingly.
*/
void
cpu_fork(p1, p2, stack, stacksize, func, arg)
struct proc *p1, *p2;
cpu_lwp_fork(l1, l2, stack, stacksize, func, arg)
struct lwp *l1, *l2;
void *stack;
size_t stacksize;
void (*func)(void *);
@ -87,30 +87,30 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
struct switchframe *sf;
caddr_t stktop1, stktop2;
void fork_trampoline(void);
struct pcb *pcb = &p2->p_addr->u_pcb;
struct pcb *pcb = &l2->l_addr->u_pcb;
#ifdef DIAGNOSTIC
/*
* if p1 != curproc && p1 == &proc0, we're creating a kernel thread.
* if p1 != curlwp && p1 == &proc0, we're creating a kernel thread.
*/
if (p1 != curproc && p1 != &proc0)
panic("cpu_fork: curproc");
if (l1 != curlwp && l1 != &lwp0)
panic("cpu_lwp_fork: curlwp");
#endif
#ifdef PPC_HAVE_FPU
if (p1->p_addr->u_pcb.pcb_fpcpu)
save_fpu_proc(p1);
if (l1->l_addr->u_pcb.pcb_fpcpu)
save_fpu_lwp(l1);
#endif
*pcb = p1->p_addr->u_pcb;
*pcb = l1->l_addr->u_pcb;
#ifdef ALTIVEC
if (p1->p_addr->u_pcb.pcb_vr != NULL) {
save_vec_proc(p1);
if (l1->l_addr->u_pcb.pcb_vr != NULL) {
save_vec_lwp(l1);
pcb->pcb_vr = pool_get(&vecpool, PR_WAITOK);
*pcb->pcb_vr = *p1->p_addr->u_pcb.pcb_vr;
*pcb->pcb_vr = *l1->l_addr->u_pcb.pcb_vr;
}
#endif
pcb->pcb_pm = p2->p_vmspace->vm_map.pmap;
pcb->pcb_pm = l2->l_proc->p_vmspace->vm_map.pmap;
#ifndef OLDPMAP
pcb->pcb_pmreal = pcb->pcb_pm; /* XXX */
#else
@ -121,19 +121,26 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
/*
* Setup the trap frame for the new process
*/
stktop1 = (caddr_t)trapframe(p1);
stktop2 = (caddr_t)trapframe(p2);
stktop1 = (caddr_t)trapframe(l1);
stktop2 = (caddr_t)trapframe(l2);
memcpy(stktop2, stktop1, sizeof(struct trapframe));
/*
* If specified, give the child a different stack.
*/
if (stack != NULL) {
tf = trapframe(p2);
tf = trapframe(l2);
tf->fixreg[1] = (register_t)stack + stacksize;
}
stktop2 = (caddr_t)((u_long)stktop2 & ~15); /* Align stack pointer */
/*
* Align stack pointer
* Since sizeof(struct trapframe) is 41 words, this will
* give us 12 bytes on the stack, which pad us somewhat
* for an extra call frame (or at least space for callee
* to store LR).
*/
stktop2 = (caddr_t)((u_long)stktop2 & ~15);
/*
* There happens to be a callframe, too.
@ -164,10 +171,41 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
}
void
cpu_swapin(p)
struct proc *p;
cpu_setfunc(l, func, arg)
struct lwp *l;
void (*func) __P((void *));
void *arg;
{
struct pcb *pcb = &p->p_addr->u_pcb;
extern void fork_trampoline(void);
struct pcb *pcb = &l->l_addr->u_pcb;
struct trapframe *tf;
struct callframe *cf;
struct switchframe *sf;
caddr_t vaddr;
tf = trapframe(l);
cf = (struct callframe *) ((u_long)tf & ~15);
cf->lr = (register_t) fork_trampoline;
cf--;
cf->r31 = (register_t) func;
cf->r30 = (register_t) arg;
vaddr = (unsigned char *) cf;
vaddr -= roundup(sizeof *sf, 16);
sf = (struct switchframe *) vaddr;
memset((void *)sf, 0, sizeof *sf); /* just in case */
sf->sp = (register_t) cf;
#ifndef PPC_IBM4XX
sf->user_sr = pmap_kernel()->pm_sr[USER_SR]; /* again, just in case */
#endif
pcb->pcb_sp = (int)sf;
pcb->pcb_spl = 0;
}
void
cpu_swapin(l)
struct lwp *l;
{
struct pcb *pcb = &l->l_addr->u_pcb;
#ifndef OLDPMAP
pcb->pcb_pmreal = pcb->pcb_pm; /* XXX */
@ -207,21 +245,21 @@ pagemove(from, to, size)
* run.
*/
void
cpu_exit(p)
struct proc *p;
cpu_exit(struct lwp *l, int proc)
{
void switchexit(struct proc *); /* Defined in locore.S */
/* This is in locore_subr.S */
void switch_exit(struct lwp *, void (*)(struct lwp *));
#if defined(PPC_HAVE_FPU) || defined(ALTIVEC)
struct pcb *pcb = &p->p_addr->u_pcb;
struct pcb *pcb = &l->l_addr->u_pcb;
#endif
#ifdef PPC_HAVE_FPU
if (pcb->pcb_fpcpu) /* release the FPU */
save_fpu_proc(p);
save_fpu_lwp(l);
#endif
#ifdef ALTIVEC
if (pcb->pcb_veccpu) { /* release the AltiVEC */
save_vec_proc(p);
save_vec_lwp(l);
__asm __volatile("dssall;sync"); /* stop any streams */
/* XXX this stops streams on the current cpu, should be pcb->pcb_veccpu */
}
@ -230,22 +268,23 @@ cpu_exit(p)
#endif
splsched();
switchexit(p);
switch_exit(l, proc ? exit2 : lwp_exit2);
}
/*
* Write the machine-dependent part of a core dump.
*/
int
cpu_coredump(p, vp, cred, chdr)
struct proc *p;
cpu_coredump(l, vp, cred, chdr)
struct lwp *l;
struct vnode *vp;
struct ucred *cred;
struct core *chdr;
{
struct coreseg cseg;
struct md_coredump md_core;
struct pcb *pcb = &p->p_addr->u_pcb;
struct proc *p = l->l_proc;
struct pcb *pcb = &l->l_addr->u_pcb;
int error;
CORE_SETMAGIC(*chdr, COREMAGIC, MID_POWERPC, 0);
@ -253,11 +292,11 @@ cpu_coredump(p, vp, cred, chdr)
chdr->c_seghdrsize = ALIGN(sizeof cseg);
chdr->c_cpusize = sizeof md_core;
md_core.frame = *trapframe(p);
md_core.frame = *trapframe(l);
if (pcb->pcb_flags & PCB_FPU) {
#ifdef PPC_HAVE_FPU
if (p->p_addr->u_pcb.pcb_fpcpu)
save_fpu_proc(p);
if (l->l_addr->u_pcb.pcb_fpcpu)
save_fpu_lwp(l);
#endif
md_core.fpstate = pcb->pcb_fpu;
} else
@ -266,7 +305,7 @@ cpu_coredump(p, vp, cred, chdr)
#ifdef ALTIVEC
if (pcb->pcb_flags & PCB_ALTIVEC) {
if (pcb->pcb_veccpu)
save_vec_proc(p);
save_vec_lwp(l);
md_core.vstate = *pcb->pcb_vr;
} else
#endif

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.13 2002/11/26 23:30:22 lukem Exp $
# $NetBSD: Makefile,v 1.14 2003/01/18 06:25:24 thorpej Exp $
INCSDIR= /usr/include/prep
@ -13,7 +13,7 @@ INCS= ansi.h aout_machdep.h asm.h \
intr.h ipkdb.h \
kcore.h kgdb.h \
limits.h lock.h \
math.h mouse.h \
math.h mcontext.h mouse.h \
param.h pcb.h pio.h pmap.h pmc.h powerpc.h proc.h profile.h \
psl.h pte.h ptrace.h \
reg.h reloc.h \

View File

@ -0,0 +1,3 @@
/* $NetBSD: mcontext.h,v 1.2 2003/01/18 06:25:24 thorpej Exp $ */
#include <powerpc/mcontext.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.42 2002/09/25 22:21:18 thorpej Exp $ */
/* $NetBSD: machdep.c,v 1.43 2003/01/18 06:25:25 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -46,6 +46,7 @@
#include <sys/msgbuf.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/sa.h>
#include <sys/syscallargs.h>
#include <sys/syslog.h>
#include <sys/systm.h>

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.13 2002/11/26 23:30:28 lukem Exp $
# $NetBSD: Makefile,v 1.14 2003/01/18 06:26:40 thorpej Exp $
INCSDIR= /usr/include/sandpoint
@ -13,7 +13,7 @@ INCS= ansi.h aout_machdep.h asm.h \
intr.h ipkdb.h \
kcore.h kgdb.h \
limits.h lock.h \
math.h \
math.h mcontext.h \
param.h pcb.h pio.h pmap.h pmc.h powerpc.h proc.h profile.h psl.h \
ptrace.h \
reg.h reloc.h \

View File

@ -0,0 +1,3 @@
/* $NetBSD: mcontext.h,v 1.2 2003/01/18 06:26:39 thorpej Exp $ */
#include <powerpc/mcontext.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.21 2002/09/25 22:21:18 thorpej Exp $ */
/* $NetBSD: machdep.c,v 1.22 2003/01/18 06:26:41 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -51,6 +51,7 @@
#include <sys/msgbuf.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/sa.h>
#include <sys/syscallargs.h>
#include <sys/syslog.h>
#include <sys/sysctl.h>

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.4 2002/11/26 23:30:28 lukem Exp $
# $NetBSD: Makefile,v 1.5 2003/01/18 06:28:41 thorpej Exp $
INCSDIR= /usr/include/sbmips
@ -15,7 +15,7 @@ INCS= ansi.h aout_machdep.h asm.h \
int_const.h int_fmtio.h int_limits.h int_mwgwtypes.h int_types.h \
kcore.h kdbparam.h \
limits.h lock.h locore.h \
math.h mips_opcode.h \
math.h mcontext.h mips_opcode.h \
param.h pcb.h pmap.h pmc.h proc.h profile.h psl.h pte.h ptrace.h \
reg.h regdef.h regnum.h reloc.h \
setjmp.h signal.h stdarg.h \

View File

@ -0,0 +1,3 @@
/* $NetBSD: mcontext.h,v 1.2 2003/01/18 06:28:41 thorpej Exp $ */
#include <mips/mcontext.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.15 2002/11/12 00:49:08 simonb Exp $ */
/* $NetBSD: machdep.c,v 1.16 2003/01/18 06:28:42 thorpej Exp $ */
/*
* Copyright 2000, 2001
@ -76,6 +76,7 @@
#include <sys/user.h>
#include <sys/exec.h>
#include <sys/mount.h>
#include <sys/sa.h>
#include <sys/syscallargs.h>
#include <sys/kcore.h>
@ -318,9 +319,9 @@ mach_init(long fwhandle, long magic, long bootdata, long reserved)
* Allocate space for proc0's USPACE
*/
p0 = (caddr_t)pmap_steal_memory(USPACE, NULL, NULL);
proc0.p_addr = proc0paddr = (struct user *)p0;
proc0.p_md.md_regs = (struct frame *)(p0 + USPACE) - 1;
curpcb = &proc0.p_addr->u_pcb;
lwp0.l_addr = proc0paddr = (struct user *)p0;
lwp0.l_md.md_regs = (struct frame *)(p0 + USPACE) - 1;
curpcb = &lwp0.l_addr->u_pcb;
curpcb->pcb_context[11] = MIPS_INT_MASK | MIPS_SR_INT_IE; /* SR */
/*
@ -446,7 +447,7 @@ cpu_reboot(int howto, char *bootstr)
{
/* Take a snapshot before clobbering any registers. */
if (curproc)
if (curlwp)
savectx((struct user *)curpcb);
if (cold) {

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.12 2002/11/26 23:30:22 lukem Exp $
# $NetBSD: Makefile,v 1.13 2003/01/18 06:30:23 thorpej Exp $
INCSDIR= /usr/include/sgimips
@ -13,7 +13,7 @@ INCS= asm.h ansi.h aout_machdep.h autoconf.h \
intr.h \
kcore.h kdbparam.h \
limits.h lock.h locore.h \
math.h mips_opcode.h \
math.h mcontext.h mips_opcode.h \
param.h pci_machdep.h pcb.h pmap.h pmc.h proc.h profile.h psl.h pte.h \
ptrace.h \
reg.h regdef.h regnum.h reloc.h \

View File

@ -0,0 +1,3 @@
/* $NetBSD: mcontext.h,v 1.2 2003/01/18 06:30:23 thorpej Exp $ */
#include <mips/mcontext.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.49 2003/01/10 03:48:40 rafal Exp $ */
/* $NetBSD: machdep.c,v 1.50 2003/01/18 06:30:24 thorpej Exp $ */
/*
* Copyright (c) 2000 Soren S. Jorvang
@ -54,6 +54,7 @@
#include <sys/user.h>
#include <sys/exec.h>
#include <sys/mount.h>
#include <sys/sa.h>
#include <sys/syscallargs.h>
#include <sys/kcore.h>
@ -515,9 +516,9 @@ mach_init(argc, argv, magic, btinfo)
* Allocate space for proc0's USPACE.
*/
v = (caddr_t)uvm_pageboot_alloc(USPACE);
proc0.p_addr = proc0paddr = (struct user *)v;
proc0.p_md.md_regs = (struct frame *)(v + USPACE) - 1;
curpcb = &proc0.p_addr->u_pcb;
lwp0.l_addr = proc0paddr = (struct user *)v;
lwp0.l_md.md_regs = (struct frame *)(v + USPACE) - 1;
curpcb = &lwp0.l_addr->u_pcb;
curpcb->pcb_context[11] = MIPS_INT_MASK | MIPS_SR_INT_IE; /* SR */
/*
@ -643,7 +644,7 @@ cpu_reboot(howto, bootstr)
char *bootstr;
{
/* Take a snapshot before clobbering any registers. */
if (curproc)
if (curlwp)
savectx((struct user *)curpcb);
if (cold) {