Merge the nathanw_sa branch.
This commit is contained in:
parent
f91b0bb3f2
commit
49784e4bd0
@ -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 \
|
||||
|
@ -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)
|
||||
|
||||
/*
|
||||
|
@ -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_ */
|
||||
|
@ -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 */
|
||||
|
87
sys/arch/sh3/include/mcontext.h
Normal file
87
sys/arch/sh3/include/mcontext.h
Normal 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_ */
|
@ -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);
|
||||
|
@ -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_ */
|
||||
|
@ -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_ */
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 \
|
||||
|
3
sys/arch/shark/include/mcontext.h
Normal file
3
sys/arch/shark/include/mcontext.h
Normal file
@ -0,0 +1,3 @@
|
||||
/* $NetBSD: mcontext.h,v 1.2 2003/01/18 06:37:05 thorpej Exp $ */
|
||||
|
||||
#include <arm/mcontext.h>
|
@ -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",
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user