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
|
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 \
|
int_const.h int_fmtio.h int_limits.h int_mwgwtypes.h int_types.h \
|
||||||
intr.h \
|
intr.h \
|
||||||
limits.h lock.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 \
|
param.h pcb.h pmap.h pmc.h proc.h profile.h psl.h \
|
||||||
pte.h ptrace.h \
|
pte.h ptrace.h \
|
||||||
reg.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.
|
* 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_swapin(p) /* nothing */
|
||||||
#define cpu_swapout(p) panic("cpu_swapout: can't get here");
|
#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
|
* Arguments to hardclock and gatherstats encapsulate the previous
|
||||||
@ -111,7 +112,7 @@ struct clockframe {
|
|||||||
do { \
|
do { \
|
||||||
want_resched = 1; \
|
want_resched = 1; \
|
||||||
if (curproc != NULL) \
|
if (curproc != NULL) \
|
||||||
aston(curproc); \
|
aston(curproc); \
|
||||||
} while (/*CONSTCOND*/0)
|
} 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.
|
* Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
|
||||||
@ -44,6 +44,7 @@
|
|||||||
#define _SH3_FRAME_H_
|
#define _SH3_FRAME_H_
|
||||||
|
|
||||||
#include <sys/signal.h>
|
#include <sys/signal.h>
|
||||||
|
#include <sys/sa.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exception Stack Frame
|
* Exception Stack Frame
|
||||||
@ -101,4 +102,17 @@ struct sigframe {
|
|||||||
struct sigcontext sf_sc;
|
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_ */
|
#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.
|
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||||
@ -198,9 +198,9 @@
|
|||||||
ldc Rm, sr /* unmask all interrupt */
|
ldc Rm, sr /* unmask all interrupt */
|
||||||
|
|
||||||
#ifndef _LOCORE
|
#ifndef _LOCORE
|
||||||
void sh3_switch_setup(struct proc *);
|
void sh3_switch_setup(struct lwp *);
|
||||||
void sh4_switch_setup(struct proc *);
|
void sh4_switch_setup(struct lwp *);
|
||||||
void sh3_switch_resume(struct proc *);
|
void sh3_switch_resume(struct lwp *);
|
||||||
void sh4_switch_resume(struct proc *);
|
void sh4_switch_resume(struct lwp *);
|
||||||
extern void (*__sh_switch_resume)(struct proc *);
|
extern void (*__sh_switch_resume)(struct lwp *);
|
||||||
#endif /* !_LOCORE */
|
#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.
|
* Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
|
||||||
@ -38,28 +38,34 @@
|
|||||||
|
|
||||||
#ifndef _SH3_PROC_H_
|
#ifndef _SH3_PROC_H_
|
||||||
#define _SH3_PROC_H_
|
#define _SH3_PROC_H_
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Machine-dependent part of the proc structure for sh3.
|
* Machine-dependent part of the proc structure for sh3.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <machine/param.h>
|
||||||
|
|
||||||
/* Kernel stack PTE */
|
/* Kernel stack PTE */
|
||||||
struct md_upte {
|
struct md_upte {
|
||||||
u_int32_t addr;
|
u_int32_t addr;
|
||||||
u_int32_t data;
|
u_int32_t data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mdproc {
|
struct mdlwp {
|
||||||
struct trapframe *md_regs; /* user context */
|
struct trapframe *md_regs; /* user context */
|
||||||
struct pcb *md_pcb; /* pcb access address */
|
struct pcb *md_pcb; /* pcb access address */
|
||||||
int md_flags; /* machine-dependent flags */
|
int md_flags; /* machine-dependent flags */
|
||||||
/* u-area PTE: *2 .. SH4 data/address data array access */
|
/* u-area PTE: *2 .. SH4 data/address data array access */
|
||||||
struct md_upte md_upte[UPAGES * 2];
|
struct md_upte md_upte[UPAGES * 2];
|
||||||
__volatile int md_astpending; /* AST pending on return to userland */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* md_flags */
|
/* md_flags */
|
||||||
#define MDP_USEDFPU 0x0001 /* has used the FPU */
|
#define MDP_USEDFPU 0x0001 /* has used the FPU */
|
||||||
|
|
||||||
|
struct mdproc {
|
||||||
|
__volatile int md_astpending; /* AST pending on return to userland */
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef _KERNEL
|
#ifdef _KERNEL
|
||||||
#ifndef _LOCORE
|
#ifndef _LOCORE
|
||||||
void sh_proc0_init(void);
|
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.
|
* 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) */
|
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 /* !_ANSI_SOURCE && !_POSIX_C_SOURCE && !_XOPEN_SOURCE */
|
||||||
#endif /* !_SH3_SIGNAL_H_ */
|
#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.
|
* Copyright (c) 1988 University of Utah.
|
||||||
@ -46,10 +46,24 @@
|
|||||||
#define _SH3_USERRET_H_
|
#define _SH3_USERRET_H_
|
||||||
|
|
||||||
static __inline void
|
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_ */
|
#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.
|
* Copyright (c) 1996, 1997, 2002 The NetBSD Foundation, Inc.
|
||||||
@ -95,8 +95,8 @@
|
|||||||
#include <sh3/mmu_sh3.h>
|
#include <sh3/mmu_sh3.h>
|
||||||
#include <sh3/mmu_sh4.h>
|
#include <sh3/mmu_sh4.h>
|
||||||
|
|
||||||
void (*__sh_switch_resume)(struct proc *);
|
void (*__sh_switch_resume)(struct lwp *);
|
||||||
struct proc *cpu_switch_search(struct proc *);
|
struct lwp *cpu_switch_search(struct lwp *);
|
||||||
void idle(void);
|
void idle(void);
|
||||||
int want_resched;
|
int want_resched;
|
||||||
|
|
||||||
@ -112,13 +112,13 @@ int want_resched;
|
|||||||
* struct proc *cpu_switch_search(struct proc *oldproc):
|
* struct proc *cpu_switch_search(struct proc *oldproc):
|
||||||
* Find the highest priority process.
|
* Find the highest priority process.
|
||||||
*/
|
*/
|
||||||
struct proc *
|
struct lwp *
|
||||||
cpu_switch_search(struct proc *oldproc)
|
cpu_switch_search(struct lwp *oldlwp)
|
||||||
{
|
{
|
||||||
struct prochd *q;
|
struct prochd *q;
|
||||||
struct proc *p;
|
struct lwp *l;
|
||||||
|
|
||||||
curproc = 0;
|
curlwp = 0;
|
||||||
|
|
||||||
SCHED_LOCK_IDLE();
|
SCHED_LOCK_IDLE();
|
||||||
while (sched_whichqs == 0) {
|
while (sched_whichqs == 0) {
|
||||||
@ -128,29 +128,31 @@ cpu_switch_search(struct proc *oldproc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
q = &sched_qs[ffs(sched_whichqs) - 1];
|
q = &sched_qs[ffs(sched_whichqs) - 1];
|
||||||
p = q->ph_link;
|
l = q->ph_link;
|
||||||
remrunqueue(p);
|
remrunqueue(l);
|
||||||
want_resched = 0;
|
want_resched = 0;
|
||||||
SCHED_UNLOCK_IDLE();
|
SCHED_UNLOCK_IDLE();
|
||||||
|
|
||||||
p->p_stat = SONPROC;
|
l->l_stat = LSONPROC;
|
||||||
|
|
||||||
if (p != oldproc) {
|
if (l != oldlwp) {
|
||||||
curpcb = p->p_md.md_pcb;
|
struct proc *p = l->l_proc;
|
||||||
pmap_activate(p);
|
|
||||||
|
curpcb = l->l_md.md_pcb;
|
||||||
|
pmap_activate(l);
|
||||||
|
|
||||||
/* Check for Restartable Atomic Sequences. */
|
/* Check for Restartable Atomic Sequences. */
|
||||||
if (p->p_nras != 0) {
|
if (p->p_nras != 0) {
|
||||||
caddr_t pc;
|
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)
|
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.
|
* prepare kernel stack PTE table. TLB miss handler check these.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
sh3_switch_setup(struct proc *p)
|
sh3_switch_setup(struct lwp *l)
|
||||||
{
|
{
|
||||||
pt_entry_t *pte;
|
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;
|
u_int32_t vpn;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
vpn = (u_int32_t)p->p_addr;
|
vpn = (u_int32_t)l->l_addr;
|
||||||
vpn &= ~PGOFSET;
|
vpn &= ~PGOFSET;
|
||||||
for (i = 0; i < UPAGES; i++, vpn += NBPG, md_upte++) {
|
for (i = 0; i < UPAGES; i++, vpn += NBPG, md_upte++) {
|
||||||
pte = __pmap_kpte_lookup(vpn);
|
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.
|
* prepare kernel stack PTE table. sh4_switch_resume wired this PTE.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
sh4_switch_setup(struct proc *p)
|
sh4_switch_setup(struct lwp *l)
|
||||||
{
|
{
|
||||||
pt_entry_t *pte;
|
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;
|
u_int32_t vpn;
|
||||||
int i, e;
|
int i, e;
|
||||||
|
|
||||||
vpn = (u_int32_t)p->p_addr;
|
vpn = (u_int32_t)l->l_addr;
|
||||||
vpn &= ~PGOFSET;
|
vpn &= ~PGOFSET;
|
||||||
e = SH4_UTLB_ENTRY - UPAGES;
|
e = SH4_UTLB_ENTRY - UPAGES;
|
||||||
for (i = 0; i < UPAGES; i++, e++, vpn += NBPG) {
|
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.
|
* Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
|
||||||
@ -55,10 +55,13 @@
|
|||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
|
#include <sys/pool.h>
|
||||||
#include <sys/user.h>
|
#include <sys/user.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
#include <sys/signal.h>
|
#include <sys/signal.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
|
#include <sys/sa.h>
|
||||||
|
#include <sys/savar.h>
|
||||||
|
|
||||||
#ifdef KTRACE
|
#ifdef KTRACE
|
||||||
#include <sys/ktrace.h>
|
#include <sys/ktrace.h>
|
||||||
@ -100,29 +103,29 @@ const char *exp_type[] = {
|
|||||||
};
|
};
|
||||||
const int exp_types = sizeof exp_type / sizeof exp_type[0];
|
const int exp_types = sizeof exp_type / sizeof exp_type[0];
|
||||||
|
|
||||||
void general_exception(struct proc *, struct trapframe *);
|
void general_exception(struct lwp *, struct trapframe *);
|
||||||
void tlb_exception(struct proc *, struct trapframe *, u_int32_t);
|
void tlb_exception(struct lwp *, struct trapframe *, u_int32_t);
|
||||||
void syscall(struct proc *, struct trapframe *);
|
void syscall(struct lwp *, struct trapframe *);
|
||||||
void ast(struct proc *, struct trapframe *);
|
void ast(struct lwp *, struct trapframe *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void general_exception(struct proc *p, struct trapframe *tf):
|
* void general_exception(struct lwp *l, struct trapframe *tf):
|
||||||
* p ... curproc when exception occur.
|
* l ... curlwp when exception occur.
|
||||||
* tf ... full user context.
|
* tf ... full user context.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
general_exception(struct proc *p, struct trapframe *tf)
|
general_exception(struct lwp *l, struct trapframe *tf)
|
||||||
{
|
{
|
||||||
int expevt = tf->tf_expevt;
|
int expevt = tf->tf_expevt;
|
||||||
boolean_t usermode = !KERNELMODE(tf->tf_ssr);
|
boolean_t usermode = !KERNELMODE(tf->tf_ssr);
|
||||||
|
|
||||||
uvmexp.traps++;
|
uvmexp.traps++;
|
||||||
|
|
||||||
if (p == NULL)
|
if (l == NULL)
|
||||||
goto do_panic;
|
goto do_panic;
|
||||||
|
|
||||||
if (usermode) {
|
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;
|
expevt |= EXP_USER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,17 +133,17 @@ general_exception(struct proc *p, struct trapframe *tf)
|
|||||||
case EXPEVT_TRAPA | EXP_USER:
|
case EXPEVT_TRAPA | EXP_USER:
|
||||||
/* Check for debugger break */
|
/* Check for debugger break */
|
||||||
if (_reg_read_4(SH_(TRA)) == (_SH_TRA_BREAK << 2)) {
|
if (_reg_read_4(SH_(TRA)) == (_SH_TRA_BREAK << 2)) {
|
||||||
trapsignal(p, SIGTRAP, tf->tf_expevt);
|
trapsignal(l, SIGTRAP, tf->tf_expevt);
|
||||||
} else {
|
} else {
|
||||||
syscall(p, tf);
|
syscall(l, tf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EXPEVT_ADDR_ERR_LD:
|
case EXPEVT_ADDR_ERR_LD:
|
||||||
/*FALLTHROUGH*/
|
/*FALLTHROUGH*/
|
||||||
case EXPEVT_ADDR_ERR_ST:
|
case EXPEVT_ADDR_ERR_ST:
|
||||||
KDASSERT(p->p_md.md_pcb->pcb_onfault != NULL);
|
KDASSERT(l->l_md.md_pcb->pcb_onfault != NULL);
|
||||||
tf->tf_spc = (int)p->p_md.md_pcb->pcb_onfault;
|
tf->tf_spc = (int)l->l_md.md_pcb->pcb_onfault;
|
||||||
if (tf->tf_spc == NULL)
|
if (tf->tf_spc == NULL)
|
||||||
goto do_panic;
|
goto do_panic;
|
||||||
break;
|
break;
|
||||||
@ -148,24 +151,24 @@ general_exception(struct proc *p, struct trapframe *tf)
|
|||||||
case EXPEVT_ADDR_ERR_LD | EXP_USER:
|
case EXPEVT_ADDR_ERR_LD | EXP_USER:
|
||||||
/*FALLTHROUGH*/
|
/*FALLTHROUGH*/
|
||||||
case EXPEVT_ADDR_ERR_ST | EXP_USER:
|
case EXPEVT_ADDR_ERR_ST | EXP_USER:
|
||||||
trapsignal(p, SIGSEGV, tf->tf_expevt);
|
trapsignal(l, SIGSEGV, tf->tf_expevt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EXPEVT_RES_INST | EXP_USER:
|
case EXPEVT_RES_INST | EXP_USER:
|
||||||
/*FALLTHROUGH*/
|
/*FALLTHROUGH*/
|
||||||
case EXPEVT_SLOT_INST | EXP_USER:
|
case EXPEVT_SLOT_INST | EXP_USER:
|
||||||
trapsignal(p, SIGILL, tf->tf_expevt);
|
trapsignal(l, SIGILL, tf->tf_expevt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EXPEVT_BREAK | EXP_USER:
|
case EXPEVT_BREAK | EXP_USER:
|
||||||
trapsignal(p, SIGTRAP, tf->tf_expevt);
|
trapsignal(l, SIGTRAP, tf->tf_expevt);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto do_panic;
|
goto do_panic;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usermode)
|
if (usermode)
|
||||||
userret(p);
|
userret(l);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
do_panic:
|
do_panic:
|
||||||
@ -191,14 +194,15 @@ general_exception(struct proc *p, struct trapframe *tf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void syscall(struct proc *p, struct trapframe *tf):
|
* void syscall(struct lwp *l, struct trapframe *tf):
|
||||||
* p ... curproc when exception occur.
|
* l ... curlwp when exception occur.
|
||||||
* tf ... full user context.
|
* tf ... full user context.
|
||||||
* System call request from POSIX system call gate interface to kernel.
|
* System call request from POSIX system call gate interface to kernel.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
syscall(struct proc *p, struct trapframe *tf)
|
syscall(struct lwp *l, struct trapframe *tf)
|
||||||
{
|
{
|
||||||
|
struct proc *p = l->l_proc;
|
||||||
caddr_t params;
|
caddr_t params;
|
||||||
const struct sysent *callp;
|
const struct sysent *callp;
|
||||||
int error, opc, nsys;
|
int error, opc, nsys;
|
||||||
@ -292,19 +296,14 @@ syscall(struct proc *p, struct trapframe *tf)
|
|||||||
if (error)
|
if (error)
|
||||||
goto bad;
|
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;
|
goto bad;
|
||||||
|
|
||||||
rval[0] = 0;
|
rval[0] = 0;
|
||||||
rval[1] = tf->tf_r1;
|
rval[1] = tf->tf_r1;
|
||||||
error = (*callp->sy_call)(p, args, rval);
|
error = (*callp->sy_call)(l, args, rval);
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case 0:
|
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_r0 = rval[0];
|
||||||
tf->tf_r1 = rval[1];
|
tf->tf_r1 = rval[1];
|
||||||
tf->tf_ssr |= PSL_TBIT; /* T bit */
|
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):
|
* void tlb_exception(struct lwp *l, struct trapframe *tf, u_int32_t va):
|
||||||
* p ... curproc when exception occur.
|
* l ... curlwp when exception occur.
|
||||||
* tf ... full user context.
|
* tf ... full user context.
|
||||||
* va ... fault address.
|
* va ... fault address.
|
||||||
*/
|
*/
|
||||||
void
|
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) \
|
#define TLB_ASSERT(assert, msg) \
|
||||||
do { \
|
do { \
|
||||||
@ -358,11 +357,11 @@ do { \
|
|||||||
|
|
||||||
usermode = !KERNELMODE(tf->tf_ssr);
|
usermode = !KERNELMODE(tf->tf_ssr);
|
||||||
if (usermode) {
|
if (usermode) {
|
||||||
KDASSERT(p->p_md.md_regs == tf);
|
KDASSERT(l->l_md.md_regs == tf);
|
||||||
} else {
|
} else {
|
||||||
KDASSERT(p == NULL || /* idle */
|
KDASSERT(l == NULL || /* idle */
|
||||||
p == &proc0 || /* kthread */
|
l == &lwp0 || /* kthread */
|
||||||
p->p_md.md_regs != tf); /* other */
|
l->l_md.md_regs != tf); /* other */
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (tf->tf_expevt) {
|
switch (tf->tf_expevt) {
|
||||||
@ -382,12 +381,12 @@ do { \
|
|||||||
TLB_ASSERT((int)va > 0,
|
TLB_ASSERT((int)va > 0,
|
||||||
"kernel virtual protection fault (load)");
|
"kernel virtual protection fault (load)");
|
||||||
if (usermode) {
|
if (usermode) {
|
||||||
trapsignal(p, SIGSEGV, tf->tf_expevt);
|
trapsignal(l, SIGSEGV, tf->tf_expevt);
|
||||||
goto user_fault;
|
goto user_fault;
|
||||||
} else {
|
} 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)");
|
"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;
|
return;
|
||||||
|
|
||||||
@ -399,18 +398,18 @@ do { \
|
|||||||
|
|
||||||
/* Select address space */
|
/* Select address space */
|
||||||
if (usermode) {
|
if (usermode) {
|
||||||
TLB_ASSERT(p != NULL, "no curproc");
|
TLB_ASSERT(l != NULL, "no curlwp");
|
||||||
map = &p->p_vmspace->vm_map;
|
map = &l->l_proc->p_vmspace->vm_map;
|
||||||
pmap = map->pmap;
|
pmap = map->pmap;
|
||||||
} else {
|
} else {
|
||||||
if ((int)va < 0) {
|
if ((int)va < 0) {
|
||||||
map = kernel_map;
|
map = kernel_map;
|
||||||
pmap = pmap_kernel();
|
pmap = pmap_kernel();
|
||||||
} else {
|
} else {
|
||||||
TLB_ASSERT(va != 0 && p != NULL &&
|
TLB_ASSERT(va != 0 && l != NULL &&
|
||||||
p->p_md.md_pcb->pcb_onfault != NULL,
|
l->l_md.md_pcb->pcb_onfault != NULL,
|
||||||
"invalid user-space access from kernel mode");
|
"invalid user-space access from kernel mode");
|
||||||
map = &p->p_vmspace->vm_map;
|
map = &l->l_proc->p_vmspace->vm_map;
|
||||||
pmap = map->pmap;
|
pmap = map->pmap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -418,16 +417,16 @@ do { \
|
|||||||
/* Lookup page table. if entry found, load it. */
|
/* Lookup page table. if entry found, load it. */
|
||||||
if (track && __pmap_pte_load(pmap, va, track)) {
|
if (track && __pmap_pte_load(pmap, va, track)) {
|
||||||
if (usermode)
|
if (usermode)
|
||||||
userret(p);
|
userret(l);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Page not found. call fault handler */
|
/* Page not found. call fault handler */
|
||||||
if (!usermode && pmap != pmap_kernel() &&
|
if (!usermode && pmap != pmap_kernel() &&
|
||||||
p->p_md.md_pcb->pcb_faultbail) {
|
l->l_md.md_pcb->pcb_faultbail) {
|
||||||
TLB_ASSERT(p->p_md.md_pcb->pcb_onfault != NULL,
|
TLB_ASSERT(l->l_md.md_pcb->pcb_onfault != NULL,
|
||||||
"no copyin/out fault handler (interrupt context)");
|
"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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,9 +434,10 @@ do { \
|
|||||||
|
|
||||||
/* User stack extension */
|
/* User stack extension */
|
||||||
if (map != kernel_map &&
|
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) {
|
if (err == 0) {
|
||||||
struct vmspace *vm = p->p_vmspace;
|
struct vmspace *vm = l->l_proc->p_vmspace;
|
||||||
u_int32_t nss;
|
u_int32_t nss;
|
||||||
nss = btoc(USRSTACK - va);
|
nss = btoc(USRSTACK - va);
|
||||||
if (nss > vm->vm_ssize)
|
if (nss > vm->vm_ssize)
|
||||||
@ -452,49 +452,51 @@ do { \
|
|||||||
boolean_t loaded = __pmap_pte_load(pmap, va, track);
|
boolean_t loaded = __pmap_pte_load(pmap, va, track);
|
||||||
TLB_ASSERT(loaded, "page table entry not found");
|
TLB_ASSERT(loaded, "page table entry not found");
|
||||||
if (usermode)
|
if (usermode)
|
||||||
userret(p);
|
userret(l);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Page not found. */
|
/* Page not found. */
|
||||||
if (usermode) {
|
if (usermode) {
|
||||||
trapsignal(p, err == ENOMEM ? SIGKILL : SIGSEGV, tf->tf_expevt);
|
trapsignal(l, err == ENOMEM ? SIGKILL : SIGSEGV, tf->tf_expevt);
|
||||||
goto user_fault;
|
goto user_fault;
|
||||||
} else {
|
} 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)");
|
"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;
|
return;
|
||||||
|
|
||||||
user_fault:
|
user_fault:
|
||||||
userret(p);
|
userret(l);
|
||||||
ast(p, tf);
|
ast(l, tf);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tlb_panic:
|
tlb_panic:
|
||||||
panic("tlb_handler: %s va=0x%08x, ssr=0x%08x, spc=0x%08x"
|
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,
|
" lwp=%p onfault=%p", panic_msg, va, tf->tf_ssr, tf->tf_spc,
|
||||||
p, p ? p->p_md.md_pcb->pcb_onfault : 0);
|
l, l ? l->l_md.md_pcb->pcb_onfault : 0);
|
||||||
#undef TLB_ASSERT
|
#undef TLB_ASSERT
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void ast(struct proc *p, struct trapframe *tf):
|
* void ast(struct lwp *l, struct trapframe *tf):
|
||||||
* p ... curproc when exception occur.
|
* l ... curlwp when exception occur.
|
||||||
* tf ... full user context.
|
* tf ... full user context.
|
||||||
* This is called when exception return. if return from kernel to user,
|
* This is called when exception return. if return from kernel to user,
|
||||||
* handle asynchronous software traps and context switch if needed.
|
* handle asynchronous software traps and context switch if needed.
|
||||||
*/
|
*/
|
||||||
void
|
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))
|
if (KERNELMODE(tf->tf_ssr))
|
||||||
return;
|
return;
|
||||||
KDASSERT(p != NULL);
|
KDASSERT(l != NULL);
|
||||||
KDASSERT(p->p_md.md_regs == tf);
|
KDASSERT(l->l_md.md_regs == tf);
|
||||||
|
|
||||||
|
p = l->l_proc;
|
||||||
|
|
||||||
while (p->p_md.md_astpending) {
|
while (p->p_md.md_astpending) {
|
||||||
uvmexp.softs++;
|
uvmexp.softs++;
|
||||||
@ -505,16 +507,12 @@ ast(struct proc *p, struct trapframe *tf)
|
|||||||
ADDUPROF(p);
|
ADDUPROF(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Take pending signals. */
|
|
||||||
while ((sig = CURSIG(p)) != 0)
|
|
||||||
postsig(sig);
|
|
||||||
|
|
||||||
if (want_resched) {
|
if (want_resched) {
|
||||||
/* We are being preempted. */
|
/* We are being preempted. */
|
||||||
preempt(NULL);
|
preempt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
userret(p);
|
userret(l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -527,15 +525,53 @@ ast(struct proc *p, struct trapframe *tf)
|
|||||||
void
|
void
|
||||||
child_return(void *arg)
|
child_return(void *arg)
|
||||||
{
|
{
|
||||||
struct proc *p = arg;
|
struct lwp *l = arg;
|
||||||
struct trapframe *tf = p->p_md.md_regs;
|
#ifdef KTRACE
|
||||||
|
struct proc *p = l->l_proc;
|
||||||
|
#endif
|
||||||
|
struct trapframe *tf = l->l_md.md_regs;
|
||||||
|
|
||||||
tf->tf_r0 = 0;
|
tf->tf_r0 = 0;
|
||||||
tf->tf_ssr |= PSL_TBIT; /* This indicates no error. */
|
tf->tf_ssr |= PSL_TBIT; /* This indicates no error. */
|
||||||
|
|
||||||
userret(p);
|
userret(l);
|
||||||
#ifdef KTRACE
|
#ifdef KTRACE
|
||||||
if (KTRPOINT(p, KTR_SYSRET))
|
if (KTRPOINT(p, KTR_SYSRET))
|
||||||
ktrsysret(p, SYS_fork, 0, 0);
|
ktrsysret(p, SYS_fork, 0, 0);
|
||||||
#endif
|
#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.
|
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||||
@ -67,7 +67,7 @@ _C_LABEL(sh_vector_generic):
|
|||||||
MOV (EXPEVT, r0)
|
MOV (EXPEVT, r0)
|
||||||
mov.l @r0, r0
|
mov.l @r0, r0
|
||||||
mov.l r0, @(TF_EXPEVT, r14) /* trapframe->tf_expevt = EXPEVT */
|
mov.l r0, @(TF_EXPEVT, r14) /* trapframe->tf_expevt = EXPEVT */
|
||||||
/* Get curproc */
|
/* Get curlwp */
|
||||||
mov.l 3f, r1
|
mov.l 3f, r1
|
||||||
mov.l @r1, r4 /* 1st arg */
|
mov.l @r1, r4 /* 1st arg */
|
||||||
/* Check TLB exception or not */
|
/* Check TLB exception or not */
|
||||||
@ -110,7 +110,7 @@ _C_LABEL(sh_vector_generic):
|
|||||||
2: __EXCEPTION_RETURN
|
2: __EXCEPTION_RETURN
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
.align 2
|
.align 2
|
||||||
3: .long _C_LABEL(curproc)
|
3: .long _C_LABEL(curlwp)
|
||||||
REG_SYMBOL(EXPEVT)
|
REG_SYMBOL(EXPEVT)
|
||||||
REG_SYMBOL(BBRA)
|
REG_SYMBOL(BBRA)
|
||||||
REG_SYMBOL(TEA)
|
REG_SYMBOL(TEA)
|
||||||
@ -178,7 +178,7 @@ _C_LABEL(sh3_vector_tlbmiss):
|
|||||||
mov r14, r5 /* 2nd arg */
|
mov r14, r5 /* 2nd arg */
|
||||||
3: __EXCEPTION_RETURN
|
3: __EXCEPTION_RETURN
|
||||||
.align 2
|
.align 2
|
||||||
2: .long _C_LABEL(curproc)
|
2: .long _C_LABEL(curlwp)
|
||||||
1: .long _C_LABEL(tlb_exception)
|
1: .long _C_LABEL(tlb_exception)
|
||||||
_L.EXPEVT3: .long SH3_EXPEVT
|
_L.EXPEVT3: .long SH3_EXPEVT
|
||||||
_L.TEA3: .long SH3_TEA
|
_L.TEA3: .long SH3_TEA
|
||||||
@ -218,7 +218,7 @@ _C_LABEL(sh4_vector_tlbmiss):
|
|||||||
__EXCEPTION_RETURN
|
__EXCEPTION_RETURN
|
||||||
.align 2
|
.align 2
|
||||||
1: .long _C_LABEL(tlb_exception)
|
1: .long _C_LABEL(tlb_exception)
|
||||||
2: .long _C_LABEL(curproc)
|
2: .long _C_LABEL(curlwp)
|
||||||
_L.EXPEVT4: .long SH4_EXPEVT
|
_L.EXPEVT4: .long SH4_EXPEVT
|
||||||
_L.TEA4: .long SH4_TEA
|
_L.TEA4: .long SH4_TEA
|
||||||
___L.VPN_MASK: .long 0xfffff000
|
___L.VPN_MASK: .long 0xfffff000
|
||||||
@ -257,7 +257,7 @@ _C_LABEL(sh_vector_interrupt):
|
|||||||
mov r14, r5 /* 2nd arg */
|
mov r14, r5 /* 2nd arg */
|
||||||
__EXCEPTION_RETURN
|
__EXCEPTION_RETURN
|
||||||
.align 2
|
.align 2
|
||||||
1: .long _C_LABEL(curproc)
|
1: .long _C_LABEL(curlwp)
|
||||||
__L.intc_intr: .long _C_LABEL(intc_intr)
|
__L.intc_intr: .long _C_LABEL(intc_intr)
|
||||||
__L.ast: .long _C_LABEL(ast)
|
__L.ast: .long _C_LABEL(ast)
|
||||||
__L.uvmexp.intrs: .long _C_LABEL(uvmexp) + UVMEXP_INTRS
|
__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.
|
# 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_R0 offsetof(struct trapframe, tf_r0)
|
||||||
define TF_R15 offsetof(struct trapframe, tf_r15)
|
define TF_R15 offsetof(struct trapframe, tf_r15)
|
||||||
|
|
||||||
define P_ADDR offsetof(struct proc, p_addr)
|
define L_ADDR offsetof(struct lwp, l_addr)
|
||||||
define P_BACK offsetof(struct proc, p_back)
|
define L_BACK offsetof(struct lwp, l_back)
|
||||||
define P_FORW offsetof(struct proc, p_forw)
|
define L_FORW offsetof(struct lwp, l_forw)
|
||||||
define P_STAT offsetof(struct proc, p_stat)
|
define L_STAT offsetof(struct lwp, l_stat)
|
||||||
define P_WCHAN offsetof(struct proc, p_wchan)
|
define L_WCHAN offsetof(struct lwp, l_wchan)
|
||||||
define P_MD offsetof(struct proc, p_md)
|
|
||||||
|
|
||||||
define MD_UPTE offsetof(struct mdproc, md_upte)
|
define L_MD_UPTE offsetof(struct lwp, l_md.md_upte)
|
||||||
define MD_PCB offsetof(struct mdproc, md_pcb)
|
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_SIZE sizeof(struct switchframe)
|
||||||
define SF_SR offsetof(struct switchframe, sf_sr)
|
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)
|
define SC_EFLAGS offsetof(struct sigcontext, sc_ssr)
|
||||||
|
|
||||||
# can't include sys/proc.h directly.
|
define LSONPROC LSONPROC
|
||||||
define SONPROC SONPROC
|
define LSRUN LSRUN
|
||||||
define SRUN SRUN
|
|
||||||
|
|
||||||
define UVMEXP_INTRS offsetof(struct uvmexp, intrs)
|
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.
|
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||||
@ -48,7 +48,7 @@
|
|||||||
.text
|
.text
|
||||||
.align 5 /* align cache line size (32B) */
|
.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.
|
* Find a runnable process and switch to it. Wait if necessary.
|
||||||
*/
|
*/
|
||||||
ENTRY(cpu_switch)
|
ENTRY(cpu_switch)
|
||||||
@ -79,6 +79,7 @@ ENTRY(cpu_switch)
|
|||||||
bt/s 1f
|
bt/s 1f
|
||||||
mov r0, r4 /* new proc */
|
mov r0, r4 /* new proc */
|
||||||
|
|
||||||
|
_L.doswitch:
|
||||||
/* Setup kernel stack */
|
/* Setup kernel stack */
|
||||||
mov.l _L.SF, r0
|
mov.l _L.SF, r0
|
||||||
mov.l @(r0, r4), r1 /* switch frame */
|
mov.l @(r0, r4), r1 /* switch frame */
|
||||||
@ -100,8 +101,16 @@ ENTRY(cpu_switch)
|
|||||||
__EXCEPTION_UNBLOCK(r0, r1)
|
__EXCEPTION_UNBLOCK(r0, r1)
|
||||||
/* Now OK to use kernel stack. */
|
/* 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 */
|
/* 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
|
mov.l @(r0, r4), r1
|
||||||
add #4, r1 /* r15 already restored */
|
add #4, r1 /* r15 already restored */
|
||||||
mov.l @r1+, r14
|
mov.l @r1+, r14
|
||||||
@ -114,13 +123,48 @@ ENTRY(cpu_switch)
|
|||||||
lds.l @r1+, pr
|
lds.l @r1+, pr
|
||||||
add #4, r1 /* r6_bank already restored */
|
add #4, r1 /* r6_bank already restored */
|
||||||
ldc.l @r1+, sr
|
ldc.l @r1+, sr
|
||||||
|
|
||||||
|
/* r2 has the return value; stuff it into r0 now. */
|
||||||
rts
|
rts
|
||||||
nop
|
mov r2, r0
|
||||||
.align 2
|
.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)
|
_L.cpu_switch_search: .long _C_LABEL(cpu_switch_search)
|
||||||
FUNC_SYMBOL(switch_resume)
|
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
|
#ifdef SH3
|
||||||
/*
|
/*
|
||||||
* void sh3_switch_resume(sturct proc *p)
|
* 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.VPN_MASK: .long 0xfffff000
|
||||||
_L.P2BASE: .long 0xa0000000
|
_L.P2BASE: .long 0xa0000000
|
||||||
#endif /* SH4 */
|
#endif /* SH4 */
|
||||||
_L.UPTE: .long (P_MD + MD_UPTE)
|
_L.UPTE: .long (L_MD_UPTE)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* int _cpu_intr_raise(int s):
|
* 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.
|
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||||
@ -291,9 +291,9 @@ pmap_reference(pmap_t pmap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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)
|
if (pmap->pm_asid == -1)
|
||||||
pmap->pm_asid = __pmap_asid_alloc();
|
pmap->pm_asid = __pmap_asid_alloc();
|
||||||
@ -303,7 +303,7 @@ pmap_activate(struct proc *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pmap_deactivate(struct proc *p)
|
pmap_deactivate(struct lwp *l)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Nothing to do */
|
/* 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
|
* Copyright (c) 1995, 1996, 1997
|
||||||
@ -76,19 +76,17 @@
|
|||||||
#include <machine/psl.h>
|
#include <machine/psl.h>
|
||||||
#include <machine/reg.h>
|
#include <machine/reg.h>
|
||||||
|
|
||||||
static __inline struct trapframe *process_frame(struct proc *);
|
|
||||||
|
|
||||||
static __inline struct trapframe *
|
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
|
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_spc = tf->tf_spc;
|
||||||
regs->r_ssr = tf->tf_ssr;
|
regs->r_ssr = tf->tf_ssr;
|
||||||
@ -116,9 +114,9 @@ process_read_regs(struct proc *p, struct reg *regs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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.
|
* Check for security violations.
|
||||||
@ -154,8 +152,8 @@ process_write_regs(struct proc *p, struct reg *regs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
process_sstep(p, sstep)
|
process_sstep(l, sstep)
|
||||||
struct proc *p;
|
struct lwp *l;
|
||||||
{
|
{
|
||||||
|
|
||||||
if (sstep)
|
if (sstep)
|
||||||
@ -165,9 +163,9 @@ process_sstep(p, sstep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
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.
|
* Copyright (c) 1996, 1997, 1998, 2002 The NetBSD Foundation, Inc.
|
||||||
@ -90,7 +90,10 @@
|
|||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
#include <sys/signalvar.h>
|
#include <sys/signalvar.h>
|
||||||
|
#include <sys/sa.h>
|
||||||
|
#include <sys/savar.h>
|
||||||
#include <sys/syscallargs.h>
|
#include <sys/syscallargs.h>
|
||||||
|
#include <sys/ucontext.h>
|
||||||
#include <sys/user.h>
|
#include <sys/user.h>
|
||||||
|
|
||||||
#ifdef KGDB
|
#ifdef KGDB
|
||||||
@ -216,7 +219,7 @@ sh_proc0_init()
|
|||||||
|
|
||||||
/* Setup proc0 */
|
/* Setup proc0 */
|
||||||
proc0paddr = (struct user *)u;
|
proc0paddr = (struct user *)u;
|
||||||
proc0.p_addr = proc0paddr;
|
lwp0.l_addr = proc0paddr;
|
||||||
/*
|
/*
|
||||||
* u-area map:
|
* u-area map:
|
||||||
* |user| .... | ............... |
|
* |user| .... | ............... |
|
||||||
@ -226,8 +229,8 @@ sh_proc0_init()
|
|||||||
* stack top ... r7_bank
|
* stack top ... r7_bank
|
||||||
* current stack ... r15
|
* current stack ... r15
|
||||||
*/
|
*/
|
||||||
curpcb = proc0.p_md.md_pcb = &proc0.p_addr->u_pcb;
|
curpcb = lwp0.l_md.md_pcb = &lwp0.l_addr->u_pcb;
|
||||||
curupte = proc0.p_md.md_upte;
|
curupte = lwp0.l_md.md_upte;
|
||||||
|
|
||||||
sf = &curpcb->pcb_sf;
|
sf = &curpcb->pcb_sf;
|
||||||
sf->sf_r6_bank = u + NBPG;
|
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, r6_bank" :: "r"(sf->sf_r6_bank));
|
||||||
__asm__ __volatile__("ldc %0, r7_bank" :: "r"(sf->sf_r7_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
|
#ifdef KSTACK_DEBUG
|
||||||
memset((char *)(u + sizeof(struct user)), 0x5a,
|
memset((char *)(u + sizeof(struct user)), 0x5a,
|
||||||
NBPG - sizeof(struct user));
|
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.
|
* Send an interrupt to process.
|
||||||
*
|
*
|
||||||
@ -374,14 +418,15 @@ dumpsys()
|
|||||||
void
|
void
|
||||||
sendsig(int sig, sigset_t *mask, u_long code)
|
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 sigacts *ps = p->p_sigacts;
|
||||||
struct trapframe *tf;
|
struct trapframe *tf;
|
||||||
struct sigframe *fp, frame;
|
struct sigframe *fp, frame;
|
||||||
int onstack;
|
int onstack;
|
||||||
sig_t catcher = SIGACTION(p, sig).sa_handler;
|
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? */
|
/* Do we need to jump onto the signal stack? */
|
||||||
onstack =
|
onstack =
|
||||||
@ -429,7 +474,7 @@ sendsig(int sig, sigset_t *mask, u_long code)
|
|||||||
* Process has trashed its stack; give it an illegal
|
* Process has trashed its stack; give it an illegal
|
||||||
* instruction to halt it in its tracks.
|
* instruction to halt it in its tracks.
|
||||||
*/
|
*/
|
||||||
sigexit(p, SIGILL);
|
sigexit(l, SIGILL);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,7 +495,7 @@ sendsig(int sig, sigset_t *mask, u_long code)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
/* Don't know what trampoline version; kill it. */
|
/* Don't know what trampoline version; kill it. */
|
||||||
sigexit(p, SIGILL);
|
sigexit(l, SIGILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
tf->tf_r4 = sig;
|
tf->tf_r4 = sig;
|
||||||
@ -475,13 +520,14 @@ sendsig(int sig, sigset_t *mask, u_long code)
|
|||||||
* a machine fault.
|
* a machine fault.
|
||||||
*/
|
*/
|
||||||
int
|
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 /* {
|
struct sys___sigreturn14_args /* {
|
||||||
syscallarg(struct sigcontext *) sigcntxp;
|
syscallarg(struct sigcontext *) sigcntxp;
|
||||||
} */ *uap = v;
|
} */ *uap = v;
|
||||||
struct sigcontext *scp, context;
|
struct sigcontext *scp, context;
|
||||||
struct trapframe *tf;
|
struct trapframe *tf;
|
||||||
|
struct proc *p = l->l_proc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The trampoline code hands us the context.
|
* The trampoline code hands us the context.
|
||||||
@ -493,7 +539,7 @@ sys___sigreturn14(struct proc *p, void *v, register_t *retval)
|
|||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
|
|
||||||
/* Restore signal context. */
|
/* Restore signal context. */
|
||||||
tf = p->p_md.md_regs;
|
tf = l->l_md.md_regs;
|
||||||
|
|
||||||
/* Check for security violations. */
|
/* Check for security violations. */
|
||||||
if (((context.sc_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0)
|
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);
|
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
|
* Clear registers on exec
|
||||||
*/
|
*/
|
||||||
void
|
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;
|
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_r0 = 0;
|
||||||
tf->tf_r1 = 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_r6 = stack + 4 * tf->tf_r4 + 8; /* envp */
|
||||||
tf->tf_r7 = 0;
|
tf->tf_r7 = 0;
|
||||||
tf->tf_r8 = 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_r10 = 0;
|
||||||
tf->tf_r11 = 0;
|
tf->tf_r11 = 0;
|
||||||
tf->tf_r12 = 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
|
* Copyright (c) 1995, 1997
|
||||||
@ -43,10 +43,11 @@
|
|||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
|
#include <sys/sa.h>
|
||||||
#include <sys/syscallargs.h>
|
#include <sys/syscallargs.h>
|
||||||
|
|
||||||
int
|
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;
|
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.
|
* Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
|
||||||
@ -67,6 +67,8 @@
|
|||||||
#include <sh3/mmu.h>
|
#include <sh3/mmu.h>
|
||||||
#include <sh3/cache.h>
|
#include <sh3/cache.h>
|
||||||
|
|
||||||
|
extern void proc_trampoline(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finish a fork operation, with process p2 nearly set up.
|
* Finish a fork operation, with process p2 nearly set up.
|
||||||
* Copy and update the pcb and trap frame, making the child ready to run.
|
* Copy and update the pcb and trap frame, making the child ready to run.
|
||||||
@ -86,20 +88,19 @@
|
|||||||
* accordingly.
|
* accordingly.
|
||||||
*/
|
*/
|
||||||
void
|
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)
|
size_t stacksize, void (*func)(void *), void *arg)
|
||||||
{
|
{
|
||||||
extern void proc_trampoline(void);
|
|
||||||
struct pcb *pcb;
|
struct pcb *pcb;
|
||||||
struct trapframe *tf;
|
struct trapframe *tf;
|
||||||
struct switchframe *sf;
|
struct switchframe *sf;
|
||||||
vaddr_t spbase, fptop;
|
vaddr_t spbase, fptop;
|
||||||
#define P1ADDR(x) (SH3_PHYS_TO_P1SEG(*__pmap_kpte_lookup(x) & PG_PPN))
|
#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 */
|
/* Copy flags */
|
||||||
p2->p_md.md_flags = p1->p_md.md_flags;
|
l2->l_md.md_flags = l1->l_md.md_flags;
|
||||||
|
|
||||||
#ifdef SH3
|
#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
|
* exception. For SH3, we are 4K page, P3/P1 conversion don't
|
||||||
* cause virtual-aliasing.
|
* cause virtual-aliasing.
|
||||||
*/
|
*/
|
||||||
if (CPU_IS_SH3) {
|
if (CPU_IS_SH3)
|
||||||
pcb = (struct pcb *)P1ADDR((vaddr_t)&p2->p_addr->u_pcb);
|
pcb = (struct pcb *)P1ADDR((vaddr_t)&l2->l_addr->u_pcb);
|
||||||
p2->p_md.md_pcb = pcb;
|
|
||||||
fptop = (vaddr_t)pcb + NBPG;
|
|
||||||
}
|
|
||||||
#endif /* SH3 */
|
#endif /* SH3 */
|
||||||
#ifdef SH4
|
#ifdef SH4
|
||||||
/* SH4 can make wired entry, no need to convert to P1. */
|
/* SH4 can make wired entry, no need to convert to P1. */
|
||||||
if (CPU_IS_SH4) {
|
if (CPU_IS_SH4)
|
||||||
pcb = &p2->p_addr->u_pcb;
|
pcb = &l2->l_addr->u_pcb;
|
||||||
p2->p_md.md_pcb = pcb;
|
|
||||||
fptop = (vaddr_t)pcb + NBPG;
|
|
||||||
}
|
|
||||||
#endif /* SH4 */
|
#endif /* SH4 */
|
||||||
|
|
||||||
|
l2->l_md.md_pcb = pcb;
|
||||||
|
fptop = (vaddr_t)pcb + NBPG;
|
||||||
|
|
||||||
/* set up the kernel stack pointer */
|
/* set up the kernel stack pointer */
|
||||||
spbase = (vaddr_t)p2->p_addr + NBPG;
|
spbase = (vaddr_t)l2->l_addr + NBPG;
|
||||||
#ifdef P1_STACK
|
#ifdef P1_STACK
|
||||||
/* Convert to P1 from P3 */
|
/* 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.
|
* is accessed from P1 instead of P3.
|
||||||
*/
|
*/
|
||||||
if (SH_HAS_VIRTUAL_ALIAS)
|
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);
|
spbase = P1ADDR(spbase);
|
||||||
#else /* P1_STACK */
|
#else /* P1_STACK */
|
||||||
/* Prepare u-area PTEs */
|
/* Prepare u-area PTEs */
|
||||||
#ifdef SH3
|
#ifdef SH3
|
||||||
if (CPU_IS_SH3)
|
if (CPU_IS_SH3)
|
||||||
sh3_switch_setup(p2);
|
sh3_switch_setup(l2);
|
||||||
#endif
|
#endif
|
||||||
#ifdef SH4
|
#ifdef SH4
|
||||||
if (CPU_IS_SH4)
|
if (CPU_IS_SH4)
|
||||||
sh4_switch_setup(p2);
|
sh4_switch_setup(l2);
|
||||||
#endif
|
#endif
|
||||||
#endif /* P1_STACK */
|
#endif /* P1_STACK */
|
||||||
|
|
||||||
@ -157,8 +155,8 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack,
|
|||||||
/*
|
/*
|
||||||
* Copy the user context.
|
* Copy the user context.
|
||||||
*/
|
*/
|
||||||
p2->p_md.md_regs = tf = (struct trapframe *)fptop - 1;
|
l2->l_md.md_regs = tf = (struct trapframe *)fptop - 1;
|
||||||
memcpy(tf, p1->p_md.md_regs, sizeof(struct trapframe));
|
memcpy(tf, l1->l_md.md_regs, sizeof(struct trapframe));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If specified, give the child a different stack.
|
* 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):
|
* void cpu_setfunc(struct lwp *l, void (*func)(void *), void *arg):
|
||||||
* + Change kernel context to proc0's one.
|
* + Reset the stack pointer for the process.
|
||||||
* + Schedule freeing process 'p' resources.
|
* + 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.
|
* + switch to another process.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
cpu_exit(struct proc *p)
|
cpu_exit(struct lwp *l, int proc)
|
||||||
{
|
{
|
||||||
struct switchframe *sf;
|
struct switchframe *sf;
|
||||||
|
|
||||||
splsched();
|
splsched();
|
||||||
uvmexp.swtch++;
|
uvmexp.swtch++;
|
||||||
|
|
||||||
/* Switch to proc0 stack */
|
/* Switch to lwp0 stack */
|
||||||
curproc = 0;
|
curlwp = 0;
|
||||||
curpcb = proc0.p_md.md_pcb;
|
curpcb = lwp0.l_md.md_pcb;
|
||||||
sf = &curpcb->pcb_sf;
|
sf = &curpcb->pcb_sf;
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"mov %0, r15;" /* current stack */
|
"mov %0, r15;" /* current stack */
|
||||||
@ -210,9 +293,12 @@ cpu_exit(struct proc *p)
|
|||||||
"r"(sf->sf_r7_bank));
|
"r"(sf->sf_r7_bank));
|
||||||
|
|
||||||
/* Schedule freeing process resources */
|
/* Schedule freeing process resources */
|
||||||
exit2(p);
|
if (proc)
|
||||||
|
exit2(l);
|
||||||
|
else
|
||||||
|
lwp_exit2(l);
|
||||||
|
|
||||||
cpu_switch(p, NULL);
|
cpu_switch(l, NULL);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,7 +310,7 @@ struct md_core {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int
|
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 core *chdr)
|
||||||
{
|
{
|
||||||
struct md_core md_core;
|
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);
|
chdr->c_cpusize = sizeof(md_core);
|
||||||
|
|
||||||
/* Save integer registers. */
|
/* Save integer registers. */
|
||||||
error = process_read_regs(p, &md_core.intreg);
|
error = process_read_regs(l, &md_core.intreg);
|
||||||
if (error)
|
if (error)
|
||||||
return 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,
|
error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cseg, chdr->c_seghdrsize,
|
||||||
(off_t)chdr->c_hdrsize, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred,
|
(off_t)chdr->c_hdrsize, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred,
|
||||||
(int *)0, p);
|
(int *)0, l->l_proc);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&md_core, sizeof(md_core),
|
error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&md_core, sizeof(md_core),
|
||||||
(off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), UIO_SYSSPACE,
|
(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)
|
if (error)
|
||||||
return 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
|
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 \
|
int_const.h int_fmtio.h int_limits.h int_mwgwtypes.h int_types.h \
|
||||||
intr.h ipkdb.h \
|
intr.h ipkdb.h \
|
||||||
limits.h lock.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 \
|
param.h pcb.h pmap.h pmc.h proc.h profile.h ptrace.h \
|
||||||
reg.h \
|
reg.h \
|
||||||
setjmp.h signal.h stdarg.h sysarch.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
|
* Copyright 1997
|
||||||
@ -317,7 +317,7 @@ ofw_boot(howto, bootstr)
|
|||||||
{
|
{
|
||||||
|
|
||||||
#ifdef DIAGNOSTIC
|
#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("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",
|
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
|
* Copyright 1997
|
||||||
@ -516,7 +516,7 @@ profFiq(int x)
|
|||||||
if ( (profTable->hdr.mode & SAMPLE_PROC) &&
|
if ( (profTable->hdr.mode & SAMPLE_PROC) &&
|
||||||
((spsr & STATUS_MODE_MASK) == USER_MODE) )
|
((spsr & STATUS_MODE_MASK) == USER_MODE) )
|
||||||
{
|
{
|
||||||
if ( curproc->p_pid == profTable->hdr.pid )
|
if ( curlwp->p_pid == profTable->hdr.pid )
|
||||||
{
|
{
|
||||||
profEnter(profTable, stacklr-4);
|
profEnter(profTable, stacklr-4);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user