Subject: nathanw_sa changes for sh3
To: None <port-sh3@netbsd.org>
From: Jason R Thorpe <thorpej@wasabisystems.com>
List: port-sh3
Date: 06/20/2002 23:37:10
--DocE+STaALJfprDB
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Tonight I wrote the sh3-specific changes for nathanw_sa for sh3. The
kernel links, but I have not yet booted it (my test machine will be
a Dreamcast).
I'll do a test boot tomorrow, but I'd like to get some feedback from
folks who might be more familiar w/ SH than me.
My concerns:
* changes to locore_subr.S follow register saving
rules.
* cpu_setfunc() is correct
* cpu_exit(): I'm worried that the stack changes in
the middle of this function.
Anyway, if it boots on my DC, I'll check it in, and then make the
other SH ports compile.
--
-- Jason R. Thorpe <thorpej@wasabisystems.com>
--DocE+STaALJfprDB
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=sh3-sa-patch
Index: include/cpu.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sh3/include/cpu.h,v
retrieving revision 1.29
diff -c -r1.29 cpu.h
*** include/cpu.h 2002/05/07 04:01:59 1.29
--- include/cpu.h 2002/06/21 06:11:17
***************
*** 80,85 ****
--- 80,86 ----
*/
#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,117 ****
do { \
want_resched = 1; \
if (curproc != NULL) \
! aston(curproc); \
} while (/*CONSTCOND*/0)
/*
--- 112,118 ----
do { \
want_resched = 1; \
if (curproc != NULL) \
! aston(curproc->l_proc); \
} while (/*CONSTCOND*/0)
/*
Index: include/frame.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sh3/include/frame.h,v
retrieving revision 1.8
diff -c -r1.8 frame.h
*** include/frame.h 2002/05/09 12:25:41 1.8
--- include/frame.h 2002/06/21 06:11:17
***************
*** 44,49 ****
--- 44,50 ----
#define _SH3_FRAME_H_
#include <sys/signal.h>
+ #include <sys/sa.h>
/*
* Exception Stack Frame
***************
*** 103,108 ****
--- 104,123 ----
struct sigcontext *sf_scp;
sig_t sf_handler;
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;
+ sa_upcall_t sa_upcall;
};
#endif /* !_SH3_FRAME_H_ */
Index: include/locore.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sh3/include/locore.h,v
retrieving revision 1.7
diff -c -r1.7 locore.h
*** include/locore.h 2002/05/09 12:25:41 1.7
--- include/locore.h 2002/06/21 06:11:18
***************
*** 198,206 ****
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 *);
#endif /* !_LOCORE */
--- 198,206 ----
ldc Rm, sr /* unmask all interrupt */
#ifndef _LOCORE
! 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 */
Index: include/proc.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sh3/include/proc.h,v
retrieving revision 1.4
diff -c -r1.4 proc.h
*** include/proc.h 2002/05/09 12:28:08 1.4
--- include/proc.h 2002/06/21 06:11:18
***************
*** 38,43 ****
--- 38,44 ----
#ifndef _SH3_PROC_H_
#define _SH3_PROC_H_
+
/*
* Machine-dependent part of the proc structure for sh3.
*/
***************
*** 48,64 ****
u_int32_t data;
};
! struct mdproc {
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 */
#ifdef _KERNEL
#ifndef _LOCORE
--- 49,68 ----
u_int32_t data;
};
! 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];
};
/* 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
Index: include/userret.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sh3/include/userret.h,v
retrieving revision 1.3
diff -c -r1.3 userret.h
*** include/userret.h 2002/05/09 12:31:19 1.3
--- include/userret.h 2002/06/21 06:11:18
***************
*** 46,55 ****
#define _SH3_USERRET_H_
static __inline void
! userret(struct proc *p)
{
! curcpu()->ci_schedstate.spc_curpriority = p->p_priority = p->p_usrpri;
}
#endif /* !_SH3_USERRET_H_ */
--- 46,69 ----
#define _SH3_USERRET_H_
static __inline void
! userret(struct lwp *l)
{
+ struct proc *p = l->l_proc;
+ int sig;
! /* 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. */
! if (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_ */
Index: sh3/Locore.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sh3/sh3/Locore.c,v
retrieving revision 1.12
diff -c -r1.12 Locore.c
*** sh3/Locore.c 2002/05/09 12:28:08 1.12
--- sh3/Locore.c 2002/06/21 06:11:18
***************
*** 94,101 ****
#include <sh3/mmu_sh3.h>
#include <sh3/mmu_sh4.h>
! void (*__sh_switch_resume)(struct proc *);
! struct proc *cpu_switch_search(struct proc *);
void idle(void);
int want_resched;
--- 94,101 ----
#include <sh3/mmu_sh3.h>
#include <sh3/mmu_sh4.h>
! void (*__sh_switch_resume)(struct lwp *);
! struct lwp *cpu_switch_search(struct lwp *);
void idle(void);
int want_resched;
***************
*** 111,121 ****
* struct proc *cpu_switch_search(struct proc *oldproc):
* Find the highest priority process.
*/
! struct proc *
! cpu_switch_search(struct proc *oldproc)
{
struct prochd *q;
! struct proc *p;
curproc = 0;
--- 111,121 ----
* struct proc *cpu_switch_search(struct proc *oldproc):
* Find the highest priority process.
*/
! struct lwp *
! cpu_switch_search(struct lwp *oldlwp)
{
struct prochd *q;
! struct lwp *l;
curproc = 0;
***************
*** 127,146 ****
}
q = &sched_qs[ffs(sched_whichqs) - 1];
! p = q->ph_link;
! remrunqueue(p);
want_resched = 0;
SCHED_UNLOCK_IDLE();
! p->p_stat = SONPROC;
! if (p != oldproc) {
! curpcb = p->p_md.md_pcb;
! pmap_activate(p);
}
! curproc = p;
! return (p);
}
/*
--- 127,146 ----
}
q = &sched_qs[ffs(sched_whichqs) - 1];
! l = q->ph_link;
! remrunqueue(l);
want_resched = 0;
SCHED_UNLOCK_IDLE();
! l->l_stat = LSONPROC;
! if (l != oldlwp) {
! curpcb = l->l_md.md_pcb;
! pmap_activate(l);
}
! curproc = l;
! return (l);
}
/*
***************
*** 159,176 ****
}
/*
! * Put process p on the run queue indicated by its priority.
! * Calls should be made at splstatclock(), and p->p_stat should be SRUN.
*/
void
! setrunqueue(struct proc *p)
{
struct prochd *q;
! struct proc *oldlast;
! int which = p->p_priority >> 2;
#ifdef DIAGNOSTIC
! if (p->p_back || which >= 32 || which < 0)
panic("setrunqueue");
#endif
q = &sched_qs[which];
--- 159,176 ----
}
/*
! * Put lwp p on the run queue indicated by its priority.
! * Calls should be made at splstatclock(), and l->l_stat should be SRUN.
*/
void
! setrunqueue(struct lwp *l)
{
struct prochd *q;
! struct lwp *oldlast;
! int which = l->l_priority >> 2;
#ifdef DIAGNOSTIC
! if (l->l_back || which >= 32 || which < 0)
panic("setrunqueue");
#endif
q = &sched_qs[which];
***************
*** 178,225 ****
if (sched_whichqs == 0) {
panic("setrunqueue[whichqs == 0 ]");
}
! p->p_forw = (struct proc *)q;
! p->p_back = oldlast = q->ph_rlink;
! q->ph_rlink = p;
! oldlast->p_forw = p;
}
/*
! * Remove process p from its run queue, which should be the one
* indicated by its priority.
* Calls should be made at splstatclock().
*/
void
! remrunqueue(struct proc *p)
{
! int which = p->p_priority >> 2;
struct prochd *q;
#ifdef DIAGNOSTIC
if (!(sched_whichqs & (0x00000001 << which)))
panic("remrunqueue");
#endif
! p->p_forw->p_back = p->p_back;
! p->p_back->p_forw = p->p_forw;
! p->p_back = NULL;
q = &sched_qs[which];
! if (q->ph_link == (struct proc *)q)
sched_whichqs &= ~(0x00000001 << which);
}
/*
! * void sh3_switch_setup(struct proc *p):
* prepare kernel stack PTE table. TLB miss handler check these.
*/
void
! sh3_switch_setup(struct proc *p)
{
pt_entry_t *pte;
! struct md_upte *md_upte = p->p_md.md_upte;
u_int32_t vpn;
int i;
! vpn = (u_int32_t)p->p_addr;
vpn &= ~PGOFSET;
for (i = 0; i < UPAGES; i++, vpn += NBPG, md_upte++) {
pte = __pmap_kpte_lookup(vpn);
--- 178,225 ----
if (sched_whichqs == 0) {
panic("setrunqueue[whichqs == 0 ]");
}
! l->l_forw = (struct lwp *)q;
! l->l_back = oldlast = q->ph_rlink;
! q->ph_rlink = l;
! oldlast->l_forw = l;
}
/*
! * Remove process l from its run queue, which should be the one
* indicated by its priority.
* Calls should be made at splstatclock().
*/
void
! remrunqueue(struct lwp *l)
{
! int which = l->l_priority >> 2;
struct prochd *q;
#ifdef DIAGNOSTIC
if (!(sched_whichqs & (0x00000001 << which)))
panic("remrunqueue");
#endif
! l->l_forw->l_back = l->l_back;
! l->l_back->l_forw = l->l_forw;
! l->l_back = NULL;
q = &sched_qs[which];
! if (q->ph_link == (struct lwp *)q)
sched_whichqs &= ~(0x00000001 << which);
}
/*
! * void sh3_switch_setup(struct lwp *l):
* prepare kernel stack PTE table. TLB miss handler check these.
*/
void
! sh3_switch_setup(struct lwp *l)
{
pt_entry_t *pte;
! struct md_upte *md_upte = l->l_md.md_upte;
u_int32_t vpn;
int i;
! vpn = (u_int32_t)l->l_addr;
vpn &= ~PGOFSET;
for (i = 0; i < UPAGES; i++, vpn += NBPG, md_upte++) {
pte = __pmap_kpte_lookup(vpn);
***************
*** 231,248 ****
}
/*
! * void sh4_switch_setup(struct proc *p):
* prepare kernel stack PTE table. sh4_switch_resume wired this PTE.
*/
void
! sh4_switch_setup(struct proc *p)
{
pt_entry_t *pte;
! struct md_upte *md_upte = p->p_md.md_upte;
u_int32_t vpn;
int i, e;
! vpn = (u_int32_t)p->p_addr;
vpn &= ~PGOFSET;
e = SH4_UTLB_ENTRY - UPAGES;
for (i = 0; i < UPAGES; i++, e++, vpn += NBPG) {
--- 231,248 ----
}
/*
! * void sh4_switch_setup(struct lwp *l):
* prepare kernel stack PTE table. sh4_switch_resume wired this PTE.
*/
void
! sh4_switch_setup(struct lwp *l)
{
pt_entry_t *pte;
! struct md_upte *md_upte = l->l_md.md_upte;
u_int32_t vpn;
int i, e;
! vpn = (u_int32_t)l->l_addr;
vpn &= ~PGOFSET;
e = SH4_UTLB_ENTRY - UPAGES;
for (i = 0; i < UPAGES; i++, e++, vpn += NBPG) {
Index: sh3/exception.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sh3/sh3/exception.c,v
retrieving revision 1.2
diff -c -r1.2 exception.c
*** sh3/exception.c 2002/06/17 16:33:17 1.2
--- sh3/exception.c 2002/06/21 06:11:19
***************
*** 55,64 ****
--- 55,67 ----
#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,128 ****
};
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 proc *p, struct trapframe *tf):
! * p ... curproc when exception occur.
* tf ... full user context.
*/
void
! general_exception(struct proc *p, struct trapframe *tf)
{
int expevt = tf->tf_expevt;
boolean_t usermode = !KERNELMODE(tf->tf_ssr);
uvmexp.traps++;
! if (p == NULL)
goto do_panic;
if (usermode) {
! KDASSERT(p->p_md.md_regs == tf); /* check exception depth */
expevt |= EXP_USER;
}
--- 103,131 ----
};
const int exp_types = sizeof exp_type / sizeof exp_type[0];
! 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 lwp *l, struct trapframe *tf):
! * l ... curproc when exception occur.
* tf ... full user context.
*/
void
! general_exception(struct lwp *l, struct trapframe *tf)
{
int expevt = tf->tf_expevt;
boolean_t usermode = !KERNELMODE(tf->tf_ssr);
uvmexp.traps++;
! if (l == NULL)
goto do_panic;
if (usermode) {
! KDASSERT(l->l_md.md_regs == tf); /* check exception depth */
expevt |= EXP_USER;
}
***************
*** 130,146 ****
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);
} else {
! syscall(p, 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;
if (tf->tf_spc == NULL)
goto do_panic;
break;
--- 133,149 ----
case EXPEVT_TRAPA | EXP_USER:
/* Check for debugger break */
if (_reg_read_4(SH_(TRA)) == (_SH_TRA_BREAK << 2)) {
! trapsignal(l, SIGTRAP, tf->tf_expevt);
} else {
! syscall(l, tf);
return;
}
break;
case EXPEVT_ADDR_ERR_LD:
/*FALLTHROUGH*/
case EXPEVT_ADDR_ERR_ST:
! 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,171 ****
case EXPEVT_ADDR_ERR_LD | EXP_USER:
/*FALLTHROUGH*/
case EXPEVT_ADDR_ERR_ST | EXP_USER:
! trapsignal(p, SIGSEGV, tf->tf_expevt);
break;
case EXPEVT_RES_INST | EXP_USER:
/*FALLTHROUGH*/
case EXPEVT_SLOT_INST | EXP_USER:
! trapsignal(p, SIGILL, tf->tf_expevt);
break;
case EXPEVT_BREAK | EXP_USER:
! trapsignal(p, SIGTRAP, tf->tf_expevt);
break;
default:
goto do_panic;
}
if (usermode)
! userret(p);
return;
do_panic:
--- 151,174 ----
case EXPEVT_ADDR_ERR_LD | EXP_USER:
/*FALLTHROUGH*/
case EXPEVT_ADDR_ERR_ST | EXP_USER:
! trapsignal(l, SIGSEGV, tf->tf_expevt);
break;
case EXPEVT_RES_INST | EXP_USER:
/*FALLTHROUGH*/
case EXPEVT_SLOT_INST | EXP_USER:
! trapsignal(l, SIGILL, tf->tf_expevt);
break;
case EXPEVT_BREAK | EXP_USER:
! trapsignal(l, SIGTRAP, tf->tf_expevt);
break;
default:
goto do_panic;
}
if (usermode)
! userret(l);
return;
do_panic:
***************
*** 191,204 ****
}
/*
! * void syscall(struct proc *p, struct trapframe *tf):
! * p ... curproc 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)
{
caddr_t params;
const struct sysent *callp;
int error, opc, nsys;
--- 194,208 ----
}
/*
! * void syscall(struct lwp *l, struct trapframe *tf):
! * l ... curproc when exception occur.
* tf ... full user context.
* System call request from POSIX system call gate interface to kernel.
*/
void
! 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,310 ****
if (error)
goto bad;
! if ((error = trace_enter(p, code, args, rval)) != 0)
goto bad;
rval[0] = 0;
rval[1] = tf->tf_r1;
! error = (*callp->sy_call)(p, 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 */
--- 296,309 ----
if (error)
goto bad;
! if ((error = trace_enter(l, code, args, rval)) != 0)
goto bad;
rval[0] = 0;
rval[1] = tf->tf_r1;
! error = (*callp->sy_call)(l, args, rval);
switch (error) {
case 0:
tf->tf_r0 = rval[0];
tf->tf_r1 = rval[1];
tf->tf_ssr |= PSL_TBIT; /* T bit */
***************
*** 329,347 ****
}
! trace_exit(p, code, args, rval, error);
! userret(p);
}
/*
! * void tlb_exception(struct proc *p, struct trapframe *tf, u_int32_t va):
! * p ... curproc when exception occur.
* tf ... full user context.
* va ... fault address.
*/
void
! tlb_exception(struct proc *p, struct trapframe *tf, u_int32_t va)
{
#define TLB_ASSERT(assert, msg) \
do { \
--- 328,346 ----
}
! trace_exit(l, code, args, rval, error);
! userret(l);
}
/*
! * void tlb_exception(struct lwp *l, struct trapframe *tf, u_int32_t va):
! * l ... curproc when exception occur.
* tf ... full user context.
* va ... fault address.
*/
void
! tlb_exception(struct lwp *l, struct trapframe *tf, u_int32_t va)
{
#define TLB_ASSERT(assert, msg) \
do { \
***************
*** 382,393 ****
TLB_ASSERT((int)va > 0,
"kernel virtual protection fault (load)");
if (usermode) {
! trapsignal(p, SIGSEGV, tf->tf_expevt);
goto user_fault;
} else {
! TLB_ASSERT(p && p->p_md.md_pcb->pcb_onfault != NULL,
"no copyin/out fault handler (load protection)");
! tf->tf_spc = (int)p->p_md.md_pcb->pcb_onfault;
}
return;
--- 381,392 ----
TLB_ASSERT((int)va > 0,
"kernel virtual protection fault (load)");
if (usermode) {
! trapsignal(l, SIGSEGV, tf->tf_expevt);
goto user_fault;
} else {
! TLB_ASSERT(l && l->l_md.md_pcb->pcb_onfault != NULL,
"no copyin/out fault handler (load protection)");
! tf->tf_spc = (int)l->l_md.md_pcb->pcb_onfault;
}
return;
***************
*** 399,416 ****
/* Select address space */
if (usermode) {
! TLB_ASSERT(p != NULL, "no curproc");
! map = &p->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,
"invalid user-space access from kernel mode");
! map = &p->p_vmspace->vm_map;
pmap = map->pmap;
}
}
--- 398,415 ----
/* Select address space */
if (usermode) {
! TLB_ASSERT(l != NULL, "no curproc");
! 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 && l != NULL &&
! l->l_md.md_pcb->pcb_onfault != NULL,
"invalid user-space access from kernel mode");
! map = &l->l_proc->p_vmspace->vm_map;
pmap = map->pmap;
}
}
***************
*** 418,433 ****
/* Lookup page table. if entry found, load it. */
if (track && __pmap_pte_load(pmap, va, track)) {
if (usermode)
! userret(p);
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,
"no copyin/out fault handler (interrupt context)");
! tf->tf_spc = (int)p->p_md.md_pcb->pcb_onfault;
return;
}
--- 417,432 ----
/* Lookup page table. if entry found, load it. */
if (track && __pmap_pte_load(pmap, va, track)) {
if (usermode)
! userret(l);
return;
}
/* Page not found. call fault handler */
if (!usermode && pmap != pmap_kernel() &&
! 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)l->l_md.md_pcb->pcb_onfault;
return;
}
***************
*** 435,443 ****
/* User stack extension */
if (map != kernel_map &&
! (va >= (vaddr_t)p->p_vmspace->vm_maxsaddr) && (va < USRSTACK)) {
if (err == 0) {
! struct vmspace *vm = p->p_vmspace;
u_int32_t nss;
nss = btoc(USRSTACK - va);
if (nss > vm->vm_ssize)
--- 434,443 ----
/* User stack extension */
if (map != kernel_map &&
! (va >= (vaddr_t)l->l_proc->p_vmspace->vm_maxsaddr) &&
! (va < USRSTACK)) {
if (err == 0) {
! struct vmspace *vm = l->l_proc->p_vmspace;
u_int32_t nss;
nss = btoc(USRSTACK - va);
if (nss > vm->vm_ssize)
***************
*** 452,501 ****
boolean_t loaded = __pmap_pte_load(pmap, va, track);
TLB_ASSERT(loaded, "page table entry not found");
if (usermode)
! userret(p);
return;
}
/* Page not found. */
if (usermode) {
! trapsignal(p, err == ENOMEM ? SIGKILL : SIGSEGV, tf->tf_expevt);
goto user_fault;
} else {
! TLB_ASSERT(p->p_md.md_pcb->pcb_onfault,
"no copyin/out fault handler (page not found)");
! tf->tf_spc = (int)p->p_md.md_pcb->pcb_onfault;
}
return;
user_fault:
! userret(p);
! ast(p, 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);
#undef TLB_ASSERT
}
/*
! * void ast(struct proc *p, struct trapframe *tf):
! * p ... curproc 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)
{
! int sig;
if (KERNELMODE(tf->tf_ssr))
return;
! KDASSERT(p != NULL);
! KDASSERT(p->p_md.md_regs == tf);
while (p->p_md.md_astpending) {
uvmexp.softs++;
p->p_md.md_astpending = 0;
--- 452,503 ----
boolean_t loaded = __pmap_pte_load(pmap, va, track);
TLB_ASSERT(loaded, "page table entry not found");
if (usermode)
! userret(l);
return;
}
/* Page not found. */
if (usermode) {
! trapsignal(l, err == ENOMEM ? SIGKILL : SIGSEGV, tf->tf_expevt);
goto user_fault;
} else {
! TLB_ASSERT(l->l_md.md_pcb->pcb_onfault,
"no copyin/out fault handler (page not found)");
! tf->tf_spc = (int)l->l_md.md_pcb->pcb_onfault;
}
return;
user_fault:
! userret(l);
! ast(l, tf);
return;
tlb_panic:
panic("tlb_handler: %s va=0x%08x, ssr=0x%08x, spc=0x%08x"
! " 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 lwp *l, struct trapframe *tf):
! * l ... curproc 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 lwp *l, struct trapframe *tf)
{
! struct proc *p;
if (KERNELMODE(tf->tf_ssr))
return;
! KDASSERT(l != NULL);
! KDASSERT(l->p_md.md_regs == tf);
+ p = l->l_proc;
+
while (p->p_md.md_astpending) {
uvmexp.softs++;
p->p_md.md_astpending = 0;
***************
*** 505,520 ****
ADDUPROF(p);
}
- /* Take pending signals. */
- while ((sig = CURSIG(p)) != 0)
- postsig(sig);
-
if (want_resched) {
/* We are being preempted. */
preempt(NULL);
}
! userret(p);
}
}
--- 507,518 ----
ADDUPROF(p);
}
if (want_resched) {
/* We are being preempted. */
preempt(NULL);
}
! userret(l);
}
}
***************
*** 527,541 ****
void
child_return(void *arg)
{
! struct proc *p = arg;
! struct trapframe *tf = p->p_md.md_regs;
tf->tf_r0 = 0;
tf->tf_ssr |= PSL_TBIT; /* This indicates no error. */
! userret(p);
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSRET))
ktrsysret(p, SYS_fork, 0, 0);
#endif
}
--- 525,577 ----
void
child_return(void *arg)
{
! 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(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 = curproc;
+ 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);
}
Index: sh3/genassym.cf
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sh3/sh3/genassym.cf,v
retrieving revision 1.5
diff -c -r1.5 genassym.cf
*** sh3/genassym.cf 2002/05/09 12:29:16 1.5
--- sh3/genassym.cf 2002/06/21 06:11:19
***************
*** 67,82 ****
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 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)
define SF_R15 offsetof(struct switchframe, sf_r15)
--- 67,85 ----
define TF_R0 offsetof(struct trapframe, tf_r0)
define TF_R15 offsetof(struct trapframe, tf_r15)
! define L_ADDR offsetof(struct lwp, l_addr)
! define L_BACK offsetof(struct lwp, l_back)
! define L_FORW offsetof(struct lwp, l_forw)
! define L_STAT offsetof(struct lwp, l_stat)
! define L_WCHAN offsetof(struct lwp, l_wchan)
! define L_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)
define SF_R15 offsetof(struct switchframe, sf_r15)
***************
*** 93,102 ****
define SIGF_HANDLER offsetof(struct sigframe, sf_handler)
define SIGF_SC offsetof(struct sigframe, sf_sc)
define SC_EFLAGS offsetof(struct sigcontext, sc_ssr)
! # can't include sys/proc.h directly.
! define SONPROC SONPROC
! define SRUN SRUN
define UVMEXP_INTRS offsetof(struct uvmexp, intrs)
--- 96,106 ----
define SIGF_HANDLER offsetof(struct sigframe, sf_handler)
define SIGF_SC offsetof(struct sigframe, sf_sc)
define SC_EFLAGS offsetof(struct sigcontext, sc_ssr)
+
+ define SAF_UPCALL offsetof(struct saframe, sa_upcall)
! define LSONPROC LSONPROC
! define LSRUN LSRUN
define UVMEXP_INTRS offsetof(struct uvmexp, intrs)
Index: sh3/locore_subr.S
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sh3/sh3/locore_subr.S,v
retrieving revision 1.10
diff -c -r1.10 locore_subr.S
*** sh3/locore_subr.S 2002/05/09 12:28:08 1.10
--- sh3/locore_subr.S 2002/06/21 06:11:19
***************
*** 48,54 ****
.text
.align 5 /* align cache line size (32B) */
/*
! * void cpu_switch(struct proc *):
* Find a runnable process and switch to it. Wait if necessary.
*/
ENTRY(cpu_switch)
--- 48,54 ----
.text
.align 5 /* align cache line size (32B) */
/*
! * void cpu_switch(struct lwp *):
* Find a runnable process and switch to it. Wait if necessary.
*/
ENTRY(cpu_switch)
***************
*** 79,84 ****
--- 79,85 ----
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,107 ****
__EXCEPTION_UNBLOCK(r0, r1)
/* Now OK to use kernel stack. */
/* Restore new process's context from switchframe */
! 1: mov.l _L.SF, r0
mov.l @(r0, r4), r1
add #4, r1 /* r15 already restored */
mov.l @r1+, r14
--- 101,116 ----
__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 */
! /* 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,126 ****
lds.l @r1+, pr
add #4, r1 /* r6_bank already restored */
ldc.l @r1+, sr
rts
! nop
.align 2
! _L.SF: .long (P_MD + MD_PCB)
_L.cpu_switch_search: .long _C_LABEL(cpu_switch_search)
FUNC_SYMBOL(switch_resume)
#ifdef SH3
/*
* void sh3_switch_resume(sturct proc *p)
--- 123,182 ----
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
! mov r2, r0
.align 2
! _L.SF: .long (L_MD_PCB)
_L.cpu_switch_search: .long _C_LABEL(cpu_switch_search)
FUNC_SYMBOL(switch_resume)
+ /*
+ * void cpu_preempt(struct lwp *current, struct lwp *next)
+ * Switch to the specified next LWP.
+ */
+ ENTRY(cpu_preempt)
+ /* 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
+
+ /*
+ * Don't need the outgoing LWP anymore. Stash the incoming
+ * LWP into a callee-saved register.
+ */
+ mov r5, r8
+
+ /* Unlink the new LWP from its run queue. */
+ mov.l _L.remrunqueue, r0
+ jsr @r0
+ mov r8, r4
+
+ /*
+ * Put the incoming proc 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 r8, r4
+
+ .align 2
+ _L.SFp: .long (L_MD_PCB)
+ _L.remrunqueue: .long _C_LABEL(remrunqueue)
+
#ifdef SH3
/*
* void sh3_switch_resume(sturct proc *p)
***************
*** 211,217 ****
_L.VPN_MASK: .long 0xfffff000
_L.P2BASE: .long 0xa0000000
#endif /* SH4 */
! _L.UPTE: .long (P_MD + MD_UPTE)
/*
* int _cpu_intr_raise(int s):
--- 267,273 ----
_L.VPN_MASK: .long 0xfffff000
_L.P2BASE: .long 0xa0000000
#endif /* SH4 */
! _L.UPTE: .long (L_MD_UPTE)
/*
* int _cpu_intr_raise(int s):
***************
*** 356,361 ****
--- 412,436 ----
trapa #0x80 /* exit if sigreturn fails */
.align 2
_L.SYS___sigreturn14: .long SYS___sigreturn14
+
+ /*
+ * upcallcode:
+ * Scheduler activation upcall trampoline.
+ *
+ * r4-r7 are the first 4 upcall arguments. The rest of the arguments
+ * are on the stack in the right places. Pointer to the upcall routine
+ * follows args.
+ */
+ NENTRY(upcallcode)
+ mov.l @(SAF_UPCALL,r15), r0 /* fetch upcall routine.. */
+ jsr @r0 /* ..and call it! */
+ nop
+
+ /* Returned?! Die! */
+ mov.l _L.SYS_exit, r0
+ trapa #0x80
+
+ .align 2
_L.SYS_exit: .long SYS_exit
.globl _C_LABEL(esigcode)
_C_LABEL(esigcode):
Index: sh3/mem.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sh3/sh3/mem.c,v
retrieving revision 1.11
diff -c -r1.11 mem.c
*** sh3/mem.c 2002/05/09 12:29:48 1.11
--- sh3/mem.c 2002/06/21 06:11:19
***************
*** 159,165 ****
paddr_t
mmmmap(dev_t dev, off_t off, int prot)
{
! struct proc *p = curproc;
if (minor(dev) != DEV_MEM)
return (-1);
--- 159,165 ----
paddr_t
mmmmap(dev_t dev, off_t off, int prot)
{
! struct proc *p = curproc->l_proc;
if (minor(dev) != DEV_MEM)
return (-1);
Index: sh3/pmap.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sh3/sh3/pmap.c,v
retrieving revision 1.40
diff -c -r1.40 pmap.c
*** sh3/pmap.c 2002/05/09 12:28:08 1.40
--- sh3/pmap.c 2002/06/21 06:11:20
***************
*** 293,301 ****
}
void
! pmap_activate(struct proc *p)
{
! pmap_t pmap = p->p_vmspace->vm_map.pmap;
if (pmap->pm_asid == -1)
pmap->pm_asid = __pmap_asid_alloc();
--- 293,301 ----
}
void
! pmap_activate(struct lwp *l)
{
! pmap_t pmap = l->l_proc->p_vmspace->vm_map.pmap;
if (pmap->pm_asid == -1)
pmap->pm_asid = __pmap_asid_alloc();
***************
*** 305,311 ****
}
void
! pmap_deactivate(struct proc *p)
{
/* Nothing to do */
--- 305,311 ----
}
void
! pmap_deactivate(struct lwp *l)
{
/* Nothing to do */
Index: sh3/process_machdep.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sh3/sh3/process_machdep.c,v
retrieving revision 1.5
diff -c -r1.5 process_machdep.c
*** sh3/process_machdep.c 2002/04/29 09:33:30 1.5
--- sh3/process_machdep.c 2002/06/21 06:11:20
***************
*** 76,94 ****
#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)
{
! return (p->p_md.md_regs);
}
int
! process_read_regs(struct proc *p, struct reg *regs)
{
! struct trapframe *tf = process_frame(p);
regs->r_spc = tf->tf_spc;
regs->r_ssr = tf->tf_ssr;
--- 76,92 ----
#include <machine/psl.h>
#include <machine/reg.h>
static __inline struct trapframe *
! process_frame(struct lwp *l)
{
! return (l->l_md.md_regs);
}
int
! process_read_regs(struct lwp *l, struct reg *regs)
{
! struct trapframe *tf = process_frame(l);
regs->r_spc = tf->tf_spc;
regs->r_ssr = tf->tf_ssr;
***************
*** 116,124 ****
}
int
! process_write_regs(struct proc *p, struct reg *regs)
{
! struct trapframe *tf = process_frame(p);
/*
* Check for security violations.
--- 114,122 ----
}
int
! process_write_regs(struct lwp *l, struct reg *regs)
{
! struct trapframe *tf = process_frame(l);
/*
* Check for security violations.
***************
*** 154,161 ****
}
int
! process_sstep(p, sstep)
! struct proc *p;
{
if (sstep)
--- 152,159 ----
}
int
! process_sstep(l, sstep)
! struct lwp *l;
{
if (sstep)
***************
*** 165,173 ****
}
int
! process_set_pc(struct proc *p, caddr_t addr)
{
! struct trapframe *tf = process_frame(p);
tf->tf_spc = (int)addr;
--- 163,171 ----
}
int
! process_set_pc(struct lwp *l, caddr_t addr)
{
! struct trapframe *tf = process_frame(l);
tf->tf_spc = (int)addr;
Index: sh3/sh3_machdep.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sh3/sh3/sh3_machdep.c,v
retrieving revision 1.41.6.1
diff -c -r1.41.6.1 sh3_machdep.c
*** sh3/sh3_machdep.c 2002/06/20 23:00:51 1.41.6.1
--- sh3/sh3_machdep.c 2002/06/21 06:11:20
***************
*** 90,95 ****
--- 90,97 ----
#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>
***************
*** 217,223 ****
/* Setup proc0 */
proc0paddr = (struct user *)u;
! proc0.p_addr = proc0paddr;
/*
* u-area map:
* |user| .... | ............... |
--- 219,225 ----
/* Setup proc0 */
proc0paddr = (struct user *)u;
! lwp0.l_addr = proc0paddr;
/*
* u-area map:
* |user| .... | ............... |
***************
*** 227,234 ****
* stack top ... r7_bank
* current stack ... r15
*/
! curpcb = proc0.p_md.md_pcb = &proc0.p_addr->u_pcb;
! curupte = proc0.p_md.md_upte;
sf = &curpcb->pcb_sf;
sf->sf_r6_bank = u + NBPG;
--- 229,236 ----
* stack top ... r7_bank
* current stack ... r15
*/
! 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;
***************
*** 236,242 ****
__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;
#ifdef KSTACK_DEBUG
memset((char *)(u + sizeof(struct user)), 0x5a,
NBPG - sizeof(struct user));
--- 238,244 ----
__asm__ __volatile__("ldc %0, r6_bank" :: "r"(sf->sf_r6_bank));
__asm__ __volatile__("ldc %0, r7_bank" :: "r"(sf->sf_r7_bank));
! 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));
***************
*** 363,368 ****
--- 365,414 ----
}
/*
+ * 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 proc *p = l->l_proc;
+ struct trapframe *tf;
+ struct saframe *sf, frame;
+ extern char sigcode[], upcallcode[];
+
+ 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;
+ frame.sa_upcall = upcall;
+
+ 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) ((caddr_t)p->p_sigctx.ps_sigcode +
+ ((caddr_t)upcallcode - (caddr_t)sigcode));
+ tf->tf_r15 = (int) sf;
+ }
+
+ /*
* Send an interrupt to process.
*
* Stack is set up to allow sigcode stored
***************
*** 375,386 ****
void
sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
{
! struct proc *p = curproc;
struct trapframe *tf;
struct sigframe *fp, frame;
int onstack;
! tf = p->p_md.md_regs;
/* Do we need to jump onto the signal stack? */
onstack =
--- 421,433 ----
void
sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
{
! struct lwp *l = curproc;
! struct proc *p = l->l_proc;
struct trapframe *tf;
struct sigframe *fp, frame;
int onstack;
! tf = l->l_md.md_regs;
/* Do we need to jump onto the signal stack? */
onstack =
***************
*** 434,440 ****
* Process has trashed its stack; give it an illegal
* instruction to halt it in its tracks.
*/
! sigexit(p, SIGILL);
/* NOTREACHED */
}
--- 481,487 ----
* Process has trashed its stack; give it an illegal
* instruction to halt it in its tracks.
*/
! sigexit(l, SIGILL);
/* NOTREACHED */
}
***************
*** 460,472 ****
* a machine fault.
*/
int
! sys___sigreturn14(struct proc *p, void *v, register_t *retval)
{
struct sys___sigreturn14_args /* {
syscallarg(struct sigcontext *) sigcntxp;
} */ *uap = v;
struct sigcontext *scp, context;
struct trapframe *tf;
/*
* The trampoline code hands us the context.
--- 507,520 ----
* a machine fault.
*/
int
! 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.
***************
*** 478,484 ****
return (EFAULT);
/* Restore signal context. */
! tf = p->p_md.md_regs;
/* Check for security violations. */
if (((context.sc_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0)
--- 526,532 ----
return (EFAULT);
/* Restore signal context. */
! tf = l->l_md.md_regs;
/* Check for security violations. */
if (((context.sc_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0)
***************
*** 517,532 ****
}
void
! cpu_getmcontext(p, mcp, flags)
! struct proc *p;
mcontext_t *mcp;
unsigned int *flags;
{
! const struct trapframe *tf = p->p_md.md_regs;
__greg_t *gr = mcp->__gregs;
/* Save register context. */
! gr[_REG_EXPEVT] = tf->tf_trapno;
gr[_REG_PC] = tf->tf_spc;
gr[_REG_SR] = tf->tf_ssr;
gr[_REG_MACL] = tf->tf_macl;
--- 565,580 ----
}
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;
***************
*** 555,566 ****
}
int
! cpu_setmcontext(p, mcp, flags)
! struct proc *p;
const mcontext_t *mcp;
unsigned int flags;
{
! struct trapframe *tf = p->p_md.md_regs;
const __greg_t *gr = mcp->__gregs;
/* Restore register context, if any. */
--- 603,614 ----
}
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. */
***************
*** 600,612 ****
* Clear registers on exec
*/
void
! setregs(struct proc *p, struct exec_package *pack, u_long stack)
{
struct trapframe *tf;
! p->p_md.md_flags &= ~MDP_USEDFPU;
! tf = p->p_md.md_regs;
tf->tf_r0 = 0;
tf->tf_r1 = 0;
--- 648,660 ----
* Clear registers on exec
*/
void
! setregs(struct lwp *l, struct exec_package *pack, u_long stack)
{
struct trapframe *tf;
! l->l_md.md_flags &= ~MDP_USEDFPU;
! tf = l->l_md.md_regs;
tf->tf_r0 = 0;
tf->tf_r1 = 0;
***************
*** 617,623 ****
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_r10 = 0;
tf->tf_r11 = 0;
tf->tf_r12 = 0;
--- 665,671 ----
tf->tf_r6 = stack + 4 * tf->tf_r4 + 8; /* envp */
tf->tf_r7 = 0;
tf->tf_r8 = 0;
! tf->tf_r9 = (int)l->l_proc->p_psstr;
tf->tf_r10 = 0;
tf->tf_r11 = 0;
tf->tf_r12 = 0;
Index: sh3/sys_machdep.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sh3/sh3/sys_machdep.c,v
retrieving revision 1.7
diff -c -r1.7 sys_machdep.c
*** sh3/sys_machdep.c 2002/05/10 15:28:45 1.7
--- sh3/sys_machdep.c 2002/06/21 06:11:20
***************
*** 43,52 ****
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mount.h>
#include <sys/syscallargs.h>
int
! sys_sysarch(struct proc *p, void *v, register_t *retval)
{
struct sys_sysarch_args __attribute__((__unused__)) *uap = v;
--- 43,53 ----
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mount.h>
+ #include <sys/sa.h>
#include <sys/syscallargs.h>
int
! sys_sysarch(struct lwp *l, void *v, register_t *retval)
{
struct sys_sysarch_args __attribute__((__unused__)) *uap = v;
Index: sh3/vm_machdep.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sh3/sh3/vm_machdep.c,v
retrieving revision 1.33
diff -c -r1.33 vm_machdep.c
*** sh3/vm_machdep.c 2002/05/09 12:28:09 1.33
--- sh3/vm_machdep.c 2002/06/21 06:11:21
***************
*** 67,72 ****
--- 67,74 ----
#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,105 ****
* accordingly.
*/
void
! cpu_fork(struct proc *p1, struct proc *p2, 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));
/* Copy flags */
! p2->p_md.md_flags = p1->p_md.md_flags;
#ifdef SH3
/*
--- 88,106 ----
* accordingly.
*/
void
! cpu_lwp_fork(struct lwp *l1, struct lwp *l2, void *stack,
size_t stacksize, void (*func)(void *), void *arg)
{
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(!(l1 != curproc && l1 != &lwp0));
/* Copy flags */
! l2->l_md.md_flags = l1->l_md.md_flags;
#ifdef SH3
/*
***************
*** 109,130 ****
* 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;
}
#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;
}
#endif /* SH4 */
/* set up the kernel stack pointer */
! spbase = (vaddr_t)p2->p_addr + NBPG;
#ifdef P1_STACK
/* Convert to P1 from P3 */
/*
--- 110,131 ----
* cause virtual-aliasing.
*/
if (CPU_IS_SH3) {
! pcb = (struct pcb *)P1ADDR((vaddr_t)&l2->l_addr->u_pcb);
! l2->l_md.md_pcb = pcb;
fptop = (vaddr_t)pcb + NBPG;
}
#endif /* SH3 */
#ifdef SH4
/* SH4 can make wired entry, no need to convert to P1. */
if (CPU_IS_SH4) {
! pcb = &l2->l_addr->u_pcb;
! l2->l_md.md_pcb = pcb;
fptop = (vaddr_t)pcb + NBPG;
}
#endif /* SH4 */
/* set up the kernel stack pointer */
! spbase = (vaddr_t)l2->l_addr + NBPG;
#ifdef P1_STACK
/* Convert to P1 from P3 */
/*
***************
*** 132,148 ****
* is accessed from P1 instead of P3.
*/
if (SH_HAS_VIRTUAL_ALIAS)
! sh_dcache_wbinv_range((vaddr_t)p2->p_addr, USPACE);
spbase = P1ADDR(spbase);
#else /* P1_STACK */
/* Prepare u-area PTEs */
#ifdef SH3
if (CPU_IS_SH3)
! sh3_switch_setup(p2);
#endif
#ifdef SH4
if (CPU_IS_SH4)
! sh4_switch_setup(p2);
#endif
#endif /* P1_STACK */
--- 133,149 ----
* is accessed from P1 instead of P3.
*/
if (SH_HAS_VIRTUAL_ALIAS)
! 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(l2);
#endif
#ifdef SH4
if (CPU_IS_SH4)
! sh4_switch_setup(l2);
#endif
#endif /* P1_STACK */
***************
*** 157,164 ****
/*
* Copy the user context.
*/
! p2->p_md.md_regs = tf = (struct trapframe *)fptop - 1;
! memcpy(tf, p1->p_md.md_regs, sizeof(struct trapframe));
/*
* If specified, give the child a different stack.
--- 158,165 ----
/*
* Copy the user context.
*/
! 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.
***************
*** 182,204 ****
sf->sf_sr = PSL_MD; /* kernel mode, interrupt enable */
}
/*
! * void cpu_exit(sturct proc *p):
! * + Change kernel context to proc0's one.
! * + Schedule freeing process 'p' resources.
* + switch to another process.
*/
void
! cpu_exit(struct proc *p)
{
struct switchframe *sf;
splsched();
uvmexp.swtch++;
! /* Switch to proc0 stack */
curproc = 0;
! curpcb = proc0.p_md.md_pcb;
sf = &curpcb->pcb_sf;
__asm__ __volatile__(
"mov %0, r15;" /* current stack */
--- 183,272 ----
sf->sf_sr = PSL_MD; /* kernel mode, interrupt enable */
}
+ /*
+ * 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 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 */
+
+ /* 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.
+ *
+ * XXX Is this needed here?
+ */
+ if (SH_HAS_VIRTUAL_ALIAS)
+ sh_dcache_wbinv_range((vaddr_t)l2->l_addr, USPACE);
+ spbase = P1ADDR(spbase);
+ #else /* P1_STACK */
+ /* Don't need to set up u-area PTEs again. */
+ #endif /* P1_STACK */
+
+ /* 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 lwp *l, int proc)
{
struct switchframe *sf;
splsched();
uvmexp.swtch++;
! /* Switch to lwp0 stack */
curproc = 0;
! curpcb = lwp0.l_md.md_pcb;
sf = &curpcb->pcb_sf;
__asm__ __volatile__(
"mov %0, r15;" /* current stack */
***************
*** 210,218 ****
"r"(sf->sf_r7_bank));
/* Schedule freeing process resources */
! exit2(p);
! cpu_switch(p);
/* NOTREACHED */
}
--- 278,289 ----
"r"(sf->sf_r7_bank));
/* Schedule freeing process resources */
! if (proc)
! exit2(l);
! else
! lwp_exit2(l);
! cpu_switch(l);
/* NOTREACHED */
}
***************
*** 224,230 ****
};
int
! cpu_coredump(struct proc *p, struct vnode *vp, struct ucred *cred,
struct core *chdr)
{
struct md_core md_core;
--- 295,301 ----
};
int
! cpu_coredump(struct lwp *l, struct vnode *vp, struct ucred *cred,
struct core *chdr)
{
struct md_core md_core;
***************
*** 237,243 ****
chdr->c_cpusize = sizeof(md_core);
/* Save integer registers. */
! error = process_read_regs(p, &md_core.intreg);
if (error)
return error;
--- 308,314 ----
chdr->c_cpusize = sizeof(md_core);
/* Save integer registers. */
! error = process_read_regs(l, &md_core.intreg);
if (error)
return error;
***************
*** 248,260 ****
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);
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);
if (error)
return error;
--- 319,331 ----
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, 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, l->l_proc);
if (error)
return error;
--DocE+STaALJfprDB--