Merge the nathanw_sa branch.

This commit is contained in:
thorpej 2003-01-18 06:33:41 +00:00
parent f91b0bb3f2
commit 49784e4bd0
22 changed files with 660 additions and 215 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.17 2002/11/26 23:30:18 lukem Exp $
# $NetBSD: Makefile,v 1.18 2003/01/18 06:33:41 thorpej Exp $
INCSDIR= /usr/include/sh3
@ -12,7 +12,7 @@ INCS= ansi.h aout_machdep.h asm.h \
int_const.h int_fmtio.h int_limits.h int_mwgwtypes.h int_types.h \
intr.h \
limits.h lock.h \
math.h \
math.h mcontext.h \
param.h pcb.h pmap.h pmc.h proc.h profile.h psl.h \
pte.h ptrace.h \
reg.h \

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.30 2002/11/13 14:00:27 msaitoh Exp $ */
/* $NetBSD: cpu.h,v 1.31 2003/01/18 06:33:41 thorpej Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
@ -80,6 +80,7 @@ extern struct cpu_info cpu_info_store;
*/
#define cpu_swapin(p) /* nothing */
#define cpu_swapout(p) panic("cpu_swapout: can't get here");
#define cpu_proc_fork(p1, p2) /* nothing */
/*
* Arguments to hardclock and gatherstats encapsulate the previous
@ -111,7 +112,7 @@ struct clockframe {
do { \
want_resched = 1; \
if (curproc != NULL) \
aston(curproc); \
aston(curproc); \
} while (/*CONSTCOND*/0)
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: frame.h,v 1.9 2002/06/23 18:35:05 thorpej Exp $ */
/* $NetBSD: frame.h,v 1.10 2003/01/18 06:33:42 thorpej Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
@ -44,6 +44,7 @@
#define _SH3_FRAME_H_
#include <sys/signal.h>
#include <sys/sa.h>
/*
* Exception Stack Frame
@ -101,4 +102,17 @@ struct sigframe {
struct sigcontext sf_sc;
};
/*
* Scheduler activations upcall frame
*/
struct saframe {
#if 0 /* in registers on entry to upcallcode */
int sa_type; /* r4 */
struct sa_t ** sa_sas; /* r5 */
int sa_events; /* r6 */
int sa_interrupted; /* r7 */
#endif
void * sa_arg;
};
#endif /* !_SH3_FRAME_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.h,v 1.7 2002/05/09 12:25:41 uch Exp $ */
/* $NetBSD: locore.h,v 1.8 2003/01/18 06:33:42 thorpej Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -198,9 +198,9 @@
ldc Rm, sr /* unmask all interrupt */
#ifndef _LOCORE
void sh3_switch_setup(struct proc *);
void sh4_switch_setup(struct proc *);
void sh3_switch_resume(struct proc *);
void sh4_switch_resume(struct proc *);
extern void (*__sh_switch_resume)(struct proc *);
void sh3_switch_setup(struct lwp *);
void sh4_switch_setup(struct lwp *);
void sh3_switch_resume(struct lwp *);
void sh4_switch_resume(struct lwp *);
extern void (*__sh_switch_resume)(struct lwp *);
#endif /* !_LOCORE */

View File

@ -0,0 +1,87 @@
/* $NetBSD: mcontext.h,v 1.2 2003/01/18 06:33:41 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 _SH3_MCONTEXT_H_
#define _SH3_MCONTEXT_H_
/*
* Layout of mcontext_t for the sh3 architecture.
*/
#define _NGREG 22
typedef int __greg_t;
typedef __greg_t __gregset_t[_NGREG];
#define _REG_EXPEVT 0
#define _REG_PC 1
#define _REG_SR 2
#define _REG_MACL 3
#define _REG_MACH 4
#define _REG_PR 5
#define _REG_R14 6
#define _REG_R13 7
#define _REG_R12 8
#define _REG_R11 9
#define _REG_R10 10
#define _REG_R9 11
#define _REG_R8 12
#define _REG_R7 13
#define _REG_R6 14
#define _REG_R5 15
#define _REG_R4 16
#define _REG_R3 17
#define _REG_R2 18
#define _REG_R1 19
#define _REG_R0 20
#define _REG_R15 21
/* Convenience synonym */
#define _REG_SP _REG_R15
typedef struct {
int __fpr_fpscr;
double __fpr_regs[8];
} __fpregset_t;
typedef struct {
__gregset_t __gregs;
__fpregset_t __fpregs;
} mcontext_t;
#define _UC_MACHINE_SP(uc) ((uc)->uc_mcontext.__gregs[_REG_SP])
#endif /* !_SH3_MCONTEXT_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: proc.h,v 1.4 2002/05/09 12:28:08 uch Exp $ */
/* $NetBSD: proc.h,v 1.5 2003/01/18 06:33:42 thorpej Exp $ */
/*
* Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
@ -38,28 +38,34 @@
#ifndef _SH3_PROC_H_
#define _SH3_PROC_H_
/*
* Machine-dependent part of the proc structure for sh3.
*/
#include <machine/param.h>
/* Kernel stack PTE */
struct md_upte {
u_int32_t addr;
u_int32_t data;
};
struct mdproc {
struct mdlwp {
struct trapframe *md_regs; /* user context */
struct pcb *md_pcb; /* pcb access address */
int md_flags; /* machine-dependent flags */
/* u-area PTE: *2 .. SH4 data/address data array access */
struct md_upte md_upte[UPAGES * 2];
__volatile int md_astpending; /* AST pending on return to userland */
};
/* md_flags */
#define MDP_USEDFPU 0x0001 /* has used the FPU */
struct mdproc {
__volatile int md_astpending; /* AST pending on return to userland */
};
#ifdef _KERNEL
#ifndef _LOCORE
void sh_proc0_init(void);

View File

@ -1,4 +1,4 @@
/* $NetBSD: signal.h,v 1.4 2002/05/10 15:25:13 uch Exp $ */
/* $NetBSD: signal.h,v 1.5 2003/01/18 06:33:42 thorpej Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
@ -109,5 +109,30 @@ struct sigcontext {
sigset_t sc_mask; /* signal mask to restore (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_pr, &(uc)->uc_mcontext.__gregs[_REG_PR], \
17 * sizeof(unsigned int)); \
(sc)->sc_spc = (uc)->uc_mcontext.__gregs[_REG_PC]; \
(sc)->sc_ssr = (uc)->uc_mcontext.__gregs[_REG_SR]; \
(sc)->sc_expevt = (uc)->uc_mcontext.__gregs[_REG_EXPEVT]; \
(sc)->sc_err = 0; /* XXX */ \
} while (/*CONSTCOND*/0)
#define _SIGCONTEXT_TO_MCONTEXT(sc, uc) \
do { \
memcpy(&(uc)->uc_mcontext.__gregs[_REG_PR], &(sc)->sc_pr, \
17 * sizeof(unsigned int)); \
(uc)->uc_mcontext.__gregs[_REG_PC] = (sc)->sc_spc; \
(uc)->uc_mcontext.__gregs[_REG_SR] = (sc)->sc_ssr; \
(uc)->uc_mcontext.__gregs[_REG_EXPEVT] = (sc)->sc_expevt; \
} while (/*CONSTCOND*/0)
#endif /* !_ANSI_SOURCE && !_POSIX_C_SOURCE && !_XOPEN_SOURCE */
#endif /* !_SH3_SIGNAL_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: userret.h,v 1.3 2002/05/09 12:31:19 uch Exp $ */
/* $NetBSD: userret.h,v 1.4 2003/01/18 06:33:42 thorpej Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -46,10 +46,24 @@
#define _SH3_USERRET_H_
static __inline void
userret(struct proc *p)
userret(struct lwp *l)
{
struct proc *p = l->l_proc;
int sig;
curcpu()->ci_schedstate.spc_curpriority = p->p_priority = p->p_usrpri;
/* Take pending signals. */
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);
curcpu()->ci_schedstate.spc_curpriority = l->l_priority = l->l_usrpri;
}
#endif /* !_SH3_USERRET_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: Locore.c,v 1.14 2002/12/16 02:15:59 thorpej Exp $ */
/* $NetBSD: Locore.c,v 1.15 2003/01/18 06:33:43 thorpej Exp $ */
/*-
* Copyright (c) 1996, 1997, 2002 The NetBSD Foundation, Inc.
@ -95,8 +95,8 @@
#include <sh3/mmu_sh3.h>
#include <sh3/mmu_sh4.h>
void (*__sh_switch_resume)(struct proc *);
struct proc *cpu_switch_search(struct proc *);
void (*__sh_switch_resume)(struct lwp *);
struct lwp *cpu_switch_search(struct lwp *);
void idle(void);
int want_resched;
@ -112,13 +112,13 @@ int want_resched;
* struct proc *cpu_switch_search(struct proc *oldproc):
* Find the highest priority process.
*/
struct proc *
cpu_switch_search(struct proc *oldproc)
struct lwp *
cpu_switch_search(struct lwp *oldlwp)
{
struct prochd *q;
struct proc *p;
struct lwp *l;
curproc = 0;
curlwp = 0;
SCHED_LOCK_IDLE();
while (sched_whichqs == 0) {
@ -128,29 +128,31 @@ cpu_switch_search(struct proc *oldproc)
}
q = &sched_qs[ffs(sched_whichqs) - 1];
p = q->ph_link;
remrunqueue(p);
l = q->ph_link;
remrunqueue(l);
want_resched = 0;
SCHED_UNLOCK_IDLE();
p->p_stat = SONPROC;
l->l_stat = LSONPROC;
if (p != oldproc) {
curpcb = p->p_md.md_pcb;
pmap_activate(p);
if (l != oldlwp) {
struct proc *p = l->l_proc;
curpcb = l->l_md.md_pcb;
pmap_activate(l);
/* Check for Restartable Atomic Sequences. */
if (p->p_nras != 0) {
caddr_t pc;
pc = ras_lookup(p, (caddr_t) p->p_md.md_regs->tf_spc);
pc = ras_lookup(p, (caddr_t) l->l_md.md_regs->tf_spc);
if (pc != (caddr_t) -1)
p->p_md.md_regs->tf_spc = (int) pc;
l->l_md.md_regs->tf_spc = (int) pc;
}
}
curproc = p;
curlwp = l;
return (p);
return (l);
}
/*
@ -169,18 +171,18 @@ idle()
}
/*
* void sh3_switch_setup(struct proc *p):
* void sh3_switch_setup(struct lwp *l):
* prepare kernel stack PTE table. TLB miss handler check these.
*/
void
sh3_switch_setup(struct proc *p)
sh3_switch_setup(struct lwp *l)
{
pt_entry_t *pte;
struct md_upte *md_upte = p->p_md.md_upte;
struct md_upte *md_upte = l->l_md.md_upte;
u_int32_t vpn;
int i;
vpn = (u_int32_t)p->p_addr;
vpn = (u_int32_t)l->l_addr;
vpn &= ~PGOFSET;
for (i = 0; i < UPAGES; i++, vpn += NBPG, md_upte++) {
pte = __pmap_kpte_lookup(vpn);
@ -192,18 +194,18 @@ sh3_switch_setup(struct proc *p)
}
/*
* void sh4_switch_setup(struct proc *p):
* void sh4_switch_setup(struct lwp *l):
* prepare kernel stack PTE table. sh4_switch_resume wired this PTE.
*/
void
sh4_switch_setup(struct proc *p)
sh4_switch_setup(struct lwp *l)
{
pt_entry_t *pte;
struct md_upte *md_upte = p->p_md.md_upte;
struct md_upte *md_upte = l->l_md.md_upte;
u_int32_t vpn;
int i, e;
vpn = (u_int32_t)p->p_addr;
vpn = (u_int32_t)l->l_addr;
vpn &= ~PGOFSET;
e = SH4_UTLB_ENTRY - UPAGES;
for (i = 0; i < UPAGES; i++, e++, vpn += NBPG) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: exception.c,v 1.4 2002/12/21 16:23:59 manu Exp $ */
/* $NetBSD: exception.c,v 1.5 2003/01/18 06:33:43 thorpej Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
@ -55,10 +55,13 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/pool.h>
#include <sys/user.h>
#include <sys/kernel.h>
#include <sys/signal.h>
#include <sys/syscall.h>
#include <sys/sa.h>
#include <sys/savar.h>
#ifdef KTRACE
#include <sys/ktrace.h>
@ -100,29 +103,29 @@ const char *exp_type[] = {
};
const int exp_types = sizeof exp_type / sizeof exp_type[0];
void general_exception(struct proc *, struct trapframe *);
void tlb_exception(struct proc *, struct trapframe *, u_int32_t);
void syscall(struct proc *, struct trapframe *);
void ast(struct proc *, struct trapframe *);
void general_exception(struct lwp *, struct trapframe *);
void tlb_exception(struct lwp *, struct trapframe *, u_int32_t);
void syscall(struct lwp *, struct trapframe *);
void ast(struct lwp *, struct trapframe *);
/*
* void general_exception(struct proc *p, struct trapframe *tf):
* p ... curproc when exception occur.
* void general_exception(struct lwp *l, struct trapframe *tf):
* l ... curlwp when exception occur.
* tf ... full user context.
*/
void
general_exception(struct proc *p, struct trapframe *tf)
general_exception(struct lwp *l, struct trapframe *tf)
{
int expevt = tf->tf_expevt;
boolean_t usermode = !KERNELMODE(tf->tf_ssr);
uvmexp.traps++;
if (p == NULL)
if (l == NULL)
goto do_panic;
if (usermode) {
KDASSERT(p->p_md.md_regs == tf); /* check exception depth */
KDASSERT(l->l_md.md_regs == tf); /* check exception depth */
expevt |= EXP_USER;
}
@ -130,17 +133,17 @@ general_exception(struct proc *p, struct trapframe *tf)
case EXPEVT_TRAPA | EXP_USER:
/* Check for debugger break */
if (_reg_read_4(SH_(TRA)) == (_SH_TRA_BREAK << 2)) {
trapsignal(p, SIGTRAP, tf->tf_expevt);
trapsignal(l, SIGTRAP, tf->tf_expevt);
} else {
syscall(p, tf);
syscall(l, tf);
return;
}
break;
case EXPEVT_ADDR_ERR_LD:
/*FALLTHROUGH*/
case EXPEVT_ADDR_ERR_ST:
KDASSERT(p->p_md.md_pcb->pcb_onfault != NULL);
tf->tf_spc = (int)p->p_md.md_pcb->pcb_onfault;
KDASSERT(l->l_md.md_pcb->pcb_onfault != NULL);
tf->tf_spc = (int)l->l_md.md_pcb->pcb_onfault;
if (tf->tf_spc == NULL)
goto do_panic;
break;
@ -148,24 +151,24 @@ general_exception(struct proc *p, struct trapframe *tf)
case EXPEVT_ADDR_ERR_LD | EXP_USER:
/*FALLTHROUGH*/
case EXPEVT_ADDR_ERR_ST | EXP_USER:
trapsignal(p, SIGSEGV, tf->tf_expevt);
trapsignal(l, SIGSEGV, tf->tf_expevt);
break;
case EXPEVT_RES_INST | EXP_USER:
/*FALLTHROUGH*/
case EXPEVT_SLOT_INST | EXP_USER:
trapsignal(p, SIGILL, tf->tf_expevt);
trapsignal(l, SIGILL, tf->tf_expevt);
break;
case EXPEVT_BREAK | EXP_USER:
trapsignal(p, SIGTRAP, tf->tf_expevt);
trapsignal(l, SIGTRAP, tf->tf_expevt);
break;
default:
goto do_panic;
}
if (usermode)
userret(p);
userret(l);
return;
do_panic:
@ -191,14 +194,15 @@ general_exception(struct proc *p, struct trapframe *tf)
}
/*
* void syscall(struct proc *p, struct trapframe *tf):
* p ... curproc when exception occur.
* void syscall(struct lwp *l, struct trapframe *tf):
* l ... curlwp when exception occur.
* tf ... full user context.
* System call request from POSIX system call gate interface to kernel.
*/
void
syscall(struct proc *p, struct trapframe *tf)
syscall(struct lwp *l, struct trapframe *tf)
{
struct proc *p = l->l_proc;
caddr_t params;
const struct sysent *callp;
int error, opc, nsys;
@ -292,19 +296,14 @@ syscall(struct proc *p, struct trapframe *tf)
if (error)
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] = tf->tf_r1;
error = (*callp->sy_call)(p, args, rval);
error = (*callp->sy_call)(l, args, rval);
switch (error) {
case 0:
/*
* Reinitialize proc pointer `p' as it may be different
* if this is a child returning from fork syscall.
*/
p = curproc;
tf->tf_r0 = rval[0];
tf->tf_r1 = rval[1];
tf->tf_ssr |= PSL_TBIT; /* T bit */
@ -329,19 +328,19 @@ syscall(struct proc *p, struct trapframe *tf)
}
trace_exit(p, code, args, rval, error);
trace_exit(l, code, args, rval, error);
userret(p);
userret(l);
}
/*
* void tlb_exception(struct proc *p, struct trapframe *tf, u_int32_t va):
* p ... curproc when exception occur.
* void tlb_exception(struct lwp *l, struct trapframe *tf, u_int32_t va):
* l ... curlwp when exception occur.
* tf ... full user context.
* va ... fault address.
*/
void
tlb_exception(struct proc *p, struct trapframe *tf, u_int32_t va)
tlb_exception(struct lwp *l, struct trapframe *tf, u_int32_t va)
{
#define TLB_ASSERT(assert, msg) \
do { \
@ -358,11 +357,11 @@ do { \
usermode = !KERNELMODE(tf->tf_ssr);
if (usermode) {
KDASSERT(p->p_md.md_regs == tf);
KDASSERT(l->l_md.md_regs == tf);
} else {
KDASSERT(p == NULL || /* idle */
p == &proc0 || /* kthread */
p->p_md.md_regs != tf); /* other */
KDASSERT(l == NULL || /* idle */
l == &lwp0 || /* kthread */
l->l_md.md_regs != tf); /* other */
}
switch (tf->tf_expevt) {
@ -382,12 +381,12 @@ do { \
TLB_ASSERT((int)va > 0,
"kernel virtual protection fault (load)");
if (usermode) {
trapsignal(p, SIGSEGV, tf->tf_expevt);
trapsignal(l, SIGSEGV, tf->tf_expevt);
goto user_fault;
} else {
TLB_ASSERT(p && p->p_md.md_pcb->pcb_onfault != NULL,
TLB_ASSERT(l && l->l_md.md_pcb->pcb_onfault != NULL,
"no copyin/out fault handler (load protection)");
tf->tf_spc = (int)p->p_md.md_pcb->pcb_onfault;
tf->tf_spc = (int)l->l_md.md_pcb->pcb_onfault;
}
return;
@ -399,18 +398,18 @@ do { \
/* Select address space */
if (usermode) {
TLB_ASSERT(p != NULL, "no curproc");
map = &p->p_vmspace->vm_map;
TLB_ASSERT(l != NULL, "no curlwp");
map = &l->l_proc->p_vmspace->vm_map;
pmap = map->pmap;
} else {
if ((int)va < 0) {
map = kernel_map;
pmap = pmap_kernel();
} else {
TLB_ASSERT(va != 0 && p != NULL &&
p->p_md.md_pcb->pcb_onfault != NULL,
TLB_ASSERT(va != 0 && l != NULL &&
l->l_md.md_pcb->pcb_onfault != NULL,
"invalid user-space access from kernel mode");
map = &p->p_vmspace->vm_map;
map = &l->l_proc->p_vmspace->vm_map;
pmap = map->pmap;
}
}
@ -418,16 +417,16 @@ do { \
/* Lookup page table. if entry found, load it. */
if (track && __pmap_pte_load(pmap, va, track)) {
if (usermode)
userret(p);
userret(l);
return;
}
/* Page not found. call fault handler */
if (!usermode && pmap != pmap_kernel() &&
p->p_md.md_pcb->pcb_faultbail) {
TLB_ASSERT(p->p_md.md_pcb->pcb_onfault != NULL,
l->l_md.md_pcb->pcb_faultbail) {
TLB_ASSERT(l->l_md.md_pcb->pcb_onfault != NULL,
"no copyin/out fault handler (interrupt context)");
tf->tf_spc = (int)p->p_md.md_pcb->pcb_onfault;
tf->tf_spc = (int)l->l_md.md_pcb->pcb_onfault;
return;
}
@ -435,9 +434,10 @@ do { \
/* User stack extension */
if (map != kernel_map &&
(va >= (vaddr_t)p->p_vmspace->vm_maxsaddr) && (va < USRSTACK)) {
(va >= (vaddr_t)l->l_proc->p_vmspace->vm_maxsaddr) &&
(va < USRSTACK)) {
if (err == 0) {
struct vmspace *vm = p->p_vmspace;
struct vmspace *vm = l->l_proc->p_vmspace;
u_int32_t nss;
nss = btoc(USRSTACK - va);
if (nss > vm->vm_ssize)
@ -452,49 +452,51 @@ do { \
boolean_t loaded = __pmap_pte_load(pmap, va, track);
TLB_ASSERT(loaded, "page table entry not found");
if (usermode)
userret(p);
userret(l);
return;
}
/* Page not found. */
if (usermode) {
trapsignal(p, err == ENOMEM ? SIGKILL : SIGSEGV, tf->tf_expevt);
trapsignal(l, err == ENOMEM ? SIGKILL : SIGSEGV, tf->tf_expevt);
goto user_fault;
} else {
TLB_ASSERT(p->p_md.md_pcb->pcb_onfault,
TLB_ASSERT(l->l_md.md_pcb->pcb_onfault,
"no copyin/out fault handler (page not found)");
tf->tf_spc = (int)p->p_md.md_pcb->pcb_onfault;
tf->tf_spc = (int)l->l_md.md_pcb->pcb_onfault;
}
return;
user_fault:
userret(p);
ast(p, tf);
userret(l);
ast(l, tf);
return;
tlb_panic:
panic("tlb_handler: %s va=0x%08x, ssr=0x%08x, spc=0x%08x"
" proc=%p onfault=%p", panic_msg, va, tf->tf_ssr, tf->tf_spc,
p, p ? p->p_md.md_pcb->pcb_onfault : 0);
" lwp=%p onfault=%p", panic_msg, va, tf->tf_ssr, tf->tf_spc,
l, l ? l->l_md.md_pcb->pcb_onfault : 0);
#undef TLB_ASSERT
}
/*
* void ast(struct proc *p, struct trapframe *tf):
* p ... curproc when exception occur.
* void ast(struct lwp *l, struct trapframe *tf):
* l ... curlwp when exception occur.
* tf ... full user context.
* This is called when exception return. if return from kernel to user,
* handle asynchronous software traps and context switch if needed.
*/
void
ast(struct proc *p, struct trapframe *tf)
ast(struct lwp *l, struct trapframe *tf)
{
int sig;
struct proc *p;
if (KERNELMODE(tf->tf_ssr))
return;
KDASSERT(p != NULL);
KDASSERT(p->p_md.md_regs == tf);
KDASSERT(l != NULL);
KDASSERT(l->l_md.md_regs == tf);
p = l->l_proc;
while (p->p_md.md_astpending) {
uvmexp.softs++;
@ -505,16 +507,12 @@ ast(struct proc *p, struct trapframe *tf)
ADDUPROF(p);
}
/* Take pending signals. */
while ((sig = CURSIG(p)) != 0)
postsig(sig);
if (want_resched) {
/* We are being preempted. */
preempt(NULL);
preempt(0);
}
userret(p);
userret(l);
}
}
@ -527,15 +525,53 @@ ast(struct proc *p, struct trapframe *tf)
void
child_return(void *arg)
{
struct proc *p = arg;
struct trapframe *tf = p->p_md.md_regs;
struct lwp *l = arg;
#ifdef KTRACE
struct proc *p = l->l_proc;
#endif
struct trapframe *tf = l->l_md.md_regs;
tf->tf_r0 = 0;
tf->tf_ssr |= PSL_TBIT; /* This indicates no error. */
userret(p);
userret(l);
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSRET))
ktrsysret(p, SYS_fork, 0, 0);
#endif
}
/*
* void startlwp(void *arg):
*
* Start a new LWP.
*/
void
startlwp(void *arg)
{
ucontext_t *uc = arg;
struct lwp *l = curlwp;
int error;
error = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
#ifdef DIAGNOSTIC
if (error)
printf("startlwp: error %d from cpu_setmcontext()", error);
#endif
pool_put(&lwp_uc_pool, uc);
userret(l);
}
/*
* void upcallret(struct lwp *l):
*
* Perform userret() for an LWP.
* XXX This is a terrible name.
*/
void
upcallret(struct lwp *l)
{
userret(l);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: exception_vector.S,v 1.9 2002/05/09 12:24:21 uch Exp $ */
/* $NetBSD: exception_vector.S,v 1.10 2003/01/18 06:33:43 thorpej Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -67,7 +67,7 @@ _C_LABEL(sh_vector_generic):
MOV (EXPEVT, r0)
mov.l @r0, r0
mov.l r0, @(TF_EXPEVT, r14) /* trapframe->tf_expevt = EXPEVT */
/* Get curproc */
/* Get curlwp */
mov.l 3f, r1
mov.l @r1, r4 /* 1st arg */
/* Check TLB exception or not */
@ -110,7 +110,7 @@ _C_LABEL(sh_vector_generic):
2: __EXCEPTION_RETURN
/* NOTREACHED */
.align 2
3: .long _C_LABEL(curproc)
3: .long _C_LABEL(curlwp)
REG_SYMBOL(EXPEVT)
REG_SYMBOL(BBRA)
REG_SYMBOL(TEA)
@ -178,7 +178,7 @@ _C_LABEL(sh3_vector_tlbmiss):
mov r14, r5 /* 2nd arg */
3: __EXCEPTION_RETURN
.align 2
2: .long _C_LABEL(curproc)
2: .long _C_LABEL(curlwp)
1: .long _C_LABEL(tlb_exception)
_L.EXPEVT3: .long SH3_EXPEVT
_L.TEA3: .long SH3_TEA
@ -218,7 +218,7 @@ _C_LABEL(sh4_vector_tlbmiss):
__EXCEPTION_RETURN
.align 2
1: .long _C_LABEL(tlb_exception)
2: .long _C_LABEL(curproc)
2: .long _C_LABEL(curlwp)
_L.EXPEVT4: .long SH4_EXPEVT
_L.TEA4: .long SH4_TEA
___L.VPN_MASK: .long 0xfffff000
@ -257,7 +257,7 @@ _C_LABEL(sh_vector_interrupt):
mov r14, r5 /* 2nd arg */
__EXCEPTION_RETURN
.align 2
1: .long _C_LABEL(curproc)
1: .long _C_LABEL(curlwp)
__L.intc_intr: .long _C_LABEL(intc_intr)
__L.ast: .long _C_LABEL(ast)
__L.uvmexp.intrs: .long _C_LABEL(uvmexp) + UVMEXP_INTRS

View File

@ -1,4 +1,4 @@
# $NetBSD: genassym.cf,v 1.6 2002/06/23 18:35:07 thorpej Exp $
# $NetBSD: genassym.cf,v 1.7 2003/01/18 06:33:43 thorpej Exp $
#-
# Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -67,15 +67,18 @@ define TF_R1 offsetof(struct trapframe, tf_r1)
define TF_R0 offsetof(struct trapframe, tf_r0)
define TF_R15 offsetof(struct trapframe, tf_r15)
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_STAT offsetof(struct proc, p_stat)
define P_WCHAN offsetof(struct proc, p_wchan)
define P_MD offsetof(struct proc, p_md)
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 MD_UPTE offsetof(struct mdproc, md_upte)
define MD_PCB offsetof(struct mdproc, md_pcb)
define L_MD_UPTE offsetof(struct lwp, l_md.md_upte)
define L_MD_PCB offsetof(struct lwp, l_md.md_pcb)
#define P_MD offsetof(struct proc, p_md)
#define MD_UPTE offsetof(struct mdproc, md_upte)
#define MD_PCB offsetof(struct mdproc, md_pcb)
define SF_SIZE sizeof(struct switchframe)
define SF_SR offsetof(struct switchframe, sf_sr)
@ -92,9 +95,8 @@ define SF_R7_BANK offsetof(struct switchframe, sf_r7_bank)
define SC_EFLAGS offsetof(struct sigcontext, sc_ssr)
# can't include sys/proc.h directly.
define SONPROC SONPROC
define SRUN SRUN
define LSONPROC LSONPROC
define LSRUN LSRUN
define UVMEXP_INTRS offsetof(struct uvmexp, intrs)

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore_subr.S,v 1.12 2002/06/23 18:49:33 thorpej Exp $ */
/* $NetBSD: locore_subr.S,v 1.13 2003/01/18 06:33:43 thorpej Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -48,7 +48,7 @@
.text
.align 5 /* align cache line size (32B) */
/*
* void cpu_switch(struct proc *):
* void cpu_switch(struct lwp *):
* Find a runnable process and switch to it. Wait if necessary.
*/
ENTRY(cpu_switch)
@ -79,6 +79,7 @@ ENTRY(cpu_switch)
bt/s 1f
mov r0, r4 /* new proc */
_L.doswitch:
/* Setup kernel stack */
mov.l _L.SF, r0
mov.l @(r0, r4), r1 /* switch frame */
@ -100,8 +101,16 @@ ENTRY(cpu_switch)
__EXCEPTION_UNBLOCK(r0, r1)
/* Now OK to use kernel stack. */
/* Return 1 indicating "we switched". */
bra 2f
mov #1, r2
1: /* Return 0 indicating "didn't switch". */
mov #0, r2
/* Restore new process's context from switchframe */
1: mov.l _L.SF, r0
/* NOTE: r2 has return value! */
2: mov.l _L.SF, r0
mov.l @(r0, r4), r1
add #4, r1 /* r15 already restored */
mov.l @r1+, r14
@ -114,13 +123,48 @@ ENTRY(cpu_switch)
lds.l @r1+, pr
add #4, r1 /* r6_bank already restored */
ldc.l @r1+, sr
/* r2 has the return value; stuff it into r0 now. */
rts
nop
mov r2, r0
.align 2
_L.SF: .long (P_MD + MD_PCB)
_L.SF: .long (L_MD_PCB)
_L.cpu_switch_search: .long _C_LABEL(cpu_switch_search)
FUNC_SYMBOL(switch_resume)
/*
* void cpu_switchto(struct lwp *current, struct lwp *next)
* Switch to the specified next LWP.
*/
ENTRY(cpu_switchto)
/* Save current process's context to switchframe. */
mov.l _L.SFp, r0
mov.l @(r0, r4), r1
add #SF_SIZE, r1
stc.l r7_bank,@-r1
stc.l sr, @-r1
stc.l r6_bank,@-r1
sts.l pr, @-r1
mov.l r8, @-r1
mov.l r9, @-r1
mov.l r10, @-r1
mov.l r11, @-r1
mov.l r12, @-r1
mov.l r13, @-r1
mov.l r14, @-r1
mov.l r15, @-r1
/*
* Put the incoming LWP in r4 and jump into the middle
* of cpu_switch(), and let it do the work to restore the
* incoming LWP's context.
*/
bra _L.doswitch
mov r5, r4
.align 2
_L.SFp: .long (L_MD_PCB)
#ifdef SH3
/*
* void sh3_switch_resume(sturct proc *p)
@ -211,7 +255,7 @@ _L.4_ITLB_AA: .long SH4_ITLB_AA
_L.VPN_MASK: .long 0xfffff000
_L.P2BASE: .long 0xa0000000
#endif /* SH4 */
_L.UPTE: .long (P_MD + MD_UPTE)
_L.UPTE: .long (L_MD_UPTE)
/*
* int _cpu_intr_raise(int s):

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.c,v 1.41 2002/12/16 07:18:30 thorpej Exp $ */
/* $NetBSD: pmap.c,v 1.42 2003/01/18 06:33:44 thorpej Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -291,9 +291,9 @@ pmap_reference(pmap_t pmap)
}
void
pmap_activate(struct proc *p)
pmap_activate(struct lwp *l)
{
pmap_t pmap = p->p_vmspace->vm_map.pmap;
pmap_t pmap = l->l_proc->p_vmspace->vm_map.pmap;
if (pmap->pm_asid == -1)
pmap->pm_asid = __pmap_asid_alloc();
@ -303,7 +303,7 @@ pmap_activate(struct proc *p)
}
void
pmap_deactivate(struct proc *p)
pmap_deactivate(struct lwp *l)
{
/* Nothing to do */

View File

@ -1,4 +1,4 @@
/* $NetBSD: process_machdep.c,v 1.5 2002/04/29 09:33:30 uch Exp $ */
/* $NetBSD: process_machdep.c,v 1.6 2003/01/18 06:33:44 thorpej Exp $ */
/*
* Copyright (c) 1995, 1996, 1997
@ -76,19 +76,17 @@
#include <machine/psl.h>
#include <machine/reg.h>
static __inline struct trapframe *process_frame(struct proc *);
static __inline struct trapframe *
process_frame(struct proc *p)
process_frame(struct lwp *l)
{
return (p->p_md.md_regs);
return (l->l_md.md_regs);
}
int
process_read_regs(struct proc *p, struct reg *regs)
process_read_regs(struct lwp *l, struct reg *regs)
{
struct trapframe *tf = process_frame(p);
struct trapframe *tf = process_frame(l);
regs->r_spc = tf->tf_spc;
regs->r_ssr = tf->tf_ssr;
@ -116,9 +114,9 @@ process_read_regs(struct proc *p, struct reg *regs)
}
int
process_write_regs(struct proc *p, struct reg *regs)
process_write_regs(struct lwp *l, struct reg *regs)
{
struct trapframe *tf = process_frame(p);
struct trapframe *tf = process_frame(l);
/*
* Check for security violations.
@ -154,8 +152,8 @@ process_write_regs(struct proc *p, struct reg *regs)
}
int
process_sstep(p, sstep)
struct proc *p;
process_sstep(l, sstep)
struct lwp *l;
{
if (sstep)
@ -165,9 +163,9 @@ process_sstep(p, sstep)
}
int
process_set_pc(struct proc *p, caddr_t addr)
process_set_pc(struct lwp *l, caddr_t addr)
{
struct trapframe *tf = process_frame(p);
struct trapframe *tf = process_frame(l);
tf->tf_spc = (int)addr;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sh3_machdep.c,v 1.45 2002/08/25 20:21:42 thorpej Exp $ */
/* $NetBSD: sh3_machdep.c,v 1.46 2003/01/18 06:33:44 thorpej Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998, 2002 The NetBSD Foundation, Inc.
@ -90,7 +90,10 @@
#include <sys/mount.h>
#include <sys/proc.h>
#include <sys/signalvar.h>
#include <sys/sa.h>
#include <sys/savar.h>
#include <sys/syscallargs.h>
#include <sys/ucontext.h>
#include <sys/user.h>
#ifdef KGDB
@ -216,7 +219,7 @@ sh_proc0_init()
/* Setup proc0 */
proc0paddr = (struct user *)u;
proc0.p_addr = proc0paddr;
lwp0.l_addr = proc0paddr;
/*
* u-area map:
* |user| .... | ............... |
@ -226,8 +229,8 @@ sh_proc0_init()
* stack top ... r7_bank
* current stack ... r15
*/
curpcb = proc0.p_md.md_pcb = &proc0.p_addr->u_pcb;
curupte = proc0.p_md.md_upte;
curpcb = lwp0.l_md.md_pcb = &lwp0.l_addr->u_pcb;
curupte = lwp0.l_md.md_upte;
sf = &curpcb->pcb_sf;
sf->sf_r6_bank = u + NBPG;
@ -235,7 +238,7 @@ sh_proc0_init()
__asm__ __volatile__("ldc %0, r6_bank" :: "r"(sf->sf_r6_bank));
__asm__ __volatile__("ldc %0, r7_bank" :: "r"(sf->sf_r7_bank));
proc0.p_md.md_regs = (struct trapframe *)sf->sf_r6_bank - 1;
lwp0.l_md.md_regs = (struct trapframe *)sf->sf_r6_bank - 1;
#ifdef KSTACK_DEBUG
memset((char *)(u + sizeof(struct user)), 0x5a,
NBPG - sizeof(struct user));
@ -361,6 +364,47 @@ dumpsys()
{
}
/*
* void cpu_upcall(struct lwp *l, int type, int nevents, int ninterrupted,
* void *sas, void *ap, void *sp, sa_upcall_t upcall):
*
* Send an upcall to userland.
*/
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;
struct saframe *sf, frame;
tf = l->l_md.md_regs;
/* Build the stack frame. */
#if 0 /* First 4 args in regs (see below). */
frame.sa_type = type;
frame.sa_sas = sas;
frame.sa_events = nevents;
frame.sa_interrupted = ninterrupted;
#endif
frame.sa_arg = ap;
sf = (struct saframe *)sp - 1;
if (copyout(&frame, sf, sizeof(frame)) != 0) {
/* Copying onto the stack didn't work. Die. */
sigexit(l, SIGILL);
/* NOTREACHED */
}
tf->tf_r4 = type;
tf->tf_r5 = (int) sas;
tf->tf_r6 = nevents;
tf->tf_r7 = ninterrupted;
tf->tf_spc = (int) upcall;
tf->tf_pr = 0; /* no return */
tf->tf_r15 = (int) sf;
}
/*
* Send an interrupt to process.
*
@ -374,14 +418,15 @@ dumpsys()
void
sendsig(int sig, 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 = p->p_md.md_regs;
tf = l->l_md.md_regs;
/* Do we need to jump onto the signal stack? */
onstack =
@ -429,7 +474,7 @@ sendsig(int sig, sigset_t *mask, u_long code)
* Process has trashed its stack; give it an illegal
* instruction to halt it in its tracks.
*/
sigexit(p, SIGILL);
sigexit(l, SIGILL);
/* NOTREACHED */
}
@ -450,7 +495,7 @@ sendsig(int sig, sigset_t *mask, u_long code)
default:
/* Don't know what trampoline version; kill it. */
sigexit(p, SIGILL);
sigexit(l, SIGILL);
}
tf->tf_r4 = sig;
@ -475,13 +520,14 @@ sendsig(int sig, sigset_t *mask, u_long code)
* a machine fault.
*/
int
sys___sigreturn14(struct proc *p, void *v, register_t *retval)
sys___sigreturn14(struct lwp *l, void *v, register_t *retval)
{
struct sys___sigreturn14_args /* {
syscallarg(struct sigcontext *) sigcntxp;
} */ *uap = v;
struct sigcontext *scp, context;
struct trapframe *tf;
struct proc *p = l->l_proc;
/*
* The trampoline code hands us the context.
@ -493,7 +539,7 @@ sys___sigreturn14(struct proc *p, void *v, register_t *retval)
return (EFAULT);
/* Restore signal context. */
tf = p->p_md.md_regs;
tf = l->l_md.md_regs;
/* Check for security violations. */
if (((context.sc_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0)
@ -531,17 +577,97 @@ sys___sigreturn14(struct proc *p, void *v, register_t *retval)
return (EJUSTRETURN);
}
void
cpu_getmcontext(l, mcp, flags)
struct lwp *l;
mcontext_t *mcp;
unsigned int *flags;
{
const struct trapframe *tf = l->l_md.md_regs;
__greg_t *gr = mcp->__gregs;
/* Save register context. */
gr[_REG_EXPEVT] = tf->tf_expevt;
gr[_REG_PC] = tf->tf_spc;
gr[_REG_SR] = tf->tf_ssr;
gr[_REG_MACL] = tf->tf_macl;
gr[_REG_MACH] = tf->tf_mach;
gr[_REG_PR] = tf->tf_pr;
gr[_REG_R14] = tf->tf_r14;
gr[_REG_R13] = tf->tf_r13;
gr[_REG_R12] = tf->tf_r12;
gr[_REG_R11] = tf->tf_r11;
gr[_REG_R10] = tf->tf_r10;
gr[_REG_R9] = tf->tf_r9;
gr[_REG_R8] = tf->tf_r8;
gr[_REG_R7] = tf->tf_r7;
gr[_REG_R6] = tf->tf_r6;
gr[_REG_R5] = tf->tf_r5;
gr[_REG_R4] = tf->tf_r4;
gr[_REG_R3] = tf->tf_r3;
gr[_REG_R2] = tf->tf_r2;
gr[_REG_R1] = tf->tf_r1;
gr[_REG_R0] = tf->tf_r0;
gr[_REG_R15] = tf->tf_r15;
*flags |= _UC_CPU;
/* FPU context is currently not handled by the kernel. */
memset(&mcp->__fpregs, 0, sizeof (mcp->__fpregs));
}
int
cpu_setmcontext(l, mcp, flags)
struct lwp *l;
const mcontext_t *mcp;
unsigned int flags;
{
struct trapframe *tf = l->l_md.md_regs;
const __greg_t *gr = mcp->__gregs;
/* Restore register context, if any. */
if ((flags & _UC_CPU) != 0) {
/* Check for security violations. */
if (((tf->tf_ssr ^ gr[_REG_SR]) & PSL_USERSTATIC) != 0)
return (EINVAL);
/* _REG_EXPEVT not restored */
tf->tf_spc = gr[_REG_PC];
tf->tf_ssr = gr[_REG_SR];
tf->tf_macl = gr[_REG_MACL];
tf->tf_mach = gr[_REG_MACH];
tf->tf_pr = gr[_REG_PR];
tf->tf_r14 = gr[_REG_R14];
tf->tf_r13 = gr[_REG_R13];
tf->tf_r12 = gr[_REG_R12];
tf->tf_r11 = gr[_REG_R11];
tf->tf_r10 = gr[_REG_R10];
tf->tf_r9 = gr[_REG_R9];
tf->tf_r8 = gr[_REG_R8];
tf->tf_r7 = gr[_REG_R7];
tf->tf_r6 = gr[_REG_R6];
tf->tf_r5 = gr[_REG_R5];
tf->tf_r4 = gr[_REG_R4];
tf->tf_r3 = gr[_REG_R3];
tf->tf_r2 = gr[_REG_R2];
tf->tf_r1 = gr[_REG_R1];
tf->tf_r0 = gr[_REG_R0];
tf->tf_r15 = gr[_REG_R15];
}
return (0);
}
/*
* Clear registers on exec
*/
void
setregs(struct proc *p, struct exec_package *pack, u_long stack)
setregs(struct lwp *l, struct exec_package *pack, u_long stack)
{
struct trapframe *tf;
p->p_md.md_flags &= ~MDP_USEDFPU;
l->l_md.md_flags &= ~MDP_USEDFPU;
tf = p->p_md.md_regs;
tf = l->l_md.md_regs;
tf->tf_r0 = 0;
tf->tf_r1 = 0;
@ -552,7 +678,7 @@ setregs(struct proc *p, struct exec_package *pack, u_long stack)
tf->tf_r6 = stack + 4 * tf->tf_r4 + 8; /* envp */
tf->tf_r7 = 0;
tf->tf_r8 = 0;
tf->tf_r9 = (int)p->p_psstr;
tf->tf_r9 = (int)l->l_proc->p_psstr;
tf->tf_r10 = 0;
tf->tf_r11 = 0;
tf->tf_r12 = 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sys_machdep.c,v 1.7 2002/05/10 15:28:45 uch Exp $ */
/* $NetBSD: sys_machdep.c,v 1.8 2003/01/18 06:33:45 thorpej Exp $ */
/*-
* Copyright (c) 1995, 1997
@ -43,10 +43,11 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mount.h>
#include <sys/sa.h>
#include <sys/syscallargs.h>
int
sys_sysarch(struct proc *p, void *v, register_t *retval)
sys_sysarch(struct lwp *l, void *v, register_t *retval)
{
struct sys_sysarch_args __attribute__((__unused__)) *uap = v;

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.34 2002/09/22 05:42:20 gmcgarry Exp $ */
/* $NetBSD: vm_machdep.c,v 1.35 2003/01/18 06:33:45 thorpej Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
@ -67,6 +67,8 @@
#include <sh3/mmu.h>
#include <sh3/cache.h>
extern void proc_trampoline(void);
/*
* Finish a fork operation, with process p2 nearly set up.
* Copy and update the pcb and trap frame, making the child ready to run.
@ -86,20 +88,19 @@
* accordingly.
*/
void
cpu_fork(struct proc *p1, struct proc *p2, void *stack,
cpu_lwp_fork(struct lwp *l1, struct lwp *l2, void *stack,
size_t stacksize, void (*func)(void *), void *arg)
{
extern void proc_trampoline(void);
struct pcb *pcb;
struct trapframe *tf;
struct switchframe *sf;
vaddr_t spbase, fptop;
#define P1ADDR(x) (SH3_PHYS_TO_P1SEG(*__pmap_kpte_lookup(x) & PG_PPN))
KDASSERT(!(p1 != curproc && p1 != &proc0));
KDASSERT(!(l1 != curlwp && l1 != &lwp0));
/* Copy flags */
p2->p_md.md_flags = p1->p_md.md_flags;
l2->l_md.md_flags = l1->l_md.md_flags;
#ifdef SH3
/*
@ -108,23 +109,20 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack,
* exception. For SH3, we are 4K page, P3/P1 conversion don't
* cause virtual-aliasing.
*/
if (CPU_IS_SH3) {
pcb = (struct pcb *)P1ADDR((vaddr_t)&p2->p_addr->u_pcb);
p2->p_md.md_pcb = pcb;
fptop = (vaddr_t)pcb + NBPG;
}
if (CPU_IS_SH3)
pcb = (struct pcb *)P1ADDR((vaddr_t)&l2->l_addr->u_pcb);
#endif /* SH3 */
#ifdef SH4
/* SH4 can make wired entry, no need to convert to P1. */
if (CPU_IS_SH4) {
pcb = &p2->p_addr->u_pcb;
p2->p_md.md_pcb = pcb;
fptop = (vaddr_t)pcb + NBPG;
}
if (CPU_IS_SH4)
pcb = &l2->l_addr->u_pcb;
#endif /* SH4 */
l2->l_md.md_pcb = pcb;
fptop = (vaddr_t)pcb + NBPG;
/* set up the kernel stack pointer */
spbase = (vaddr_t)p2->p_addr + NBPG;
spbase = (vaddr_t)l2->l_addr + NBPG;
#ifdef P1_STACK
/* Convert to P1 from P3 */
/*
@ -132,17 +130,17 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack,
* is accessed from P1 instead of P3.
*/
if (SH_HAS_VIRTUAL_ALIAS)
sh_dcache_wbinv_range((vaddr_t)p2->p_addr, USPACE);
sh_dcache_wbinv_range((vaddr_t)l2->l_addr, USPACE);
spbase = P1ADDR(spbase);
#else /* P1_STACK */
/* Prepare u-area PTEs */
#ifdef SH3
if (CPU_IS_SH3)
sh3_switch_setup(p2);
sh3_switch_setup(l2);
#endif
#ifdef SH4
if (CPU_IS_SH4)
sh4_switch_setup(p2);
sh4_switch_setup(l2);
#endif
#endif /* P1_STACK */
@ -157,8 +155,8 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack,
/*
* Copy the user context.
*/
p2->p_md.md_regs = tf = (struct trapframe *)fptop - 1;
memcpy(tf, p1->p_md.md_regs, sizeof(struct trapframe));
l2->l_md.md_regs = tf = (struct trapframe *)fptop - 1;
memcpy(tf, l1->l_md.md_regs, sizeof(struct trapframe));
/*
* If specified, give the child a different stack.
@ -183,22 +181,107 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack,
}
/*
* void cpu_exit(sturct proc *p):
* + Change kernel context to proc0's one.
* + Schedule freeing process 'p' resources.
* void cpu_setfunc(struct lwp *l, void (*func)(void *), void *arg):
* + Reset the stack pointer for the process.
* + Arrange to the process to call the specified func
* with argument via the proc_trampoline.
*
* XXX There is a lot of duplicated code here (with cpu_lwp_fork()).
*/
void
cpu_setfunc(struct lwp *l, void (*func)(void *), void *arg)
{
struct pcb *pcb;
struct trapframe *tf;
struct switchframe *sf;
vaddr_t fptop, spbase;
#ifdef SH3
/*
* Convert frame pointer top to P1. because SH3 can't make
* wired TLB entry, context store space accessing must not cause
* exception. For SH3, we are 4K page, P3/P1 conversion don't
* cause virtual-aliasing.
*/
if (CPU_IS_SH3)
pcb = (struct pcb *)P1ADDR((vaddr_t)&l->l_addr->u_pcb);
#endif /* SH3 */
#ifdef SH4
/* SH4 can make wired entry, no need to convert to P1. */
if (CPU_IS_SH4)
pcb = &l->l_addr->u_pcb;
#endif /* SH4 */
fptop = (vaddr_t)pcb + NBPG;
l->l_md.md_pcb = pcb;
/* set up the kernel stack pointer */
spbase = (vaddr_t)l->l_addr + NBPG;
#ifdef P1_STACK
/* Convert to P1 from P3 */
/*
* wbinv u-area to avoid cache-aliasing, since kernel stack
* is accessed from P1 instead of P3.
*/
if (SH_HAS_VIRTUAL_ALIAS)
sh_dcache_wbinv_range((vaddr_t)l->l_addr, USPACE);
spbase = P1ADDR(spbase);
#else /* P1_STACK */
/* Prepare u-area PTEs */
#ifdef SH3
if (CPU_IS_SH3)
sh3_switch_setup(l);
#endif
#ifdef SH4
if (CPU_IS_SH4)
sh4_switch_setup(l);
#endif
#endif /* P1_STACK */
#ifdef KSTACK_DEBUG
/* Fill magic number for tracking */
memset((char *)fptop - NBPG + sizeof(struct user), 0x5a,
NBPG - sizeof(struct user));
memset((char *)spbase, 0xa5, (USPACE - NBPG));
memset(&pcb->pcb_sf, 0xb4, sizeof(struct switchframe));
#endif /* KSTACK_DEBUG */
l->l_md.md_regs = tf = (struct trapframe *)fptop - 1;
tf->tf_ssr = PSL_USERSET;
/* Setup switch frame */
sf = &pcb->pcb_sf;
sf->sf_r11 = (int)arg; /* proc_trampoline hook func */
sf->sf_r12 = (int)func; /* proc_trampoline hook func's arg */
sf->sf_r15 = spbase + USPACE - NBPG; /* current stack pointer */
sf->sf_r7_bank = sf->sf_r15; /* stack top */
sf->sf_r6_bank = (vaddr_t)tf; /* current frame pointer */
/* when switch to me, jump to proc_trampoline */
sf->sf_pr = (int)proc_trampoline;
/*
* Enable interrupt when switch frame is restored, since
* kernel thread begin to run without restoring trapframe.
*/
sf->sf_sr = PSL_MD; /* kernel mode, interrupt enable */
}
/*
* void cpu_exit(struct lwp *l):
* + Change kernel context to lwp0's one.
* + Schedule freeing process 'l' resources.
* + switch to another process.
*/
void
cpu_exit(struct proc *p)
cpu_exit(struct lwp *l, int proc)
{
struct switchframe *sf;
splsched();
uvmexp.swtch++;
/* Switch to proc0 stack */
curproc = 0;
curpcb = proc0.p_md.md_pcb;
/* Switch to lwp0 stack */
curlwp = 0;
curpcb = lwp0.l_md.md_pcb;
sf = &curpcb->pcb_sf;
__asm__ __volatile__(
"mov %0, r15;" /* current stack */
@ -210,9 +293,12 @@ cpu_exit(struct proc *p)
"r"(sf->sf_r7_bank));
/* Schedule freeing process resources */
exit2(p);
if (proc)
exit2(l);
else
lwp_exit2(l);
cpu_switch(p, NULL);
cpu_switch(l, NULL);
/* NOTREACHED */
}
@ -224,7 +310,7 @@ struct md_core {
};
int
cpu_coredump(struct proc *p, struct vnode *vp, struct ucred *cred,
cpu_coredump(struct lwp *l, struct vnode *vp, struct ucred *cred,
struct core *chdr)
{
struct md_core md_core;
@ -237,7 +323,7 @@ cpu_coredump(struct proc *p, struct vnode *vp, struct ucred *cred,
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;
@ -248,13 +334,13 @@ cpu_coredump(struct proc *p, struct vnode *vp, struct ucred *cred,
error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cseg, chdr->c_seghdrsize,
(off_t)chdr->c_hdrsize, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred,
(int *)0, p);
(int *)0, l->l_proc);
if (error)
return error;
error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&md_core, sizeof(md_core),
(off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), UIO_SYSSPACE,
IO_NODELOCKED|IO_UNIT, cred, (int *)0, p);
IO_NODELOCKED|IO_UNIT, cred, (int *)0, l->l_proc);
if (error)
return error;

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.4 2002/11/26 23:30:28 lukem Exp $
# $NetBSD: Makefile,v 1.5 2003/01/18 06:37:05 thorpej Exp $
INCSDIR= /usr/include/shark
@ -12,7 +12,7 @@ INCS= ansi.h aout_machdep.h asm.h \
int_const.h int_fmtio.h int_limits.h int_mwgwtypes.h int_types.h \
intr.h ipkdb.h \
limits.h lock.h \
math.h \
math.h mcontext.h \
param.h pcb.h pmap.h pmc.h proc.h profile.h ptrace.h \
reg.h \
setjmp.h signal.h stdarg.h sysarch.h \

View File

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

View File

@ -1,4 +1,4 @@
/* $NetBSD: ofw.c,v 1.21 2002/10/05 17:01:50 chs Exp $ */
/* $NetBSD: ofw.c,v 1.22 2003/01/18 06:37:05 thorpej Exp $ */
/*
* Copyright 1997
@ -317,7 +317,7 @@ ofw_boot(howto, bootstr)
{
#ifdef DIAGNOSTIC
printf("boot: howto=%08x curproc=%p\n", howto, curproc);
printf("boot: howto=%08x curlwp=%p\n", howto, curlwp);
printf("current_mask=%08x spl_mask=%08x\n", current_mask, spl_mask);
printf("ipl_bio=%08x ipl_net=%08x ipl_tty=%08x ipl_imp=%08x\n",

View File

@ -1,4 +1,4 @@
/* $NetBSD: profile.c,v 1.5 2002/10/23 09:12:03 jdolecek Exp $ */
/* $NetBSD: profile.c,v 1.6 2003/01/18 06:37:06 thorpej Exp $ */
/*
* Copyright 1997
@ -516,7 +516,7 @@ profFiq(int x)
if ( (profTable->hdr.mode & SAMPLE_PROC) &&
((spsr & STATUS_MODE_MASK) == USER_MODE) )
{
if ( curproc->p_pid == profTable->hdr.pid )
if ( curlwp->p_pid == profTable->hdr.pid )
{
profEnter(profTable, stacklr-4);
}