Attempt to adacpt acorn26 to idlelwp. This is untested.
OK'd by Ben Harris
This commit is contained in:
parent
fb64759fb7
commit
a6c4dd7bcd
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 $")
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user