Adapt to the Scheduler Activations changes.
Boots to multi-user when compiled with GCC 3.3 (20021123) (pre-3.3 release), boots to single-user but hangs going multi-user when compiled with 3.4 (20030623). This is most likely a compiler problem.
This commit is contained in:
parent
9432809ee1
commit
49b91b6679
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ieee_handler.h,v 1.4 1998/09/02 19:17:12 matthias Exp $ */
|
||||
/* $NetBSD: ieee_handler.h,v 1.5 2003/06/23 13:06:54 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* IEEE floating point support for NS32081 and NS32381 fpus.
|
||||
|
@ -69,21 +69,21 @@ typedef struct {
|
|||
#include <sys/proc.h>
|
||||
#include <sys/user.h>
|
||||
|
||||
typedef struct proc state;
|
||||
typedef struct lwp state;
|
||||
|
||||
#define LREGBASE(s) ((vaddr_t) (s)->p_addr->u_pcb.pcb_freg)
|
||||
#define LREGBASE(s) ((vaddr_t) (s)->l_addr->u_pcb.pcb_freg)
|
||||
#define LREGOFFSET(n) (n * sizeof(double))
|
||||
#define FREGBASE(s) ((vaddr_t) (s)->p_addr->u_pcb.pcb_freg)
|
||||
#define FREGBASE(s) ((vaddr_t) (s)->l_addr->u_pcb.pcb_freg)
|
||||
#define FREGOFFSET(n) ((n & ~1) * sizeof(double) + (n & 1) * sizeof(float))
|
||||
#define REGBASE(s) ((vaddr_t) (s)->p_md.md_regs)
|
||||
#define REGBASE(s) ((vaddr_t) (s)->l_md.md_regs)
|
||||
#define REGOFFSET(n) offsetof(struct reg, r_r ## n)
|
||||
|
||||
#define FSR p_addr->u_pcb.pcb_fsr
|
||||
#define FP p_md.md_regs->r_fp
|
||||
#define SP p_md.md_regs->r_sp
|
||||
#define SB p_md.md_regs->r_sb
|
||||
#define PC p_md.md_regs->r_pc
|
||||
#define PSR p_md.md_regs->r_psr
|
||||
#define FSR l_addr->u_pcb.pcb_fsr
|
||||
#define FP l_md.md_regs->r_fp
|
||||
#define SP l_md.md_regs->r_sp
|
||||
#define SB l_md.md_regs->r_sb
|
||||
#define PC l_md.md_regs->r_pc
|
||||
#define PSR l_md.md_regs->r_psr
|
||||
|
||||
#define PSR_N PSL_N
|
||||
#define PSR_Z PSL_Z
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cpu.h,v 1.35 2002/05/25 04:30:16 simonb Exp $ */
|
||||
/* $NetBSD: cpu.h,v 1.36 2003/06/23 13:06:55 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
|
@ -74,6 +74,7 @@ extern struct cpu_info cpu_info_store;
|
|||
* definitions of cpu-dependent requirements
|
||||
* referenced in generic code
|
||||
*/
|
||||
#define cpu_proc_fork(p1, p2) /* nothing */
|
||||
#define cpu_swapin(p) /* nothing */
|
||||
#define cpu_wait(p) /* nothing */
|
||||
#define cpu_number() 0
|
||||
|
@ -119,7 +120,7 @@ void delay __P((int));
|
|||
|
||||
#ifdef _KERNEL
|
||||
/* ieee_handler.c */
|
||||
int ieee_handle_exception __P((struct proc *));
|
||||
int ieee_handle_exception __P((struct lwp *));
|
||||
|
||||
/* locore.s */
|
||||
void delay __P((int));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: frame.h,v 1.8 2002/07/09 23:10:03 simonb Exp $ */
|
||||
/* $NetBSD: frame.h,v 1.9 2003/06/23 13:06:55 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
|
@ -87,7 +87,7 @@ struct switchframe {
|
|||
long sf_r3;
|
||||
long sf_fp;
|
||||
int sf_pc;
|
||||
struct proc *sf_p;
|
||||
struct lwp *sf_lwp;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -101,4 +101,16 @@ struct sigframe {
|
|||
struct sigcontext sf_sc; /* actual saved context */
|
||||
};
|
||||
|
||||
/*
|
||||
* Scheduler Activation upcall frame
|
||||
*/
|
||||
struct saframe {
|
||||
int sa_ra;
|
||||
int sa_type;
|
||||
struct sa_t** sa_sas;
|
||||
int sa_events;
|
||||
int sa_interrupted;
|
||||
void* sa_arg;
|
||||
};
|
||||
|
||||
#endif /* _NS532_FRAME_H_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pmap.h,v 1.37 2003/04/02 07:36:02 thorpej Exp $ */
|
||||
/* $NetBSD: pmap.h,v 1.38 2003/06/23 13:06:55 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -338,10 +338,8 @@ extern int nkpde; /* current # of PDEs for kernel */
|
|||
* prototypes
|
||||
*/
|
||||
|
||||
void pmap_activate __P((struct proc *));
|
||||
void pmap_bootstrap __P((vaddr_t));
|
||||
boolean_t pmap_change_attrs __P((struct vm_page *, int, int));
|
||||
void pmap_deactivate __P((struct proc *));
|
||||
static void pmap_page_protect __P((struct vm_page *, vm_prot_t));
|
||||
void pmap_page_remove __P((struct vm_page *));
|
||||
static void pmap_protect __P((struct pmap *, vaddr_t,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: proc.h,v 1.5 1996/04/04 06:36:50 phil Exp $ */
|
||||
/* $NetBSD: proc.h,v 1.6 2003/06/23 13:06:55 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991 Regents of the University of California.
|
||||
|
@ -39,10 +39,17 @@
|
|||
#define _NS532_PROC_H_
|
||||
|
||||
/*
|
||||
* Machine-dependent part of the proc structure for the pc532.
|
||||
* Machine-dependent part of the lwp structure for the pc532.
|
||||
*/
|
||||
struct mdproc {
|
||||
struct mdlwp {
|
||||
struct reg *md_regs; /* pointer to regs on the stack */
|
||||
};
|
||||
|
||||
/*
|
||||
* Machine-dependent part of the proc structure for the pc532.
|
||||
*/
|
||||
struct mdproc {
|
||||
int md_dummy;
|
||||
};
|
||||
|
||||
#endif /* _NS532_PROC_H_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: compat_13_machdep.c,v 1.3 2002/09/25 22:21:16 thorpej Exp $ */
|
||||
/* $NetBSD: compat_13_machdep.c,v 1.4 2003/06/23 13:06:55 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996 Matthias Pfaller.
|
||||
|
@ -49,17 +49,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 *scp, context;
|
||||
struct reg *regs;
|
||||
sigset_t mask;
|
||||
|
@ -74,7 +76,7 @@ compat_13_sys_sigreturn(p, v, retval)
|
|||
return (EFAULT);
|
||||
|
||||
/* Restore the register context. */
|
||||
regs = p->p_md.md_regs;
|
||||
regs = l->l_md.md_regs;
|
||||
|
||||
/*
|
||||
* Check for security violations.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: genassym.cf,v 1.10 2002/11/22 13:26:40 simonb Exp $
|
||||
# $NetBSD: genassym.cf,v 1.11 2003/06/23 13:06:56 thorpej Exp $
|
||||
|
||||
#
|
||||
# Copyright (c) 1982, 1990 The Regents of the University of California.
|
||||
|
@ -53,8 +53,8 @@ include <machine/trap.h>
|
|||
include <machine/pmap.h>
|
||||
include <machine/vmparam.h>
|
||||
|
||||
define SRUN SRUN
|
||||
define SONPROC SONPROC
|
||||
define LSRUN LSRUN
|
||||
define LSONPROC LSONPROC
|
||||
|
||||
define PDSHIFT PDSHIFT
|
||||
define PGSHIFT PGSHIFT
|
||||
|
@ -67,12 +67,12 @@ define KERNBASE KERNBASE
|
|||
|
||||
define VM_MAXUSER_ADDRESS VM_MAXUSER_ADDRESS
|
||||
|
||||
define P_ADDR offsetof(struct proc, p_addr)
|
||||
define P_BACK offsetof(struct proc, p_back)
|
||||
define P_FORW offsetof(struct proc, p_forw)
|
||||
define P_PRIORITY offsetof(struct proc, p_priority)
|
||||
define P_STAT offsetof(struct proc, p_stat)
|
||||
define P_WCHAN offsetof(struct proc, p_wchan)
|
||||
define L_ADDR offsetof(struct lwp, l_addr)
|
||||
define L_BACK offsetof(struct lwp, l_back)
|
||||
define L_FORW offsetof(struct lwp, l_forw)
|
||||
define L_STAT offsetof(struct lwp, l_stat)
|
||||
define L_WCHAN offsetof(struct lwp, l_wchan)
|
||||
define L_PRIORITY offsetof(struct lwp, l_priority)
|
||||
define P_VMSPACE offsetof(struct proc, p_vmspace)
|
||||
define P_FLAG offsetof(struct proc, p_flag)
|
||||
define P_PID offsetof(struct proc, p_pid)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: locore.s,v 1.69 2003/01/06 13:05:05 wiz Exp $ */
|
||||
/* $NetBSD: locore.s,v 1.70 2003/06/23 13:06:56 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993 Philip A. Nelson.
|
||||
|
@ -103,7 +103,7 @@ ASENTRY(start)
|
|||
|
||||
ENTRY_NOPROFILE(proc_trampoline)
|
||||
#if !defined(MRTD)
|
||||
movd r4,0(sp) /* There was curproc on the stack */
|
||||
movd r4,0(sp) /* There was curlwp on the stack */
|
||||
jsr 0(r3)
|
||||
cmpqd 0,tos
|
||||
br rei
|
||||
|
@ -663,28 +663,28 @@ KENTRY(longjmp, 4)
|
|||
*/
|
||||
|
||||
/*
|
||||
* setrunqueue(struct proc *p);
|
||||
* setrunqueue(struct lwp *p);
|
||||
* Insert a process on the appropriate queue. Should be called at splclock().
|
||||
*/
|
||||
KENTRY(setrunqueue, 4)
|
||||
movd S_ARG0,r0
|
||||
#ifdef DIAGNOSTIC
|
||||
cmpqd 0,P_BACK(r0) /* should not be on q already */
|
||||
cmpqd 0,L_BACK(r0) /* should not be on q already */
|
||||
bne 1f
|
||||
cmpqd 0,P_WCHAN(r0)
|
||||
cmpqd 0,L_WCHAN(r0)
|
||||
bne 1f
|
||||
cmpb SRUN,P_STAT(r0)
|
||||
cmpb LSRUN,L_STAT(r0)
|
||||
bne 1f
|
||||
#endif
|
||||
movzbd P_PRIORITY(r0),r1
|
||||
movzbd L_PRIORITY(r0),r1
|
||||
lshd -2,r1
|
||||
sbitd r1,_C_LABEL(sched_whichqs)(pc) /* set queue full bit */
|
||||
addr _C_LABEL(sched_qs)(pc)[r1:q],r1 /* locate q hdr */
|
||||
movd P_BACK(r1),r2 /* locate q tail */
|
||||
movd r1,P_FORW(r0) /* set p->p_forw */
|
||||
movd r0,P_BACK(r1) /* update q's p_back */
|
||||
movd r0,P_FORW(r2) /* update tail's p_forw */
|
||||
movd r2,P_BACK(r0) /* set p->p_back */
|
||||
movd L_BACK(r1),r2 /* locate q tail */
|
||||
movd r1,L_FORW(r0) /* set l->l_forw */
|
||||
movd r0,L_BACK(r1) /* update q's l_back */
|
||||
movd r0,L_FORW(r2) /* update tail's l_forw */
|
||||
movd r2,L_BACK(r0) /* set l->l_back */
|
||||
ret ARGS
|
||||
#ifdef DIAGNOSTIC
|
||||
1: PANIC("setrunqueue") /* Was on the list! */
|
||||
|
@ -696,17 +696,17 @@ KENTRY(setrunqueue, 4)
|
|||
*/
|
||||
KENTRY(remrunqueue, 4)
|
||||
movd S_ARG0,r1
|
||||
movzbd P_PRIORITY(r1),r0
|
||||
movzbd L_PRIORITY(r1),r0
|
||||
#ifdef DIAGNOSTIC
|
||||
lshd -2,r0
|
||||
tbitd r0,_C_LABEL(sched_whichqs)(pc)
|
||||
bfc 1f
|
||||
#endif
|
||||
movd P_BACK(r1),r2 /* Address of prev. item */
|
||||
movqd 0,P_BACK(r1) /* Clear reverse link */
|
||||
movd P_FORW(r1),r1 /* Addr of next item. */
|
||||
movd r1,P_FORW(r2) /* Unlink item. */
|
||||
movd r2,P_BACK(r1)
|
||||
movd L_BACK(r1),r2 /* Address of prev. item */
|
||||
movqd 0,L_BACK(r1) /* Clear reverse link */
|
||||
movd L_FORW(r1),r1 /* Addr of next item. */
|
||||
movd r1,L_FORW(r2) /* Unlink item. */
|
||||
movd r2,L_BACK(r1)
|
||||
cmpd r1,r2 /* r1 = r2 => empty queue */
|
||||
bne 2f
|
||||
#ifndef DIAGNOSTIC
|
||||
|
@ -739,22 +739,22 @@ ENTRY_NOPROFILE(idle)
|
|||
br 0b
|
||||
|
||||
/*
|
||||
* void cpu_switch(struct proc *)
|
||||
* int cpu_switch(struct lwp *)
|
||||
* Find a runnable process and switch to it. Wait if necessary.
|
||||
*/
|
||||
KENTRY(cpu_switch, 4)
|
||||
enter [r3,r4,r5,r6,r7],0
|
||||
|
||||
movd _C_LABEL(curproc)(pc),r4
|
||||
movd _C_LABEL(curlwp)(pc),r4
|
||||
|
||||
/*
|
||||
* Clear curproc so that we don't accumulate system time while idle.
|
||||
* Clear curlwp so that we don't accumulate system time while idle.
|
||||
* This also insures that schedcpu() will move the old process to
|
||||
* the correct queue if it happens to get called from the spl0()
|
||||
* below and changes the priority. (See corresponding comment in
|
||||
* userret()).
|
||||
*/
|
||||
movqd 0,_C_LABEL(curproc)(pc)
|
||||
movqd 0,_C_LABEL(curlwp)(pc)
|
||||
|
||||
movd _C_LABEL(imask)(pc),tos
|
||||
bsr _C_LABEL(splx) /* spl0 - process pending interrupts */
|
||||
|
@ -788,45 +788,50 @@ KENTRY(cpu_switch, 4)
|
|||
sw1: /* Get the process and unlink it from the queue. */
|
||||
addr _C_LABEL(sched_qs)(pc)[r0:q],r1 /* address of qs entry! */
|
||||
|
||||
movd P_FORW(r1),r2 /* unlink from front of process q */
|
||||
movd L_FORW(r1),r2 /* unlink from front of process q */
|
||||
#ifdef DIAGNOSTIC
|
||||
cmpd r2,r1 /* linked to self (i.e. nothing queued? */
|
||||
beq _C_LABEL(switch_error) /* not possible */
|
||||
#endif
|
||||
movd P_FORW(r2),r3
|
||||
movd r3,P_FORW(r1)
|
||||
movd r1,P_BACK(r3)
|
||||
movd L_FORW(r2),r3
|
||||
movd r3,L_FORW(r1)
|
||||
movd r1,L_BACK(r3)
|
||||
|
||||
cmpd r1,r3 /* q empty? */
|
||||
bne 3f
|
||||
|
||||
cbitd r0,_C_LABEL(sched_whichqs)(pc) /* queue is empty, turn off whichqs. */
|
||||
|
||||
3: movqd 0,_C_LABEL(want_resched)(pc) /* We did a resched! */
|
||||
|
||||
3:
|
||||
#ifdef DIAGNOSTIC
|
||||
cmpqd 0,P_WCHAN(r2) /* Waiting for something? */
|
||||
bne _C_LABEL(switch_error) /* Yes; shouldn't be queued. */
|
||||
cmpb SRUN,P_STAT(r2) /* In run state? */
|
||||
cmpb LSRUN,L_STAT(r2) /* In run state? */
|
||||
bne _C_LABEL(switch_error) /* No; shouldn't be queued. */
|
||||
#endif
|
||||
|
||||
/* Isolate process. XXX Is this necessary? */
|
||||
movqd 0,P_BACK(r2)
|
||||
movqd 0,L_BACK(r2)
|
||||
|
||||
switch_resume:
|
||||
movqd 0,_C_LABEL(want_resched)(pc) /* We did a resched! */
|
||||
|
||||
/* p->p_cpu initialized in fork1() for single-processor */
|
||||
|
||||
/* Record new process. */
|
||||
movb SONPROC,P_STAT(r2) /* p->p_stat = SONPROC */
|
||||
movd r2,_C_LABEL(curproc)(pc)
|
||||
movb LSONPROC,L_STAT(r2) /* l->l_stat = LSONPROC */
|
||||
movd r2,_C_LABEL(curlwp)(pc)
|
||||
|
||||
/* It's okay to take interrupts here. */
|
||||
ints_on
|
||||
|
||||
/* Skip context switch if same process. */
|
||||
movqd 0,r0 /* return "didn't switch" */
|
||||
cmpd r2,r4
|
||||
beq _ASM_LABEL(switch_return)
|
||||
|
||||
movqd 1,r0 /* return "did switch" */
|
||||
|
||||
/* If old process exited, don't bother. */
|
||||
cmpqd 0,r4
|
||||
beq _ASM_LABEL(switch_exited)
|
||||
|
@ -839,7 +844,7 @@ sw1: /* Get the process and unlink it from the queue. */
|
|||
* r2 - new process
|
||||
*/
|
||||
|
||||
movd P_ADDR(r4),r4
|
||||
movd L_ADDR(r4),r4
|
||||
|
||||
/* save stack and frame pointer registers. */
|
||||
sprd sp,PCB_KSP(r4)
|
||||
|
@ -856,7 +861,7 @@ ASLOCAL(switch_exited)
|
|||
|
||||
/* No interrupts while loading new state. */
|
||||
ints_off
|
||||
movd P_ADDR(r2),r1
|
||||
movd L_ADDR(r2),r1
|
||||
|
||||
/* Switch address space. */
|
||||
lmr ptb0,PCB_PTB(r1)
|
||||
|
@ -872,9 +877,9 @@ ASLOCAL(switch_exited)
|
|||
/*
|
||||
* Disable the FPU.
|
||||
*/
|
||||
sprw cfg,r0
|
||||
andw ~CFG_F,r0
|
||||
lprw cfg,r0
|
||||
sprw cfg,r3
|
||||
andw ~CFG_F,r3
|
||||
lprw cfg,r3
|
||||
|
||||
/* Interrupts are okay again. */
|
||||
ints_on
|
||||
|
@ -896,6 +901,41 @@ ENTRY(switch_error)
|
|||
PANIC("cpu_switch")
|
||||
#endif
|
||||
|
||||
/*
|
||||
* void cpu_switchto(struct lwp *old, struct lwp *new)
|
||||
* Switch to to the specified new LWP.
|
||||
*/
|
||||
KENTRY(cpu_switchto, 4)
|
||||
enter [r3,r4,r5,r6,r7],0
|
||||
|
||||
movd 8(fp),r4 /* old LWP */
|
||||
movd 12(fp),r2 /* new LWP */
|
||||
|
||||
movd _C_LABEL(imask)(pc),tos
|
||||
bsr _C_LABEL(splx) /* spl0 - process pending interrupts */
|
||||
#if !defined(MRTD)
|
||||
# if defined(DDB) || defined(KGDB)
|
||||
cmpqd 0,tos
|
||||
movd r0,tos
|
||||
# else
|
||||
movd r0,0(sp)
|
||||
# endif
|
||||
#else
|
||||
movd r0,tos
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Ok, right now we have:
|
||||
* r2 - new process
|
||||
* r4 - old process
|
||||
* ...and the stack just the way cpu_switch() wants. Disable
|
||||
* interrupts and then jump into the middle of cpu_switch().
|
||||
*
|
||||
* XXX This strategy might have problems with MRTD.
|
||||
*/
|
||||
ints_off
|
||||
br switch_resume
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: machdep.c,v 1.140 2003/05/10 21:10:35 thorpej Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.141 2003/06/23 13:06:56 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996 Matthias Pfaller.
|
||||
|
@ -63,6 +63,8 @@
|
|||
#include <sys/mount.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/sa.h>
|
||||
#include <sys/savar.h>
|
||||
#include <sys/syscallargs.h>
|
||||
#include <sys/core.h>
|
||||
#include <sys/kcore.h>
|
||||
|
@ -326,14 +328,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 reg *regs;
|
||||
struct sigframe *fp, frame;
|
||||
int onstack;
|
||||
sig_t catcher = SIGACTION(p, sig).sa_handler;
|
||||
|
||||
regs = p->p_md.md_regs;
|
||||
regs = l->l_md.md_regs;
|
||||
|
||||
/* Do we need to jump onto the signal stack? */
|
||||
onstack =
|
||||
|
@ -362,7 +365,7 @@ sendsig(sig, mask, code)
|
|||
|
||||
default:
|
||||
/* Don't know what trampoline version; kill it. */
|
||||
sigexit(p, SIGILL);
|
||||
sigexit(l, SIGILL);
|
||||
}
|
||||
frame.sf_signum = sig;
|
||||
frame.sf_code = code;
|
||||
|
@ -404,7 +407,7 @@ sendsig(sig, mask, code)
|
|||
* Process has trashed its stack; give it an illegal
|
||||
* instruction to halt it in its tracks.
|
||||
*/
|
||||
sigexit(p, SIGILL);
|
||||
sigexit(l, SIGILL);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
|
@ -422,6 +425,37 @@ sendsig(sig, mask, code)
|
|||
p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
}
|
||||
|
||||
void
|
||||
cpu_upcall(l, type, nevents, ninterrupted, sas, ap, sp, upcall)
|
||||
struct lwp *l;
|
||||
int type, nevents, ninterrupted;
|
||||
void *sas, *ap, *sp;
|
||||
sa_upcall_t upcall;
|
||||
{
|
||||
struct saframe *sf, frame;
|
||||
struct reg *regs;
|
||||
|
||||
regs = l->l_md.md_regs;
|
||||
|
||||
/* Build up and copy the SA frame. */
|
||||
frame.sa_type = type;
|
||||
frame.sa_sas = sas;
|
||||
frame.sa_events = nevents;
|
||||
frame.sa_interrupted = ninterrupted;
|
||||
frame.sa_arg = ap;
|
||||
frame.sa_ra = 0;
|
||||
|
||||
sf = (struct saframe *)sp - 1;
|
||||
if (copyout(&frame, sf, sizeof(frame)) != 0) {
|
||||
/* Copying onto the stack didn't work. Die. */
|
||||
sigexit(l, SIGILL);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
regs->r_sp = (int) sf;
|
||||
regs->r_pc = (int) upcall;
|
||||
}
|
||||
|
||||
/*
|
||||
* System call to cleanup state after a signal
|
||||
* has been taken. Reset signal mask and
|
||||
|
@ -433,14 +467,15 @@ sendsig(sig, mask, code)
|
|||
* a machine fault.
|
||||
*/
|
||||
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 *scp, context;
|
||||
struct reg *regs;
|
||||
|
||||
|
@ -454,7 +489,7 @@ sys___sigreturn14(p, v, retval)
|
|||
return (EFAULT);
|
||||
|
||||
/* Restore the register context. */
|
||||
regs = p->p_md.md_regs;
|
||||
regs = l->l_md.md_regs;
|
||||
|
||||
/*
|
||||
* Check for security violations.
|
||||
|
@ -500,13 +535,10 @@ cpu_getmcontext(l, mcp, flags)
|
|||
|
||||
#ifdef NS381
|
||||
{
|
||||
/*
|
||||
* XXX Unaware of LWP universe.
|
||||
*/
|
||||
extern struct proc *fpu_proc;
|
||||
extern struct lwp *fpu_lwp;
|
||||
|
||||
/* If we're the FPU owner, dump its state to the PCB first. */
|
||||
if (fpu_proc == p)
|
||||
if (fpu_lwp == l)
|
||||
save_fpu_context(&l->l_addr->u_pcb);
|
||||
|
||||
mcp->__fpregs.__fpr_psr = l->l_addr->u_pcb.pcb_fsr;
|
||||
|
@ -529,7 +561,7 @@ cpu_setmcontext(l, mcp, flags)
|
|||
/* Restore CPU context, if any. */
|
||||
if (flags & _UC_CPU) {
|
||||
/* Check for security violations. */
|
||||
if (((mcp.__gregs[_REG_PS] ^ regs->r_psr) & PSL_USERSTATIC)
|
||||
if (((mcp->__gregs[_REG_PS] ^ regs->r_psr) & PSL_USERSTATIC)
|
||||
!= 0)
|
||||
return (EINVAL);
|
||||
(void)memcpy(l->l_md.md_regs, mcp->__gregs,
|
||||
|
@ -538,16 +570,15 @@ cpu_setmcontext(l, mcp, flags)
|
|||
|
||||
#ifdef NS381
|
||||
/* Restore FPU context, if any. */
|
||||
/*
|
||||
* XXX Unaware of LWP universe.
|
||||
*/
|
||||
if (flags & _UC_FPU) {
|
||||
extern struct lwp *fpu_lwp;
|
||||
|
||||
l->l_addr->u_pcb.pcb_fsr = mcp->__fpregs.__fpr_psr;
|
||||
(void)memcpy(l->l_addr->u_pcb.pcb_freg,
|
||||
mcp->__fpregs.__fpr_regs,
|
||||
sizeof (l->l_addr->u_pcb.pcb_freg));
|
||||
/* If we're the FPU owner, force a reload. */
|
||||
if (fpu_proc == p)
|
||||
if (fpu_lwp == l)
|
||||
restore_fpu_context(&l->l_addr->u_pcb);
|
||||
}
|
||||
#endif
|
||||
|
@ -616,7 +647,7 @@ cpu_reboot(howto, bootstr)
|
|||
dump_sf.sf_fp = fp[0];
|
||||
dump_sf.sf_pc = fp[1];
|
||||
dump_sf.sf_pl = s;
|
||||
dump_sf.sf_p = curproc;
|
||||
dump_sf.sf_lwp = curlwp;
|
||||
}
|
||||
dumpsys();
|
||||
}
|
||||
|
@ -868,17 +899,18 @@ err:
|
|||
* Clear 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 reg *r = p->p_md.md_regs;
|
||||
struct pcb *pcbp = &p->p_addr->u_pcb;
|
||||
extern struct proc *fpu_proc;
|
||||
struct proc *p = l->l_proc;
|
||||
struct reg *r = l->l_md.md_regs;
|
||||
struct pcb *pcbp = &l->l_addr->u_pcb;
|
||||
extern struct lwp *fpu_lwp;
|
||||
|
||||
if (p == fpu_proc)
|
||||
fpu_proc = 0;
|
||||
if (l == fpu_lwp)
|
||||
fpu_lwp = 0;
|
||||
|
||||
memset(r, 0, sizeof(*r));
|
||||
r->r_sp = stack;
|
||||
|
@ -1063,7 +1095,7 @@ init532()
|
|||
proc0paddr = (struct user *)alloc_pages(UPAGES);
|
||||
proc0paddr->u_pcb.pcb_ptb = (int) pd;
|
||||
proc0paddr = (struct user *) ((vaddr_t)proc0paddr + KERNBASE);
|
||||
proc0.p_addr = proc0paddr;
|
||||
lwp0.l_addr = proc0paddr;
|
||||
|
||||
/* Allocate second level page tables for kernel virtual address space */
|
||||
map(pd, VM_MIN_KERNEL_ADDRESS, PA(-1), 0, nkpde << PDSHIFT);
|
||||
|
@ -1102,11 +1134,11 @@ init532()
|
|||
pmap_bootstrap(avail_start + KERNBASE);
|
||||
|
||||
/* Construct an empty syscframe for proc0. */
|
||||
curpcb = &proc0.p_addr->u_pcb;
|
||||
curpcb = &lwp0.l_addr->u_pcb;
|
||||
curpcb->pcb_onstack = (struct reg *)
|
||||
((u_int)proc0.p_addr + USPACE) - 1;
|
||||
((u_int)lwp0.l_addr + USPACE) - 1;
|
||||
|
||||
/* Switch to proc0's stack. */
|
||||
/* Switch to lwp0's stack. */
|
||||
lprd(sp, curpcb->pcb_onstack);
|
||||
lprd(fp, 0);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pmap.c,v 1.72 2003/05/10 21:10:36 thorpej Exp $ */
|
||||
/* $NetBSD: pmap.c,v 1.73 2003/06/23 13:06:57 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -685,8 +685,8 @@ pmap_bootstrap(kva_start)
|
|||
kpm->pm_obj.uo_npages = 0;
|
||||
kpm->pm_obj.uo_refs = 1;
|
||||
memset(&kpm->pm_list, 0, sizeof(kpm->pm_list)); /* pm_list not used */
|
||||
kpm->pm_pdir = (pd_entry_t *)(proc0.p_addr->u_pcb.pcb_ptb + KERNBASE);
|
||||
kpm->pm_pdirpa = (u_int32_t) proc0.p_addr->u_pcb.pcb_ptb;
|
||||
kpm->pm_pdir = (pd_entry_t *)(lwp0.l_addr->u_pcb.pcb_ptb + KERNBASE);
|
||||
kpm->pm_pdirpa = (u_int32_t) lwp0.l_addr->u_pcb.pcb_ptb;
|
||||
kpm->pm_stats.wired_count = kpm->pm_stats.resident_count =
|
||||
ns532_btop(kva_start - VM_MIN_KERNEL_ADDRESS);
|
||||
|
||||
|
@ -1489,15 +1489,15 @@ pmap_reference(pmap)
|
|||
*/
|
||||
|
||||
void
|
||||
pmap_activate(p)
|
||||
struct proc *p;
|
||||
pmap_activate(l)
|
||||
struct lwp *l;
|
||||
{
|
||||
struct pcb *pcb = &p->p_addr->u_pcb;
|
||||
struct pmap *pmap = p->p_vmspace->vm_map.pmap;
|
||||
struct pcb *pcb = &l->l_addr->u_pcb;
|
||||
struct pmap *pmap = l->l_proc->p_vmspace->vm_map.pmap;
|
||||
|
||||
pcb->pcb_ptb = pmap->pm_pdirpa;
|
||||
pcb->pcb_pmap = pmap;
|
||||
if (p == curproc) {
|
||||
if (l == curlwp) {
|
||||
load_ptb(pcb->pcb_ptb);
|
||||
}
|
||||
}
|
||||
|
@ -1509,8 +1509,8 @@ pmap_activate(p)
|
|||
*/
|
||||
|
||||
void
|
||||
pmap_deactivate(p)
|
||||
struct proc *p;
|
||||
pmap_deactivate(l)
|
||||
struct lwp *l;
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: process_machdep.c,v 1.11 1998/09/12 19:14:59 matthias Exp $ */
|
||||
/* $NetBSD: process_machdep.c,v 1.12 2003/06/23 13:06:57 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993 The Regents of the University of California.
|
||||
|
@ -73,16 +73,16 @@
|
|||
#include <machine/reg.h>
|
||||
#include <machine/frame.h>
|
||||
|
||||
extern struct proc *fpu_proc;
|
||||
extern struct lwp *fpu_lwp;
|
||||
|
||||
int
|
||||
process_read_regs(p, regs)
|
||||
struct proc *p;
|
||||
process_read_regs(l, regs)
|
||||
struct lwp *l;
|
||||
struct reg *regs;
|
||||
{
|
||||
struct reg *pregs;
|
||||
|
||||
pregs = p->p_md.md_regs;
|
||||
pregs = l->l_md.md_regs;
|
||||
if (pregs == NULL)
|
||||
return (EIO);
|
||||
|
||||
|
@ -91,13 +91,13 @@ 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 reg *pregs;
|
||||
|
||||
pregs = p->p_md.md_regs;
|
||||
pregs = l->l_md.md_regs;
|
||||
if (pregs == NULL)
|
||||
return (EIO);
|
||||
|
||||
|
@ -109,45 +109,45 @@ 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;
|
||||
{
|
||||
if ((p->p_flag & P_INMEM) == 0)
|
||||
if ((l->l_flag & L_INMEM) == 0)
|
||||
return (EIO);
|
||||
|
||||
if (fpu_proc == p) {
|
||||
save_fpu_context(&p->p_addr->u_pcb);
|
||||
fpu_proc = 0;
|
||||
if (fpu_lwp == l) {
|
||||
save_fpu_context(&l->l_addr->u_pcb);
|
||||
fpu_lwp = 0;
|
||||
}
|
||||
memcpy(regs, &p->p_addr->u_pcb.pcb_fsr, sizeof(*regs));
|
||||
memcpy(regs, &l->l_addr->u_pcb.pcb_fsr, sizeof(*regs));
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
process_write_fpregs(p, regs)
|
||||
struct proc *p;
|
||||
process_write_fpregs(l, regs)
|
||||
struct lwp *l;
|
||||
struct fpreg *regs;
|
||||
{
|
||||
if ((p->p_flag & P_INMEM) == 0)
|
||||
if ((l->l_flag & L_INMEM) == 0)
|
||||
return (EIO);
|
||||
|
||||
if (fpu_proc == p)
|
||||
fpu_proc = 0;
|
||||
if (fpu_lwp == l)
|
||||
fpu_lwp = 0;
|
||||
|
||||
memcpy(&p->p_addr->u_pcb.pcb_fsr, regs, sizeof(*regs));
|
||||
memcpy(&l->l_addr->u_pcb.pcb_fsr, regs, sizeof(*regs));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
process_sstep(p, sstep)
|
||||
struct proc *p;
|
||||
process_sstep(l, sstep)
|
||||
struct lwp *l;
|
||||
int sstep;
|
||||
{
|
||||
struct reg *pregs;
|
||||
|
||||
pregs = p->p_md.md_regs;
|
||||
pregs = l->l_md.md_regs;
|
||||
if (pregs == NULL)
|
||||
return (EIO);
|
||||
|
||||
|
@ -160,13 +160,13 @@ process_sstep(p, sstep)
|
|||
}
|
||||
|
||||
int
|
||||
process_set_pc(p, addr)
|
||||
struct proc *p;
|
||||
process_set_pc(l, addr)
|
||||
struct lwp *l;
|
||||
caddr_t addr;
|
||||
{
|
||||
struct reg *pregs;
|
||||
|
||||
pregs = p->p_md.md_regs;
|
||||
pregs = l->l_md.md_regs;
|
||||
if (pregs == NULL)
|
||||
return (EIO);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sys_machdep.c,v 1.10 2000/12/13 18:13:10 jdolecek Exp $ */
|
||||
/* $NetBSD: sys_machdep.c,v 1.11 2003/06/23 13:06:58 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
|
@ -48,11 +48,12 @@
|
|||
#include <sys/kernel.h>
|
||||
#include <sys/buf.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;
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: trap.c,v 1.51 2003/06/23 11:01:34 martin Exp $ */
|
||||
/* $NetBSD: trap.c,v 1.52 2003/06/23 13:06:58 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996 Matthias Pfaller. All rights reserved.
|
||||
|
@ -58,6 +58,9 @@
|
|||
#include <sys/acct.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/pool.h>
|
||||
#include <sys/sa.h>
|
||||
#include <sys/savar.h>
|
||||
#ifdef KTRACE
|
||||
#include <sys/ktrace.h>
|
||||
#endif
|
||||
|
@ -81,7 +84,7 @@
|
|||
#include <machine/db_machdep.h>
|
||||
#endif
|
||||
|
||||
struct proc *fpu_proc; /* Process owning the FPU. */
|
||||
struct lwp *fpu_lwp; /* LWP owning the FPU. */
|
||||
|
||||
/* Allow turning off if ieee_handler for debugging */
|
||||
int ieee_handler_disable = 0;
|
||||
|
@ -94,33 +97,42 @@ int ieee_handler_disable = 0;
|
|||
|
||||
void syscall __P((struct syscframe)) __CDECL__;
|
||||
void trap __P((struct trapframe)) __CDECL__;
|
||||
static __inline void userret __P((struct proc *, int, u_quad_t));
|
||||
static __inline void userret __P((struct lwp *, int, u_quad_t));
|
||||
|
||||
/*
|
||||
* Define the code needed before returning to user mode, for
|
||||
* trap and syscall.
|
||||
*/
|
||||
static __inline void
|
||||
userret(p, pc, oticks)
|
||||
struct proc *p;
|
||||
userret(l, pc, oticks)
|
||||
struct lwp *l;
|
||||
int pc;
|
||||
u_quad_t oticks;
|
||||
{
|
||||
struct proc *p = l->l_proc;
|
||||
int sig;
|
||||
|
||||
/* take pending signals */
|
||||
while ((sig = CURSIG(p)) != 0)
|
||||
while ((sig = CURSIG(l)) != 0)
|
||||
postsig(sig);
|
||||
p->p_priority = p->p_usrpri;
|
||||
if (want_resched) {
|
||||
l->l_priority = l->l_usrpri;
|
||||
if (want_resched) { /* XXX Move to AST handler. */
|
||||
/*
|
||||
* We are being preempted.
|
||||
*/
|
||||
preempt(NULL);
|
||||
while ((sig = CURSIG(p)) != 0)
|
||||
while ((sig = CURSIG(l)) != 0)
|
||||
postsig(sig);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/*
|
||||
* If profiling, charge recent system time to the trapped pc.
|
||||
*/
|
||||
|
@ -130,7 +142,7 @@ userret(p, pc, oticks)
|
|||
addupc_task(p, pc, (int)(p->p_sticks - oticks) * psratio);
|
||||
}
|
||||
|
||||
curcpu()->ci_schedstate.spc_curpriority = p->p_priority;
|
||||
curcpu()->ci_schedstate.spc_curpriority = l->l_priority;
|
||||
}
|
||||
|
||||
char *trap_type[] = {
|
||||
|
@ -173,7 +185,8 @@ void
|
|||
trap(frame)
|
||||
struct trapframe frame;
|
||||
{
|
||||
struct proc *p = curproc;
|
||||
struct lwp *l = curlwp;
|
||||
struct proc *p = l->l_proc;
|
||||
int type = frame.tf_trapno;
|
||||
u_quad_t sticks;
|
||||
struct pcb *pcb = NULL;
|
||||
|
@ -196,7 +209,7 @@ trap(frame)
|
|||
if (USERMODE(frame.tf_regs.r_psr)) {
|
||||
type |= T_USER;
|
||||
sticks = p->p_sticks;
|
||||
p->p_md.md_regs = &frame.tf_regs;
|
||||
l->l_md.md_regs = &frame.tf_regs;
|
||||
} else
|
||||
sticks = 0;
|
||||
|
||||
|
@ -278,20 +291,20 @@ trap(frame)
|
|||
sprd(cfg, cfg);
|
||||
if ((cfg & CFG_F) == 0) {
|
||||
lprd(cfg, cfg | CFG_F);
|
||||
if (fpu_proc == p)
|
||||
if (fpu_lwp == l)
|
||||
return;
|
||||
pcb = &p->p_addr->u_pcb;
|
||||
if (fpu_proc != 0)
|
||||
save_fpu_context(&fpu_proc->p_addr->u_pcb);
|
||||
pcb = &l->l_addr->u_pcb;
|
||||
if (fpu_lwp != 0)
|
||||
save_fpu_context(&fpu_lwp->l_addr->u_pcb);
|
||||
restore_fpu_context(pcb);
|
||||
fpu_proc = p;
|
||||
fpu_lwp = l;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case T_ILL | T_USER: /* privileged instruction fault */
|
||||
trapsignal(p, SIGILL, type &~ T_USER);
|
||||
trapsignal(l, SIGILL, type &~ T_USER);
|
||||
goto out;
|
||||
|
||||
case T_AST | T_USER: /* Allow process switch */
|
||||
|
@ -304,15 +317,15 @@ trap(frame)
|
|||
|
||||
case T_OVF | T_USER:
|
||||
case T_DVZ | T_USER:
|
||||
trapsignal(p, SIGFPE, type &~ T_USER);
|
||||
trapsignal(l, SIGFPE, type &~ T_USER);
|
||||
goto out;
|
||||
|
||||
case T_SLAVE | T_USER: {
|
||||
int fsr, sig = SIGFPE;
|
||||
pcb = &p->p_addr->u_pcb;
|
||||
pcb = &l->l_addr->u_pcb;
|
||||
if (ieee_handler_disable == 0) {
|
||||
save_fpu_context(pcb);
|
||||
switch(ieee_handle_exception(p)) {
|
||||
switch(ieee_handle_exception(l)) {
|
||||
case FPC_TT_NONE:
|
||||
restore_fpu_context(pcb);
|
||||
if (frame.tf_regs.r_psr & PSL_T) {
|
||||
|
@ -329,7 +342,7 @@ trap(frame)
|
|||
restore_fpu_context(pcb);
|
||||
}
|
||||
sfsr(fsr);
|
||||
trapsignal(p, sig, 0x80000000 | fsr);
|
||||
trapsignal(l, sig, 0x80000000 | fsr);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -338,7 +351,7 @@ trap(frame)
|
|||
(frame.tf_msr & MSR_STT) == STT_NSQ_INS ||
|
||||
(p == 0))
|
||||
goto we_re_toast;
|
||||
pcb = &p->p_addr->u_pcb;
|
||||
pcb = &l->l_addr->u_pcb;
|
||||
/*
|
||||
* {fu,su}bail is used by [fs]uswintr() to prevent page
|
||||
* faulting from inside the profiling interrupt.
|
||||
|
@ -429,9 +442,9 @@ trap(frame)
|
|||
p->p_pid, p->p_comm,
|
||||
p->p_cred && p->p_ucred ?
|
||||
p->p_ucred->cr_uid : -1);
|
||||
trapsignal(p, SIGKILL, T_ABT);
|
||||
trapsignal(l, SIGKILL, T_ABT);
|
||||
} else {
|
||||
trapsignal(p, SIGSEGV, T_ABT);
|
||||
trapsignal(l, SIGSEGV, T_ABT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -440,7 +453,7 @@ trap(frame)
|
|||
case T_BPT | T_USER: /* breakpoint instruction */
|
||||
case T_DBG | T_USER: /* debug trap */
|
||||
trace:
|
||||
trapsignal(p, SIGTRAP, type &~ T_USER);
|
||||
trapsignal(l, SIGTRAP, type &~ T_USER);
|
||||
break;
|
||||
|
||||
case T_NMI: /* non-maskable interrupt */
|
||||
|
@ -463,7 +476,7 @@ trap(frame)
|
|||
if ((type & T_USER) == 0)
|
||||
return;
|
||||
out:
|
||||
userret(p, frame.tf_regs.r_pc, sticks);
|
||||
userret(l, frame.tf_regs.r_pc, sticks);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -478,6 +491,7 @@ syscall(frame)
|
|||
{
|
||||
caddr_t params;
|
||||
const struct sysent *callp;
|
||||
struct lwp *l;
|
||||
struct proc *p;
|
||||
int error, opc, nsys;
|
||||
size_t argsize;
|
||||
|
@ -487,9 +501,10 @@ syscall(frame)
|
|||
uvmexp.syscalls++;
|
||||
if (!USERMODE(frame.sf_regs.r_psr))
|
||||
panic("syscall");
|
||||
p = curproc;
|
||||
l = curlwp;
|
||||
p = l->l_proc;
|
||||
sticks = p->p_sticks;
|
||||
p->p_md.md_regs = &frame.sf_regs;
|
||||
l->l_md.md_regs = &frame.sf_regs;
|
||||
opc = frame.sf_regs.r_pc++;
|
||||
code = frame.sf_regs.r_r0;
|
||||
|
||||
|
@ -530,12 +545,12 @@ syscall(frame)
|
|||
goto bad;
|
||||
}
|
||||
|
||||
if ((error = trace_enter(p, code, code, NULL, args, rval)) != 0)
|
||||
if ((error = trace_enter(l, code, code, NULL, args, rval)) != 0)
|
||||
goto bad;
|
||||
|
||||
rval[0] = 0;
|
||||
rval[1] = frame.sf_regs.r_r1;
|
||||
error = (*callp->sy_call)(p, args, rval);
|
||||
error = (*callp->sy_call)(l, args, rval);
|
||||
switch (error) {
|
||||
case 0:
|
||||
/*
|
||||
|
@ -565,23 +580,60 @@ syscall(frame)
|
|||
break;
|
||||
}
|
||||
|
||||
trace_exit(p, code, args, rval, error);
|
||||
trace_exit(l, code, args, rval, error);
|
||||
|
||||
userret(p, frame.sf_regs.r_pc, sticks);
|
||||
userret(l, frame.sf_regs.r_pc, sticks);
|
||||
}
|
||||
|
||||
void
|
||||
child_return(arg)
|
||||
void *arg;
|
||||
{
|
||||
struct proc *p = arg;
|
||||
struct lwp *l = arg;
|
||||
|
||||
p->p_md.md_regs->r_r0 = 0;
|
||||
p->p_md.md_regs->r_psr &= ~PSL_C;
|
||||
l->l_md.md_regs->r_r0 = 0;
|
||||
l->l_md.md_regs->r_psr &= ~PSL_C;
|
||||
|
||||
userret(p, p->p_md.md_regs->r_pc, 0);
|
||||
userret(l, l->l_md.md_regs->r_pc, 0);
|
||||
#ifdef KTRACE
|
||||
if (KTRPOINT(p, KTR_SYSRET))
|
||||
ktrsysret(p, SYS_fork, 0, 0);
|
||||
if (KTRPOINT(l->l_proc, KTR_SYSRET))
|
||||
ktrsysret(l->l_proc, SYS_fork, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Start a new LWP.
|
||||
*/
|
||||
void
|
||||
startlwp(arg)
|
||||
void *arg;
|
||||
{
|
||||
int error;
|
||||
ucontext_t *uc = arg;
|
||||
struct lwp *l = curlwp;
|
||||
struct proc *p = l->l_proc;
|
||||
|
||||
l->l_md.md_regs->r_r0 = 0;
|
||||
l->l_md.md_regs->r_psr &= ~PSL_C;
|
||||
|
||||
error = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
|
||||
#if DIAGNOSTIC
|
||||
if (error)
|
||||
printf("Error %d from cpu_setmcontext.", error);
|
||||
#endif
|
||||
pool_put(&lwp_uc_pool, uc);
|
||||
|
||||
userret(l, l->l_md.md_regs->r_pc, p->p_sticks);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX This is a terrible name.
|
||||
*/
|
||||
void
|
||||
upcallret(l)
|
||||
struct lwp *l;
|
||||
{
|
||||
struct proc *p = l->l_proc;
|
||||
|
||||
userret(l, l->l_md.md_regs->r_pc, p->p_sticks);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: vm_machdep.c,v 1.54 2003/04/02 02:24:16 thorpej Exp $ */
|
||||
/* $NetBSD: vm_machdep.c,v 1.55 2003/06/23 13:06:58 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996 Matthias Pfaller.
|
||||
|
@ -59,7 +59,7 @@
|
|||
#include <machine/cpu.h>
|
||||
#include <machine/cpufunc.h>
|
||||
|
||||
extern struct proc *fpu_proc;
|
||||
extern struct lwp *fpu_lwp;
|
||||
|
||||
void setredzone __P((u_short *, caddr_t));
|
||||
|
||||
|
@ -82,38 +82,38 @@ void setredzone __P((u_short *, caddr_t));
|
|||
* accordingly.
|
||||
*/
|
||||
void
|
||||
cpu_fork(p1, p2, stack, stacksize, func, arg)
|
||||
register struct proc *p1, *p2;
|
||||
cpu_lwp_fork(l1, l2, stack, stacksize, func, arg)
|
||||
struct lwp *l1, *l2;
|
||||
void *stack;
|
||||
size_t stacksize;
|
||||
void (*func) __P((void *));
|
||||
void *arg;
|
||||
{
|
||||
register struct pcb *pcb = &p2->p_addr->u_pcb;
|
||||
register struct syscframe *tf;
|
||||
register struct switchframe *sf;
|
||||
struct pcb *pcb = &l2->l_addr->u_pcb;
|
||||
struct syscframe *tf;
|
||||
struct switchframe *sf;
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
/*
|
||||
* if p1 != curproc && p1 == &proc0, we're creating a kernel thread.
|
||||
* if l1 != curlwp && l1 == &lwp0, 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
|
||||
|
||||
/* Copy pcb from proc p1 to p2. */
|
||||
*pcb = p1->p_addr->u_pcb;
|
||||
pcb->pcb_onstack = (struct reg *)((u_int)p2->p_addr + USPACE) - 1;
|
||||
*pcb->pcb_onstack = *p1->p_addr->u_pcb.pcb_onstack;
|
||||
/* If p1 is holding the FPU, update the FPU context of p2. */
|
||||
if (fpu_proc == p1)
|
||||
/* Copy pcb from lwp l1 to l2. */
|
||||
*pcb = l1->l_addr->u_pcb;
|
||||
pcb->pcb_onstack = (struct reg *)((u_int)l2->l_addr + USPACE) - 1;
|
||||
*pcb->pcb_onstack = *l1->l_addr->u_pcb.pcb_onstack;
|
||||
/* If l1 is holding the FPU, update the FPU context of l2. */
|
||||
if (fpu_lwp == l1)
|
||||
save_fpu_context(pcb);
|
||||
pmap_activate(p2);
|
||||
pmap_activate(l2);
|
||||
|
||||
/*
|
||||
* Copy the syscframe.
|
||||
*/
|
||||
tf = (struct syscframe *)((u_int)p2->p_addr + USPACE) - 1;
|
||||
tf = (struct syscframe *)((u_int)l2->l_addr + USPACE) - 1;
|
||||
|
||||
/*
|
||||
* If specified, give the child a different stack.
|
||||
|
@ -121,9 +121,31 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
|
|||
if (stack != NULL)
|
||||
tf->sf_regs.r_sp = (u_int)stack + stacksize;
|
||||
|
||||
p2->p_md.md_regs = &tf->sf_regs;
|
||||
l2->l_md.md_regs = &tf->sf_regs;
|
||||
sf = (struct switchframe *)tf - 1;
|
||||
sf->sf_p = p2;
|
||||
sf->sf_lwp= l2;
|
||||
sf->sf_pc = (long) proc_trampoline;
|
||||
sf->sf_fp = (long) &tf->sf_regs.r_fp;
|
||||
sf->sf_r3 = (long) func;
|
||||
sf->sf_r4 = (long) arg;
|
||||
sf->sf_pl = imask[IPL_ZERO];
|
||||
pcb->pcb_ksp = (long) sf;
|
||||
pcb->pcb_kfp = (long) &sf->sf_fp;
|
||||
}
|
||||
|
||||
void
|
||||
cpu_setfunc(l, func, arg)
|
||||
struct lwp *l;
|
||||
void (*func) __P((void *));
|
||||
void *arg;
|
||||
{
|
||||
struct pcb *pcb = &l->l_addr->u_pcb;
|
||||
struct syscframe *tf;
|
||||
struct switchframe *sf;
|
||||
|
||||
tf = (struct syscframe *)((u_int)l->l_addr + USPACE) - 1;
|
||||
sf = (struct switchframe *)tf - 1;
|
||||
sf->sf_lwp = l;
|
||||
sf->sf_pc = (long) proc_trampoline;
|
||||
sf->sf_fp = (long) &tf->sf_regs.r_fp;
|
||||
sf->sf_r3 = (long) func;
|
||||
|
@ -141,16 +163,16 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
|
|||
* saved, so that it goes out with the pcb, which is in the user area.
|
||||
*/
|
||||
void
|
||||
cpu_swapout(p)
|
||||
struct proc *p;
|
||||
cpu_swapout(l)
|
||||
struct lwp *l;
|
||||
{
|
||||
/*
|
||||
* Make sure we save the FP state before the user area vanishes.
|
||||
*/
|
||||
if (fpu_proc != p)
|
||||
if (fpu_lwp != l)
|
||||
return;
|
||||
save_fpu_context(&p->p_addr->u_pcb);
|
||||
fpu_proc = 0;
|
||||
save_fpu_context(&l->l_addr->u_pcb);
|
||||
fpu_lwp = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -161,19 +183,20 @@ cpu_swapout(p)
|
|||
* jumps into switch() to wait for another process to wake up.
|
||||
*/
|
||||
void
|
||||
cpu_exit(arg)
|
||||
struct proc *arg;
|
||||
cpu_exit(arg, proc)
|
||||
struct lwp *arg;
|
||||
int proc;
|
||||
{
|
||||
extern struct user *proc0paddr;
|
||||
register struct proc *p __asm("r3");
|
||||
register struct lwp *l __asm("r3");
|
||||
uvmexp.swtch++;
|
||||
|
||||
/* Copy arg into a register. */
|
||||
movd(arg, p);
|
||||
movd(arg, l);
|
||||
|
||||
/* If we were using the FPU, forget about it. */
|
||||
if (fpu_proc == p)
|
||||
fpu_proc = 0;
|
||||
if (fpu_lwp == l)
|
||||
fpu_lwp = 0;
|
||||
|
||||
/* Switch to temporary stack and address space. */
|
||||
lprd(sp, INTSTACK);
|
||||
|
@ -181,10 +204,13 @@ cpu_exit(arg)
|
|||
|
||||
/* Schedule the vmspace and stack to be freed. */
|
||||
(void) splhigh();
|
||||
exit2(p);
|
||||
if (proc) /* XXXJRT FRAGILE! USE A REGISTER! */
|
||||
exit2(l);
|
||||
else
|
||||
lwp_exit2(l);
|
||||
|
||||
/* Don't update pcb in cpu_switch. */
|
||||
curproc = NULL;
|
||||
curlwp = NULL;
|
||||
cpu_switch(NULL, NULL);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
@ -198,12 +224,13 @@ struct md_core {
|
|||
};
|
||||
|
||||
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 proc *p = l->l_proc;
|
||||
struct md_core md_core;
|
||||
struct coreseg cseg;
|
||||
int error;
|
||||
|
@ -214,12 +241,12 @@ cpu_coredump(p, vp, cred, chdr)
|
|||
chdr->c_cpusize = sizeof(md_core);
|
||||
|
||||
/* Save integer registers. */
|
||||
error = process_read_regs(p, &md_core.intreg);
|
||||
error = process_read_regs(l, &md_core.intreg);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/* Save floating point registers. */
|
||||
error = process_read_fpregs(p, &md_core.freg);
|
||||
error = process_read_fpregs(l, &md_core.freg);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
|
Loading…
Reference in New Issue