diff --git a/sys/arch/powerpc/ibm4xx/pmap.c b/sys/arch/powerpc/ibm4xx/pmap.c index b8de24fa29b2..723a20ee8011 100644 --- a/sys/arch/powerpc/ibm4xx/pmap.c +++ b/sys/arch/powerpc/ibm4xx/pmap.c @@ -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) { } diff --git a/sys/arch/powerpc/ibm4xx/trap.c b/sys/arch/powerpc/ibm4xx/trap.c index dac536540238..e88154708ca3 100644 --- a/sys/arch/powerpc/ibm4xx/trap.c +++ b/sys/arch/powerpc/ibm4xx/trap.c @@ -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 #endif +#include +#include +#include #ifdef SYSTRACE #include #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; +} diff --git a/sys/arch/powerpc/ibm4xx/trap_subr.S b/sys/arch/powerpc/ibm4xx/trap_subr.S index 1414be6432ec..68d6bc01b591 100644 --- a/sys/arch/powerpc/ibm4xx/trap_subr.S +++ b/sys/arch/powerpc/ibm4xx/trap_subr.S @@ -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 diff --git a/sys/arch/powerpc/include/Makefile b/sys/arch/powerpc/include/Makefile index dcaaf862eb37..6cf9dba624db 100644 --- a/sys/arch/powerpc/include/Makefile +++ b/sys/arch/powerpc/include/Makefile @@ -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 \ diff --git a/sys/arch/powerpc/include/altivec.h b/sys/arch/powerpc/include/altivec.h index 5e757817ab72..1dee6caa82aa 100644 --- a/sys/arch/powerpc/include/altivec.h +++ b/sys/arch/powerpc/include/altivec.h @@ -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); diff --git a/sys/arch/powerpc/include/cpu.h b/sys/arch/powerpc/include/cpu.h index cc31cbd33ca1..a7fb1cb6b873 100644 --- a/sys/arch/powerpc/include/cpu.h +++ b/sys/arch/powerpc/include/cpu.h @@ -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; diff --git a/sys/arch/powerpc/include/fpu.h b/sys/arch/powerpc/include/fpu.h index c8cbc789429c..85b8e89f79c9 100644 --- a/sys/arch/powerpc/include/fpu.h +++ b/sys/arch/powerpc/include/fpu.h @@ -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 */ diff --git a/sys/arch/powerpc/include/frame.h b/sys/arch/powerpc/include/frame.h index f9dad423f380..7599bc6fcfd0 100644 --- a/sys/arch/powerpc/include/frame.h +++ b/sys/arch/powerpc/include/frame.h @@ -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 { diff --git a/sys/arch/powerpc/include/mcontext.h b/sys/arch/powerpc/include/mcontext.h new file mode 100644 index 000000000000..6370da1a5647 --- /dev/null +++ b/sys/arch/powerpc/include/mcontext.h @@ -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_ */ diff --git a/sys/arch/powerpc/include/proc.h b/sys/arch/powerpc/include/proc.h index dde003d0c56b..4c8a5deb4271 100644 --- a/sys/arch/powerpc/include/proc.h +++ b/sys/arch/powerpc/include/proc.h @@ -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 diff --git a/sys/arch/powerpc/include/signal.h b/sys/arch/powerpc/include/signal.h index accdc9944da9..d7dba5a0118e 100644 --- a/sys/arch/powerpc/include/signal.h +++ b/sys/arch/powerpc/include/signal.h @@ -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; }; diff --git a/sys/arch/powerpc/include/userret.h b/sys/arch/powerpc/include/userret.h index a18dfe6372d3..f0eeaad858da 100644 --- a/sys/arch/powerpc/include/userret.h +++ b/sys/arch/powerpc/include/userret.h @@ -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; } diff --git a/sys/arch/powerpc/mpc6xx/altivec.c b/sys/arch/powerpc/mpc6xx/altivec.c index 353a1a5f0c70..755b0b2247f9 100644 --- a/sys/arch/powerpc/mpc6xx/altivec.c +++ b/sys/arch/powerpc/mpc6xx/altivec.c @@ -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 #include +#include #include #include #include @@ -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 } diff --git a/sys/arch/powerpc/mpc6xx/genassym.cf b/sys/arch/powerpc/mpc6xx/genassym.cf index f08736a609fb..504b6e13010a 100644 --- a/sys/arch/powerpc/mpc6xx/genassym.cf +++ b/sys/arch/powerpc/mpc6xx/genassym.cf @@ -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) diff --git a/sys/arch/powerpc/mpc6xx/mpc6xx_machdep.c b/sys/arch/powerpc/mpc6xx/mpc6xx_machdep.c index 3e9d1c2b6086..6987b6e5debf 100644 --- a/sys/arch/powerpc/mpc6xx/mpc6xx_machdep.c +++ b/sys/arch/powerpc/mpc6xx/mpc6xx_machdep.c @@ -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 #include #include +#include #include #include #include @@ -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(); diff --git a/sys/arch/powerpc/mpc6xx/pmap.c b/sys/arch/powerpc/mpc6xx/pmap.c index 77cb9043ad78..2eab591bbd0f 100644 --- a/sys/arch/powerpc/mpc6xx/pmap.c +++ b/sys/arch/powerpc/mpc6xx/pmap.c @@ -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) { } diff --git a/sys/arch/powerpc/powerpc/Locore.c b/sys/arch/powerpc/powerpc/Locore.c index aab5af43eb02..e6ad93bd7435 100644 --- a/sys/arch/powerpc/powerpc/Locore.c +++ b/sys/arch/powerpc/powerpc/Locore.c @@ -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); } diff --git a/sys/arch/powerpc/powerpc/compat_13_machdep.c b/sys/arch/powerpc/powerpc/compat_13_machdep.c index 56c158523e38..06f10a6d6e42 100644 --- a/sys/arch/powerpc/powerpc/compat_13_machdep.c +++ b/sys/arch/powerpc/powerpc/compat_13_machdep.c @@ -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 #include #include +#include #include 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; diff --git a/sys/arch/powerpc/powerpc/db_trace.c b/sys/arch/powerpc/powerpc/db_trace.c index 00a09d439cdf..7663461f17c3 100644 --- a/sys/arch/powerpc/powerpc/db_trace.c +++ b/sys/arch/powerpc/powerpc/db_trace.c @@ -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 diff --git a/sys/arch/powerpc/powerpc/fpu.c b/sys/arch/powerpc/powerpc/fpu.c index c7d85e12a048..91456d80292d 100644 --- a/sys/arch/powerpc/powerpc/fpu.c +++ b/sys/arch/powerpc/powerpc/fpu.c @@ -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 } diff --git a/sys/arch/powerpc/powerpc/genassym.cf b/sys/arch/powerpc/powerpc/genassym.cf index 11ca04604673..b5f9d3ab1461 100644 --- a/sys/arch/powerpc/powerpc/genassym.cf +++ b/sys/arch/powerpc/powerpc/genassym.cf @@ -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) diff --git a/sys/arch/powerpc/powerpc/linux_trap.c b/sys/arch/powerpc/powerpc/linux_trap.c index fdd7cdd2d5f4..3d03fd6e9e0c 100644 --- a/sys/arch/powerpc/powerpc/linux_trap.c +++ b/sys/arch/powerpc/powerpc/linux_trap.c @@ -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 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); } diff --git a/sys/arch/powerpc/powerpc/locore_subr.S b/sys/arch/powerpc/powerpc/locore_subr.S index bd22ed92f909..ebc618e6a83c 100644 --- a/sys/arch/powerpc/powerpc/locore_subr.S +++ b/sys/arch/powerpc/powerpc/locore_subr.S @@ -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. diff --git a/sys/arch/powerpc/powerpc/pmap.c b/sys/arch/powerpc/powerpc/pmap.c index cda0240a3927..f616e3a8459d 100644 --- a/sys/arch/powerpc/powerpc/pmap.c +++ b/sys/arch/powerpc/powerpc/pmap.c @@ -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; { } diff --git a/sys/arch/powerpc/powerpc/powerpc_machdep.c b/sys/arch/powerpc/powerpc/powerpc_machdep.c index dcf084756be3..e105eb6046c5 100644 --- a/sys/arch/powerpc/powerpc/powerpc_machdep.c +++ b/sys/arch/powerpc/powerpc/powerpc_machdep.c @@ -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 #include #include +#include +#include +#include +#include +#include #include +#include #include 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; + +} + diff --git a/sys/arch/powerpc/powerpc/process_machdep.c b/sys/arch/powerpc/powerpc/process_machdep.c index 024cabf36663..d66f0d4e0e73 100644 --- a/sys/arch/powerpc/powerpc/process_machdep.c +++ b/sys/arch/powerpc/powerpc/process_machdep.c @@ -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 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; diff --git a/sys/arch/powerpc/powerpc/sig_machdep.c b/sys/arch/powerpc/powerpc/sig_machdep.c index 9a1c9bcb62e1..cf9f05fdcb07 100644 --- a/sys/arch/powerpc/powerpc/sig_machdep.c +++ b/sys/arch/powerpc/powerpc/sig_machdep.c @@ -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 #include #include +#include +#include #include #include +#include #include +#include + /* * 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); +} diff --git a/sys/arch/powerpc/powerpc/sys_machdep.c b/sys/arch/powerpc/powerpc/sys_machdep.c index 40f1e9282276..c38061eee434 100644 --- a/sys/arch/powerpc/powerpc/sys_machdep.c +++ b/sys/arch/powerpc/powerpc/sys_machdep.c @@ -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 #include +#include #include int -sys_sysarch(p, v, retval) - struct proc *p; +sys_sysarch(l, v, retval) + struct lwp *l; void *v; register_t *retval; { diff --git a/sys/arch/powerpc/powerpc/syscall.c b/sys/arch/powerpc/powerpc/syscall.c index b38fd8f4b052..40ad1fce7ffa 100644 --- a/sys/arch/powerpc/powerpc/syscall.c +++ b/sys/arch/powerpc/powerpc/syscall.c @@ -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 #include #include +#include +#include #ifdef KTRACE #include #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); } - diff --git a/sys/arch/powerpc/powerpc/trap.c b/sys/arch/powerpc/powerpc/trap.c index 087e74f884f9..c56678cdc4cf 100644 --- a/sys/arch/powerpc/powerpc/trap.c +++ b/sys/arch/powerpc/powerpc/trap.c @@ -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 +#include #include #include +#include +#include #include #include @@ -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); +} diff --git a/sys/arch/powerpc/powerpc/trap_subr.S b/sys/arch/powerpc/powerpc/trap_subr.S index ea50578e0ff4..d5189a3cfabf 100644 --- a/sys/arch/powerpc/powerpc/trap_subr.S +++ b/sys/arch/powerpc/powerpc/trap_subr.S @@ -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 diff --git a/sys/arch/powerpc/powerpc/trap_subr_mp.S b/sys/arch/powerpc/powerpc/trap_subr_mp.S index 864877ab915c..592adbf75bc0 100644 --- a/sys/arch/powerpc/powerpc/trap_subr_mp.S +++ b/sys/arch/powerpc/powerpc/trap_subr_mp.S @@ -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 diff --git a/sys/arch/powerpc/powerpc/vm_machdep.c b/sys/arch/powerpc/powerpc/vm_machdep.c index e9624961be40..48c67c5cb373 100644 --- a/sys/arch/powerpc/powerpc/vm_machdep.c +++ b/sys/arch/powerpc/powerpc/vm_machdep.c @@ -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 diff --git a/sys/arch/prep/include/Makefile b/sys/arch/prep/include/Makefile index 2ddba1d8819f..faaf269d0be4 100644 --- a/sys/arch/prep/include/Makefile +++ b/sys/arch/prep/include/Makefile @@ -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 \ diff --git a/sys/arch/prep/include/mcontext.h b/sys/arch/prep/include/mcontext.h new file mode 100644 index 000000000000..353f8de0a75c --- /dev/null +++ b/sys/arch/prep/include/mcontext.h @@ -0,0 +1,3 @@ +/* $NetBSD: mcontext.h,v 1.2 2003/01/18 06:25:24 thorpej Exp $ */ + +#include diff --git a/sys/arch/prep/prep/machdep.c b/sys/arch/prep/prep/machdep.c index 7db6a663fd3a..743cc3003c55 100644 --- a/sys/arch/prep/prep/machdep.c +++ b/sys/arch/prep/prep/machdep.c @@ -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 #include #include +#include #include #include #include diff --git a/sys/arch/sandpoint/include/Makefile b/sys/arch/sandpoint/include/Makefile index 187aac93f767..864e03c3431d 100644 --- a/sys/arch/sandpoint/include/Makefile +++ b/sys/arch/sandpoint/include/Makefile @@ -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 \ diff --git a/sys/arch/sandpoint/include/mcontext.h b/sys/arch/sandpoint/include/mcontext.h new file mode 100644 index 000000000000..f8ed1412f988 --- /dev/null +++ b/sys/arch/sandpoint/include/mcontext.h @@ -0,0 +1,3 @@ +/* $NetBSD: mcontext.h,v 1.2 2003/01/18 06:26:39 thorpej Exp $ */ + +#include diff --git a/sys/arch/sandpoint/sandpoint/machdep.c b/sys/arch/sandpoint/sandpoint/machdep.c index f659f9b7511a..f73fa172e1c0 100644 --- a/sys/arch/sandpoint/sandpoint/machdep.c +++ b/sys/arch/sandpoint/sandpoint/machdep.c @@ -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 #include #include +#include #include #include #include diff --git a/sys/arch/sbmips/include/Makefile b/sys/arch/sbmips/include/Makefile index 8487a442e395..cacc0d5ef124 100644 --- a/sys/arch/sbmips/include/Makefile +++ b/sys/arch/sbmips/include/Makefile @@ -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 \ diff --git a/sys/arch/sbmips/include/mcontext.h b/sys/arch/sbmips/include/mcontext.h new file mode 100644 index 000000000000..7246bb81e2eb --- /dev/null +++ b/sys/arch/sbmips/include/mcontext.h @@ -0,0 +1,3 @@ +/* $NetBSD: mcontext.h,v 1.2 2003/01/18 06:28:41 thorpej Exp $ */ + +#include diff --git a/sys/arch/sbmips/sbmips/machdep.c b/sys/arch/sbmips/sbmips/machdep.c index d8c08c3fe79b..08c30c77d1f0 100644 --- a/sys/arch/sbmips/sbmips/machdep.c +++ b/sys/arch/sbmips/sbmips/machdep.c @@ -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 #include #include +#include #include #include @@ -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) { diff --git a/sys/arch/sgimips/include/Makefile b/sys/arch/sgimips/include/Makefile index 7249e34aeefa..c0b545ff9f05 100644 --- a/sys/arch/sgimips/include/Makefile +++ b/sys/arch/sgimips/include/Makefile @@ -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 \ diff --git a/sys/arch/sgimips/include/mcontext.h b/sys/arch/sgimips/include/mcontext.h new file mode 100644 index 000000000000..e8fa2171a664 --- /dev/null +++ b/sys/arch/sgimips/include/mcontext.h @@ -0,0 +1,3 @@ +/* $NetBSD: mcontext.h,v 1.2 2003/01/18 06:30:23 thorpej Exp $ */ + +#include diff --git a/sys/arch/sgimips/sgimips/machdep.c b/sys/arch/sgimips/sgimips/machdep.c index 4acef0860fca..62051820253c 100644 --- a/sys/arch/sgimips/sgimips/machdep.c +++ b/sys/arch/sgimips/sgimips/machdep.c @@ -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 #include #include +#include #include #include @@ -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) {