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. * Copyright (c) 2000 Ben Harris.
@ -38,7 +38,7 @@
*/ */
#include <sys/cdefs.h> #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" #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/systm.h>
#include <sys/user.h> #include <sys/user.h>
#include <sys/ras.h> #include <sys/ras.h>
#include <sys/cpu.h>
#include <uvm/uvm_extern.h> #include <uvm/uvm_extern.h>
#include <machine/frame.h> #include <machine/frame.h>
#include <machine/machdep.h> #include <machine/machdep.h>
void idle(void);
struct pcb *curpcb; 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> */ 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. * Switch to the indicated lwp.
*/ */
void lwp_t *
cpu_switchto(struct lwp *old, struct lwp *new) cpu_switchto(lwp_t *old, lwp_t *new)
{ {
struct proc *p2;
/* /*
* We enter here with interrupts blocked and sched_lock held. * We enter here with interrupts blocked and sched_lock held.
@ -150,14 +74,23 @@ cpu_switchto(struct lwp *old, struct lwp *new)
#if 0 #if 0
printf("cpu_switchto: %p -> %p", old, new); printf("cpu_switchto: %p -> %p", old, new);
#endif #endif
want_resched = 0;
/* p->p_cpu initialized in fork1() for single-processor */
new->l_stat = LSONPROC;
curlwp = new; curlwp = new;
curpcb = &curlwp->l_addr->u_pcb; curpcb = &curlwp->l_addr->u_pcb;
sched_unlock_idle();
pmap_deactivate(old); if ((new->l_flag & LW_SYSTEM) == 0) {
pmap_activate(new); /* Check for Restartable Atomic Sequences. */
cpu_loswitch(&old->l_addr->u_pcb.pcb_sf, new->l_addr->u_pcb.pcb_sf); p2 = new->l_proc;
/* We only get back here after the other process has run. */ 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 # Copyright (c) 1999 Ben Harris
# All rights reserved. # All rights reserved.
@ -47,6 +47,7 @@ endif
define __PROG26 1 define __PROG26 1
define U_PCB offsetof(struct user, u_pcb) 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 PCB_ONFAULT offsetof(struct pcb, pcb_onfault)
define L_ADDR offsetof(struct lwp, l_addr) 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_RX_MYADDR offsetof(struct eca_fiqstate, efs_rx_myaddr)
define EFS_TX_CURMBUF offsetof(struct eca_fiqstate, efs_tx_curmbuf) define EFS_TX_CURMBUF offsetof(struct eca_fiqstate, efs_tx_curmbuf)
endif 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) 1998, 1999, 2000 Ben Harris
* Copyright (C) 1994-1997 Mark Brinicombe * Copyright (C) 1994-1997 Mark Brinicombe
@ -383,44 +383,62 @@ ENTRY_NP(get_r15)
mov r0, r14 mov r0, r14
mov r15, lr mov r15, lr
/* /*
* Low-level context-switch operation. cpu_switch() is in C -- this * Low-level context-switch operation. cpu_switchto() is in C -- this
* just handles the bits that can't be done in C. * just handles the bits that can't be done in C.
* *
* void cpu_loswitch(struct switchframe **fromp, * struct lwp *cpu_loswitch(struct lwp *oldl, struct lwp *newl)
* struct switchframe *to) *
* * We leave a switchframe on the stack pointed to by and save this in
* We leave a switchframe on the stack pointed to by fromp, * oldl's PCB, and return to the context in newl. This should be called at
* and return to the context in to. This should be called in * splhigh();
* splhigh(); *
*/ * r0 and r1 must be left intact as they're needed by lwp_startup in
/* LINTSTUB: Func: void cpu_loswitch(struct switchframe **fromp, struct switchframe *to) */ * lwp_trampoline
*/
/* LINTSTUB: Func: struct lwp *cpu_loswitch(struct lwp *oldl, struct lwp *newl) */
ENTRY(cpu_loswitch) 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 */ mov r2, sp /* Temporary stack pointer */
stmfd r2!, {r4-r11, r13-r14} /* Save all relevant registers */ stmfd r2!, {r4-r11, r13-r14} /* Save all relevant registers */
str r2, [r0] /* Save switchframe pointer */ str r2, [r3] /* Save switchframe pointer */
ldmfd r1, {r4-r11, r13-r14} /* Restore from old switchframe */
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 */ mov pc, r14 /* and return */
/* /*
* This funny little routine implements starting a process. * This funny little routine implements starting a process.
* It's called by cpu_loswitch returning from a faked * It's called by cpu_loswitch returning from a faked
* switchframe set up by cpu_fork(), and gets * switchframe set up by cpu_lwp_fork(), and gets
* the function it's meant to enter passed in R4 with its * the function it's meant to enter passed in R4 with its
* argument in R5. If that function's NULL, or if it returns, * 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 * we hope there's a trapframe on the stack that'll take us
* back to userland. * back to userland.
*/ *
ENTRY(proc_trampoline) * 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 */ mov fp, #0 /* Tie knot in top of stack */
bl _C_LABEL(lwp_startup)
mov r0, #0 mov r0, #0
bl _C_LABEL(lowerspl) /* spl0() */ bl _C_LABEL(lowerspl) /* spl0() */
cmp r4, #0 /* Function to call? */ cmp r4, #0 /* Function to call? */
beq Lproc_trampoline_nofunc beq Llwp_trampoline_nofunc
mov r0, r5 mov r0, r5
mov r14, pc /* Save return address */ mov r14, pc /* Save return address */
mov pc, r4 /* Call function */ mov pc, r4 /* Call function */
Lproc_trampoline_nofunc: Llwp_trampoline_nofunc:
b pull_trapframe b pull_trapframe
/* LINTSTUB: Func: int setjmp(label_t *l) */ /* LINTSTUB: Func: int setjmp(label_t *l) */
@ -444,4 +462,4 @@ ENTRY(cpu_Debugger)
ldmfd r13!, {pc} ldmfd r13!, {pc}
#endif #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 * Copyright (c) 1998 Ben Harris
@ -32,7 +32,7 @@
#include <sys/param.h> #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/buf.h>
#include <sys/kernel.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/reboot.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <sys/systm.h> #include <sys/systm.h>
#include <sys/cpu.h>
#include <dev/i2c/i2cvar.h> #include <dev/i2c/i2cvar.h>
#include <dev/i2c/pcf8583var.h> #include <dev/i2c/pcf8583var.h>
@ -214,3 +215,16 @@ cmos_write(int location, int value)
return (pcfrtc_bootstrap_write(acorn26_i2c_tag, 0x50, return (pcfrtc_bootstrap_write(acorn26_i2c_tag, 0x50,
location, &val, 1)); 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 * Copyright (c) 1998 Ben Harris
* All rights reserved. * All rights reserved.
@ -55,8 +55,8 @@ extern void int_on __P((void));
extern void int_off __P((void)); extern void int_off __P((void));
extern void fiq_on __P((void)); extern void fiq_on __P((void));
extern void fiq_off __P((void)); extern void fiq_off __P((void));
extern void cpu_loswitch(struct switchframe **, struct switchframe *); extern struct lwp *cpu_loswitch(struct lwp *, struct lwp *);
extern void proc_trampoline(void); /* not quite true */ extern void lwp_trampoline(void); /* not quite true */
/* pmap.c */ /* pmap.c */
extern register_t update_memc __P((register_t, register_t)); extern register_t update_memc __P((register_t, register_t));