Attempt to adacpt acorn26 to idlelwp. This is untested.

OK'd by Ben Harris
This commit is contained in:
skrll 2007-06-01 07:04:53 +00:00
parent fb64759fb7
commit a6c4dd7bcd
5 changed files with 91 additions and 126 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpuswitch.c,v 1.10 2007/03/04 05:59:03 christos Exp $ */
/* $NetBSD: cpuswitch.c,v 1.11 2007/06/01 07:04:53 skrll Exp $ */
/*
* Copyright (c) 2000 Ben Harris.
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: cpuswitch.c,v 1.10 2007/03/04 05:59:03 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: cpuswitch.c,v 1.11 2007/06/01 07:04:53 skrll Exp $");
#include "opt_lockdebug.h"
@ -48,100 +48,24 @@ __KERNEL_RCSID(0, "$NetBSD: cpuswitch.c,v 1.10 2007/03/04 05:59:03 christos Exp
#include <sys/systm.h>
#include <sys/user.h>
#include <sys/ras.h>
#include <sys/cpu.h>
#include <uvm/uvm_extern.h>
#include <machine/frame.h>
#include <machine/machdep.h>
void idle(void);
struct pcb *curpcb;
/*
* Idle
*/
void
idle()
{
sched_unlock_idle();
spl0();
while (sched_whichqs == 0)
continue;
splhigh();
sched_lock_idle();
}
extern int want_resched; /* XXX should be in <machine/cpu.h> */
/*
* Find the highest-priority runnable process and switch to it.
*
* If l1 is NULL, we're switching away from a dying process. We hope it's
* safe to run on its stack until the switch.
*/
int
cpu_switch(struct lwp *l1, struct lwp *newl)
{
int which;
struct prochd *q;
struct lwp *l2;
struct proc *p2;
struct switchframe *dummy;
/*
* We enter here with interrupts blocked and sched_lock held.
*/
#if 0
printf("cpu_switch: %p ->", l1);
#endif
curlwp = NULL;
curpcb = NULL;
while (sched_whichqs == 0)
idle();
which = ffs(sched_whichqs) - 1;
q = &sched_qs[which];
l2 = q->ph_link;
remrunqueue(l2);
want_resched = 0;
sched_unlock_idle();
/* p->p_cpu initialized in fork1() for single-processor */
l2->l_stat = LSONPROC;
curlwp = l2;
curpcb = &curlwp->l_addr->u_pcb;
#if 0
printf(" %p\n", l2);
#endif
if (l2 == l1)
return (0);
if (l1 != NULL)
pmap_deactivate(l1);
pmap_activate(l2);
/* Check for Restartable Atomic Sequences. */
p2 = l2->l_proc;
if (!LIST_EMPTY(&p2->p_raslist)) {
struct trapframe *tf = l2->l_addr->u_pcb.pcb_tf;
void *pc;
pc = ras_lookup(p2, (void *)(tf->tf_r15 & R15_PC));
if (pc != (void *) -1)
tf->tf_r15 = (tf->tf_r15 & ~R15_PC) | (register_t) pc;
}
cpu_loswitch(l1 ? &l1->l_addr->u_pcb.pcb_sf : &dummy,
l2->l_addr->u_pcb.pcb_sf);
/* We only get back here after the other process has run. */
return (1);
}
/*
* Switch to the indicated lwp.
*/
void
cpu_switchto(struct lwp *old, struct lwp *new)
lwp_t *
cpu_switchto(lwp_t *old, lwp_t *new)
{
struct proc *p2;
/*
* We enter here with interrupts blocked and sched_lock held.
@ -150,14 +74,23 @@ cpu_switchto(struct lwp *old, struct lwp *new)
#if 0
printf("cpu_switchto: %p -> %p", old, new);
#endif
want_resched = 0;
/* p->p_cpu initialized in fork1() for single-processor */
new->l_stat = LSONPROC;
curlwp = new;
curpcb = &curlwp->l_addr->u_pcb;
sched_unlock_idle();
pmap_deactivate(old);
pmap_activate(new);
cpu_loswitch(&old->l_addr->u_pcb.pcb_sf, new->l_addr->u_pcb.pcb_sf);
/* We only get back here after the other process has run. */
if ((new->l_flag & LW_SYSTEM) == 0) {
/* Check for Restartable Atomic Sequences. */
p2 = new->l_proc;
if (!LIST_EMPTY(&p2->p_raslist)) {
struct trapframe *tf = new->l_addr->u_pcb.pcb_tf;
void *pc;
pc = ras_lookup(p2, (void *)(tf->tf_r15 & R15_PC));
if (pc != (void *) -1)
tf->tf_r15 = (tf->tf_r15 & ~R15_PC) |
(register_t) pc;
}
}
return cpu_loswitch(old, new);
}

View File

@ -1,4 +1,4 @@
# $NetBSD: genassym.cf,v 1.7 2006/10/08 12:22:35 bjh21 Exp $
# $NetBSD: genassym.cf,v 1.8 2007/06/01 07:04:53 skrll Exp $
#
# Copyright (c) 1999 Ben Harris
# All rights reserved.
@ -47,6 +47,7 @@ endif
define __PROG26 1
define U_PCB offsetof(struct user, u_pcb)
define PCB_SF offsetof(struct pcb, pcb_sf)
define PCB_ONFAULT offsetof(struct pcb, pcb_onfault)
define L_ADDR offsetof(struct lwp, l_addr)
@ -73,4 +74,3 @@ define EFS_RX_FLAGS offsetof(struct eca_fiqstate, efs_rx_flags)
define EFS_RX_MYADDR offsetof(struct eca_fiqstate, efs_rx_myaddr)
define EFS_TX_CURMBUF offsetof(struct eca_fiqstate, efs_tx_curmbuf)
endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.S,v 1.11 2007/02/28 23:47:09 bjh21 Exp $ */
/* $NetBSD: locore.S,v 1.12 2007/06/01 07:04:54 skrll Exp $ */
/*
* Copyright (c) 1998, 1999, 2000 Ben Harris
* Copyright (C) 1994-1997 Mark Brinicombe
@ -383,44 +383,62 @@ ENTRY_NP(get_r15)
mov r0, r14
mov r15, lr
/*
* Low-level context-switch operation. cpu_switch() is in C -- this
* just handles the bits that can't be done in C.
*
* void cpu_loswitch(struct switchframe **fromp,
* struct switchframe *to)
*
* We leave a switchframe on the stack pointed to by fromp,
* and return to the context in to. This should be called in
* splhigh();
*/
/* LINTSTUB: Func: void cpu_loswitch(struct switchframe **fromp, struct switchframe *to) */
/*
* Low-level context-switch operation. cpu_switchto() is in C -- this
* just handles the bits that can't be done in C.
*
* struct lwp *cpu_loswitch(struct lwp *oldl, struct lwp *newl)
*
* We leave a switchframe on the stack pointed to by and save this in
* oldl's PCB, and return to the context in newl. This should be called at
* splhigh();
*
* r0 and r1 must be left intact as they're needed by lwp_startup in
* lwp_trampoline
*/
/* LINTSTUB: Func: struct lwp *cpu_loswitch(struct lwp *oldl, struct lwp *newl) */
ENTRY(cpu_loswitch)
teq r0, #0x00000000
beq Lswitch_exited
ldr r3, [r0, #(L_ADDR)]
add r3, r3, #PCB_SF /* r3 = &old->l_addr->u_pcb.pcb_sf */
mov r2, sp /* Temporary stack pointer */
stmfd r2!, {r4-r11, r13-r14} /* Save all relevant registers */
str r2, [r0] /* Save switchframe pointer */
ldmfd r1, {r4-r11, r13-r14} /* Restore from old switchframe */
str r2, [r3] /* Save switchframe pointer */
Lswitch_exited:
ldr r2, [r1, #(L_ADDR)]
ldr r3, [r2, #(PCB_SF)] /* r3 = new->l_addr->u_pcb.pcb_sf; */
ldmfd r3, {r4-r11, r13-r14} /* Restore from old switchframe */
mov pc, r14 /* and return */
/*
* This funny little routine implements starting a process.
* It's called by cpu_loswitch returning from a faked
* switchframe set up by cpu_fork(), and gets
* the function it's meant to enter passed in R4 with its
* argument in R5. If that function's NULL, or if it returns,
* we hope there's a trapframe on the stack that'll take us
* back to userland.
*/
ENTRY(proc_trampoline)
/*
* This funny little routine implements starting a process.
* It's called by cpu_loswitch returning from a faked
* switchframe set up by cpu_lwp_fork(), and gets
* the function it's meant to enter passed in R4 with its
* argument in R5. If that function's NULL, or if it returns,
* we hope there's a trapframe on the stack that'll take us
* back to userland.
*
* cpu_loswitch also ensures that r0 is oldl and r1 is newl
* for our call to lwp_startup.
*/
ENTRY(lwp_trampoline)
mov fp, #0 /* Tie knot in top of stack */
bl _C_LABEL(lwp_startup)
mov r0, #0
bl _C_LABEL(lowerspl) /* spl0() */
bl _C_LABEL(lowerspl) /* spl0() */
cmp r4, #0 /* Function to call? */
beq Lproc_trampoline_nofunc
beq Llwp_trampoline_nofunc
mov r0, r5
mov r14, pc /* Save return address */
mov pc, r4 /* Call function */
Lproc_trampoline_nofunc:
Llwp_trampoline_nofunc:
b pull_trapframe
/* LINTSTUB: Func: int setjmp(label_t *l) */
@ -444,4 +462,4 @@ ENTRY(cpu_Debugger)
ldmfd r13!, {pc}
#endif
RCSID("$NetBSD: locore.S,v 1.11 2007/02/28 23:47:09 bjh21 Exp $")
RCSID("$NetBSD: locore.S,v 1.12 2007/06/01 07:04:54 skrll Exp $")

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.19 2007/02/22 04:47:28 thorpej Exp $ */
/* $NetBSD: machdep.c,v 1.20 2007/06/01 07:04:54 skrll Exp $ */
/*-
* Copyright (c) 1998 Ben Harris
@ -32,7 +32,7 @@
#include <sys/param.h>
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.19 2007/02/22 04:47:28 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.20 2007/06/01 07:04:54 skrll Exp $");
#include <sys/buf.h>
#include <sys/kernel.h>
@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.19 2007/02/22 04:47:28 thorpej Exp $")
#include <sys/reboot.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/cpu.h>
#include <dev/i2c/i2cvar.h>
#include <dev/i2c/pcf8583var.h>
@ -214,3 +215,16 @@ cmos_write(int location, int value)
return (pcfrtc_bootstrap_write(acorn26_i2c_tag, 0x50,
location, &val, 1));
}
void
cpu_need_resched(struct cpu_info *ci, int flags)
{
bool immed = (flags & RESCHED_IMMED) != 0;
if (want_resched && !immed)
return;
want_resched = 1;
if (curlwp != ci->ci_data.cpu_idlelwp)
setsoftast();
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.h,v 1.2 2002/03/24 23:37:43 bjh21 Exp $ */
/* $NetBSD: machdep.h,v 1.3 2007/06/01 07:04:54 skrll Exp $ */
/*-
* Copyright (c) 1998 Ben Harris
* All rights reserved.
@ -55,8 +55,8 @@ extern void int_on __P((void));
extern void int_off __P((void));
extern void fiq_on __P((void));
extern void fiq_off __P((void));
extern void cpu_loswitch(struct switchframe **, struct switchframe *);
extern void proc_trampoline(void); /* not quite true */
extern struct lwp *cpu_loswitch(struct lwp *, struct lwp *);
extern void lwp_trampoline(void); /* not quite true */
/* pmap.c */
extern register_t update_memc __P((register_t, register_t));