summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libkvm/kvm_proc.c6
-rw-r--r--sys/arch/alpha/alpha/genassym.cf7
-rw-r--r--sys/arch/alpha/alpha/locore.s195
-rw-r--r--sys/arch/alpha/alpha/machdep.c62
-rw-r--r--sys/arch/alpha/alpha/vm_machdep.c6
-rw-r--r--sys/arch/amd64/amd64/cpu.c6
-rw-r--r--sys/arch/amd64/amd64/genassym.cf4
-rw-r--r--sys/arch/amd64/amd64/locore.S277
-rw-r--r--sys/arch/amd64/amd64/mptramp.S5
-rw-r--r--sys/arch/amd64/amd64/vm_machdep.c10
-rw-r--r--sys/arch/amd64/conf/files.amd643
-rw-r--r--sys/arch/arm/arm/cpuswitch.S697
-rw-r--r--sys/arch/arm/arm/genassym.cf8
-rw-r--r--sys/arch/arm/arm/pmap.c9
-rw-r--r--sys/arch/arm/arm/vm_machdep.c42
-rw-r--r--sys/arch/arm/include/pmap.h9
-rw-r--r--sys/arch/aviion/aviion/locore.S10
-rw-r--r--sys/arch/aviion/aviion/machdep.c13
-rw-r--r--sys/arch/hp300/hp300/locore.s99
-rw-r--r--sys/arch/hp300/hp300/vm_machdep.c8
-rw-r--r--sys/arch/hppa/hppa/genassym.cf4
-rw-r--r--sys/arch/hppa/hppa/locore.S255
-rw-r--r--sys/arch/hppa/hppa/vm_machdep.c9
-rw-r--r--sys/arch/hppa/include/cpu.h3
-rw-r--r--sys/arch/i386/i386/cpu.c6
-rw-r--r--sys/arch/i386/i386/genassym.cf4
-rw-r--r--sys/arch/i386/i386/locore.s385
-rw-r--r--sys/arch/i386/i386/mptramp.s6
-rw-r--r--sys/arch/i386/i386/vm_machdep.c5
-rw-r--r--sys/arch/i386/include/frame.h3
-rw-r--r--sys/arch/luna88k/luna88k/locore.S35
-rw-r--r--sys/arch/luna88k/luna88k/machdep.c28
-rw-r--r--sys/arch/m68k/include/cpu.h6
-rw-r--r--sys/arch/m68k/m68k/genassym.cf7
-rw-r--r--sys/arch/m68k/m68k/proc_subr.s129
-rw-r--r--sys/arch/m88k/include/cpu.h5
-rw-r--r--sys/arch/m88k/m88k/genassym.cf8
-rw-r--r--sys/arch/m88k/m88k/m88k_machdep.c46
-rw-r--r--sys/arch/m88k/m88k/process.S261
-rw-r--r--sys/arch/m88k/m88k/vm_machdep.c15
-rw-r--r--sys/arch/mac68k/mac68k/locore.s100
-rw-r--r--sys/arch/mac68k/mac68k/vm_machdep.c15
-rw-r--r--sys/arch/macppc/macppc/cpu.c11
-rw-r--r--sys/arch/macppc/macppc/genassym.cf5
-rw-r--r--sys/arch/macppc/macppc/locore.S201
-rw-r--r--sys/arch/mips64/mips64/context.S225
-rw-r--r--sys/arch/mips64/mips64/db_machdep.c13
-rw-r--r--sys/arch/mips64/mips64/vm_machdep.c8
-rw-r--r--sys/arch/mvme68k/mvme68k/locore.s100
-rw-r--r--sys/arch/mvme68k/mvme68k/vm_machdep.c16
-rw-r--r--sys/arch/mvme88k/mvme88k/locore.S10
-rw-r--r--sys/arch/mvme88k/mvme88k/machdep.c11
-rw-r--r--sys/arch/powerpc/conf/files.powerpc3
-rw-r--r--sys/arch/powerpc/include/pcb.h3
-rw-r--r--sys/arch/powerpc/powerpc/vm_machdep.c7
-rw-r--r--sys/arch/sgi/localbus/macebus.c6
-rw-r--r--sys/arch/sgi/sgi/genassym.cf6
-rw-r--r--sys/arch/sh/include/cpu.h7
-rw-r--r--sys/arch/sh/sh/genassym.cf4
-rw-r--r--sys/arch/sh/sh/locore_c.c74
-rw-r--r--sys/arch/sh/sh/locore_subr.S71
-rw-r--r--sys/arch/sh/sh/sh_machdep.c41
-rw-r--r--sys/arch/solbourne/solbourne/locore.s286
-rw-r--r--sys/arch/sparc/conf/files.sparc3
-rw-r--r--sys/arch/sparc/sparc/locore.s281
-rw-r--r--sys/arch/sparc/sparc/locore2.c99
-rw-r--r--sys/arch/sparc/sparc/vm_machdep.c13
-rw-r--r--sys/arch/sparc64/conf/files.sparc643
-rw-r--r--sys/arch/sparc64/sparc64/locore.s382
-rw-r--r--sys/arch/sparc64/sparc64/vm_machdep.c10
-rw-r--r--sys/arch/vax/include/cpu.h6
-rw-r--r--sys/arch/vax/include/macros.h15
-rw-r--r--sys/arch/vax/vax/subr.s107
-rw-r--r--sys/arch/vax/vax/vm_machdep.c19
-rw-r--r--sys/conf/files3
-rw-r--r--sys/kern/init_main.c6
-rw-r--r--sys/kern/kern_clock.c4
-rw-r--r--sys/kern/kern_exit.c18
-rw-r--r--sys/kern/kern_fork.c8
-rw-r--r--sys/kern/kern_proc.c6
-rw-r--r--sys/kern/kern_sched.c242
-rw-r--r--sys/kern/kern_synch.c66
-rw-r--r--sys/kern/kern_sysctl.c6
-rw-r--r--sys/kern/sched_bsd.c68
-rw-r--r--sys/sys/proc.h27
-rw-r--r--sys/sys/sched.h27
-rw-r--r--sys/uvm/uvm_meter.c6
87 files changed, 1045 insertions, 4299 deletions
diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c
index 9a97d9b4e90..ff9b9b377a9 100644
--- a/lib/libkvm/kvm_proc.c
+++ b/lib/libkvm/kvm_proc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kvm_proc.c,v 1.34 2007/06/18 21:51:15 pedro Exp $ */
+/* $OpenBSD: kvm_proc.c,v 1.35 2007/10/10 15:53:51 art Exp $ */
/* $NetBSD: kvm_proc.c,v 1.30 1999/03/24 05:50:50 mrg Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -73,7 +73,7 @@
#if 0
static char sccsid[] = "@(#)kvm_proc.c 8.3 (Berkeley) 9/23/93";
#else
-static char *rcsid = "$OpenBSD: kvm_proc.c,v 1.34 2007/06/18 21:51:15 pedro Exp $";
+static char *rcsid = "$OpenBSD: kvm_proc.c,v 1.35 2007/10/10 15:53:51 art Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -477,8 +477,6 @@ kvm_getproc2(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
kp2p = &kp2;
for (i = 0; i < nprocs; i++, kp++) {
memset(kp2p, 0, sizeof(kp2));
- kp2p->p_forw = PTRTOINT64(kp->kp_proc.p_forw);
- kp2p->p_back = PTRTOINT64(kp->kp_proc.p_back);
kp2p->p_paddr = PTRTOINT64(kp->kp_eproc.e_paddr);
kp2p->p_addr = PTRTOINT64(kp->kp_proc.p_addr);
diff --git a/sys/arch/alpha/alpha/genassym.cf b/sys/arch/alpha/alpha/genassym.cf
index cddc3760215..d8393934035 100644
--- a/sys/arch/alpha/alpha/genassym.cf
+++ b/sys/arch/alpha/alpha/genassym.cf
@@ -1,4 +1,4 @@
-# $OpenBSD: genassym.cf,v 1.10 2007/05/28 23:10:10 beck Exp $
+# $OpenBSD: genassym.cf,v 1.11 2007/10/10 15:53:51 art Exp $
# Copyright (c) 1994, 1995 Gordon W. Ross
# Copyright (c) 1993 Adam Glass
@@ -103,17 +103,12 @@ export ALPHA_PTE_KW
# Important offsets into the proc struct & associated constants
struct proc
-member p_forw
-member p_back
member p_addr
member p_vmspace
member p_stat
member P_MD_FLAGS p_md.md_flags
member P_MD_PCBPADDR p_md.md_pcbpaddr
member p_cpu
-struct prochd
-member ph_link
-member ph_rlink
export SONPROC
diff --git a/sys/arch/alpha/alpha/locore.s b/sys/arch/alpha/alpha/locore.s
index 6b9f238138f..fe7453cec66 100644
--- a/sys/arch/alpha/alpha/locore.s
+++ b/sys/arch/alpha/alpha/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.30 2007/05/28 23:10:10 beck Exp $ */
+/* $OpenBSD: locore.s,v 1.31 2007/10/10 15:53:51 art Exp $ */
/* $NetBSD: locore.s,v 1.94 2001/04/26 03:10:44 ross Exp $ */
/*-
@@ -716,123 +716,38 @@ LEAF(savectx, 1)
/**************************************************************************/
-IMPORT(whichqs, 4)
-
-/*
- * When no processes are on the runq, cpu_switch branches to idle
- * to wait for something to come ready.
- * Note: this is really a part of cpu_switch() but defined here for kernel
- * profiling.
- */
-LEAF(idle, 0)
- br pv, 1f
-1: LDGP(pv)
- /* Note: GET_CURPROC clobbers v0, t0, t8...t11. */
- GET_CURPROC
- stq zero, 0(v0) /* curproc <- NULL for stats */
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- CALL(sched_unlock_idle) /* release sched_lock */
-#endif
- mov zero, a0 /* enable all interrupts */
- call_pal PAL_OSF1_swpipl
-2: ldl t0, whichqs /* look for non-empty queue */
- beq t0, 2b
- ldiq a0, ALPHA_PSL_IPL_HIGH /* disable all interrupts */
- call_pal PAL_OSF1_swpipl
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- CALL(sched_lock_idle) /* acquire sched_lock */
-#endif
- jmp zero, cpu_switch_queuescan /* jump back into the fire */
- END(idle)
-
/*
- * cpu_switch()
- * Find the highest priority process and resume it.
+ * cpu_switchto(struct proc *old, struct proc *new)
+ * Switch from "old" proc to "new".
*/
-LEAF(cpu_switch, 0)
+LEAF(cpu_switchto, 2)
LDGP(pv)
- /*
- * do an inline savectx(), to save old context
- * Note: GET_CURPROC clobbers v0, t0, t8...t11.
- */
- GET_CURPROC
- ldq a0, 0(v0)
- ldq a1, P_ADDR(a0)
- /* NOTE: ksp is stored by the swpctx */
- stq s0, U_PCB_CONTEXT+(0 * 8)(a1) /* store s0 - s6 */
- stq s1, U_PCB_CONTEXT+(1 * 8)(a1)
- stq s2, U_PCB_CONTEXT+(2 * 8)(a1)
- stq s3, U_PCB_CONTEXT+(3 * 8)(a1)
- stq s4, U_PCB_CONTEXT+(4 * 8)(a1)
- stq s5, U_PCB_CONTEXT+(5 * 8)(a1)
- stq s6, U_PCB_CONTEXT+(6 * 8)(a1)
- stq ra, U_PCB_CONTEXT+(7 * 8)(a1) /* store ra */
- call_pal PAL_OSF1_rdps /* NOTE: doesn't kill a0 */
- stq v0, U_PCB_CONTEXT+(8 * 8)(a1) /* store ps, for ipl */
- mov a0, s0 /* save old curproc */
- mov a1, s1 /* save old U-area */
-
-cpu_switch_queuescan:
- br pv, 1f
-1: LDGP(pv)
- ldl t0, whichqs /* look for non-empty queue */
- beq t0, idle /* and if none, go idle */
- mov t0, t3 /* t3 = saved whichqs */
- mov zero, t2 /* t2 = lowest bit set */
- blbs t0, 3f /* if low bit set, done! */
-
-2: srl t0, 1, t0 /* try next bit */
- addq t2, 1, t2
- blbc t0, 2b /* if clear, try again */
-
-3: /*
- * Remove process from queue
- */
- lda t1, qs /* get queues */
- sll t2, 4, t0 /* queue head is 16 bytes */
- addq t1, t0, t0 /* t0 = qp = &qs[firstbit] */
-
- ldq t4, PH_LINK(t0) /* t4 = p = highest pri proc */
- bne t4, 4f /* make sure p != NULL */
- PANIC("cpu_switch",Lcpu_switch_pmsg) /* nothing in queue! */
-
-4:
- ldq t5, P_FORW(t4) /* t5 = p->p_forw */
- stq t5, PH_LINK(t0) /* qp->ph_link = p->p_forw */
- stq t0, P_BACK(t5) /* p->p_forw->p_back = qp */
- stq zero, P_BACK(t4) /* firewall: p->p_back = NULL */
- cmpeq t0, t5, t0 /* see if queue is empty */
- beq t0, 5f /* nope, it's not! */
-
- ldiq t0, 1 /* compute bit in whichqs */
- sll t0, t2, t0
- xor t3, t0, t3 /* clear bit in whichqs */
- stl t3, whichqs
-
-5:
- mov t4, s2 /* save new proc */
- ldq s3, P_MD_PCBPADDR(s2) /* save new pcbpaddr */
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
/*
- * Done mucking with the run queues, release the
- * scheduler lock, but keep interrupts out.
+ * Don't bother saving the old context if oldproc is NULL.
*/
- CALL(sched_unlock_idle)
-#endif
+ beq a0, 1f
/*
- * Check to see if we're switching to ourself. If we are,
- * don't bother loading the new context.
- *
- * Note that even if we re-enter cpu_switch() from idle(),
- * s0 will still contain the old curproc value because any
- * users of that register between then and now must have
- * saved it. Also note that switch_exit() ensures that
- * s0 is clear before jumping here to find a new process.
+ * do an inline savectx(), to save old context
*/
- cmpeq s0, s2, t0 /* oldproc == newproc? */
- bne t0, 7f /* Yes! Skip! */
+ call_pal PAL_OSF1_rdps /* NOTE: doesn't kill a0 */
+ ldq t0, P_ADDR(a0)
+ /* NOTE: ksp is stored by the swpctx */
+ stq s0, U_PCB_CONTEXT+(0 * 8)(t0) /* store s0 - s6 */
+ stq s1, U_PCB_CONTEXT+(1 * 8)(t0)
+ stq s2, U_PCB_CONTEXT+(2 * 8)(t0)
+ stq s3, U_PCB_CONTEXT+(3 * 8)(t0)
+ stq s4, U_PCB_CONTEXT+(4 * 8)(t0)
+ stq s5, U_PCB_CONTEXT+(5 * 8)(t0)
+ stq s6, U_PCB_CONTEXT+(6 * 8)(t0)
+ stq ra, U_PCB_CONTEXT+(7 * 8)(t0) /* store ra */
+ stq v0, U_PCB_CONTEXT+(8 * 8)(t0) /* store ps, for ipl */
+
+1:
+ mov a0, s0 /* save old proc */
+ mov a1, s2 /* save new proc */
+ ldq s3, P_MD_PCBPADDR(s2) /* save new pcbpaddr */
/*
* Deactivate the old address space before activating the
@@ -842,18 +757,18 @@ cpu_switch_queuescan:
* do this after we activate, then we might end up
* incorrectly marking the pmap inactive!
*
- * We don't deactivate if we came here from switch_exit
+ * We don't deactivate if we came here from sched_exit
* (old pmap no longer exists; vmspace has been freed).
* oldproc will be NULL in this case. We have actually
* taken care of calling pmap_deactivate() in cpu_exit(),
* before the vmspace went away.
*/
- beq s0, 6f
+ beq s0, 2f
mov s0, a0 /* pmap_deactivate(oldproc) */
CALL(pmap_deactivate)
-6: /*
+2: /*
* Activate the new process's address space and perform
* the actual context swap.
*/
@@ -864,7 +779,7 @@ cpu_switch_queuescan:
mov s3, a0 /* swap the context */
SWITCH_CONTEXT
-7: /*
+ /*
* Now that the switch is done, update curproc and other
* globals. We must do this even if switching to ourselves
* because we might have re-entered cpu_switch() from idle(),
@@ -911,7 +826,7 @@ EXPORT(__bwx_switch1)
ldiq v0, 1 /* possible ret to savectx() */
RET
- END(cpu_switch)
+ END(cpu_switchto)
#ifndef SMALL_KERNEL
/*
@@ -926,6 +841,18 @@ EXPORT(__bwx_switch2)
EXPORT(__bwx_switch3)
#endif
+LEAF(cpu_idle_enter, 0)
+ RET
+ END(cpu_idle_enter)
+
+LEAF(cpu_idle_cycle, 0)
+ RET
+ END(cpu_idle_cycle)
+
+LEAF(cpu_idle_leave, 0)
+ RET
+ END(cpu_idle_leave)
+
/*
* switch_trampoline()
*
@@ -945,46 +872,6 @@ LEAF(switch_trampoline, 0)
jmp zero, (pv)
END(switch_trampoline)
-/*
- * switch_exit(struct proc *p)
- * Make a the named process exit. Partially switch to our idle thread
- * (we don't update curproc or restore registers), and jump into the middle
- * of cpu_switch to switch into a few process. The process reaper will
- * free the dead process's VM resources. MUST BE CALLED AT SPLHIGH.
- */
-LEAF(switch_exit, 1)
- LDGP(pv)
-
- /* save the exiting proc pointer */
- mov a0, s2
-
- /* Switch to our idle stack. */
- GET_IDLE_PCB(a0) /* clobbers v0, t0, t8-t11 */
- SWITCH_CONTEXT
-
- /*
- * Now running as idle thread, except for the value of 'curproc' and
- * the saved regs.
- */
-
- /* Schedule the vmspace and stack to be freed. */
- mov s2, a0
- CALL(exit2)
-
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- CALL(sched_lock_idle) /* acquire sched_lock */
-#endif
-
- /*
- * Now jump back into the middle of cpu_switch(). Note that
- * we must clear s0 to guarantee that the check for switching
- * to ourselves in cpu_switch() will fail. This is safe since
- * s0 will be restored when a new process is resumed.
- */
- mov zero, s0
- jmp zero, cpu_switch_queuescan
- END(switch_exit)
-
/**************************************************************************/
/*
diff --git a/sys/arch/alpha/alpha/machdep.c b/sys/arch/alpha/alpha/machdep.c
index ce9d237b8d8..4f7836c9de1 100644
--- a/sys/arch/alpha/alpha/machdep.c
+++ b/sys/arch/alpha/alpha/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.112 2007/09/15 10:10:37 martin Exp $ */
+/* $OpenBSD: machdep.c,v 1.113 2007/10/10 15:53:51 art Exp $ */
/* $NetBSD: machdep.c,v 1.210 2000/06/01 17:12:38 thorpej Exp $ */
/*-
@@ -1874,66 +1874,6 @@ spl0()
}
/*
- * The following primitives manipulate the run queues. _whichqs tells which
- * of the 32 queues _qs have processes in them. Setrunqueue puts processes
- * into queues, Remrunqueue removes them from queues. The running process is
- * on no queue, other processes are on a queue related to p->p_priority,
- * divided by 4 actually to shrink the 0-127 range of priorities into the 32
- * available queues.
- */
-/*
- * setrunqueue(p)
- * proc *p;
- *
- * Call should be made at splclock(), and p->p_stat should be SRUN.
- */
-
-/* XXXART - grmble */
-#define sched_qs qs
-#define sched_whichqs whichqs
-
-void
-setrunqueue(p)
- struct proc *p;
-{
- int bit;
-
- /* firewall: p->p_back must be NULL */
- if (p->p_back != NULL)
- panic("setrunqueue");
-
- bit = p->p_priority >> 2;
- sched_whichqs |= (1 << bit);
- p->p_forw = (struct proc *)&sched_qs[bit];
- p->p_back = sched_qs[bit].ph_rlink;
- p->p_back->p_forw = p;
- sched_qs[bit].ph_rlink = p;
-}
-
-/*
- * remrunqueue(p)
- *
- * Call should be made at splclock().
- */
-void
-remrunqueue(p)
- struct proc *p;
-{
- int bit;
-
- bit = p->p_priority >> 2;
- if ((sched_whichqs & (1 << bit)) == 0)
- panic("remrunqueue");
-
- p->p_back->p_forw = p->p_forw;
- p->p_forw->p_back = p->p_back;
- p->p_back = NULL; /* for firewall checking. */
-
- if ((struct proc *)&sched_qs[bit] == sched_qs[bit].ph_link)
- sched_whichqs &= ~(1 << bit);
-}
-
-/*
* Wait "n" microseconds.
*/
void
diff --git a/sys/arch/alpha/alpha/vm_machdep.c b/sys/arch/alpha/alpha/vm_machdep.c
index 16191729b90..eda0437fb46 100644
--- a/sys/arch/alpha/alpha/vm_machdep.c
+++ b/sys/arch/alpha/alpha/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.34 2007/09/03 01:24:22 krw Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.35 2007/10/10 15:53:51 art Exp $ */
/* $NetBSD: vm_machdep.c,v 1.55 2000/03/29 03:49:48 simonb Exp $ */
/*
@@ -114,9 +114,7 @@ cpu_exit(p)
* vmspace's context until the switch to proc0 in switch_exit().
*/
pmap_deactivate(p);
-
- (void) splhigh();
- switch_exit(p);
+ sched_exit(p);
/* NOTREACHED */
}
diff --git a/sys/arch/amd64/amd64/cpu.c b/sys/arch/amd64/amd64/cpu.c
index 2f29892d219..554a62ef344 100644
--- a/sys/arch/amd64/amd64/cpu.c
+++ b/sys/arch/amd64/amd64/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.14 2007/09/17 15:34:38 chl Exp $ */
+/* $OpenBSD: cpu.c,v 1.15 2007/10/10 15:53:51 art Exp $ */
/* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */
/*-
@@ -345,6 +345,7 @@ cpu_attach(struct device *parent, struct device *self, void *aux)
#if defined(MULTIPROCESSOR)
cpu_intr_init(ci);
gdt_alloc_cpu(ci);
+ sched_init_cpu(ci);
cpu_start_secondary(ci);
ncpus++;
if (ci->ci_flags & CPUF_PRESENT) {
@@ -540,6 +541,9 @@ cpu_hatch(void *v)
microuptime(&ci->ci_schedstate.spc_runtime);
splx(s);
+
+ SCHED_LOCK(s);
+ cpu_switchto(NULL, sched_chooseproc());
}
#if defined(DDB)
diff --git a/sys/arch/amd64/amd64/genassym.cf b/sys/arch/amd64/amd64/genassym.cf
index 1632d9b7c8f..f591049c3dc 100644
--- a/sys/arch/amd64/amd64/genassym.cf
+++ b/sys/arch/amd64/amd64/genassym.cf
@@ -1,4 +1,4 @@
-# $OpenBSD: genassym.cf,v 1.14 2007/06/01 21:01:51 art Exp $
+# $OpenBSD: genassym.cf,v 1.15 2007/10/10 15:53:51 art Exp $
# Written by Artur Grabowski art@openbsd.org, Public Domain
include <sys/param.h>
@@ -33,8 +33,6 @@ define UVM_PAGE_IDLE_ZERO offsetof(struct uvm, page_idle_zero)
struct proc
member p_addr
-member p_back
-member p_forw
member p_priority
member p_stat
member p_wchan
diff --git a/sys/arch/amd64/amd64/locore.S b/sys/arch/amd64/amd64/locore.S
index e44923662e8..7a382441870 100644
--- a/sys/arch/amd64/amd64/locore.S
+++ b/sys/arch/amd64/amd64/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.23 2007/09/12 18:18:27 deraadt Exp $ */
+/* $OpenBSD: locore.S,v 1.24 2007/10/10 15:53:51 art Exp $ */
/* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */
/*
@@ -723,13 +723,8 @@ ENTRY(longjmp)
* actually to shrink the 0-127 range of priorities into the 32 available
* queues.
*/
- .globl _C_LABEL(whichqs),_C_LABEL(qs)
.globl _C_LABEL(uvmexp),_C_LABEL(panic)
-#if NAPM > 0
- .globl _C_LABEL(apm_cpu_idle),_C_LABEL(apm_cpu_busy)
-#endif
-
#ifdef DIAGNOSTIC
NENTRY(switch_error1)
movabsq $1f,%rdi
@@ -749,12 +744,10 @@ NENTRY(switch_error3)
#endif /* DIAGNOSTIC */
/*
- * int cpu_switch(struct proc *)
- * Find a runnable process and switch to it. Wait if necessary. If the new
- * proc is the same as the old one, we short-circuit the context save and
- * restore.
+ * int cpu_switchto(struct proc *old, struct proc *new)
+ * Switch from "old" proc to "new".
*/
-ENTRY(cpu_switch)
+ENTRY(cpu_switchto)
pushq %rbx
pushq %rbp
pushq %r12
@@ -762,163 +755,12 @@ ENTRY(cpu_switch)
pushq %r14
pushq %r15
- movq %rdi,%r13
-
- /*
- * Clear curproc so that we don't accumulate system time while idle.
- * This also insures that schedcpu() will move the old proc to
- * the correct queue if it happens to get called from the spllower()
- * below and changes the priority. (See corresponding comment in
- * userret()).
- */
- movq $0,CPUVAR(CURPROC)
-
-
- /*
- * First phase: find new proc.
- *
- * Registers:
- * %rax - queue head, scratch, then zero
- * %r8 - queue number
- * %ecx - cached value of whichqs
- * %rdx - next process in queue
- * %r13 - old proc
- * %r12 - new proc
- */
-
- /* Look for new proc. */
- cli # splhigh doesn't do a cli
- movl _C_LABEL(whichqs)(%rip),%ecx
- bsfl %ecx,%r8d # find a full q
- jnz switch_dequeue
-
- /*
- * idling: save old context
- *
- * Registers:
- * %rax, %rcx - scratch
- * %r13 - old proc, then old pcb
- * %r12 - idle pcb
- */
-
- /* old proc still in %rdi */
- call _C_LABEL(pmap_deactivate)
-
- movq P_ADDR(%r13),%r13
-
- /* Save stack pointers */
-
- movq %rsp,PCB_RSP(%r13)
- movq %rbp,PCB_RBP(%r13)
-
- /* Find idle PCB for this CPU */
-#ifndef MULTIPROCESSOR
- leaq _C_LABEL(proc0)(%rip),%rcx
- movq P_ADDR(%rcx),%r12
- movl P_MD_TSS_SEL(%rcx),%edx
-#else
- movq CPUVAR(IDLE_PCB),%r12
- movl CPUVAR(IDLE_TSS_SEL),%edx
-#endif
- movq $0,CPUVAR(CURPROC)
-
- /* Restore the idle context (avoid interrupts) */
- cli
-
- /* Restore stack pointers. */
- movq PCB_RSP(%r12),%rsp
- movq PCB_RBP(%r12),%rbp
-
- /* Switch address space. */
- movq PCB_CR3(%r12),%rcx
- movq %rcx,%cr3
-
-#ifdef MULTIPROCESSOR
- movq CPUVAR(GDT),%rax
-#else
- movq _C_LABEL(gdtstore)(%rip),%rax
-#endif
-
- /* Switch TSS. Reset "task busy" flag before */
- andl $~0x0200,4(%rax,%rdx, 1)
- ltr %dx
-
- /* Restore cr0 (including FPU state). */
- movl PCB_CR0(%r12),%ecx
- movq %rcx,%cr0
-
- SET_CURPCB(%r12)
-
- xorq %r13,%r13
- sti
-idle_unlock:
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- call _C_LABEL(sched_unlock_idle)
-#endif
- /* Interrupts are okay again. */
- movl $IPL_NONE,%edi
- call _C_LABEL(Xspllower)
- jmp idle_start
-idle_zero:
- sti
- call _C_LABEL(uvm_pageidlezero)
- cli
- cmpl $0,_C_LABEL(whichqs)(%rip)
- jnz idle_exit
-idle_loop:
-#if NPCTR > 0
- incq _C_LABEL(pctr_idlcnt)
-#endif
- /* Try to zero some pages. */
- movl _C_LABEL(uvm)+UVM_PAGE_IDLE_ZERO(%rip),%ecx
- testl %ecx,%ecx
- jnz idle_zero
- sti
- hlt
-NENTRY(mpidle)
-idle_start:
- cli
- cmpl $0,_C_LABEL(whichqs)(%rip)
- jz idle_loop
-idle_exit:
- movl $IPL_HIGH,CPUVAR(ILEVEL)
- sti
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- call _C_LABEL(sched_lock_idle)
-#endif
-switch_search:
- movl _C_LABEL(whichqs)(%rip),%ecx
- bsfl %ecx,%r8d
- jz idle_unlock
-
-switch_dequeue:
-
- sti
- movq %r8,%r9
-
- shlq $4, %r9
- leaq _C_LABEL(qs)(%rip),%rax
- addq %r9,%rax
- /* movq (%rax),%rax */
-
- movq P_FORW(%rax),%r12 # unlink from front of process q
-#ifdef DIAGNOSTIC
- cmpq %r12,%rax # linked to self (i.e. nothing queued)?
- je _C_LABEL(switch_error1) # not possible
-#endif /* DIAGNOSTIC */
- movq P_FORW(%r12),%rdx
- movq %rdx,P_FORW(%rax)
- movq %rax,P_BACK(%rdx)
-
- cmpq %rdx,%rax # q empty?
- jne 3f
-
- btrl %r8d,%ecx # yes, clear to indicate empty
- movl %ecx,_C_LABEL(whichqs)(%rip) # update q status
+ movq %rdi, %r13
+ movq %rsi, %r12
-3: /* We just did it. */
xorq %rax,%rax
movl %eax,CPUVAR(RESCHED)
+
switch_resume:
#ifdef DIAGNOSTIC
cmpq %rax,P_WCHAN(%r12)
@@ -927,24 +769,16 @@ switch_resume:
jne _C_LABEL(switch_error3)
#endif
- /* Isolate proc. XXX Is this necessary? */
- movq %rax,P_BACK(%r12)
-
/* Record new proc. */
movb $SONPROC,P_STAT(%r12) # p->p_stat = SONPROC
SET_CURPROC(%r12,%rcx)
- /* Skip context switch if same proc. */
- xorl %ebx,%ebx
- cmpq %r12,%r13
- je switch_return
-
/* If old proc exited, don't bother. */
testq %r13,%r13
jz switch_exited
/*
- * Second phase: save old context.
+ * Save old context.
*
* Registers:
* %rax, %rcx - scratch
@@ -963,7 +797,7 @@ switch_resume:
switch_exited:
/*
- * Third phase: restore saved context.
+ * Restore saved context.
*
* Registers:
* %rax, %rcx, %rdx - scratch
@@ -1020,15 +854,13 @@ switch_restored:
sti
switch_return:
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- call _C_LABEL(sched_unlock_idle)
-#endif
+#if 0
+ /* Violation of lock ordering, since we're holding the sched_lock */
movl $IPL_NONE,%edi
call _C_LABEL(Xspllower)
movl $IPL_HIGH,CPUVAR(ILEVEL)
-
- movl %ebx,%eax
+#endif
popq %r15
popq %r14
@@ -1038,87 +870,16 @@ switch_return:
popq %rbx
ret
-ENTRY(cpu_switchto)
- pushq %rbx
- pushq %rbp
- pushq %r12
- pushq %r13
- pushq %r14
- pushq %r15
-
- movq %rdi,%r13
- movq %rsi,%r12
-
- movq $0,CPUVAR(CURPROC)
-
- xorq %rax,%rax
- jmp switch_resume
-
-
-/*
- * void switch_exit(struct proc *l, void (*exit)(struct proc *));
- * Switch to proc0's saved context and deallocate the address space and kernel
- * stack for p. Then jump into cpu_switch(), as if we were in proc0 all along.
- */
- .globl _C_LABEL(proc0)
-ENTRY(switch_exit)
-#ifdef MULTIPROCESSOR
- movq CPUVAR(IDLE_PCB),%r8
- movl CPUVAR(IDLE_TSS_SEL),%edx
-#else
- leaq _C_LABEL(proc0)(%rip),%r9
- movq P_ADDR(%r9),%r8
- movl P_MD_TSS_SEL(%r9),%edx
-#endif
-
- /* In case we fault... */
- movq $0,CPUVAR(CURPROC)
-
- cli
-
- /* Restore stack pointers. */
- movq PCB_RSP(%r8),%rsp
- movq PCB_RBP(%r8),%rbp
-
- /* Load TSS info. */
-#ifdef MULTIPROCESSOR
- movq CPUVAR(GDT),%rax
-#else
- movq _C_LABEL(gdtstore)(%rip),%rax
-#endif
-
- /* Switch address space. */
- movq PCB_CR3(%r8),%rcx
- movq %rcx,%cr3
-
- /* Switch TSS. */
- andl $~0x0200,4-SEL_KPL(%rax,%rdx,1)
- ltr %dx
-
- /* We're always in the kernel, so we don't need the LDT. */
-
- /* Restore cr0 (including FPU state). */
- movl PCB_CR0(%r8),%ecx
- movq %rcx,%cr0
-
- /* Record new pcb. */
- SET_CURPCB(%r8)
-
- /* Interrupts are okay again. */
- sti
+ENTRY(cpu_idle_enter)
+ ret
- /*
- * Schedule the dead process's vmspace and stack to be freed.
- * {lpw_}exit2(l). Function still in %rsi (2nd arg), proc in
- * %rdi (first arg).
- */
+ENTRY(cpu_idle_cycle)
+ hlt
+ ret
- call *%rsi
+ENTRY(cpu_idle_leave)
+ ret
- /* Jump into cpu_switch() with the right state. */
- xorq %r13,%r13
- movq %r13, CPUVAR(CURPROC)
- jmp switch_search
/*
* savectx(struct pcb *pcb);
diff --git a/sys/arch/amd64/amd64/mptramp.S b/sys/arch/amd64/amd64/mptramp.S
index 397c672f36c..20346084081 100644
--- a/sys/arch/amd64/amd64/mptramp.S
+++ b/sys/arch/amd64/amd64/mptramp.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: mptramp.S,v 1.3 2005/07/26 08:38:29 art Exp $ */
+/* $OpenBSD: mptramp.S,v 1.4 2007/10/10 15:53:51 art Exp $ */
/* $NetBSD: mptramp.S,v 1.1 2003/04/26 18:39:30 fvdl Exp $ */
/*-
@@ -235,5 +235,4 @@ _C_LABEL(cpu_spinup_trampoline_end): #end of code copied to MP_TRAMPOLINE
movl PCB_CR0(%rsi),%eax
movq %rax,%cr0
call _C_LABEL(cpu_hatch)
- xorq %r13,%r13
- jmp _C_LABEL(mpidle)
+ /* NOTREACHED */
diff --git a/sys/arch/amd64/amd64/vm_machdep.c b/sys/arch/amd64/amd64/vm_machdep.c
index 7cb5179c909..1b6fa8463b8 100644
--- a/sys/arch/amd64/amd64/vm_machdep.c
+++ b/sys/arch/amd64/amd64/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.10 2007/05/27 20:59:25 miod Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.11 2007/10/10 15:53:51 art Exp $ */
/* $NetBSD: vm_machdep.c,v 1.1 2003/04/26 18:39:33 fvdl Exp $ */
/*-
@@ -169,12 +169,8 @@ cpu_exit(struct proc *p)
if (p->p_md.md_flags & MDP_USEDMTRR)
mtrr_clean(p);
- /*
- * No need to do user LDT cleanup here; it's handled in
- * pmap_destroy().
- */
-
- switch_exit(p, exit2);
+ pmap_deactivate(p);
+ sched_exit(p);
}
/*
diff --git a/sys/arch/amd64/conf/files.amd64 b/sys/arch/amd64/conf/files.amd64
index 3c5fa842f78..6cd06816c70 100644
--- a/sys/arch/amd64/conf/files.amd64
+++ b/sys/arch/amd64/conf/files.amd64
@@ -1,4 +1,4 @@
-# $OpenBSD: files.amd64,v 1.35 2007/10/07 18:41:07 mbalmer Exp $
+# $OpenBSD: files.amd64,v 1.36 2007/10/10 15:53:51 art Exp $
maxpartitions 16
maxusers 2 16 128
@@ -18,7 +18,6 @@ file arch/amd64/amd64/syscall.c
file arch/amd64/amd64/trap.c
file arch/amd64/amd64/vm_machdep.c
file arch/amd64/amd64/fpu.c
-file arch/amd64/amd64/Locore.c
file arch/amd64/amd64/softintr.c
file arch/amd64/amd64/i8259.c
file arch/amd64/amd64/cacheinfo.c
diff --git a/sys/arch/arm/arm/cpuswitch.S b/sys/arch/arm/arm/cpuswitch.S
index d94219d88c0..544f7c27243 100644
--- a/sys/arch/arm/arm/cpuswitch.S
+++ b/sys/arch/arm/arm/cpuswitch.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpuswitch.S,v 1.7 2007/05/14 07:07:09 art Exp $ */
+/* $OpenBSD: cpuswitch.S,v 1.8 2007/10/10 15:53:51 art Exp $ */
/* $NetBSD: cpuswitch.S,v 1.41 2003/11/15 08:44:18 scw Exp $ */
/*
@@ -123,142 +123,11 @@
.text
-.Lwhichqs:
- .word _C_LABEL(whichqs)
-
-.Lqs:
- .word _C_LABEL(qs)
-
-/*
- * On entry
- * r0 = process
- */
-
-ENTRY(setrunqueue)
- /*
- * Local register usage
- * r0 = process
- * r1 = queue
- * r2 = &qs[queue] and temp
- * r3 = temp
- * r12 = whichqs
- */
-#ifdef DIAGNOSTIC
- ldr r1, [r0, #(P_BACK)]
- teq r1, #0x00000000
- bne Lsetrunqueue_erg
-
- ldr r1, [r0, #(P_WCHAN)]
- teq r1, #0x00000000
- bne Lsetrunqueue_erg
-#endif
-
- /* Get the priority of the queue */
- ldrb r1, [r0, #(P_PRIORITY)]
- mov r1, r1, lsr #2
-
- /* Indicate that there is a process on this queue */
- ldr r12, .Lwhichqs
- ldr r2, [r12]
- mov r3, #0x00000001
- mov r3, r3, lsl r1
- orr r2, r2, r3
- str r2, [r12]
-
- /* Get the address of the queue */
- ldr r2, .Lqs
- add r1, r2, r1, lsl # 3
-
- /* Hook the process in */
- str r1, [r0, #(P_FORW)]
- ldr r2, [r1, #(P_BACK)]
-
- str r0, [r1, #(P_BACK)]
-#ifdef DIAGNOSTIC
- teq r2, #0x00000000
- beq Lsetrunqueue_erg
-#endif
- str r0, [r2, #(P_FORW)]
- str r2, [r0, #(P_BACK)]
-
- mov pc, lr
-
-#ifdef DIAGNOSTIC
-Lsetrunqueue_erg:
- mov r2, r1
- mov r1, r0
- add r0, pc, #Ltext1 - . - 8
- bl _C_LABEL(printf)
-
- ldr r2, .Lqs
- ldr r1, [r2]
- add r0, pc, #Ltext2 - . - 8
- b _C_LABEL(panic)
-
-Ltext1:
- .asciz "setrunqueue : %08x %08x\n"
-Ltext2:
- .asciz "setrunqueue : [qs]=%08x qs=%08x\n"
- .align 0
-#endif
-
-/*
- * On entry
- * r0 = process
- */
-
-ENTRY(remrunqueue)
- /*
- * Local register usage
- * r0 = oldproc
- * r1 = queue
- * r2 = &qs[queue] and scratch
- * r3 = scratch
- * r12 = whichqs
- */
-
- /* Get the priority of the queue */
- ldrb r1, [r0, #(P_PRIORITY)]
- mov r1, r1, lsr #2
-
- /* Unhook the process */
- ldr r2, [r0, #(P_FORW)]
- ldr r3, [r0, #(P_BACK)]
-
- str r3, [r2, #(P_BACK)]
- str r2, [r3, #(P_FORW)]
-
- /* If the queue is now empty clear the queue not empty flag */
- teq r2, r3
-
- /* This could be reworked to avoid the use of r4 */
- ldreq r12, .Lwhichqs
- ldreq r2, [r12]
- moveq r3, #0x00000001
- moveq r3, r3, lsl r1
- biceq r2, r2, r3
- streq r2, [r12]
-
- /* Remove the back pointer for the process */
- mov r1, #0x00000000
- str r1, [r0, #(P_BACK)]
-
- mov pc, lr
-
-
-/*
- * cpuswitch()
- *
- * preforms a process context switch.
- * This function has several entry points
- */
-
.Lcpu_info_store:
.word _C_LABEL(cpu_info_store)
.Lcurproc:
.word _C_LABEL(cpu_info_store) + CI_CURPROC
-
.Lwant_resched:
.word _C_LABEL(want_resched)
@@ -289,320 +158,123 @@ _C_LABEL(curpcb):
/*
* Idle loop, exercised while waiting for a process to wake up.
- *
- * NOTE: When we jump back to .Lswitch_search, we must have a
- * pointer to whichqs in r7, which is what it is when we arrive
- * here.
*/
-/* LINTSTUB: Ignore */
-ASENTRY_NP(idle)
- ldr r6, .Lcpu_do_powersave
- IRQenable /* Enable interrupts */
- ldr r6, [r6] /* r6 = cpu_do_powersave */
+ENTRY(cpu_idle_enter)
+ stmfd sp!, {lr}
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- bl _C_LABEL(sched_unlock_idle)
-#endif
+ IRQenable /* Enable interrupts */
/* Drop to spl0 (returns the current spl level in r0). */
mov r0, #(IPL_NONE)
bl _C_LABEL(_spllower)
+ ldmfd sp!, {pc}
+
+ENTRY(cpu_idle_cycle)
+ stmfd sp!, {r6, lr}
+
+ ldr r6, .Lcpu_do_powersave
+ ldr r6, [r6] /* r6 = cpu_do_powersave */
+
teq r6, #0 /* cpu_do_powersave non zero? */
ldrne r6, .Lcpufuncs
- mov r4, r0 /* Old interrupt level to r4 */
ldrne r6, [r6, #(CF_SLEEP)]
- /*
- * Main idle loop.
- * r6 points to power-save idle function if required, else NULL.
- */
-1: ldr r3, [r7] /* r3 = sched_whichqs */
- teq r3, #0
- bne 2f /* We have work to do */
teq r6, #0 /* Powersave idle? */
- beq 1b /* Nope. Just sit-n-spin. */
+ beq 1f /* Nope. Just continue. */
/*
- * Before going into powersave idle mode, disable interrupts
- * and check sched_whichqs one more time.
+ * Before going into powersave idle mode, disable interrupts.
*/
IRQdisableALL
- ldr r3, [r7]
- mov r0, #0
- teq r3, #0 /* sched_whichqs still zero? */
- moveq lr, pc
- moveq pc, r6 /* If so, do powersave idle */
+ mov lr, pc
+ mov pc, r6 /* If so, do powersave idle */
IRQenableALL
- b 1b /* Back around */
- /*
- * sched_whichqs indicates that at least one proc is ready to run.
- * Restore the original interrupt priority level, grab the
- * scheduler lock if necessary, and jump back into cpu_switch.
- */
-2: mov r0, r4
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- bl _C_LABEL(splx)
- adr lr, .Lswitch_search
- b _C_LABEL(sched_lock_idle)
-#else
- adr lr, .Lswitch_search
- b _C_LABEL(splx)
-#endif
+1: ldmfd sp!, {r6, pc}
+
+ENTRY(cpu_idle_leave)
+ stmfd sp!, {lr}
+
+ mov r0, #(IPL_SCHED)
+ bl _C_LABEL(_splraise)
+
+ ldmfd sp!, {pc}
/*
- * Find a new lwp to run, save the current context and
- * load the new context
+ * cpu_switchto(struct proc *oldproc, struct proc *newproc)
+ *
+ * Performs a process context switch from oldproc (which may be NULL)
+ * to newproc.
*
* Arguments:
- * r0 'struct proc *' of the current LWP
+ * r0 'struct proc *' of the context to switch from
+ * r1 'struct proc *' of the context to switch to
*/
-ENTRY(cpu_switch)
-/*
- * Local register usage. Some of these registers are out of date.
- * r1 = oldproc
- * r2 = spl level
- * r3 = whichqs
- * r4 = queue
- * r5 = &qs[queue]
- * r6 = newlwp
- * r7 = scratch
- */
+ENTRY(cpu_switchto)
stmfd sp!, {r4-r7, lr}
- /*
- * Indicate that there is no longer a valid process (curlwp = 0).
- * Zero the current PCB pointer while we're at it.
- */
- ldr r7, .Lcurproc
- ldr r6, .Lcurpcb
- mov r2, #0x00000000
- str r2, [r7] /* curproc = NULL */
- str r2, [r6] /* curpcb = NULL */
-
- /* stash the old proc while we call functions */
- mov r5, r0
-
- /* First phase : find a new proc */
- ldr r7, .Lwhichqs
-
- /* rem: r5 = old proc */
- /* rem: r7 = &whichqs */
-
-.Lswitch_search:
- IRQdisable
-
- /* Do we have any active queues */
- ldr r3, [r7]
-
- /* If not we must idle until we do. */
- teq r3, #0x00000000
- beq _ASM_LABEL(idle)
-
- /* put old proc back in r1 */
- mov r1, r5
-
- /* rem: r1 = old proc */
- /* rem: r3 = whichqs */
- /* rem: interrupts are disabled */
-
- /* used further down, saves SA stall */
- ldr r6, .Lqs
-
- /*
- * We have found an active queue. Currently we do not know which queue
- * is active just that one of them is.
- */
- /* Non-Xscale version of the ffs algorithm devised by d.seal and
- * posted to comp.sys.arm on 16 Feb 1994.
- */
- rsb r5, r3, #0
- ands r0, r3, r5
-
-#ifndef __XSCALE__
- adr r5, .Lcpu_switch_ffs_table
-
- /* X = R0 */
- orr r4, r0, r0, lsl #4 /* r4 = X * 0x11 */
- orr r4, r4, r4, lsl #6 /* r4 = X * 0x451 */
- rsb r4, r4, r4, lsl #16 /* r4 = X * 0x0450fbaf */
-
- /* now lookup in table indexed on top 6 bits of a4 */
- ldrb r4, [ r5, r4, lsr #26 ]
-
-#else /* __XSCALE__ */
- clz r4, r0
- rsb r4, r4, #31
-#endif /* __XSCALE__ */
-
- /* rem: r0 = bit mask of chosen queue (1 << r4) */
- /* rem: r1 = old proc */
- /* rem: r3 = whichqs */
- /* rem: r4 = queue number */
- /* rem: interrupts are disabled */
-
- /* Get the address of the queue (&qs[queue]) */
- add r5, r6, r4, lsl #3
-
- /*
- * Get the proc from the queue and place the next process in
- * the queue at the head. This basically unlinks the lwp at
- * the head of the queue.
- */
- ldr r6, [r5, #(P_FORW)]
-
-#ifdef DIAGNOSTIC
- cmp r6, r5
- beq .Lswitch_bogons
-#endif
-
- /* rem: r6 = new proc */
- ldr r7, [r6, #(P_FORW)]
- str r7, [r5, #(P_FORW)]
-
- /*
- * Test to see if the queue is now empty. If the head of the queue
- * points to the queue itself then there are no more procs in
- * the queue. We can therefore clear the queue not empty flag held
- * in r3.
- */
-
- teq r5, r7
- biceq r3, r3, r0
-
- /* rem: r0 = bit mask of chosen queue (1 << r4) - NOT NEEDED AN MORE */
-
- /* Fix the back pointer for the lwp now at the head of the queue. */
- ldr r0, [r6, #(P_BACK)]
- str r0, [r7, #(P_BACK)]
-
- /* Update the RAM copy of the queue not empty flags word. */
- ldreq r7, .Lwhichqs
- streq r3, [r7]
-
- /* rem: r1 = old proc */
- /* rem: r3 = whichqs - NOT NEEDED ANY MORE */
- /* rem: r4 = queue number - NOT NEEDED ANY MORE */
- /* rem: r6 = new proc */
- /* rem: interrupts are disabled */
-
/* Clear the want_resched flag */
ldr r7, .Lwant_resched
- mov r0, #0x00000000
- str r0, [r7]
-
- /*
- * Clear the back pointer of the proc we have removed from
- * the head of the queue. The new proc is isolated now.
- */
- str r0, [r6, #(P_BACK)]
-
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- /*
- * unlock the sched_lock, but leave interrupts off, for now.
- */
- mov r7, r1
- bl _C_LABEL(sched_unlock_idle)
- mov r1, r7
-#endif
-
-
-.Lswitch_resume:
- /* rem: r1 = old proc */
- /* rem: r4 = return value [not used if came from cpu_switchto()] */
- /* rem: r6 = new process */
- /* rem: interrupts are disabled */
+ mov r2, #0x00000000
+ str r2, [r7]
#ifdef MULTIPROCESSOR
/* XXX use curcpu() */
- ldr r0, .Lcpu_info_store
- str r0, [r6, #(P_CPU)]
+ ldr r2, .Lcpu_info_store
+ str r2, [r1, #(P_CPU)]
#else
- /* l->l_cpu initialized in fork1() for single-processor */
+ /* p->p_cpu initialized in fork1() for single-processor */
#endif
/* Process is now on a processor. */
- mov r0, #SONPROC /* p->p_stat = SONPROC */
- strb r0, [r6, #(P_STAT)]
+ mov r2, #SONPROC /* p->p_stat = SONPROC */
+ strb r2, [r1, #(P_STAT)]
/* We have a new curproc now so make a note it */
ldr r7, .Lcurproc
- str r6, [r7]
+ str r1, [r7]
/* Hook in a new pcb */
ldr r7, .Lcurpcb
- ldr r0, [r6, #(P_ADDR)]
- str r0, [r7]
-
- /* At this point we can allow IRQ's again. */
- IRQenable
-
- /* rem: r1 = old proc */
- /* rem: r4 = return value */
- /* rem: r6 = new process */
- /* rem: interrupts are enabled */
-
- /*
- * If the new process is the same as the process that called
- * cpu_switch() then we do not need to save and restore any
- * contexts. This means we can make a quick exit.
- * The test is simple if curproc on entry (now in r1) is the
- * same as the proc removed from the queue we can jump to the exit.
- */
- teq r1, r6
- moveq r4, #0x00000000 /* default to "didn't switch" */
- beq .Lswitch_return
-
- /*
- * At this point, we are guaranteed to be switching to
- * a new proc.
- */
- mov r4, #0x00000001
-
- /* Remember the old proc in r0 */
- mov r0, r1
+ ldr r6, [r7] /* Remember the old PCB */
+ ldr r2, [r1, #(P_ADDR)]
+ str r2, [r7]
/*
* If the old proc on entry to cpu_switch was zero then the
* process that called it was exiting. This means that we do
- * not need to save the current context. Instead we can jump
- * straight to restoring the context for the new process.
+ * not need to save the current context (we nevertheless need
+ * to clear the cache and TLB).
*/
teq r0, #0x00000000
beq .Lswitch_exited
- /* rem: r0 = old proc */
- /* rem: r4 = return value */
- /* rem: r6 = new process */
- /* rem: interrupts are enabled */
-
/* Stage two : Save old context */
- /* Get the user structure for the old proc. */
- ldr r1, [r0, #(P_ADDR)]
-
/* Save all the registers in the old proc's pcb */
#ifndef __XSCALE__
- add r7, r1, #(PCB_R8)
+ add r7, r6, #(PCB_R8)
stmia r7, {r8-r13}
#else
- strd r8, [r1, #(PCB_R8)]
- strd r10, [r1, #(PCB_R10)]
- strd r12, [r1, #(PCB_R12)]
+ strd r8, [r6, #(PCB_R8)]
+ strd r10, [r6, #(PCB_R10)]
+ strd r12, [r6, #(PCB_R12)]
#endif
+.Lswitch_exited:
/*
* NOTE: We can now use r8-r13 until it is time to restore
* them for the new process.
*/
/* Remember the old PCB. */
- mov r8, r1
+ mov r8, r6
- /* r1 now free! */
+ /* Save new proc in r6 now. */
+ mov r6, r1
/* Get the user structure for the new process in r9 */
ldr r9, [r6, #(P_ADDR)]
@@ -616,28 +288,24 @@ ENTRY(cpu_switch)
orr r2, r2, #(PSR_UND32_MODE | I32_bit)
msr cpsr_c, r2
+#ifdef notworthit
+ teq r0, #0x00000000
+ strne sp, [r8, #(PCB_UND_SP)]
+#else
str sp, [r8, #(PCB_UND_SP)]
+#endif
msr cpsr_c, r3 /* Restore the old mode */
/* rem: r0 = old proc */
- /* rem: r4 = return value */
- /* rem: r6 = new process */
+ /* rem: r1 = r6 = new process */
/* rem: r8 = old PCB */
/* rem: r9 = new PCB */
- /* rem: interrupts are enabled */
/* What else needs to be saved Only FPA stuff when that is supported */
/* Third phase : restore saved context */
- /* rem: r0 = old proc */
- /* rem: r4 = return value */
- /* rem: r6 = new proc */
- /* rem: r8 = old PCB */
- /* rem: r9 = new PCB */
- /* rem: interrupts are enabled */
-
/*
* Get the new L1 table pointer into r11. If we're switching to
* an LWP with the same address space as the outgoing one, we can
@@ -652,7 +320,7 @@ ENTRY(cpu_switch)
ldr r0, [r8, #(PCB_DACR)] /* r0 = old DACR */
ldr r1, [r9, #(PCB_DACR)] /* r1 = new DACR */
ldr r8, [r9, #(PCB_CSTATE)] /* r8 = &new_pmap->pm_cstate */
- ldr r5, .Llast_cache_state_ptr /* Previous thread's cstate */
+ ldr r5, .Llast_cache_state_ptr /* Previous proc's cstate */
teq r10, r11 /* Same L1? */
ldr r5, [r5]
@@ -681,7 +349,7 @@ ENTRY(cpu_switch)
beq .Lcs_cache_purge_skipped /* VM space is not in cache */
/*
- * Definately need to flush the cache.
+ * Definitely need to flush the cache.
* Mark the old VM space as NOT being resident in the cache.
*/
mov r2, #0x00000000
@@ -696,7 +364,6 @@ ENTRY(cpu_switch)
.Lcs_cache_purge_skipped:
/* rem: r1 = new DACR */
- /* rem: r4 = return value */
/* rem: r5 = &old_pmap->pm_cstate (or NULL) */
/* rem: r6 = new proc */
/* rem: r8 = &new_pmap->pm_cstate */
@@ -787,7 +454,6 @@ ENTRY(cpu_switch)
cmp r5, r8
strne r8, [r0]
- /* rem: r4 = return value */
/* rem: r6 = new proc */
/* rem: r9 = new PCB */
@@ -820,14 +486,6 @@ ENTRY(cpu_switch)
ldr r13, [r7, #(PCB_SP)]
#endif
-#if 0
- ldr r5, [r6, #(L_PROC)] /* fetch the proc for below */
-#else
- mov r5, r6
-#endif
-
- /* rem: r4 = return value */
- /* rem: r5 = new proc's proc */
/* rem: r6 = new proc */
/* rem: r7 = new pcb */
@@ -840,234 +498,16 @@ ENTRY(cpu_switch)
/* We can enable interrupts again */
IRQenableALL
- /* rem: r4 = return value */
- /* rem: r5 = new proc's proc */
/* rem: r6 = new proc */
/* rem: r7 = new PCB */
-#if 0
- /*
- * Check for restartable atomic sequences (RAS).
- */
-
- ldr r2, [r5, #(P_RASLIST)]
- ldr r1, [r7, #(PCB_TF)] /* r1 = trapframe (used below) */
- teq r2, #0 /* p->p_nras == 0? */
- bne .Lswitch_do_ras /* no, check for one */
-#endif
-
.Lswitch_return:
- /* cpu_switch returns 1 == switched, 0 == didn't switch */
- mov r0, r4
-
/*
* Pull the registers that got pushed when either savectx() or
* cpu_switch() was called and return.
*/
ldmfd sp!, {r4-r7, pc}
-#if 0
-.Lswitch_do_ras:
- ldr r1, [r1, #(TF_PC)] /* second ras_lookup() arg */
- mov r0, r5 /* first ras_lookup() arg */
- bl _C_LABEL(ras_lookup)
- cmn r0, #1 /* -1 means "not in a RAS" */
- ldrne r1, [r7, #(PCB_TF)]
- strne r0, [r1, #(TF_PC)]
- b .Lswitch_return
-#endif
-
-.Lswitch_exited:
- /*
- * We skip the cache purge because switch_exit() already did it.
- * Load up registers the way .Lcs_cache_purge_skipped expects.
- * Userpsace access already blocked by switch_exit().
- */
- ldr r9, [r6, #(P_ADDR)] /* r9 = new PCB */
- mrc p15, 0, r10, c2, c0, 0 /* r10 = old L1 */
- mov r5, #0 /* No previous cache state */
- ldr r1, [r9, #(PCB_DACR)] /* r1 = new DACR */
- ldr r8, [r9, #(PCB_CSTATE)] /* r8 = new cache state */
- ldr r11, [r9, #(PCB_PAGEDIR)] /* r11 = new L1 */
- b .Lcs_cache_purge_skipped
-
-
-#ifdef DIAGNOSTIC
-.Lswitch_bogons:
- adr r0, .Lswitch_panic_str
- bl _C_LABEL(panic)
-1: nop
- b 1b
-
-.Lswitch_panic_str:
- .asciz "cpu_switch: sched_qs empty with non-zero sched_whichqs!\n"
-#endif
-
-/*
- * cpu_switchto(struct proc *current, struct proc *next)
- * Switch to the specified next LWP
- * Arguments:
- *
- * r0 'struct proc *' of the current LWP
- * r1 'struct proc *' of the LWP to switch to
- */
-ENTRY(cpu_switchto)
- stmfd sp!, {r4-r7, lr}
-
- mov r6, r1 /* save new proc */
-
-#if defined(LOCKDEBUG)
- mov r5, r0 /* save old proc */
- bl _C_LABEL(sched_unlock_idle)
- mov r1, r5
-#else
- mov r1, r0
-#endif
-
- IRQdisable
-
- /*
- * Okay, set up registers the way cpu_switch() wants them,
- * and jump into the middle of it (where we bring up the
- * new process).
- *
- * r1 = old proc (r6 = new proc)
- */
- b .Lswitch_resume
-
-/*
- * void switch_exit(struct proc *l, struct proc *l0,
- * void (*exit)(struct proc *));
- * Switch to proc0's saved context and deallocate the address space and kernel
- * stack for l. Then jump into cpu_switch(), as if we were in proc0 all along.
- */
-
-/* LINTSTUB: Func: void switch_exit(struct proc *l, struct proc *l0,
- void (*func)(struct proc *)) */
-ENTRY(switch_exit)
- /*
- * The process is going away, so we can use callee-saved
- * registers here without having to save them.
- */
-
- mov r4, r0
- ldr r0, .Lcurproc
-
- mov r5, r1
- mov r6, r2
-
- /*
- * r4 = proc
- * r5 = proc0
- * r6 = exit func
- */
-
- mov r2, #0x00000000 /* curproc = NULL */
- str r2, [r0]
-
- /*
- * We're about to clear both the cache and the TLB.
- * Make sure to zap the 'last cache state' pointer since the
- * pmap might be about to go away. Also ensure the outgoing
- * VM space's cache state is marked as NOT resident in the
- * cache, and that proc0's cache state IS resident.
- */
- ldr r7, [r4, #(P_ADDR)] /* r7 = old proc's PCB */
- ldr r0, .Llast_cache_state_ptr /* Last userland cache state */
- ldr r9, [r7, #(PCB_CSTATE)] /* Fetch cache state pointer */
- ldr r3, [r5, #(P_ADDR)] /* r3 = proc0's PCB */
- str r2, [r0] /* No previous cache state */
- str r2, [r9, #(CS_ALL)] /* Zap old proc's cache state */
- ldr r3, [r3, #(PCB_CSTATE)] /* proc0's cache state */
- mov r2, #-1
- str r2, [r3, #(CS_ALL)] /* proc0 is in da cache! */
-
- /* Switch to proc0 context */
-
- ldr r9, .Lcpufuncs
- mov lr, pc
- ldr pc, [r9, #CF_IDCACHE_WBINV_ALL]
-
- ldr r0, [r7, #(PCB_PL1VEC)]
- ldr r1, [r7, #(PCB_DACR)]
-
- /*
- * r0 = Pointer to L1 slot for vector_page (or NULL)
- * r1 = proc0's DACR
- * r4 = proc we're switching from
- * r5 = proc0
- * r6 = exit func
- * r7 = proc0's PCB
- * r9 = cpufuncs
- */
-
- IRQdisableALL
-
- /*
- * Ensure the vector table is accessible by fixing up proc0's L1
- */
- cmp r0, #0 /* No need to fixup vector table? */
- ldrne r3, [r0] /* But if yes, fetch current value */
- ldrne r2, [r7, #(PCB_L1VEC)] /* Fetch new vector_page value */
- mcr p15, 0, r1, c3, c0, 0 /* Update DACR for proc0's context */
- cmpne r3, r2 /* Stuffing the same value? */
- strne r2, [r0] /* Store if not. */
-
-#ifdef PMAP_INCLUDE_PTE_SYNC
- /*
- * Need to sync the cache to make sure that last store is
- * visible to the MMU.
- */
- movne r1, #4
- movne lr, pc
- ldrne pc, [r9, #CF_DCACHE_WB_RANGE]
-#endif /* PMAP_INCLUDE_PTE_SYNC */
-
- /*
- * Note: We don't do the same optimisation as cpu_switch() with
- * respect to avoiding flushing the TLB if we're switching to
- * the same L1 since this process' VM space may be about to go
- * away, so we don't want *any* turds left in the TLB.
- */
-
- /* Switch the memory to the new process */
- ldr r0, [r7, #(PCB_PAGEDIR)]
- mov lr, pc
- ldr pc, [r9, #CF_CONTEXT_SWITCH]
-
- ldr r0, .Lcurpcb
-
- /* Restore all the save registers */
-#ifndef __XSCALE__
- add r1, r7, #PCB_R8
- ldmia r1, {r8-r13}
-#else
- ldr r8, [r7, #(PCB_R8)]
- ldr r9, [r7, #(PCB_R9)]
- ldr r10, [r7, #(PCB_R10)]
- ldr r11, [r7, #(PCB_R11)]
- ldr r12, [r7, #(PCB_R12)]
- ldr r13, [r7, #(PCB_SP)]
-#endif
- str r7, [r0] /* curpcb = proc0's PCB */
-
- IRQenableALL
-
- /*
- * Schedule the vmspace and stack to be freed.
- */
- mov r0, r4 /* {proc_}exit2(l) */
- mov lr, pc
- mov pc, r6
-
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- bl _C_LABEL(sched_lock_idle)
-#endif
-
- ldr r7, .Lwhichqs /* r7 = &whichqs */
- mov r5, #0x00000000 /* r5 = old proc = NULL */
- b .Lswitch_search
-
/* LINTSTUB: Func: void savectx(struct pcb *pcb) */
ENTRY(savectx)
/*
@@ -1110,18 +550,3 @@ ENTRY(proc_trampoline)
PULLFRAME
movs pc, lr /* Exit */
-
-#ifndef __XSCALE__
- .type .Lcpu_switch_ffs_table, _ASM_TYPE_OBJECT;
-.Lcpu_switch_ffs_table:
-/* same as ffs table but all nums are -1 from that */
-/* 0 1 2 3 4 5 6 7 */
- .byte 0, 0, 1, 12, 2, 6, 0, 13 /* 0- 7 */
- .byte 3, 0, 7, 0, 0, 0, 0, 14 /* 8-15 */
- .byte 10, 4, 0, 0, 8, 0, 0, 25 /* 16-23 */
- .byte 0, 0, 0, 0, 0, 21, 27, 15 /* 24-31 */
- .byte 31, 11, 5, 0, 0, 0, 0, 0 /* 32-39 */
- .byte 9, 0, 0, 24, 0, 0, 20, 26 /* 40-47 */
- .byte 30, 0, 0, 0, 0, 23, 0, 19 /* 48-55 */
- .byte 29, 0, 22, 18, 28, 17, 16, 0 /* 56-63 */
-#endif /* !__XSCALE_ */
diff --git a/sys/arch/arm/arm/genassym.cf b/sys/arch/arm/arm/genassym.cf
index 63839e12196..3ffdb707531 100644
--- a/sys/arch/arm/arm/genassym.cf
+++ b/sys/arch/arm/arm/genassym.cf
@@ -1,4 +1,4 @@
-# $OpenBSD: genassym.cf,v 1.7 2007/05/14 07:07:09 art Exp $
+# $OpenBSD: genassym.cf,v 1.8 2007/10/10 15:53:51 art Exp $
# $NetBSD: genassym.cf,v 1.27 2003/11/04 10:33:16 dsl Exp$
# Copyright (c) 1982, 1990 The Regents of the University of California.
@@ -82,11 +82,9 @@ export P_PROFIL
export SONPROC
struct proc
-member p_forw
-member p_back
member p_addr
-member p_priority
-member p_wchan
+#member p_priority
+#member p_wchan
member p_stat
# XXX use PROC_SIZEOF in new code whenever possible
define PROCSIZE sizeof(struct proc)
diff --git a/sys/arch/arm/arm/pmap.c b/sys/arch/arm/arm/pmap.c
index b19bce07a63..d9c0035b3a8 100644
--- a/sys/arch/arm/arm/pmap.c
+++ b/sys/arch/arm/arm/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.13 2007/05/18 14:41:55 art Exp $ */
+/* $OpenBSD: pmap.c,v 1.14 2007/10/10 15:53:51 art Exp $ */
/* $NetBSD: pmap.c,v 1.147 2004/01/18 13:03:50 scw Exp $ */
/*
@@ -3100,11 +3100,6 @@ pmap_activate(struct proc *p)
}
void
-pmap_deactivate(struct proc *p)
-{
-}
-
-void
pmap_update(pmap_t pm)
{
@@ -3211,7 +3206,7 @@ pmap_destroy(pmap_t pm)
pmap_update(pm);
/*
- * Make sure cpu_switch(), et al, DTRT. This is safe to do
+ * Make sure cpu_switchto(), et al, DTRT. This is safe to do
* since this process has no remaining mappings of its own.
*/
curpcb->pcb_pl1vec = pcb->pcb_pl1vec;
diff --git a/sys/arch/arm/arm/vm_machdep.c b/sys/arch/arm/arm/vm_machdep.c
index d5e109dc121..a3b4115793b 100644
--- a/sys/arch/arm/arm/vm_machdep.c
+++ b/sys/arch/arm/arm/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.6 2007/05/27 20:59:25 miod Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.7 2007/10/10 15:53:51 art Exp $ */
/* $NetBSD: vm_machdep.c,v 1.31 2004/01/04 11:33:29 jdolecek Exp $ */
/*
@@ -73,8 +73,6 @@ extern pv_addr_t systempage;
int process_read_regs (struct proc *p, struct reg *regs);
int process_read_fpregs (struct proc *p, struct fpreg *regs);
-void switch_exit (struct proc *p, struct proc *p0,
- void (*)(struct proc *));
extern void proc_trampoline (void);
/*
@@ -85,23 +83,6 @@ extern void proc_trampoline (void);
* the amount of stack used.
*/
-#if 0
-void
-cpu_proc_fork(p1, p2)
- struct proc *p1, *p2;
-{
-
-#if defined(PERFCTRS)
- if (PMC_ENABLED(p1))
- pmc_md_fork(p1, p2);
- else {
- p2->p_md.pmc_enabled = 0;
- p2->p_md.pmc_state = NULL;
- }
-#endif
-}
-#endif
-
/*
* Finish a fork operation, with process p2 nearly set up.
* Copy and update the pcb and trap frame, making the child ready to run.
@@ -201,27 +182,14 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
pcb->pcb_un.un_32.pcb32_sp = (u_int)sf;
}
-#if 0
-void
-cpu_setfunc(struct proc *p, void (*func)(void *), void *arg)
-{
- struct pcb *pcb = &p->p_addr->u_pcb;
- struct trapframe *tf = pcb->pcb_tf;
- struct switchframe *sf = (struct switchframe *)tf - 1;
-
- sf->sf_r4 = (u_int)func;
- sf->sf_r5 = (u_int)arg;
- sf->sf_pc = (u_int)proc_trampoline;
- pcb->pcb_un.un_32.pcb32_sp = (u_int)sf;
-}
-#endif
-
-
void
cpu_exit(struct proc *p)
{
+#if 0
pmap_update(p->p_vmspace->vm_map.pmap); /* XXX DSR help stability */
- switch_exit(p, &proc0, exit2);
+#endif
+ pmap_deactivate(p);
+ sched_exit(p);
}
/*
diff --git a/sys/arch/arm/include/pmap.h b/sys/arch/arm/include/pmap.h
index 847374df0ae..2e5b139324d 100644
--- a/sys/arch/arm/include/pmap.h
+++ b/sys/arch/arm/include/pmap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.h,v 1.8 2007/09/10 18:49:44 miod Exp $ */
+/* $OpenBSD: pmap.h,v 1.9 2007/10/10 15:53:51 art Exp $ */
/* $NetBSD: pmap.h,v 1.76 2003/09/06 09:10:46 rearnsha Exp $ */
/*
@@ -241,12 +241,13 @@ extern int pmap_debug_level; /* Only exists if PMAP_DEBUG */
#define pmap_is_referenced(pg) \
(((pg)->mdpage.pvh_attrs & PVF_REF) != 0)
-#define pmap_copy(dp, sp, da, l, sa) /* nothing */
+#define pmap_deactivate(p) do { /* nothing */ } while (0)
+#define pmap_copy(dp, sp, da, l, sa) do { /* nothing */ } while (0)
#define pmap_phys_address(ppn) (ptoa(ppn))
-#define pmap_proc_iflush(p, va, len) /* nothing */
-#define pmap_unuse_final(p) /* nothing */
+#define pmap_proc_iflush(p, va, len) do { /* nothing */ } while (0)
+#define pmap_unuse_final(p) do { /* nothing */ } while (0)
#define pmap_remove_holes(map) do { /* nothing */ } while (0)
/*
diff --git a/sys/arch/aviion/aviion/locore.S b/sys/arch/aviion/aviion/locore.S
index 3b9ef76b003..dae5f31e0c4 100644
--- a/sys/arch/aviion/aviion/locore.S
+++ b/sys/arch/aviion/aviion/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.3 2006/05/20 22:40:43 miod Exp $ */
+/* $OpenBSD: locore.S,v 1.4 2007/10/10 15:53:51 art Exp $ */
/*
* Copyright (c) 2005, Miodrag Vallat.
* Copyright (c) 1998 Steve Murphree, Jr.
@@ -343,14 +343,6 @@ GLOBAL(secondary_start)
bsr.n _C_LABEL(secondary_main)
addu r31, r3, USIZE /* switch to idle stack */
- /*
- * At this point, the CPU has been correctly initialized and has
- * identified itself on the console.
- * All it needs now is to jump to the idle loop and wait for work to
- * be offered.
- */
- br _ASM_LABEL(cpu_switch_idle)
-
#endif /* MULTIPROCESSOR */
/*
diff --git a/sys/arch/aviion/aviion/machdep.c b/sys/arch/aviion/aviion/machdep.c
index 4676e19f088..8464a564ee1 100644
--- a/sys/arch/aviion/aviion/machdep.c
+++ b/sys/arch/aviion/aviion/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.10 2007/06/06 17:15:11 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.11 2007/10/10 15:53:51 art Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -225,8 +225,6 @@ cpu_startup()
{
caddr_t v;
int sz, i;
- vsize_t size;
- int base, residual;
vaddr_t minaddr, maxaddr;
/*
@@ -605,19 +603,18 @@ void
secondary_main()
{
struct cpu_info *ci = curcpu();
+ int s;
cpu_configuration_print(0);
+ sched_init_cpu(ci);
ncpus++;
__cpu_simple_unlock(&cpu_mutex);
microuptime(&ci->ci_schedstate.spc_runtime);
ci->ci_curproc = NULL;
- /*
- * Upon return, the secondary cpu bootstrap code in locore will
- * enter the idle loop, waiting for some food to process on this
- * processor.
- */
+ SCHED_LOCK(s);
+ cpu_switchto(NULL, sched_chooseproc());
}
#endif /* MULTIPROCESSOR */
diff --git a/sys/arch/hp300/hp300/locore.s b/sys/arch/hp300/hp300/locore.s
index 40a595f59c0..fe200e1a6fe 100644
--- a/sys/arch/hp300/hp300/locore.s
+++ b/sys/arch/hp300/hp300/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.60 2007/05/15 13:46:22 martin Exp $ */
+/* $OpenBSD: locore.s,v 1.61 2007/10/10 15:53:51 art Exp $ */
/* $NetBSD: locore.s,v 1.91 1998/11/11 06:41:25 thorpej Exp $ */
/*
@@ -1345,51 +1345,18 @@ Ldorte:
*/
#include <m68k/m68k/support.s>
-/*
- * Use common m68k process manipulation routines.
- */
-#include <m68k/m68k/proc_subr.s>
-
.data
GLOBAL(curpcb)
.long 0
ASBSS(nullpcb,SIZEOF_PCB)
-/*
- * At exit of a process, do a switch for the last time.
- * Switch to a safe stack and PCB, and deallocate the process's resources.
- */
-ENTRY(switch_exit)
- movl sp@(4),a0
- /* save state into garbage pcb */
- movl #_ASM_LABEL(nullpcb),_C_LABEL(curpcb)
- lea _ASM_LABEL(tmpstk),sp | goto a tmp stack
-
- /* Schedule the vmspace and stack to be freed. */
- movl a0,sp@- | exit2(p)
- jbsr _C_LABEL(exit2)
- lea sp@(4),sp | pop args
-
- jra _C_LABEL(cpu_switch)
-
-/*
- * When no processes are on the runq, Swtch branches to Idle
- * to wait for something to come ready.
- */
-ASENTRY_NOPROFILE(Idle)
+ENTRY_NOPROFILE(cpu_idle_cycle)
stop #PSL_LOWIPL
- movw #PSL_HIGHIPL,sr
- movl _C_LABEL(whichqs),d0
- jeq _ASM_LABEL(Idle)
- jra Lsw1
-
-Lbadsw:
- PANIC("switch")
- /*NOTREACHED*/
+ rts
/*
- * cpu_switch()
+ * cpu_switchto(struct proc *oldproc, struct proc *newproc)
*
* NOTE: On the mc68851 (318/319/330) we attempt to avoid flushing the
* entire ATC. The effort involved in selective flushing may not be
@@ -1399,55 +1366,15 @@ Lbadsw:
* user's PTEs have been changed (formerly denoted by the SPTECHG p_flag
* bit). For now, we just always flush the full ATC.
*/
-ENTRY(cpu_switch)
- movl _C_LABEL(curpcb),a0 | current pcb
- movw sr,a0@(PCB_PS) | save sr before changing ipl
-#ifdef notyet
- movl CURPROC,sp@- | remember last proc running
-#endif
- clrl CURPROC
+ENTRY(cpu_switchto)
+ movl sp@(4), d0 | oldproc
+ beq Lswnofpsave | is NULL, don't save anything
/*
- * Find the highest-priority queue that isn't empty,
- * then take the first proc from that queue.
- */
- movw #PSL_HIGHIPL,sr | lock out interrupts
- movl _C_LABEL(whichqs),d0
- jeq _ASM_LABEL(Idle)
-Lsw1:
- movl d0,d1
- negl d0
- andl d1,d0
- bfffo d0{#0:#32},d1
- eorib #31,d1
-
- movl d1,d0
- lslb #3,d1 | convert queue number to index
- addl #_C_LABEL(qs),d1 | locate queue (q)
- movl d1,a1
- movl a1@(P_FORW),a0 | p = q->p_forw
- cmpal d1,a0 | anyone on queue?
- jeq Lbadsw | no, panic
- movl a0@(P_FORW),a1@(P_FORW) | q->p_forw = p->p_forw
- movl a0@(P_FORW),a1 | n = p->p_forw
- movl d1,a1@(P_BACK) | n->p_back = q
- cmpal d1,a1 | anyone left on queue?
- jne Lsw2 | yes, skip
- movl _C_LABEL(whichqs),d1
- bclr d0,d1 | no, clear bit
- movl d1,_C_LABEL(whichqs)
-Lsw2:
- movl a0,CURPROC
- clrl _C_LABEL(want_resched)
-#ifdef notyet
- movl sp@+,a1
- cmpl a0,a1 | switching to same proc?
- jeq Lswdone | yes, skip save and restore
-#endif
- /*
* Save state of previous process in its pcb.
*/
movl _C_LABEL(curpcb),a1
+ movw sr, a1@(PCB_PS) | save sr before switching context
moveml #0xFCFC,a1@(PCB_REGS) | save non-scratch registers
movl usp,a2 | grab USP (a2 has been saved)
movl a2,a1@(PCB_USP) | and save it
@@ -1460,16 +1387,12 @@ Lsw2:
jeq Lswnofpsave | yes, all done
fmovem fp0-fp7,a2@(FPF_REGS) | save FP general registers
fmovem fpcr/fpsr/fpi,a2@(FPF_FPCR) | save FP control registers
+
Lswnofpsave:
+ movl sp@(8), a0 | newproc
-#ifdef DIAGNOSTIC
- tstl a0@(P_WCHAN)
- jne Lbadsw
- cmpb #SRUN,a0@(P_STAT)
- jne Lbadsw
-#endif
+ movl a0, CURPROC
movb #SONPROC,a0@(P_STAT)
- clrl a0@(P_BACK) | clear back link
movl a0@(P_ADDR),a1 | get p_addr
movl a1,_C_LABEL(curpcb)
diff --git a/sys/arch/hp300/hp300/vm_machdep.c b/sys/arch/hp300/hp300/vm_machdep.c
index a23b64964ed..abc6af74605 100644
--- a/sys/arch/hp300/hp300/vm_machdep.c
+++ b/sys/arch/hp300/hp300/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.43 2007/05/27 20:59:25 miod Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.44 2007/10/10 15:53:51 art Exp $ */
/* $NetBSD: vm_machdep.c,v 1.60 2001/07/06 05:53:35 chs Exp $ */
/*
@@ -133,10 +133,10 @@ void
cpu_exit(p)
struct proc *p;
{
+ (void)splhigh();
- (void) splhigh();
- switch_exit(p);
- /* NOTREACHED */
+ pmap_deactivate(p);
+ sched_exit(p);
}
/*
diff --git a/sys/arch/hppa/hppa/genassym.cf b/sys/arch/hppa/hppa/genassym.cf
index 8f4351a2877..dab3e08efc2 100644
--- a/sys/arch/hppa/hppa/genassym.cf
+++ b/sys/arch/hppa/hppa/genassym.cf
@@ -1,4 +1,4 @@
-# $OpenBSD: genassym.cf,v 1.30 2007/05/14 19:54:21 martin Exp $
+# $OpenBSD: genassym.cf,v 1.31 2007/10/10 15:53:51 art Exp $
#
# Copyright (c) 1982, 1990, 1993
@@ -130,8 +130,6 @@ member tf_cr30
# proc fields and values
struct proc
-member p_forw
-member p_back
member p_addr
member p_priority
member p_stat
diff --git a/sys/arch/hppa/hppa/locore.S b/sys/arch/hppa/hppa/locore.S
index a6e0e572e0c..fa875d8a35c 100644
--- a/sys/arch/hppa/hppa/locore.S
+++ b/sys/arch/hppa/hppa/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.155 2007/07/20 22:09:23 kettenis Exp $ */
+/* $OpenBSD: locore.S,v 1.156 2007/10/10 15:53:51 art Exp $ */
/*
* Copyright (c) 1998-2004 Michael Shalayeff
@@ -2771,171 +2771,23 @@ $spstrcpy_exit
copy r0, ret0
EXIT(spstrcpy)
- .import whichqs, data
- .import qs, data
/*
- * setrunqueue(struct proc *p);
- * Insert a process on the appropriate queue. Should be called at splclock().
+ * int cpu_switchto(struct proc *old, struct proc *new)
+ * Switch from "old" proc to "new".
*/
.align 32
-ENTRY(setrunqueue,0)
-#ifdef DIAGNOSTIC
- ldw P_BACK(arg0), t1
- comb,<>,n r0, t1, Lsetrunqueue_panic
- ldw P_WCHAN(arg0), t1
- comb,<>,n r0, t1, Lsetrunqueue_panic
- ldb P_STAT(arg0), t1
- comib,=,n SRUN, t1, Lsetrunqueue_ok
-Lsetrunqueue_panic
- copy arg0, arg1
- ldil L%panic, r1
- ldil L%Lsrqpstr, arg0
- ldo R%panic(r1), r1
- ldo R%Lsrqpstr(arg0), arg0
- .call
- blr %r0, rp
- bv,n %r0(r1)
- nop
-Lsrqpstr
- .asciz "setrunqueue(%p)"
- .align 8
-Lsetrunqueue_ok
-#endif
-
- ldb P_PRIORITY(arg0), t2
- ldil L%qs, t4
- extru t2, 29, 5, t1
- ldo R%qs(t4), t4
- sh3add t1, t4, t4
- ldil L%whichqs, arg3
- ldw P_BACK(t4), t2
- stw t4, P_FORW(arg0)
- stw arg0, P_BACK(t4)
- ldw R%whichqs(arg3), t3
- stw arg0, P_FORW(t2)
- mtctl t1, sar
- stw t2, P_BACK(arg0)
- vdepi 1, 1, t3
- bv 0(rp)
- stw t3, R%whichqs(arg3)
-EXIT(setrunqueue)
-
-/*
- * remrunqueue(struct proc *p);
- * Remove a process from its queue. Should be called at splclock().
- */
- .align 32
-ENTRY(remrunqueue,0)
- ldb P_PRIORITY(arg0), t2
- extru t2, 29, 5, arg2
- ldil L%whichqs, t2
- mtsar arg2
- ldw R%whichqs(t2), t3
-
-#ifdef DIAGNOSTIC
- bvb,<,n t3, remrunqueue_ok
-
-Lremrunqueue_panic
- copy arg0, arg1
- ldil L%panic, r1
- ldil L%Lrrqpstr, arg0
- ldo R%panic(r1), r1
- ldo R%Lrrqpstr(arg0), arg0
- .call
- blr %r0, rp
- bv,n %r0(r1)
- nop
-
-Lrrqpstr
- .asciz "remrunqueue(%p), bit=%x"
- .align 8
-remrunqueue_ok
-#endif
- ldw P_BACK(arg0), t4
- stw r0, P_BACK(arg0)
- ldw P_FORW(arg0), arg0
- stw arg0, P_FORW(t4)
- vdepi 0, 1, t3
- sub,<> t4, arg0, r0
- stw t3, R%whichqs(t2)
- bv 0(rp)
- stw t4, P_BACK(arg0)
-EXIT(remrunqueue)
-
-/*
- * cpu_switch()
- * Find the highest priority process and resume it.
- */
- .align 32
-ENTRY(cpu_switch,128)
- ldil L%cpl, t1
- ldw R%cpl(t1), ret0
+ENTRY(cpu_switchto,128)
copy r3, r1
stw rp, HPPA_FRAME_CRP(sp)
copy sp, r3
- stw ret0, HPPA_FRAME_SL(sp)
stwm r1, HPPA_FRAME_SIZE+20*4(sp)
- /*
- * Clear curproc so that we don't accumulate system time while idle.
- */
- ldil L%curproc, t1
- ldw R%curproc(t1), arg2
- b switch_search
- stw r0, R%curproc(t1)
- /* remain on the old (curproc)'s stack until we have a better choice */
-
-cpu_idle
- copy r0, arg0
- break HPPA_BREAK_KERNEL, HPPA_BREAK_SPLLOWER
- .import uvm, data
- ldil L%(uvm + PAGE_IDLE_ZERO), t3
- ldw R%(uvm + PAGE_IDLE_ZERO)(t3), t4
- sub,<> r0, t4, r0
- b cpu_loop
-
- stw arg2, 4(r3)
- ldil L%uvm_pageidlezero, t1
- ldo R%uvm_pageidlezero(t1), t2
- .call
- ble 0(sr0, t2)
- copy r31, rp
-
- ldw HPPA_FRAME_SL(r3), ret0
- ldw 4(r3), arg2
-
-cpu_loop
- ldil L%cpl, arg0
- stw ret0, R%cpl(arg0)
-
-switch_search
- /*
- * t1: &whichqs
- * arg2: old curproc
- *
- */
- ldil L%whichqs, t1
- ldw R%whichqs(t1), t3
- comb,=,n r0, t3, cpu_idle
- copy r0, arg0
-
- ldi 0, t4
-getbit
- mtsar t4
- bvb,>=,n t3, getbit
- ldo 1(t4), t4
-
- ldil L%qs, t2
- ldo R%qs(t2), t2
- sh3add t4, t2, t2
-
- ldw P_FORW(t2), arg1
#ifdef DIAGNOSTIC
- comb,<> t2, arg1, link_ok
+ b kstack_check
nop
switch_error
- copy t4, arg1
- copy t2, arg2
+ copy arg1, arg2
+ copy arg0, arg1
ldil L%panic, r1
ldil L%Lcspstr, arg0
ldo R%panic(r1), r1
@@ -2945,61 +2797,48 @@ switch_error
bv,n %r0(r1)
nop
Lcspstr
- .asciz "cpu_switch: bit=%x, q/p=%p"
+ .asciz "cpu_switch:old=%p, new=%p"
.align 8
-link_ok
-#endif
- ldil L%want_resched, t4
- stw r0, R%want_resched(t4)
-
- ldw P_FORW(arg1), arg0
- stw arg0, P_FORW(t2)
- stw t2, P_BACK(arg0)
- stw r0, P_BACK(arg1)
-
- vdepi 0, 1, t3
- sub,<> t2, arg0, r0
- stw t3, R%whichqs(t1)
-
- /* don't need &whichqs (t1) starting here */
-#ifdef DIAGNOSTIC
+kstack_check
ldw P_WCHAN(arg1), t1
comb,<>,n r0, t1, switch_error
- copy arg1, t2
+ nop
ldb P_STAT(arg1), t1
comib,<>,n SRUN, t1, switch_error
- copy arg1, t2
+ nop
/*
- * Either we must be switching to the same process, or
- * the new process' kernel stack must be reasonable.
+ * The new process' kernel stack must be reasonable.
*/
- comb,=,n arg1, arg2, kstack_ok
- ldw P_ADDR(arg1), arg0
- ldw U_PCB+PCB_KSP(arg0), t1
- ldo NBPG(arg0), arg0
- comb,>>,n arg0, t1, switch_error
- copy arg1, t2
- sub t1, arg0, t1
- ldil L%USPACE, arg0
- ldo R%USPACE(arg0), arg0
- comb,<<=,n arg0, t1, switch_error
- copy arg1, t2
+ ldw P_ADDR(arg1), arg2
+ ldw U_PCB+PCB_KSP(arg2), t1
+ ldo NBPG(arg2), arg2
+ comb,>>,n arg2, t1, switch_error
+ nop
+ sub t1, arg2, t1
+ ldil L%USPACE, arg2
+ ldo R%USPACE(arg2), arg2
+ comb,<<=,n arg2, t1, switch_error
+ nop
kstack_ok
#endif
+ ldil L%want_resched, t4
+ stw r0, R%want_resched(t4)
+
+ /* Record new proc. */
ldi SONPROC, t1
stb t1, P_STAT(arg1)
- /* Skip context switch if same process. */
- comb,=,n arg1, arg2, switch_return
+ ldil L%curproc, t1
+ stw arg1, R%curproc(t1)
/* If old process exited, don't bother. */
- comb,=,n r0, arg2, switch_exited
+ comb,=,n r0, arg0, switch_exited
/*
* 2. save old proc context
*
- * arg2: old proc
+ * arg0: old proc
*/
- ldw P_ADDR(arg2), t1
+ ldw P_ADDR(arg0), t1
/* save callee-save registers */
stw r4, 1*4(r3)
stw sp, U_PCB+PCB_KSP(t1)
@@ -3021,13 +2860,14 @@ kstack_ok
stw r0, HPPA_FRAME_ARG(1)(sp) /* say no trampoline */
sync
- /* don't need old curproc (arg2) starting from here */
+ /* don't need old curproc (arg0) starting from here */
switch_exited
/*
* 3. restore new proc context
*
* arg1: new proc
*/
+ /* XXX disable interrupts? */
ldw P_ADDR(arg1), t2
ldw P_MD_REGS(arg1), t1
ldw U_PCB+PCB_KSP(t2), sp
@@ -3036,11 +2876,12 @@ switch_exited
ldw TF_CR9(t1), t3
mtctl t2, cr30
mtctl t3, pidr2
+ /* XXX enable interrupts? */
ldo -(HPPA_FRAME_SIZE+20*4)(sp), r3
ldw HPPA_FRAME_ARG(0)(sp), arg0
ldw HPPA_FRAME_ARG(1)(sp), t4 /* in case we're on trampoline */
sub,= r0, t4, r0
- b switch_gonnajump
+ b switch_return
ldw 1*4(r3), r4
ldw 2*4(r3), r5
ldw 3*4(r3), r6
@@ -3056,21 +2897,31 @@ switch_exited
ldw 13*4(r3), r16
ldw 14*4(r3), r17
ldw 15*4(r3), r18
-switch_gonnajump
- ldw HPPA_FRAME_SL(r3), ret0
- ldil L%cpl, t1
- stw ret0, R%cpl(t1)
- sync
switch_return
- ldil L%curproc, t1
- stw arg1, R%curproc(t1)
ldw HPPA_FRAME_CRP(r3), rp
bv 0(rp)
ldwm -(HPPA_FRAME_SIZE+20*4)(sp), r3
-EXIT(cpu_switch)
+EXIT(cpu_switchto)
+
+LEAF_ENTRY(cpu_idle_enter)
+ bv 0(rp)
+ nop
+EXIT(cpu_idle_enter)
+
+LEAF_ENTRY(cpu_idle_cycle)
+ bv 0(rp)
+ nop
+EXIT(cpu_idle_cycle)
+
+LEAF_ENTRY(cpu_idle_leave)
+ bv 0(rp)
+ nop
+EXIT(cpu_idle_leave)
ENTRY(switch_trampoline,0)
+ ldil L%cpl, t1
+ stw r0, R%cpl(t1)
.call
blr r0, rp
bv,n r0(t4)
diff --git a/sys/arch/hppa/hppa/vm_machdep.c b/sys/arch/hppa/hppa/vm_machdep.c
index a4b8e0f5d5a..528a1dba26c 100644
--- a/sys/arch/hppa/hppa/vm_machdep.c
+++ b/sys/arch/hppa/hppa/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.61 2007/06/20 17:29:34 miod Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.62 2007/10/10 15:53:51 art Exp $ */
/*
* Copyright (c) 1999-2004 Michael Shalayeff
@@ -160,12 +160,11 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
tf->tf_sp = (register_t)stack;
/*
- * Build stack frames for the cpu_switch & co.
+ * Build stack frames for the cpu_switchto & co.
*/
osp = sp + HPPA_FRAME_SIZE;
*(register_t*)(osp - HPPA_FRAME_SIZE) = 0;
*(register_t*)(osp + HPPA_FRAME_CRP) = (register_t)&switch_trampoline;
- *(register_t*)(osp + HPPA_FRAME_SL) = 0; /* cpl */
*(register_t*)(osp) = (osp - HPPA_FRAME_SIZE);
sp = osp + HPPA_FRAME_SIZE + 20*4; /* frame + calee-save registers */
@@ -187,8 +186,8 @@ cpu_exit(p)
fpu_curpcb = 0;
}
- exit2(p);
- cpu_switch(p);
+ pmap_deactivate(p);
+ sched_exit(p);
}
void
diff --git a/sys/arch/hppa/include/cpu.h b/sys/arch/hppa/include/cpu.h
index 58586ebc26a..ff9f6aa916c 100644
--- a/sys/arch/hppa/include/cpu.h
+++ b/sys/arch/hppa/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.51 2007/07/20 22:12:39 kettenis Exp $ */
+/* $OpenBSD: cpu.h,v 1.52 2007/10/10 15:53:51 art Exp $ */
/*
* Copyright (c) 2000-2004 Michael Shalayeff
@@ -64,6 +64,7 @@
#ifndef _LOCORE
#ifdef _KERNEL
+#include <sys/queue.h>
#include <sys/sched.h>
struct cpu_info {
diff --git a/sys/arch/i386/i386/cpu.c b/sys/arch/i386/i386/cpu.c
index 726f3e816bb..6e9202f114b 100644
--- a/sys/arch/i386/i386/cpu.c
+++ b/sys/arch/i386/i386/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.25 2007/05/29 18:18:20 tom Exp $ */
+/* $OpenBSD: cpu.c,v 1.26 2007/10/10 15:53:51 art Exp $ */
/* $NetBSD: cpu.c,v 1.1.2.7 2000/06/26 02:04:05 sommerfeld Exp $ */
/*-
@@ -295,6 +295,7 @@ cpu_attach(struct device *parent, struct device *self, void *aux)
cpu_alloc_ldt(ci);
ci->ci_flags |= CPUF_PRESENT | CPUF_AP;
identifycpu(ci);
+ sched_init_cpu(ci);
ci->ci_next = cpu_info_list->ci_next;
cpu_info_list->ci_next = ci;
ncpus++;
@@ -463,6 +464,9 @@ cpu_hatch(void *v)
ci->ci_dev.dv_xname, ci->ci_cpuid);
microuptime(&ci->ci_schedstate.spc_runtime);
splx(s);
+
+ SCHED_LOCK(s);
+ cpu_switchto(NULL, sched_chooseproc());
}
void
diff --git a/sys/arch/i386/i386/genassym.cf b/sys/arch/i386/i386/genassym.cf
index 88c086d6526..211a677dfa5 100644
--- a/sys/arch/i386/i386/genassym.cf
+++ b/sys/arch/i386/i386/genassym.cf
@@ -1,4 +1,4 @@
-# $OpenBSD: genassym.cf,v 1.27 2007/10/03 07:51:26 kettenis Exp $
+# $OpenBSD: genassym.cf,v 1.28 2007/10/10 15:53:51 art Exp $
#
# Copyright (c) 1982, 1990 The Regents of the University of California.
# All rights reserved.
@@ -88,8 +88,6 @@ export VM_MAXUSER_ADDRESS
# proc fields and values
struct proc
member p_addr
-member p_back
-member p_forw
member p_priority
member p_stat
member p_wchan
diff --git a/sys/arch/i386/i386/locore.s b/sys/arch/i386/i386/locore.s
index d8e379cb506..ff5a97e22ce 100644
--- a/sys/arch/i386/i386/locore.s
+++ b/sys/arch/i386/i386/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.115 2007/10/03 07:51:26 kettenis Exp $ */
+/* $OpenBSD: locore.s,v 1.116 2007/10/10 15:53:51 art Exp $ */
/* $NetBSD: locore.s,v 1.145 1996/05/03 19:41:19 christos Exp $ */
/*-
@@ -1295,279 +1295,52 @@ ENTRY(longjmp)
ret
/*****************************************************************************/
-
-/*
- * The following primitives manipulate the run queues.
- * whichqs tells which of the 32 queues qs have processes in them.
- * Setrq puts processes into queues, Remrq removes them from queues.
- * The running process is on no queue, other processes are on a queue
- * related to p->p_pri, divided by 4 actually to shrink the 0-127 range
- * of priorities into the 32 available queues.
- */
- .globl _C_LABEL(whichqs),_C_LABEL(qs),_C_LABEL(uvmexp),_C_LABEL(panic)
-/*
- * setrunqueue(struct proc *p);
- * Insert a process on the appropriate queue. Should be called at splclock().
- */
-NENTRY(setrunqueue)
- movl 4(%esp),%eax
-#ifdef DIAGNOSTIC
- cmpl $0,P_BACK(%eax) # should not be on q already
- jne 1f
- cmpl $0,P_WCHAN(%eax)
- jne 1f
- cmpb $SRUN,P_STAT(%eax)
- jne 1f
-#endif /* DIAGNOSTIC */
- movzbl P_PRIORITY(%eax),%edx
- shrl $2,%edx
- btsl %edx,_C_LABEL(whichqs) # set q full bit
- leal _C_LABEL(qs)(,%edx,8),%edx # locate q hdr
- movl P_BACK(%edx),%ecx
- movl %edx,P_FORW(%eax) # link process on tail of q
- movl %eax,P_BACK(%edx)
- movl %eax,P_FORW(%ecx)
- movl %ecx,P_BACK(%eax)
- ret
-#ifdef DIAGNOSTIC
-1: pushl $2f
- call _C_LABEL(panic)
- /* NOTREACHED */
-2: .asciz "setrunqueue"
-#endif /* DIAGNOSTIC */
-
-/*
- * remrunqueue(struct proc *p);
- * Remove a process from its queue. Should be called at splclock().
- */
-NENTRY(remrunqueue)
- movl 4(%esp),%ecx
- movzbl P_PRIORITY(%ecx),%eax
-#ifdef DIAGNOSTIC
- shrl $2,%eax
- btl %eax,_C_LABEL(whichqs)
- jnc 1f
-#endif /* DIAGNOSTIC */
- movl P_BACK(%ecx),%edx # unlink process
- movl $0,P_BACK(%ecx) # zap reverse link to indicate off list
- movl P_FORW(%ecx),%ecx
- movl %ecx,P_FORW(%edx)
- movl %edx,P_BACK(%ecx)
- cmpl %ecx,%edx # q still has something?
- jne 2f
-#ifndef DIAGNOSTIC
- shrl $2,%eax
-#endif
- btrl %eax,_C_LABEL(whichqs) # no; clear bit
-2: ret
+
#ifdef DIAGNOSTIC
-1: pushl $3f
+NENTRY(switch_error1)
+ pushl %edi
+ pushl $1f
call _C_LABEL(panic)
/* NOTREACHED */
-3: .asciz "remrunqueue"
-#endif /* DIAGNOSTIC */
-
-#if NAPM > 0
- .globl _C_LABEL(apm_cpu_idle),_C_LABEL(apm_cpu_busy)
-#endif
-/*
- * When no processes are on the runq, cpu_switch() branches to here to wait for
- * something to come ready.
- */
-ENTRY(idle)
- /* Skip context saving if we have none. */
- testl %esi,%esi
- jz 1f
-
- /*
- * idling: save old context.
- *
- * Registers:
- * %eax, %ebx, %ecx - scratch
- * %esi - old proc, then old pcb
- * %edi - idle pcb
- * %edx - idle TSS selector
- */
-
- pushl %esi
- call _C_LABEL(pmap_deactivate) # pmap_deactivate(oldproc)
- addl $4,%esp
-
- movl P_ADDR(%esi),%esi
-
- /* Save stack pointers. */
- movl %esp,PCB_ESP(%esi)
- movl %ebp,PCB_EBP(%esi)
-
- /* Find idle PCB for this CPU */
-#ifndef MULTIPROCESSOR
- movl $_C_LABEL(proc0),%ebx
- movl P_ADDR(%ebx),%edi
- movl P_MD_TSS_SEL(%ebx),%edx
-#else
- movl CPUVAR(IDLE_PCB), %edi
- movl CPUVAR(IDLE_TSS_SEL), %edx
-#endif
-
- /* Restore the idle context (avoid interrupts) */
- cli
-
- /* Restore stack pointers. */
- movl PCB_ESP(%edi),%esp
- movl PCB_EBP(%edi),%ebp
-
-
- /* Switch address space. */
- movl PCB_CR3(%edi),%ecx
- movl %ecx,%cr3
-
- /* Switch TSS. Reset "task busy" flag before loading. */
- movl CPUVAR(GDT), %eax
- andl $~0x0200,4-SEL_KPL(%eax,%edx,1)
- ltr %dx
-
- /* We're always in the kernel, so we don't need the LDT. */
-
- /* Restore cr0 (including FPU state). */
- movl PCB_CR0(%edi),%ecx
- movl %ecx,%cr0
-
- /* Record new pcb. */
- SET_CURPCB(%edi)
-
- xorl %esi,%esi
- sti
-
-1:
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- call _C_LABEL(sched_unlock_idle)
-#endif
-
- movl $IPL_NONE,CPL # spl0()
- call _C_LABEL(Xspllower) # process pending interrupts
- jmp _C_LABEL(idle_start)
-
-ENTRY(idle_loop)
-#if NAPM > 0
- call _C_LABEL(apm_cpu_idle)
-#else
-#if NPCTR > 0
- addl $1,_C_LABEL(pctr_idlcnt)
- adcl $0,_C_LABEL(pctr_idlcnt)+4
-#endif
- sti
- hlt
-#endif
-ENTRY(idle_start)
- cli
- cmpl $0,_C_LABEL(whichqs)
- jz _C_LABEL(idle_loop)
-
-ENTRY(idle_exit)
- movl $IPL_HIGH,CPL # splhigh
- sti
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- call _C_LABEL(sched_lock_idle)
-#endif
-#if NAPM > 0
- call _C_LABEL(apm_cpu_busy)
-#endif
- jmp switch_search
-
-#ifdef DIAGNOSTIC
-NENTRY(switch_error)
+1: .asciz "cpu_switch1 %p"
+NENTRY(switch_error2)
+ pushl %edi
pushl $1f
call _C_LABEL(panic)
/* NOTREACHED */
-1: .asciz "cpu_switch"
+1: .asciz "cpu_switch2 %p"
#endif /* DIAGNOSTIC */
/*
- * cpu_switch(void);
- * Find a runnable process and switch to it. Wait if necessary. If the new
- * process is the same as the old one, we short-circuit the context save and
- * restore.
+ * cpu_switchto(struct proc *old, struct proc *new)
+ * Switch from the "old" proc to the "new" proc. If "old" is NULL, we
+ * don't need to bother saving old context.
*/
-ENTRY(cpu_switch)
+ENTRY(cpu_switchto)
pushl %ebx
pushl %esi
pushl %edi
- pushl CPL
-
- movl CPUVAR(CURPROC), %esi
-
- /*
- * Clear curproc so that we don't accumulate system time while idle.
- * This also insures that schedcpu() will move the old process to
- * the correct queue if it happens to get called from the spllower()
- * below and changes the priority. (See corresponding comment in
- * userret()).
- */
- movl $0, CPUVAR(CURPROC)
-
-switch_search:
- /*
- * First phase: find new process.
- *
- * Registers:
- * %eax - queue head, scratch, then zero
- * %ebx - queue number
- * %ecx - cached value of whichqs
- * %edx - next process in queue
- * %esi - old process
- * %edi - new process
- */
- /* Wait for new process. */
- movl _C_LABEL(whichqs),%ecx
- bsfl %ecx,%ebx # find a full q
- jz _C_LABEL(idle) # if none, idle
- leal _C_LABEL(qs)(,%ebx,8),%eax # select q
- movl P_FORW(%eax),%edi # unlink from front of process q
-#ifdef DIAGNOSTIC
- cmpl %edi,%eax # linked to self (i.e. nothing queued)?
- je _C_LABEL(switch_error) # not possible
-#endif /* DIAGNOSTIC */
- movl P_FORW(%edi),%edx
- movl %edx,P_FORW(%eax)
- movl %eax,P_BACK(%edx)
+ movl 16(%esp), %esi
+ movl 20(%esp), %edi
- cmpl %edx,%eax # q empty?
- jne 3f
-
- btrl %ebx,%ecx # yes, clear to indicate empty
- movl %ecx,_C_LABEL(whichqs) # update q status
+ xorl %eax, %eax
-3: xorl %eax, %eax
- /* We just did it. */
- movl $0, CPUVAR(RESCHED)
+ movl %eax, CPUVAR(RESCHED)
#ifdef DIAGNOSTIC
cmpl %eax,P_WCHAN(%edi) # Waiting for something?
- jne _C_LABEL(switch_error) # Yes; shouldn't be queued.
+ jne _C_LABEL(switch_error1) # Yes; shouldn't be queued.
cmpb $SRUN,P_STAT(%edi) # In run state?
- jne _C_LABEL(switch_error) # No; shouldn't be queued.
+ jne _C_LABEL(switch_error2) # No; shouldn't be queued.
#endif /* DIAGNOSTIC */
- /* Isolate process. XXX Is this necessary? */
- movl %eax,P_BACK(%edi)
-
- /* Record new process. */
- movb $SONPROC,P_STAT(%edi) # p->p_stat = SONPROC
- movl CPUVAR(SELF), %ecx
- movl %edi, CPUVAR(CURPROC)
- movl %ecx, P_CPU(%edi)
-
- /* Skip context switch if same process. */
- cmpl %edi,%esi
- je switch_return
-
/* If old process exited, don't bother. */
testl %esi,%esi
jz switch_exited
/*
- * Second phase: save old context.
+ * Save old context.
*
* Registers:
* %eax, %ecx - scratch
@@ -1597,18 +1370,19 @@ switch_exited:
/* No interrupts while loading new state. */
cli
+
+ /* Record new process. */
+ movl CPUVAR(SELF), %ebx
+ movl %edi, CPUVAR(CURPROC)
+ movb $SONPROC, P_STAT(%edi)
+ movl %ebx, P_CPU(%edi)
+
movl P_ADDR(%edi),%esi
/* Restore stack pointers. */
movl PCB_ESP(%esi),%esp
movl PCB_EBP(%esi),%ebp
-#if 0
- /* Don't bother with the rest if switching to a system process. */
- testl $P_SYSTEM,P_FLAG(%edi)
- jnz switch_restored
-#endif
-
/*
* Activate the address space. We're curproc, so %cr3 will
* be reloaded, but we're not yet curpcb, so the LDT won't
@@ -1639,7 +1413,6 @@ switch_exited:
lldt %dx
#endif /* USER_LDT */
-switch_restored:
/* Restore cr0 (including FPU state). */
movl PCB_CR0(%esi),%ecx
#ifdef MULTIPROCESSOR
@@ -1661,103 +1434,29 @@ switch_restored:
/* Interrupts are okay again. */
sti
-switch_return:
-#if 0
- pushl %edi
- movl CPUVAR(NAME), %ebx
- leal CPU_INFO_NAME(%ebx),%ebx
- pushl %ebx
- pushl $1f
- call _C_LABEL(printf)
- addl $0xc,%esp
-#endif
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- call _C_LABEL(sched_unlock_idle)
-#endif
- /*
- * Restore old cpl from stack. Note that this is always an increase,
- * due to the spl0() on entry.
- */
- popl CPL
-
- movl %edi,%eax # return (p);
popl %edi
popl %esi
popl %ebx
ret
-1: .asciz "%s: scheduled %x\n"
-/*
- * switch_exit(struct proc *p);
- * Switch to the appropriate idle context (proc0's if uniprocessor; the cpu's if
- * multiprocessor) and deallocate the address space and kernel stack for p.
- * Then jump into cpu_switch(), as if we were in the idle proc all along.
- */
-#ifndef MULTIPROCESSOR
- .globl _C_LABEL(proc0)
-#endif
-ENTRY(switch_exit)
- movl 4(%esp),%edi # old process
-#ifndef MULTIPROCESSOR
- movl $_C_LABEL(proc0),%ebx
- movl P_ADDR(%ebx),%esi
- movl P_MD_TSS_SEL(%ebx),%edx
-#else
- movl CPUVAR(IDLE_PCB), %esi
- movl CPUVAR(IDLE_TSS_SEL), %edx
-#endif
-
- /* In case we fault... */
- movl $0, CPUVAR(CURPROC)
-
- /* Restore the idle context. */
- cli
-
- /* Restore stack pointers. */
- movl PCB_ESP(%esi),%esp
- movl PCB_EBP(%esi),%ebp
-
- /* Load TSS info. */
- movl CPUVAR(GDT), %eax
-
- /* Switch address space. */
- movl PCB_CR3(%esi),%ecx
- movl %ecx,%cr3
-
- /* Switch TSS. */
- andl $~0x0200,4-SEL_KPL(%eax,%edx,1)
- ltr %dx
- /* We're always in the kernel, so we don't need the LDT. */
-
- /* Clear segment registers; always null in proc0. */
- xorl %ecx,%ecx
- movw %cx,%gs
-
- /* Point to cpu_info */
- movl $GSEL(GCPU_SEL, SEL_KPL),%ecx
- movw %cx,%fs
-
- /* Restore cr0 (including FPU state). */
- movl PCB_CR0(%esi),%ecx
- movl %ecx,%cr0
-
- /* Record new pcb. */
- SET_CURPCB(%esi)
+ENTRY(cpu_idle_enter)
+ ret
- /* Interrupts are okay again. */
+ENTRY(cpu_idle_cycle)
+#if NAPM > 0
+ call _C_LABEL(apm_cpu_idle)
+#else
+#if NPCTR > 0
+ addl $1,_C_LABEL(pctr_idlcnt)
+ adcl $0,_C_LABEL(pctr_idlcnt)+4
+#endif
sti
+ hlt
+#endif
+ ret
- /*
- * Schedule the dead process's vmspace and stack to be freed.
- */
- pushl %edi /* exit2(p) */
- call _C_LABEL(exit2)
- addl $4,%esp
-
- /* Jump into cpu_switch() with the right state. */
- xorl %esi,%esi
- movl $0, CPUVAR(CURPROC)
- jmp switch_search
+ENTRY(cpu_idle_leave)
+ ret
/*
* savectx(struct pcb *pcb);
diff --git a/sys/arch/i386/i386/mptramp.s b/sys/arch/i386/i386/mptramp.s
index b68ec50ed12..de120c4de55 100644
--- a/sys/arch/i386/i386/mptramp.s
+++ b/sys/arch/i386/i386/mptramp.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: mptramp.s,v 1.8 2007/02/20 21:15:01 tom Exp $ */
+/* $OpenBSD: mptramp.s,v 1.9 2007/10/10 15:53:51 art Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -249,9 +249,7 @@ mp_cont:
HALTT(0x30,%ecx)
pushl %ecx
call _C_LABEL(cpu_hatch)
- HALT(0x33)
- xorl %esi,%esi
- jmp _C_LABEL(idle_start)
+ /* NOTREACHED */
.data
_C_LABEL(mp_pdirpa):
diff --git a/sys/arch/i386/i386/vm_machdep.c b/sys/arch/i386/i386/vm_machdep.c
index 4f969a96aaa..a12b279cfb1 100644
--- a/sys/arch/i386/i386/vm_machdep.c
+++ b/sys/arch/i386/i386/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.52 2007/05/27 20:59:25 miod Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.53 2007/10/10 15:53:51 art Exp $ */
/* $NetBSD: vm_machdep.c,v 1.61 1996/05/03 19:42:35 christos Exp $ */
/*-
@@ -126,7 +126,6 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize,
tf->tf_esp = (u_int)stack + stacksize;
sf = (struct switchframe *)tf - 1;
- sf->sf_ppl = 0;
sf->sf_esi = (int)func;
sf->sf_ebx = (int)arg;
sf->sf_eip = (int)proc_trampoline;
@@ -151,7 +150,7 @@ cpu_exit(struct proc *p)
#endif
pmap_deactivate(p);
- switch_exit(p);
+ sched_exit(p);
}
void
diff --git a/sys/arch/i386/include/frame.h b/sys/arch/i386/include/frame.h
index 8ce02c8753f..cc1263e57c8 100644
--- a/sys/arch/i386/include/frame.h
+++ b/sys/arch/i386/include/frame.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: frame.h,v 1.8 2006/11/27 18:04:28 gwk Exp $ */
+/* $OpenBSD: frame.h,v 1.9 2007/10/10 15:53:52 art Exp $ */
/* $NetBSD: frame.h,v 1.12 1995/10/11 04:20:08 mycroft Exp $ */
/*-
@@ -106,7 +106,6 @@ struct intrframe {
* Stack frame inside cpu_switch()
*/
struct switchframe {
- int sf_ppl;
int sf_edi;
int sf_esi;
int sf_ebx;
diff --git a/sys/arch/luna88k/luna88k/locore.S b/sys/arch/luna88k/luna88k/locore.S
index 81a5477308a..9f8e0ec9a2e 100644
--- a/sys/arch/luna88k/luna88k/locore.S
+++ b/sys/arch/luna88k/luna88k/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.13 2007/01/12 21:41:53 aoyama Exp $ */
+/* $OpenBSD: locore.S,v 1.14 2007/10/10 15:53:52 art Exp $ */
/*
* Copyright (c) 1998 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -150,8 +150,8 @@ ASLOCAL(main_start)
* Now we will compete with the other processors to see which one
* will be elected as the main one.
*/
- or.u r11, r0, hi16(_ASM_LABEL(cpu_mutex))
- or r11, r11, lo16(_ASM_LABEL(cpu_mutex))
+ or.u r11, r0, hi16(_C_LABEL(cpu_mutex))
+ or r11, r11, lo16(_C_LABEL(cpu_mutex))
1:
FLUSH_PIPELINE
or r22, r0, 1
@@ -282,15 +282,6 @@ ASLOCAL(secondary_init)
bsr.n _C_LABEL(secondary_pre_main) /* set cpu number */
or r31, r31, lo16(_ASM_LABEL(slavestack_end))
- /*
- * Release cpu_mutex; we have a race with other secondary CPUs here
- * because the stack has not been switched yet. However, since our
- * interrupts are disabled, the worst we can get is an NMI, and, oh
- * well, it means we're in deep trouble anyway.
- */
- or.u r10, r0, hi16(_ASM_LABEL(cpu_mutex))
- st r0, r10, lo16(_ASM_LABEL(cpu_mutex))
-
ldcr r2, CPU
1:
ld r3, r2, CI_CURPCB
@@ -299,13 +290,6 @@ ASLOCAL(secondary_init)
br.n _C_LABEL(secondary_main)
add r31, r3, USIZE /* switch to idle stack */
- /*
- * At this point, the CPU has been correctly initialized and has
- * identified itself on the console.
- * All it needs now is to jump to the idle loop and wait for work to
- * be offered.
- */
- br _ASM_LABEL(cpu_switch_search)
#else
/*
@@ -315,15 +299,6 @@ ASLOCAL(secondary_init)
#endif /* MULTIPROCESSOR */
- /*
- * Release the cpu_mutex; secondary processors will now have their
- * chance to initialize.
- */
-GLOBAL(cpu_boot_secondary_processors)
- or.u r2, r0, hi16(_ASM_LABEL(cpu_mutex))
- jmp.n r1
- st r0, r2, lo16(_ASM_LABEL(cpu_mutex))
-
/*
* void delay(int count)
*
@@ -384,10 +359,6 @@ GLOBAL(proc0paddr)
ASLOCAL(master_mpu)
word 0
-/* XMEM spin lock -- controls access to master_mpu */
-ASLOCAL(cpu_mutex)
- word 0
-
#if defined(DDB) || NKSYMS > 0
GLOBAL(esym)
word 0
diff --git a/sys/arch/luna88k/luna88k/machdep.c b/sys/arch/luna88k/luna88k/machdep.c
index 0a40e973bd7..bc12f69d4fb 100644
--- a/sys/arch/luna88k/luna88k/machdep.c
+++ b/sys/arch/luna88k/luna88k/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.44 2007/06/06 17:15:12 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.45 2007/10/10 15:53:52 art Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -85,6 +85,7 @@
#include <machine/cmmu.h>
#include <machine/cpu.h>
#include <machine/kcore.h>
+#include <machine/lock.h>
#include <machine/reg.h>
#include <machine/trap.h>
#include <machine/m88100.h>
@@ -105,6 +106,7 @@
caddr_t allocsys(caddr_t);
void consinit(void);
+void cpu_boot_secondary_processors(void);
void dumpconf(void);
void dumpsys(void);
int getcpuspeed(void);
@@ -183,6 +185,8 @@ int physmem; /* available physical memory, in pages */
struct vm_map *exec_map = NULL;
struct vm_map *phys_map = NULL;
+__cpu_simple_lock_t cpu_mutex = __SIMPLELOCK_UNLOCKED;
+
/*
* Declare these as initialized data so we can patch them.
*/
@@ -756,6 +760,16 @@ abort:
#ifdef MULTIPROCESSOR
/*
+ * Release the cpu_mutex; secondary processors will now have their
+ * chance to initialize.
+ */
+void
+cpu_boot_secondary_processors()
+{
+ __cpu_simple_unlock(&cpu_mutex);
+}
+
+/*
* Secondary CPU early initialization routine.
* Determine CPU number and set it, then allocate the idle pcb (and stack).
*
@@ -793,17 +807,18 @@ void
secondary_main()
{
struct cpu_info *ci = curcpu();
+ int s;
cpu_configuration_print(0);
+ sched_init_cpu(ci);
ncpus++;
+ __cpu_simple_unlock(&cpu_mutex);
microuptime(&ci->ci_schedstate.spc_runtime);
+ ci->ci_curproc = NULL;
- /*
- * Upon return, the secondary cpu bootstrap code in locore will
- * enter the idle loop, waiting for some food to process on this
- * processor.
- */
+ SCHED_LOCK(s);
+ cpu_switchto(NULL, sched_chooseproc());
}
#endif /* MULTIPROCESSOR */
@@ -966,7 +981,6 @@ luna88k_bootstrap()
cpuid_t cpu;
extern void m8820x_initialize_cpu(cpuid_t);
extern void m8820x_set_sapr(cpuid_t, apr_t);
- extern void cpu_boot_secondary_processors(void);
cmmu = &cmmu8820x;
diff --git a/sys/arch/m68k/include/cpu.h b/sys/arch/m68k/include/cpu.h
index 9a88a3d80ea..9b3843e760e 100644
--- a/sys/arch/m68k/include/cpu.h
+++ b/sys/arch/m68k/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.17 2007/05/22 10:31:08 martin Exp $ */
+/* $OpenBSD: cpu.h,v 1.18 2007/10/10 15:53:52 art Exp $ */
/* $NetBSD: cpu.h,v 1.3 1997/02/02 06:56:57 thorpej Exp $ */
/*
@@ -66,6 +66,7 @@
#ifdef _KERNEL
#ifndef _LOCORE
+#include <sys/queue.h>
#include <sys/sched.h>
struct cpu_info {
@@ -269,6 +270,9 @@ int cachectl(struct proc *, int, vaddr_t, int);
*/
#define PROC_PC(p) (((struct trapframe *)((p)->p_md.md_regs))->tf_pc)
+#define cpu_idle_enter() do { /* nothing */ } while (0)
+#define cpu_idle_leave() do { /* nothing */ } while (0)
+
#endif /* _KERNEL */
#endif /* _M68K_CPU_H_ */
diff --git a/sys/arch/m68k/m68k/genassym.cf b/sys/arch/m68k/m68k/genassym.cf
index d608d7fa85b..05ce97c1a37 100644
--- a/sys/arch/m68k/m68k/genassym.cf
+++ b/sys/arch/m68k/m68k/genassym.cf
@@ -1,4 +1,4 @@
-# $OpenBSD: genassym.cf,v 1.12 2007/05/15 13:46:22 martin Exp $
+# $OpenBSD: genassym.cf,v 1.13 2007/10/10 15:53:52 art Exp $
#
# Copyright (c) 1995 Theo de Raadt
@@ -71,15 +71,10 @@ export NBPG
# proc fields and values
struct proc
-member p_forw
-member p_back
-member p_priority
member p_stat
-member p_wchan
member p_vmspace
member p_addr
-export SRUN
export SONPROC
# contexts
diff --git a/sys/arch/m68k/m68k/proc_subr.s b/sys/arch/m68k/m68k/proc_subr.s
index 23d3f4d61b8..e69de29bb2d 100644
--- a/sys/arch/m68k/m68k/proc_subr.s
+++ b/sys/arch/m68k/m68k/proc_subr.s
@@ -1,129 +0,0 @@
-/* $OpenBSD: proc_subr.s,v 1.2 2003/06/02 23:27:48 millert Exp $ */
-/* $NetBSD: proc_subr.s,v 1.2 1997/04/25 02:22:01 thorpej Exp $ */
-
-/*
- * Copyright (c) 1988 University of Utah.
- * Copyright (c) 1980, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * the Systems Programming Group of the University of Utah Computer
- * Science Department.
- *
- * 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. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- * from: Utah $Hdr: locore.s 1.66 92/12/22$
- *
- * @(#)locore.s 8.6 (Berkeley) 5/27/94
- */
-
-/*
- * Assembly routines related to process manipulation.
- */
-
-/*
- * NOTICE: This is not a standalone file. To use it, #include it in
- * your port's locore.s, like so:
- *
- * #include <m68k/m68k/proc_subr.s>
- */
-
-/*
- * The following primitives manipulate the run queues. _whichqs tells which
- * of the 32 queues _qs have processes in them. Setrunqueue puts processes
- * into queues, remrunqueue removes them from queues. The running process is
- * on no queue, other processes are on a queue related to p->p_priority,
- * divided by 4 actually to shrink the 0-127 range of priorities into the 32
- * available queues.
- */
-
-/*
- * Setrunqueue(p)
- *
- * Call should be made at spl6(), and p->p_stat should be SRUN
- */
-ENTRY(setrunqueue)
- movl sp@(4),a0
-#ifdef DIAGNOSTIC
- tstl a0@(P_BACK)
- jne Lset1
- tstl a0@(P_WCHAN)
- jne Lset1
- cmpb #SRUN,a0@(P_STAT)
- jne Lset1
-#endif
- clrl d0
- movb a0@(P_PRIORITY),d0
- lsrb #2,d0
- movl _C_LABEL(whichqs),d1
- bset d0,d1
- movl d1,_C_LABEL(whichqs)
- lslb #3,d0
- addl #_C_LABEL(qs),d0
- movl d0,a0@(P_FORW)
- movl d0,a1
- movl a1@(P_BACK),a0@(P_BACK)
- movl a0,a1@(P_BACK)
- movl a0@(P_BACK),a1
- movl a0,a1@(P_FORW)
- rts
-#ifdef DIAGNOSTIC
-Lset1:
- PANIC("setrunqueue")
-#endif
-
-/*
- * remrunqueue(p)
- *
- * Call should be made at spl6().
- */
-ENTRY(remrunqueue)
- movl sp@(4),a0
- movb a0@(P_PRIORITY),d0
-#ifdef DIAGNOSTIC
- lsrb #2,d0
- movl _C_LABEL(whichqs),d1
- btst d0,d1
- jeq Lrem2
-#endif
- movl a0@(P_BACK),a1
- clrl a0@(P_BACK)
- movl a0@(P_FORW),a0
- movl a0,a1@(P_FORW)
- movl a1,a0@(P_BACK)
- cmpal a0,a1
- jne Lrem1
-#ifndef DIAGNOSTIC
- lsrb #2,d0
- movl _C_LABEL(whichqs),d1
-#endif
- bclr d0,d1
- movl d1,_C_LABEL(whichqs)
-Lrem1:
- rts
-#ifdef DIAGNOSTIC
-Lrem2:
- PANIC("remrunqueue")
-#endif
diff --git a/sys/arch/m88k/include/cpu.h b/sys/arch/m88k/include/cpu.h
index 317cc61704f..ab3342c7734 100644
--- a/sys/arch/m88k/include/cpu.h
+++ b/sys/arch/m88k/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.22 2007/05/19 20:34:32 miod Exp $ */
+/* $OpenBSD: cpu.h,v 1.23 2007/10/10 15:53:52 art Exp $ */
/*
* Copyright (c) 1996 Nivas Madhur
* Copyright (c) 1992, 1993
@@ -58,6 +58,7 @@
#include <machine/pcb.h>
#include <machine/psl.h>
#include <machine/intr.h>
+#include <sys/queue.h>
#include <sys/sched.h>
#if defined(MULTIPROCESSOR)
@@ -165,6 +166,8 @@ void set_cpu_number(cpuid_t);
#define cpu_exec(p) do { /* nothing */ } while (0)
#define cpu_wait(p) do { /* nothing */ } while (0)
+#define cpu_idle_cycle() do { /* nothing */ } while (0)
+
#if defined(MULTIPROCESSOR)
#include <sys/lock.h>
#include <sys/mplock.h>
diff --git a/sys/arch/m88k/m88k/genassym.cf b/sys/arch/m88k/m88k/genassym.cf
index 5738186c08a..2afe41589d1 100644
--- a/sys/arch/m88k/m88k/genassym.cf
+++ b/sys/arch/m88k/m88k/genassym.cf
@@ -1,4 +1,4 @@
-# $OpenBSD: genassym.cf,v 1.8 2007/05/12 19:59:52 miod Exp $
+# $OpenBSD: genassym.cf,v 1.9 2007/10/10 15:53:52 art Exp $
#
# Copyright (c) 1982, 1990 The Regents of the University of California.
# All rights reserved.
@@ -28,7 +28,7 @@
# SUCH DAMAGE.
#
# @(#)genassym.c 7.8 (Berkeley) 5/7/91
-# $Id: genassym.cf,v 1.8 2007/05/12 19:59:52 miod Exp $
+# $Id: genassym.cf,v 1.9 2007/10/10 15:53:52 art Exp $
#
include <sys/param.h>
@@ -49,15 +49,11 @@ include <sys/user.h>
# proc fields and values
struct proc
-member p_forw
-member p_back
member p_addr
member p_stat
-member p_wchan
member p_cpu
member P_ASTPENDING p_md.md_astpending
-export SRUN
export SONPROC
# cpu fields
diff --git a/sys/arch/m88k/m88k/m88k_machdep.c b/sys/arch/m88k/m88k/m88k_machdep.c
index e9d7b9838ac..76e5329a1c8 100644
--- a/sys/arch/m88k/m88k/m88k_machdep.c
+++ b/sys/arch/m88k/m88k/m88k_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: m88k_machdep.c,v 1.21 2007/05/29 18:10:42 miod Exp $ */
+/* $OpenBSD: m88k_machdep.c,v 1.22 2007/10/10 15:53:52 art Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -202,50 +202,6 @@ copystr(fromaddr, toaddr, maxlength, lencopied)
return (ENAMETOOLONG);
}
-void
-setrunqueue(p)
- struct proc *p;
-{
- struct prochd *q;
- struct proc *oldlast;
- int which = p->p_priority >> 2;
-
-#ifdef DIAGNOSTIC
- if (p->p_back != NULL)
- panic("setrunqueue %p", p);
-#endif
- q = &qs[which];
- whichqs |= 1 << which;
- 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(vp)
- struct proc *vp;
-{
- struct proc *p = vp;
- int which = p->p_priority >> 2;
- struct prochd *q;
-
-#ifdef DIAGNOSTIC
- if ((whichqs & (1 << which)) == 0)
- panic("remrq %p", p);
-#endif
- p->p_forw->p_back = p->p_back;
- p->p_back->p_forw = p->p_forw;
- p->p_back = NULL;
- q = &qs[which];
- if (q->ph_link == (struct proc *)q)
- whichqs &= ~(1 << which);
-}
-
#ifdef DDB
int longformat = 1;
void
diff --git a/sys/arch/m88k/m88k/process.S b/sys/arch/m88k/m88k/process.S
index 70050662724..786b40d5c38 100644
--- a/sys/arch/m88k/m88k/process.S
+++ b/sys/arch/m88k/m88k/process.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: process.S,v 1.16 2007/05/12 19:59:52 miod Exp $ */
+/* $OpenBSD: process.S,v 1.17 2007/10/10 15:53:52 art Exp $ */
/*
* Copyright (c) 1996 Nivas Madhur
* All rights reserved.
@@ -35,242 +35,63 @@
#include <machine/psl.h>
#include <machine/intr.h>
-#ifdef DIAGNOSTIC
- data
- align 4
-ASLOCAL(swchanpanic)
- string "switch wchan %x\0"
- align 4
-ASLOCAL(swsrunpanic)
- string "switch SRUN %x\0"
-
- text
- align 8
-ASLOCAL(Lswchanpanic)
- or.u r2, r0, hi16(_ASM_LABEL(swchanpanic))
- or r2, r2, lo16(_ASM_LABEL(swchanpanic))
- bsr.n _C_LABEL(panic)
- or r3, r0, r9
-
-ASLOCAL(Lswsrunpanic)
- or.u r2, r0, hi16(_ASM_LABEL(swsrunpanic))
- or r2, r2, lo16(_ASM_LABEL(swsrunpanic))
- bsr.n _C_LABEL(panic)
- or r3, r0, r9
-#endif
-
/*
- * void switch_exit(struct proc *p)
+ * void cpu_idle_enter()
*
- * Do the final work to exit from a process. After switching to the
- * idle stack and pcb, invoke exit2() on behalf of the exiting process,
- * then continue into cpu_switch() to select another process to run.
+ * Enable all interrupts and lower spl. This actually enables interrupts
+ * in the psr; bootstrap of secondary processors depends on this.
*/
-
-ENTRY(switch_exit)
- /*
- * Disable interrupts since we are about to change the kernel
- * stack.
- */
- ldcr r3, PSR
- set r3, r3, 1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r3, PSR
+ENTRY(cpu_idle_enter)
+ ldcr r2, PSR
+ clr r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT>
+ stcr r2, PSR
FLUSH_PIPELINE
- /*
- * Change pcb to idle u. area, i.e., set r31 to top of stack
- * and set curpcb to point to the cpu's idle stack.
- * r2 contains proc *p.
- */
- ldcr r10, CPU
- ld r30, r10, CI_IDLE_PCB
- addu r31, r30, USIZE /* now on idle stack */
- st r30, r10, CI_CURPCB /* curpcb = idle_pcb */
-
- /* Schedule the vmspace and stack to be freed. */
- bsr.n _C_LABEL(exit2)
- st r0, r10, CI_CURPROC /* curproc = NULL */
-
- /*
- * exit2() has acquired the scheduler lock for us. Jump into
- * cpu_switch(), after the context save since we do not need
- * to save anything.
- */
- br _ASM_LABEL(cpu_switch_search)
+ br.n _C_LABEL(setipl)
+ or r2, r0, IPL_NONE
/*
- * void cpu_switch(struct proc *p)
+ * void cpu_idle_leave()
*
- * Find a runnable process and switch to it. On entry, the scheduler lock is
- * held; it has to be released before returning to the process.
+ * Raise ipl to IPL_SCHED, but do not attempt to disable interrupts.
+ */
+ENTRY(cpu_idle_leave)
+ br.n _C_LABEL(setipl)
+ or r2, r0, IPL_SCHED
+
+/*
+ * void cpu_switchto(struct proc *oldproc, struct proc *newproc)
*
- * Note that this code ignores its proc parameter and assumes it has the
- * same value as curproc. This may change in mi_switch() in the future,
- * be careful.
+ * Switch context from oldproc to newproc. oldproc may be NULL if there is
+ * no need to save the current context.
*/
-ENTRY(cpu_switch)
+ENTRY(cpu_switchto)
/*
- * Disable interrupts, we do not want to be disturbed while
- * saving context.
+ * Save state of previous process in its pcb if required.
*/
- ldcr r2, PSR
- set r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r2, PSR
- FLUSH_PIPELINE
+ bcnd eq0, r2, 1f
- /*
- * Save state of previous process in its pcb, and pmap_deactivate()
- * the process.
- */
ldcr r2, CPU
ld r2, r2, CI_CURPCB
st r1, r2, PCB_PC /* save return address */
bsr _ASM_LABEL(__savectx)
/* note that we don't need to recover r1 at this point */
+1:
ldcr r11, CPU
- ld r2, r11, CI_CURPROC
-
- /*
- * Note that we can still use curpcb as our stack after
- * pmap_deactivate() has been called, as it does not affect the u
- * area mappings.
- */
- bsr.n _C_LABEL(pmap_deactivate)
- st r0, r11, CI_CURPROC /* curproc = NULL */
-
-#ifdef MULTIPROCESSOR
- /*
- * We need to switch to the processor's idle stack now (in case the
- * process we are using the stack of gets scheduled on another
- * processor).
- */
- ldcr r10, CPU
- ld r30, r10, CI_IDLE_PCB
- addu r31, r30, USIZE /* now on idle stack */
- st r30, r10, CI_CURPCB /* curpcb = idle_pcb */
-#endif
-
-ASLOCAL(cpu_switch_search)
- /*
- * This is the start of the idle loop. Find the highest-priority
- * queue that isn't empty, then take the first proc from that queue.
- */
- or.u r7, r0, hi16(_C_LABEL(whichqs))
- ld r7, r7, lo16(_C_LABEL(whichqs))
- bcnd ne0, r7, _ASM_LABEL(cpu_switch_found)
-
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- bsr _C_LABEL(sched_unlock_idle)
-#endif
-
-#ifdef MULTIPROCESSOR
-ASGLOBAL(cpu_switch_idle)
-#else
-ASLOCAL(cpu_switch_idle)
-#endif
- /*
- * There were no runnable processes. Enable all interrupts and
- * busy-wait for this to change.
- * Note that, besides doing setipl(IPL_NONE), this will actually enable
- * interrupts in the psr. Bootstrap of secondary processors
- * relies upon this.
- */
- ldcr r2, PSR
- clr r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r2, PSR
- FLUSH_PIPELINE
-
- bsr.n _C_LABEL(setipl)
- or r2, r0, IPL_NONE
-
- or.u r7, r0, hi16(_C_LABEL(whichqs))
- ld r7, r7, lo16(_C_LABEL(whichqs))
- bcnd eq0, r7, _ASM_LABEL(cpu_switch_idle)
- /* XXX run fancy things here, such as page zeroing... */
-
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- bsr _C_LABEL(sched_lock_idle)
-#endif
-
-ASLOCAL(cpu_switch_found)
- /*
- * Disable interrupts.
- */
- ldcr r2, PSR
- set r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r2, PSR
- FLUSH_PIPELINE
-
- /*
- * An interrupt could have occured between the last whichqs check
- * and the call to setipl(). Check again that whichqs is nonzero.
- */
- or.u r7, r0, hi16(_C_LABEL(whichqs)) /* reload whichqs */
- ld r7, r7, lo16(_C_LABEL(whichqs))
- bcnd eq0, r7, _ASM_LABEL(cpu_switch_search)
-
- /* XXX use ff1, like powerpc... needs *runqueue() adjustments */
- xor r6, r6, r6 /* set r6 to 0 */
-1: bb1 0, r7, 2f /* if rightmost bit set, done */
- extu r7, r7, 0<1> /* else, right shift whichqs, */
- br.n 1b /* increment r6, and repeat */
- addu r6, r6, 1
-2:
- or.u r7, r0, hi16(_C_LABEL(qs))
- or r7, r7, lo16(_C_LABEL(qs))
-
- /*
- * Need to make
- * p->p_forw->p_back = p->p_back and
- * p->p_back->p_forw = p->p_forw where
- * p is q->p_forw.
- * Remember that q->p_forw == p and p->p_back == q.
- */
-
- lda.d r8, r7[r6] /* r8 = &qs[ff1(whichqs)] */
- ld r9, r8, P_FORW /* r8 is q, r9 is p */
-
- ld r12, r9, P_FORW /* r12 = p->p_forw */
- st r8, r12, P_BACK /* p->p_forw->p_back = q (p->p_back) */
- st r12, r8, P_FORW /* q->p_forw = p->p_forw */
- lda.d r8, r7[r6] /* reload r8 with qs[ff1(whichqs)] */
- ld r12, r8, P_FORW /* q->p_forw */
- cmp r12, r12, r8 /* q == q->p_forw; anyone left on queue? */
- bb1 ne, r12, 3f /* yes, skip clearing bit in whichqs */
-
- or r12, r0, 1
- mak r12, r12, r6
- or.u r7, r0, hi16(_C_LABEL(whichqs))
- ld r8, r7, lo16(_C_LABEL(whichqs))
- and.c r8, r8, r12 /* whichqs &= ~the bit */
- st r8, r7, lo16(_C_LABEL(whichqs))
-3:
-#ifdef DIAGNOSTIC
- ld r2, r9, P_WCHAN
- bcnd ne0, r2, _ASM_LABEL(Lswchanpanic)
- ld.b r2, r9, P_STAT
- cmp r2, r2, SRUN
- bb1 ne, r2, _ASM_LABEL(Lswsrunpanic)
-#endif
-
- ldcr r11, CPU
- st r0, r11, CI_WANT_RESCHED /* clear want_resched */
+ st r3, r11, CI_CURPROC /* curproc = newproc */
- st r9, r11, CI_CURPROC /* curproc = p */
or r2, r0, SONPROC
- st.b r2, r9, P_STAT
+ st.b r2, r3, P_STAT
#ifdef MULTIPROCESSOR
- st r11, r9, P_CPU /* p->p_cpu = curcpu */
+ st r11, r3, P_CPU /* p->p_cpu = curcpu */
#endif
-
- ld r3, r9, P_ADDR
- st r0, r9, P_BACK /* p->p_back = 0 */
- st r3, r11, CI_CURPCB /* curpcb = p->p_addr */
+ ld r2, r3, P_ADDR
+ st r2, r11, CI_CURPCB /* curpcb = p->p_addr */
/* pmap_activate() the process' pmap */
bsr.n _C_LABEL(pmap_activate)
- or r2, r0, r9
+ or r2, r0, r3
ldcr r10, CPU
ld r10, r10, CI_CURPCB
@@ -297,25 +118,9 @@ ASLOCAL(cpu_switch_found)
ld r29, r10, PCB_R29
ld r30, r10, PCB_R30 /* restore frame pointer & stack */
ld r31, r10, PCB_SP
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- bsr.n _C_LABEL(sched_unlock_idle)
- or r14, r10, r0
- ld r1, r14, PCB_PC
- ld r14, r14, PCB_R14
-#else
ld r1, r10, PCB_PC
- ld r14, r10, PCB_R14
-#endif
-
- /*
- * Enable interrupts again.
- */
- ldcr r2, PSR
- clr r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r2, PSR
- FLUSH_PIPELINE
-
- jmp r1
+ jmp.n r1
+ ld r14, r10, PCB_R14
/*
* savectx(pcb)
diff --git a/sys/arch/m88k/m88k/vm_machdep.c b/sys/arch/m88k/m88k/vm_machdep.c
index f6283b85b56..e967b892cf8 100644
--- a/sys/arch/m88k/m88k/vm_machdep.c
+++ b/sys/arch/m88k/m88k/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.15 2007/06/20 17:29:36 miod Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.16 2007/10/10 15:53:52 art Exp $ */
/*
* Copyright (c) 1998 Steve Murphree, Jr.
@@ -136,20 +136,17 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
/*
* cpu_exit is called as the last action during exit.
- * We release the address space and machine-dependent resources,
- * including the memory for the user structure and kernel stack.
- * Once finished, we call switch_exit, which switches to a temporary
- * pcb and stack and never returns. We block memory allocation
- * until switch_exit has made things safe again.
+ *
+ * Block context switches and then call switch_exit() which will
+ * switch to another process thus we never return.
*/
void
cpu_exit(struct proc *p)
{
- splhigh();
+ (void)splhigh();
pmap_deactivate(p);
- switch_exit(p);
- /* NOTREACHED */
+ sched_exit(p);
}
/*
diff --git a/sys/arch/mac68k/mac68k/locore.s b/sys/arch/mac68k/mac68k/locore.s
index 16809cabe7d..1c589abad89 100644
--- a/sys/arch/mac68k/mac68k/locore.s
+++ b/sys/arch/mac68k/mac68k/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.58 2007/05/15 13:46:22 martin Exp $ */
+/* $OpenBSD: locore.s,v 1.59 2007/10/10 15:53:52 art Exp $ */
/* $NetBSD: locore.s,v 1.103 1998/07/09 06:02:50 scottr Exp $ */
/*
@@ -954,52 +954,18 @@ Ldorte:
*/
#include <m68k/m68k/support.s>
-/*
- * Use common m68k process manipulation routines.
- */
-#include <m68k/m68k/proc_subr.s>
-
.data
GLOBAL(curpcb)
.long 0
ASBSS(nullpcb,SIZEOF_PCB)
-/*
- * At exit of a process, do a switch for the last time.
- * Switch to a safe stack and PCB, and select a new process to run. The
- * old stack and u-area will be freed by the reaper.
- */
-ENTRY(switch_exit)
- movl sp@(4),a0
- /* save state into garbage pcb */
- movl #_ASM_LABEL(nullpcb),_C_LABEL(curpcb)
- lea _ASM_LABEL(tmpstk),sp | goto a tmp stack
-
- /* Schedule the vmspace and stack to be freed. */
- movl a0,sp@- | exit2(p)
- jbsr _C_LABEL(exit2)
- lea sp@(4),sp | pop args
-
- jra _C_LABEL(cpu_switch)
-
-/*
- * When no processes are on the runq, Swtch branches to Idle
- * to wait for something to come ready.
- */
-ASENTRY_NOPROFILE(Idle)
+ENTRY_NOPROFILE(cpu_idle_cycle)
stop #PSL_LOWIPL
- movw #PSL_HIGHIPL,sr
- movl _C_LABEL(whichqs),d0
- jeq _ASM_LABEL(Idle)
- jra Lsw1
-
-Lbadsw:
- PANIC("switch")
- /*NOTREACHED*/
+ rts
/*
- * cpu_switch()
+ * cpu_switchto(struct proc *oldproc, struct proc *newproc)
*
* NOTE: On the mc68851 (318/319/330) we attempt to avoid flushing the
* entire ATC. The effort involved in selective flushing may not be
@@ -1009,55 +975,15 @@ Lbadsw:
* user's PTEs have been changed (formerly denoted by the SPTECHG p_flag
* bit). For now, we just always flush the full ATC.
*/
-ENTRY(cpu_switch)
- movl _C_LABEL(curpcb),a0 | current pcb
- movw sr,a0@(PCB_PS) | save sr before changing ipl
-#ifdef notyet
- movl CURPROC,sp@- | remember last proc running
-#endif
- clrl CURPROC
+ENTRY(cpu_switchto)
+ movl sp@(4), d0 | oldproc
+ beq Lswnofpsave | is NULL, don't save anything
/*
- * Find the highest-priority queue that isn't empty,
- * then take the first proc from that queue.
- */
- movw #PSL_HIGHIPL,sr | lock out interrupts
- movl _C_LABEL(whichqs),d0
- jeq _ASM_LABEL(Idle)
-Lsw1:
- movl d0,d1
- negl d0
- andl d1,d0
- bfffo d0{#0:#32},d1
- eorib #31,d1
-
- movl d1,d0
- lslb #3,d1 | convert queue number to index
- addl #_C_LABEL(qs),d1 | locate queue (q)
- movl d1,a1
- movl a1@(P_FORW),a0 | p = q->p_forw
- cmpal d1,a0 | anyone on queue?
- jeq Lbadsw | no, panic
- movl a0@(P_FORW),a1@(P_FORW) | q->p_forw = p->p_forw
- movl a0@(P_FORW),a1 | n = p->p_forw
- movl d1,a1@(P_BACK) | n->p_back = q
- cmpal d1,a1 | anyone left on queue?
- jne Lsw2 | yes, skip
- movl _C_LABEL(whichqs),d1
- bclr d0,d1 | no, clear bit
- movl d1,_C_LABEL(whichqs)
-Lsw2:
- movl a0,CURPROC
- clrl _C_LABEL(want_resched)
-#ifdef notyet
- movl sp@+,a1
- cmpl a0,a1 | switching to same proc?
- jeq Lswdone | yes, skip save and restore
-#endif
- /*
* Save state of previous process in its pcb.
*/
movl _C_LABEL(curpcb),a1
+ movw sr, a1@(PCB_PS) | save sr before switching context
moveml #0xFCFC,a1@(PCB_REGS) | save non-scratch registers
movl usp,a2 | grab USP (a2 has been saved)
movl a2,a1@(PCB_USP) | and save it
@@ -1070,16 +996,12 @@ Lsw2:
jeq Lswnofpsave | yes, all done
fmovem fp0-fp7,a2@(FPF_REGS) | save FP general registers
fmovem fpcr/fpsr/fpi,a2@(FPF_FPCR) | save FP control registers
+
Lswnofpsave:
+ movl sp@(8), a0 | newproc
-#ifdef DIAGNOSTIC
- tstl a0@(P_WCHAN)
- jne Lbadsw
- cmpb #SRUN,a0@(P_STAT)
- jne Lbadsw
-#endif
+ movl a0, CURPROC
movb #SONPROC,a0@(P_STAT)
- clrl a0@(P_BACK) | clear back link
movl a0@(P_ADDR),a1 | get p_addr
movl a1,_C_LABEL(curpcb)
diff --git a/sys/arch/mac68k/mac68k/vm_machdep.c b/sys/arch/mac68k/mac68k/vm_machdep.c
index 00bb0bce0d7..6ff6156056b 100644
--- a/sys/arch/mac68k/mac68k/vm_machdep.c
+++ b/sys/arch/mac68k/mac68k/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.39 2007/05/27 20:59:25 miod Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.40 2007/10/10 15:53:52 art Exp $ */
/* $NetBSD: vm_machdep.c,v 1.29 1998/07/28 18:34:55 thorpej Exp $ */
/*
@@ -119,19 +119,18 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
/*
* cpu_exit is called as the last action during exit.
- * We release the address space and machine-dependent resources,
- * block context switches and then call switch_exit() which will
- * free our stack and user area and switch to another process.
- * Thus, we never return.
+ *
+ * Block context switches and then call switch_exit() which will
+ * switch to another process thus we never return.
*/
void
cpu_exit(p)
struct proc *p;
{
-
(void)splhigh();
- switch_exit(p);
- /* NOTREACHED */
+
+ pmap_deactivate(p);
+ sched_exit(p);
}
/*
diff --git a/sys/arch/macppc/macppc/cpu.c b/sys/arch/macppc/macppc/cpu.c
index 9838e1d9c9c..c3ca93afd75 100644
--- a/sys/arch/macppc/macppc/cpu.c
+++ b/sys/arch/macppc/macppc/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.43 2007/05/23 23:40:21 kettenis Exp $ */
+/* $OpenBSD: cpu.c,v 1.44 2007/10/10 15:53:52 art Exp $ */
/*
* Copyright (c) 1997 Per Fogelstrom
@@ -676,7 +676,7 @@ void
cpu_hatch(void)
{
volatile struct cpu_hatch_data *h = cpu_hatch_data;
- int scratch, i;
+ int scratch, i, s;
/* Initialize timebase. */
__asm ("mttbl %0; mttbu %0; mttbl %0" :: "r"(0));
@@ -759,5 +759,12 @@ cpu_hatch(void)
curcpu()->ci_ipending = 0;
curcpu()->ci_cpl = 0;
+
+ s = splhigh();
+ microuptime(&curcpu()->ci_schedstate.spc_runtime);
+ splx(s);
+
+ SCHED_LOCK(s);
+ cpu_switchto(NULL, sched_chooseproc());
}
#endif
diff --git a/sys/arch/macppc/macppc/genassym.cf b/sys/arch/macppc/macppc/genassym.cf
index 4249820a8c6..2efd74a41b6 100644
--- a/sys/arch/macppc/macppc/genassym.cf
+++ b/sys/arch/macppc/macppc/genassym.cf
@@ -1,4 +1,4 @@
-# $OpenBSD: genassym.cf,v 1.14 2007/03/22 19:26:28 kettenis Exp $
+# $OpenBSD: genassym.cf,v 1.15 2007/10/10 15:53:52 art Exp $
#
# Copyright (c) 1982, 1990 The Regents of the University of California.
# All rights reserved.
@@ -61,7 +61,6 @@ define SFRAMELEN roundup(sizeof(struct switchframe), 16)
struct pcb
member PCB_PMR pcb_pmreal
member pcb_sp
-member pcb_spl
member PCB_FAULT pcb_onfault
struct pmap
@@ -70,8 +69,6 @@ member PM_USRSR pm_sr[PPC_USER_SR]
member PM_KERNELSR pm_sr[PPC_KERNEL_SR]
struct proc
-member p_forw
-member p_back
member p_addr
member p_stat
member p_cpu
diff --git a/sys/arch/macppc/macppc/locore.S b/sys/arch/macppc/macppc/locore.S
index b2658a7fd48..b840919182d 100644
--- a/sys/arch/macppc/macppc/locore.S
+++ b/sys/arch/macppc/macppc/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.32 2007/03/20 20:59:54 kettenis Exp $ */
+/* $OpenBSD: locore.S,v 1.33 2007/10/10 15:53:52 art Exp $ */
/* $NetBSD: locore.S,v 1.2 1996/10/16 19:33:09 ws Exp $ */
/*
@@ -133,150 +133,41 @@ _ENTRY(_C_LABEL(cpu_spinup_trampoline))
lis %r3,_C_LABEL(cpu_hatch_stack)@ha
lwz %r1,_C_LABEL(cpu_hatch_stack)@l(%r3)
- bl _C_LABEL(cpu_hatch)
- bl _C_LABEL(sched_lock_idle)
- li %r30,0
- b _C_LABEL(idle)
+ b _C_LABEL(cpu_hatch)
+ /* NOTREACHED */
#endif
-/*
- * No processes are runnable, so loop waiting for one.
- * Separate label here for accounting purposes.
- */
- .globl _C_LABEL(idle)
- .type _C_LABEL(idle),@function
-_C_LABEL(idle):
- mfmsr %r3
- /* disable interrupts while manipulating runque */
- andi. %r3,%r3,~PSL_EE@l
- mtmsr %r3
-
- lis %r8,_C_LABEL(whichqs)@ha
- lwz %r9,_C_LABEL(whichqs)@l(%r8)
-
- or. %r9,%r9,%r9
- bne- _C_LABEL(sw1) /* at least one queue non-empty */
-
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- bl _C_LABEL(sched_unlock_idle)
-#endif
-
- ori %r3,%r3,PSL_EE /* reenable ints again */
- mtmsr %r3
- isync
- sync
- /* low power mode */
- mfmsr %r3
- oris %r3, %r3, PSL_POW@h
- mtmsr %r3
- isync
-
-/* May do some power saving here? */
-
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- bl _C_LABEL(sched_lock_idle)
-#endif
- b _C_LABEL(idle)
-
-/*
- * switchexit gets called from cpu_exit to free the user structure
- * and kernel stack of the current process.
- */
-_ENTRY(_C_LABEL(switchexit))
-/* First switch to the idle pcb/kernel stack */
- GET_CPUINFO(%r7)
- lwz %r6,CI_IDLE_PCB(%r7)
- stw %r6,CI_CURPCB(%r7)
- addi %r1,%r6,USPACE-16 /* 16 bytes are reserved at stack top */
- /*
- * Schedule the vmspace and stack to be freed (the proc arg is
- * already in r3).
- */
- bl _C_LABEL(exit2)
-
- /* Fall through to cpu_switch to actually select another proc */
- li %r3,0 /* indicate exited process */
-
-/* Fall through to cpu_switch to actually select another proc */
/*
- * void cpu_switch(struct proc *p)
- * Find a runnable process and switch to it.
+ * void cpu_switchto(struct proc *old, struct proc *new)
+ * Switch from "old" proc to "new".
*/
-_ENTRY(_C_LABEL(cpu_switch))
+_ENTRY(_C_LABEL(cpu_switchto))
mflr %r0 /* save lr */
stw %r0,4(%r1)
stwu %r1,-16(%r1)
stw %r31,12(%r1)
stw %r30,8(%r1)
- mr %r30,%r3
- GET_CPUINFO(%r3)
+/*
+ * r3 - old proc
+ * r4 - new proc
+ * r5 - cpuinfo
+ */
+ GET_CPUINFO(%r5)
li %r31,0
- /* Zero to not accumulate cpu time */
- stw %r31,CI_CURPROC(%r3)
- lwz %r31,CI_CURPCB(%r3)
-
- li %r3,0
- bl _C_LABEL(lcsplx)
- stw %r3,PCB_SPL(%r31) /* save spl */
-
-/* Find a new process */
- mfmsr %r3
- andi. %r3,%r3,~PSL_EE@l /* disable interrupts while
- manipulating runque */
- mtmsr %r3
- isync
-
- lis %r8,_C_LABEL(whichqs)@ha
- lwz %r9,_C_LABEL(whichqs)@l(%r8)
-
- or. %r9,%r9,%r9
- beq- _C_LABEL(idle) /* all queues empty */
-_C_LABEL(sw1):
- cntlzw %r10,%r9
- lis %r4,_C_LABEL(qs)@ha
- addi %r4,%r4,_C_LABEL(qs)@l
- slwi %r3,%r10,3
- add %r3,%r3,%r4 /* select queue */
-
- lwz %r31,P_FORW(%r3) /* unlink first proc from queue */
- lwz %r4,P_FORW(%r31)
- stw %r4,P_FORW(%r3)
- stw %r3,P_BACK(%r4)
-
- cmpl 0,%r3,%r4 /* queue empty? */
- bne 1f
-
- lis %r3,0x80000000@ha
- srw %r3,%r3,%r10
- andc %r9,%r9,%r3
- stw %r9,_C_LABEL(whichqs)@l(%r8) /* mark it empty */
-
-1:
/* just did this resched thing, clear resched */
- li %r3,0
- GET_CPUINFO(%r4)
- stw %r3,CI_WANT_RESCHED(%r4)
-
- stw %r3,P_BACK(%r31) /* probably superfluous */
+ stw %r31,CI_WANT_RESCHED(%r5)
#ifdef MULTIPROCESSOR
- stw %r4,P_CPU(%r31)
+ stw %r5,P_CPU(%r4)
#endif
- stw %r31,CI_CURPROC(%r4) /* record new process */
-
- li %r3,SONPROC
- stb %r3,P_STAT(%r31)
-
- mfmsr %r3
- ori %r3,%r3,PSL_EE /* Now we can interrupt again */
- mtmsr %r3
+ stw %r4,CI_CURPROC(%r5) /* record new process */
- cmpl 0,%r31,%r30 /* is it the same process? */
- beq switch_return
+ li %r31,SONPROC
+ stb %r31,P_STAT(%r4)
- or. %r30,%r30,%r30 /* old process was exiting? */
+ or. %r3,%r3,%r3 /* old process was exiting? */
beq switch_exited
mfsr %r10,PPC_USER_SR /* save PPC_USER_SR for copyin/copyout*/
@@ -284,33 +175,31 @@ _C_LABEL(sw1):
mr %r12,%r2 /* save r2 */
stwu %r1,-SFRAMELEN(%r1) /* still running on old stack */
stmw %r10,8(%r1)
- lwz %r3,P_ADDR(%r30)
- stw %r1,PCB_SP(%r3) /* save SP */
+ lwz %r31,P_ADDR(%r3)
+ stw %r1,PCB_SP(%r31) /* save SP */
switch_exited:
/* disable interrupts while actually switching */
- mfmsr %r3
- andi. %r3,%r3,~PSL_EE@l
- mtmsr %r3
+ mfmsr %r30
+ andi. %r30,%r30,~PSL_EE@l
+ mtmsr %r30
- lwz %r4,P_ADDR(%r31)
- GET_CPUINFO(%r5)
- stw %r4,CI_CURPCB(%r5) /* indicate new pcb */
+ lwz %r31,P_ADDR(%r4)
+ stw %r31,CI_CURPCB(%r5) /* indicate new pcb */
- lwz %r5,PCB_PMR(%r4)
+ lwz %r6,PCB_PMR(%r31)
/* save real pmap pointer for spill fill */
- GET_CPUINFO(%r6)
- stwu %r5,CI_CURPM(%r6)
- stwcx. %r5,%r0,%r6 /* clear possible reservation */
+ stwu %r6,CI_CURPM(%r5)
+ stwcx. %r6,%r0,%r5 /* clear possible reservation */
- addic. %r5,%r5,64
- li %r6,0
+ addic. %r6,%r6,64
+ li %r5,0
- lwz %r1,PCB_SP(%r4) /* get new procs SP */
+ lwz %r1,PCB_SP(%r31) /* get new procs SP */
- ori %r3,%r3,PSL_EE /* interrupts are okay again */
- mtmsr %r3
+ ori %r30,%r30,PSL_EE /* interrupts are okay again */
+ mtmsr %r30
lmw %r10,8(%r1) /* get other regs */
lwz %r1,0(%r1) /* get saved SP */
@@ -320,17 +209,6 @@ switch_exited:
mtsr PPC_USER_SR,%r10 /* get saved PPC_USER_SR */
isync
-switch_return:
- mr %r30,%r7 /* save proc pointer */
- lwz %r3,PCB_SPL(%r4)
- bl _C_LABEL(lcsplx)
-
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- bl _C_LABEL(sched_unlock_idle)
-#endif
-
- mr %r3,%r30 /* curproc for special fork returns */
-
lwz %r31,12(%r1)
lwz %r30,8(%r1)
addi %r1,%r1,16
@@ -338,6 +216,19 @@ switch_return:
mtlr %r0
blr
+_ENTRY(_C_LABEL(cpu_idle_enter))
+ blr
+
+_ENTRY(_C_LABEL(cpu_idle_cycle))
+ /* low power mode */
+ mfmsr %r3
+ oris %r3, %r3, PSL_POW@h
+ mtmsr %r3
+ isync
+ blr
+
+_ENTRY(_C_LABEL(cpu_idle_leave))
+ blr
/*
* Data used during primary/secondary traps/interrupts
diff --git a/sys/arch/mips64/mips64/context.S b/sys/arch/mips64/mips64/context.S
index 79f9869a438..24deaf3b2ec 100644
--- a/sys/arch/mips64/mips64/context.S
+++ b/sys/arch/mips64/mips64/context.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: context.S,v 1.13 2007/07/16 20:22:18 miod Exp $ */
+/* $OpenBSD: context.S,v 1.14 2007/10/10 15:53:52 art Exp $ */
/*
* Copyright (c) 2002-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -69,92 +69,11 @@ LEAF(savectx, 0)
move v0, zero
END(savectx)
-/*
- * The following primitives manipulate the run queues. _whichqs tells which
- * of the 32 queues _qs have processes in them. Setrunqueue puts processes
- * into queues, Remrq removes them from queues. The running process is on
- * no queue, other processes are on a queue related to p->p_priority, divided
- * by 4 actually to shrink the 0-127 range of priorities into the 32 available
- * queues.
- */
-/*
- * setrunqueue(p)
- * proc *p;
- *
- * Call should be made at splclock(), and p->p_stat should be SRUN.
- */
-NON_LEAF(setrunqueue, FRAMESZ(CF_SZ), ra)
- .mask 0x80000000, (CF_RA_OFFS - FRAMESZ(CF_SZ))
- PTR_L t0, P_BACK(a0) ## firewall: p->p_back must be 0
- bne t0, zero, 1f ##
- lbu t0, P_PRIORITY(a0) # put on p->p_priority / 4 queue
- li t1, 1 # compute corresponding bit
- srl t0, t0, 2 # compute index into 'whichqs'
- sll t1, t1, t0
- lw t2, whichqs # set corresponding bit
- sll t0, t0, LOGREGSZ+1 # compute index into 'qs'
- or t2, t2, t1
- sw t2, whichqs
- LA t1, qs
- PTR_ADDU t0, t0, t1 # t0 = qp = &qs[pri >> 2]
- PTR_L t1, P_BACK(t0) # t1 = qp->ph_rlink
- PTR_S t0, P_FORW(a0) # p->p_forw = qp
- PTR_S t1, P_BACK(a0) # p->p_back = qp->ph_rlink
- PTR_S a0, P_FORW(t1) # p->p_back->p_forw = p;
- j ra
- PTR_S a0, P_BACK(t0) # qp->ph_rlink = p
-
-1:
+NON_LEAF(cpu_idle_enter, FRAMESZ(CF_SZ), ra)
PTR_SUBU sp, sp, FRAMESZ(CF_SZ)
PTR_S ra, CF_RA_OFFS(sp)
- PANIC("setrunqueue")
- jr ra
- nop
-END(setrunqueue)
-
-/*
- * Remrq(p)
- *
- * Call should be made at splclock().
- */
-NON_LEAF(remrunqueue, FRAMESZ(CF_SZ), ra)
.mask 0x80000000, (CF_RA_OFFS - FRAMESZ(CF_SZ))
- lbu t0, P_PRIORITY(a0) # get from p->p_priority / 4 queue
- li t1, 1 # compute corresponding bit
- srl t0, t0, 2 # compute index into 'whichqs'
- lw t2, whichqs # check corresponding bit
- sll t1, t1, t0
- and v0, t2, t1
- beqz v0, 2f # oops! queue is empty!
- PTR_L v0, P_BACK(a0) # v0 = p->p_back
-
- PTR_L v1, P_FORW(a0) # v1 = p->p_forw
- PTR_SLL t0, t0, LOGREGSZ+1 # compute index into 'qs'
- PTR_S v1, P_FORW(v0) # p->p_back->p_forw = p->p_forw;
- PTR_S v0, P_BACK(v1) # p->p_forw->p_back = p->r_rlink
- LA v0, qs
- PTR_ADDU t0, t0, v0 # t0 = qp = &qs[pri >> 2]
- PTR_L v0, P_FORW(t0) # check if queue empty
- bne v0, t0, 1f # No. qp->ph_link != qp
- xor t2, t2, t1 # clear corresponding bit in 'whichqs'
- sw t2, whichqs
-1:
- j ra
- PTR_S zero, P_BACK(a0) # for firewall checking
-2:
- PTR_SUBU sp, sp, FRAMESZ(CF_SZ)
- PTR_S ra, CF_RA_OFFS(sp)
- PANIC("remrunqueue empty")
- jr ra
- nop
-END(remrunqueue)
-
-/*
- * Idle, this is where we spend time when nothing to do.
- */
-LEAF(idle, 0)
-_idle:
sw zero, cpl # lower to spl0
lw t0, ipending
beqz t0, 1f
@@ -175,63 +94,57 @@ _idle:
jal updateimask # Make sure SR imask is updated
xor a0, a0
- li t1,1
#if defined(TGT_CP7000) || defined(TGT_CP7000G)
PTR_L t2, misc_h # if non zero, do Ocelot LEDs.
beqz t2, 1f
li t0, 0x40
sb t0, 0x0d(t2)
-#endif
1:
- lw t0, whichqs # look for non-empty queue
- beq t0, zero, 1b
- nop
+#endif
+
+ PTR_L ra, CF_RA_OFFS(sp)
+ j ra
+ PTR_ADDU sp, sp, FRAMESZ(CF_SZ)
+END(cpu_idle_enter)
+
+LEAF(cpu_idle_leave, 0)
#if defined(TGT_CP7000) || defined(TGT_CP7000G)
- beqz t2, sw1
+ PTR_L t2, misc_h # if non zero, do Ocelot LEDs.
+ beqz t2, 1f
li t0, 0x40
sb t0, 0x0c(t2)
+1:
#endif
- b sw1 # Hey, time to do some work!
- nop
- jr ra # DDB trace
- nop
- .globl e_idle
-e_idle:
-END(idle)
-/*
- * switch_exit(p)
- *
- * At exit of a process, do a cpu_switch for the last time.
- * All interrupts should be blocked at this point.
- */
-LEAF(switch_exit, 0)
- mfc0 v0, COP_0_STATUS_REG
- li v1, ~SR_INT_ENAB
- and v0, v0, v1
- mtc0 v0, COP_0_STATUS_REG
+ mfc0 a0, COP_0_STATUS_REG # disable interrupts
+ li a1, ~SR_INT_ENAB
+ and a0, a0, a1
+ mtc0 a0, COP_0_STATUS_REG
ITLBNOPFIX
- LA sp, idle_stack - FRAMESZ(CF_SZ)
- jal exit2
- nop
- PTR_S zero, curproc
- b sw0
+ j ra
nop
- jr ra # DDB trace
+END(cpu_idle_leave)
+
+LEAF(cpu_idle_cycle, 0)
+ j ra
nop
-END(switch_exit)
+END(cpu_idle_cycle)
/*
- * cpu_switch()
- * Find the highest priority process and resume it.
+ * cpu_switchto(struct proc *oldproc, struct proc *newproc)
*/
-NON_LEAF(cpu_switch, FRAMESZ(CF_SZ), ra)
+NON_LEAF(cpu_switchto, FRAMESZ(CF_SZ), ra)
PTR_L t3, curprocpaddr
REG_S sp, PCB_CONTEXT+8*REGSZ(t3) # save old sp
+
PTR_SUBU sp, sp, FRAMESZ(CF_SZ)
REG_S ra, CF_RA_OFFS(sp)
.mask 0x80000000, (CF_RA_OFFS - FRAMESZ(CF_SZ))
+
+ beqz a0, 1f
+ nop
+
lw t0, cpl
REG_S t0, PCB_CONTEXT+13*REGSZ(t3)
REG_S s0, PCB_CONTEXT+0*REGSZ(t3) # do a 'savectx()'
@@ -249,59 +162,23 @@ NON_LEAF(cpu_switch, FRAMESZ(CF_SZ), ra)
REG_S t0, PCB_CONTEXT+11*REGSZ(t3)
REG_S t1, PCB_CONTEXT+12*REGSZ(t3)
-sw0:
-# lw t2, cnt+V_SWTCH # for statistics
- lw t1, whichqs # look for non-empty queue
-# addu t2, t2, 1
-# sw t2, cnt+V_SWTCH
- beq t1, zero, _idle # if none, idle
- nop
-sw1:
- mfc0 v0, COP_0_STATUS_REG
+1:
+ /*
+ * Disable interrupts
+ */
+ mfc0 v0, COP_0_STATUS_REG # disable interrupts
li v1, ~SR_INT_ENAB
and v0, v0, v1
mtc0 v0, COP_0_STATUS_REG
ITLBNOPFIX
- lw t0, whichqs # look for non-empty queue
- li t2, -1 # t2 = lowest bit set
- beq t0, zero, _idle # if none, idle
- move t3, t0 # t3 = saved whichqs
-1:
- addu t2, t2, 1
- and t1, t0, 1 # bit set?
- beq t1, zero, 1b
- srl t0, t0, 1 # try next bit
-/*
- * Remove process from queue.
- */
- PTR_SLL t0, t2, LOGREGSZ+1
- LA t1, qs
- PTR_ADDU t0, t0, t1 # t0 = qp = &qs[highbit]
- PTR_L a0, P_FORW(t0) # a0 = p = highest pri process
- PTR_L v0, P_FORW(a0) # v0 = p->p_forw
- beq t0, a0, 4f # make sure something in queue
- PTR_S v0, P_FORW(t0) # qp->ph_link = p->p_forw;
- PTR_S t0, P_BACK(v0) # p->p_forw->p_back = qp
- bne v0, t0, 2f # queue still not empty
- PTR_S zero, P_BACK(a0) ## for firewall checking
- li v1, 1 # compute bit in 'whichqs'
- sll v1, v1, t2
- xor t3, t3, v1 # clear bit in 'whichqs'
- sw t3, whichqs
-2:
-/*
- * Switch to new context.
- */
- sw zero, want_resched
- jal pmap_activate # v0 = TLB PID
- move s0, a0 # BDSLOT: save p
-/*
- * We need to wire the process kernel stack mapping so there
- * will be no tlb misses in exception handlers. This is done
- * by invalidating any tlb entries mapping the U-area and
- * put valid mappings in tlb entries 0 and 1.
- */
+ /*
+ * Switch to new context
+ */
+ move s0, a1 # save p
+ sw zero, want_resched
+ jal pmap_activate
+ move a0, s0
PTR_L t3, P_ADDR(s0) # get uarea pointer.
PTR_S s0, curproc # set curproc
@@ -310,6 +187,13 @@ sw1:
li t1, SONPROC
sb t1, P_STAT(s0) # set to onproc.
+ /*
+ * We need to wire the process kernel stack mapping so there
+ * will be no tlb misses in exception handlers. This is done
+ * by invalidating any tlb entries mapping the U-area and
+ * put valid mappings in tlb entries 0 and 1.
+ */
+
or v0, t3
dmtc0 v0, COP_0_TLB_HI # init high entry (tlbid)
LA t1, (VM_MIN_KERNEL_ADDRESS)
@@ -399,9 +283,10 @@ ctx2:
ctx3:
-/*
- * Restore registers and return.
- */
+ /*
+ * Restore registers and return.
+ */
+
REG_L a0, PCB_CONTEXT+13*REGSZ(t3)
REG_L s0, PCB_CONTEXT+0*REGSZ(t3)
REG_L s1, PCB_CONTEXT+1*REGSZ(t3)
@@ -428,6 +313,4 @@ ctx3:
ITLBNOPFIX
j ra
nop
-4:
- PANIC("cpu_switch") # nothing in queue
-END(cpu_switch)
+END(cpu_switchto)
diff --git a/sys/arch/mips64/mips64/db_machdep.c b/sys/arch/mips64/mips64/db_machdep.c
index 86f6a435b1a..4e2ee91e71f 100644
--- a/sys/arch/mips64/mips64/db_machdep.c
+++ b/sys/arch/mips64/mips64/db_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: db_machdep.c,v 1.12 2007/09/03 01:15:50 krw Exp $ */
+/* $OpenBSD: db_machdep.c,v 1.13 2007/10/10 15:53:52 art Exp $ */
/*
* Copyright (c) 1998-2003 Opsycon AB (www.opsycon.se)
@@ -221,7 +221,6 @@ db_stack_trace_print(addr, have_addr, count, modif, pr)
extern char edata[];
extern char k_intr[];
extern char k_general[];
- extern char idle[];
struct trap_frame *regs = &ddb_regs;
/* get initial values from the exception frame */
@@ -396,14 +395,10 @@ loop:
}
done:
- if (symname == NULL) {
- if (subr == (long)idle)
- (*pr)("idle ");
- else
- (*pr)("%p ", subr);
- } else {
+ if (symname == NULL)
+ (*pr)("%p ", subr);
+ else
(*pr)("%s+%p ", symname, diff);
- }
(*pr)("(%llx,%llx,%llx,%llx) sp %llx ra %llx, sz %d\n", a0, a1, a2, a3, sp, ra, stksize);
if (subr == (long)k_intr || subr == (long)k_general) {
diff --git a/sys/arch/mips64/mips64/vm_machdep.c b/sys/arch/mips64/mips64/vm_machdep.c
index 30f280cc396..d6517d55ffd 100644
--- a/sys/arch/mips64/mips64/vm_machdep.c
+++ b/sys/arch/mips64/mips64/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.15 2007/09/03 17:35:51 miod Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.16 2007/10/10 15:53:52 art Exp $ */
/*
* Copyright (c) 1988 University of Utah.
* Copyright (c) 1992, 1993
@@ -134,9 +134,9 @@ cpu_exit(p)
if (machFPCurProcPtr == p)
machFPCurProcPtr = (struct proc *)0;
- (void) splhigh();
- switch_exit(p);
- /* NOTREACHED */
+ (void)splhigh();
+ pmap_deactivate(p);
+ sched_exit(p);
}
/*
diff --git a/sys/arch/mvme68k/mvme68k/locore.s b/sys/arch/mvme68k/mvme68k/locore.s
index 38015370541..c92d4fb2978 100644
--- a/sys/arch/mvme68k/mvme68k/locore.s
+++ b/sys/arch/mvme68k/mvme68k/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.54 2007/05/15 13:46:22 martin Exp $ */
+/* $OpenBSD: locore.s,v 1.55 2007/10/10 15:53:52 art Exp $ */
/*
* Copyright (c) 1995 Theo de Raadt
@@ -1165,51 +1165,18 @@ Ldorte:
*/
#include <m68k/m68k/support.s>
-/*
- * Use common m68k process manipulation routines.
- */
-#include <m68k/m68k/proc_subr.s>
-
.data
GLOBAL(curpcb)
.long 0
ASBSS(nullpcb,SIZEOF_PCB)
-/*
- * At exit of a process, do a switch for the last time.
- * Switch to a safe stack and PCB, and deallocate the process's resources.
- */
-ENTRY(switch_exit)
- movl sp@(4),a0
- | save state into garbage pcb
- movl #_ASM_LABEL(nullpcb),_C_LABEL(curpcb)
- lea _ASM_LABEL(tmpstk),sp | goto a tmp stack
-
- /* Schedule the vmspace and stack to be freed. */
- movl a0,sp@- | exit2(p)
- jbsr _C_LABEL(exit2)
- lea sp@(4),sp | pop args
-
- jra _C_LABEL(cpu_switch)
-
-/*
- * When no processes are on the runq, Swtch branches to Idle
- * to wait for something to come ready.
- */
-ASENTRY_NOPROFILE(Idle)
+ENTRY_NOPROFILE(cpu_idle_cycle)
stop #PSL_LOWIPL
- movw #PSL_HIGHIPL,sr
- movl _C_LABEL(whichqs),d0
- jeq _ASM_LABEL(Idle)
- jra Lsw1
-
-Lbadsw:
- PANIC("switch")
- /*NOTREACHED*/
+ rts
/*
- * cpu_switch()
+ * cpu_switchto(struct proc *oldproc, struct proc *newproc)
*
* NOTE: On the mc68851 we attempt to avoid flushing the
* entire ATC. The effort involved in selective flushing may not be
@@ -1219,55 +1186,15 @@ Lbadsw:
* user's PTEs have been changed (formerly denoted by the SPTECHG p_flag
* bit). For now, we just always flush the full ATC.
*/
-ENTRY(cpu_switch)
- movl _C_LABEL(curpcb),a0 | current pcb
- movw sr,a0@(PCB_PS) | save sr before changing ipl
-#ifdef notyet
- movl CURPROC,sp@- | remember last proc running
-#endif
- clrl CURPROC
+ENTRY(cpu_switchto)
+ movl sp@(4), d0 | oldproc
+ beq Lswnofpsave | is NULL, don't save anything
/*
- * Find the highest-priority queue that isn't empty,
- * then take the first proc from that queue.
- */
- movw #PSL_HIGHIPL,sr | lock out interrupts
- movl _C_LABEL(whichqs),d0
- jeq _ASM_LABEL(Idle)
-Lsw1:
- movl d0,d1
- negl d0
- andl d1,d0
- bfffo d0{#0:#32},d1
- eorib #31,d1
-
- movl d1,d0
- lslb #3,d1 | convert queue number to index
- addl #_C_LABEL(qs),d1 | locate queue (q)
- movl d1,a1
- movl a1@(P_FORW),a0 | p = q->p_forw
- cmpal d1,a0 | anyone on queue?
- jeq Lbadsw | no, panic
- movl a0@(P_FORW),a1@(P_FORW) | q->p_forw = p->p_forw
- movl a0@(P_FORW),a1 | n = p->p_forw
- movl d1,a1@(P_BACK) | n->p_back = q
- cmpal d1,a1 | anyone left on queue?
- jne Lsw2 | yes, skip
- movl _C_LABEL(whichqs),d1
- bclr d0,d1 | no, clear bit
- movl d1,_C_LABEL(whichqs)
-Lsw2:
- movl a0,CURPROC
- clrl _C_LABEL(want_resched)
-#ifdef notyet
- movl sp@+,a1
- cmpl a0,a1 | switching to same proc?
- jeq Lswdone | yes, skip save and restore
-#endif
- /*
* Save state of previous process in its pcb.
*/
movl _C_LABEL(curpcb),a1
+ movw sr, a1@(PCB_PS) | save sr before switching context
moveml #0xFCFC,a1@(PCB_REGS) | save non-scratch registers
movl usp,a2 | grab USP (a2 has been saved)
movl a2,a1@(PCB_USP) | and save it
@@ -1295,15 +1222,12 @@ Lsavfp60:
fmovem fpsr,a2@(FPF_FPSR)
fmovem fpi,a2@(FPF_FPI)
#endif /* M68060 */
+
Lswnofpsave:
-#ifdef DIAGNOSTIC
- tstl a0@(P_WCHAN)
- jne Lbadsw
- cmpb #SRUN,a0@(P_STAT)
- jne Lbadsw
-#endif
+ movl sp@(8), a0 | newproc
+
+ movl a0, CURPROC
movb #SONPROC,a0@(P_STAT)
- clrl a0@(P_BACK) | clear back link
movl a0@(P_ADDR),a1 | get p_addr
movl a1,_C_LABEL(curpcb)
diff --git a/sys/arch/mvme68k/mvme68k/vm_machdep.c b/sys/arch/mvme68k/mvme68k/vm_machdep.c
index e8ac2262a05..df44535cfda 100644
--- a/sys/arch/mvme68k/mvme68k/vm_machdep.c
+++ b/sys/arch/mvme68k/mvme68k/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.45 2007/06/20 17:29:36 miod Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.46 2007/10/10 15:53:52 art Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -117,20 +117,18 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
/*
* cpu_exit is called as the last action during exit.
- * We release the address space and machine-dependent resources,
- * including the memory for the user structure and kernel stack.
- * Once finished, we call switch_exit, which switches to a temporary
- * pcb and stack and never returns. We block memory allocation
- * until switch_exit has made things safe again.
+ *
+ * Block context switches and then call switch_exit() which will
+ * switch to another process thus we never return.
*/
void
cpu_exit(p)
struct proc *p;
{
+ (void)splhigh();
- splhigh();
- switch_exit(p);
- /* NOTREACHED */
+ pmap_deactivate(p);
+ sched_exit(p);
}
/*
diff --git a/sys/arch/mvme88k/mvme88k/locore.S b/sys/arch/mvme88k/mvme88k/locore.S
index 980804454bc..355d0dae81a 100644
--- a/sys/arch/mvme88k/mvme88k/locore.S
+++ b/sys/arch/mvme88k/mvme88k/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.49 2006/05/08 14:03:35 miod Exp $ */
+/* $OpenBSD: locore.S,v 1.50 2007/10/10 15:53:52 art Exp $ */
/*
* Copyright (c) 2005, Miodrag Vallat.
* Copyright (c) 1998 Steve Murphree, Jr.
@@ -346,14 +346,6 @@ GLOBAL(secondary_start)
bsr.n _C_LABEL(secondary_main)
addu r31, r3, USIZE /* switch to idle stack */
- /*
- * At this point, the CPU has been correctly initialized and has
- * identified itself on the console.
- * All it needs now is to jump to the idle loop and wait for work to
- * be offered.
- */
- br _ASM_LABEL(cpu_switch_idle)
-
#endif /* MULTIPROCESSOR */
/*
diff --git a/sys/arch/mvme88k/mvme88k/machdep.c b/sys/arch/mvme88k/mvme88k/machdep.c
index c743056aafa..6c94e8288aa 100644
--- a/sys/arch/mvme88k/mvme88k/machdep.c
+++ b/sys/arch/mvme88k/mvme88k/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.192 2007/06/06 17:15:12 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.193 2007/10/10 15:53:52 art Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -719,19 +719,18 @@ void
secondary_main()
{
struct cpu_info *ci = curcpu();
+ int s;
cpu_configuration_print(0);
+ sched_init_cpu(ci);
ncpus++;
__cpu_simple_unlock(&cpu_mutex);
microuptime(&ci->ci_schedstate.spc_runtime);
ci->ci_curproc = NULL;
- /*
- * Upon return, the secondary cpu bootstrap code in locore will
- * enter the idle loop, waiting for some food to process on this
- * processor.
- */
+ SCHED_LOCK(s);
+ cpu_switchto(NULL, sched_chooseproc());
}
#endif /* MULTIPROCESSOR */
diff --git a/sys/arch/powerpc/conf/files.powerpc b/sys/arch/powerpc/conf/files.powerpc
index 9bfb6960e27..d3effdc83a4 100644
--- a/sys/arch/powerpc/conf/files.powerpc
+++ b/sys/arch/powerpc/conf/files.powerpc
@@ -1,8 +1,7 @@
-# $OpenBSD: files.powerpc,v 1.42 2007/03/22 19:26:27 kettenis Exp $
+# $OpenBSD: files.powerpc,v 1.43 2007/10/10 15:53:52 art Exp $
#
file arch/powerpc/powerpc/setjmp.S ddb
-file arch/powerpc/powerpc/Locore.c
file arch/powerpc/powerpc/bcopy.c
file arch/powerpc/powerpc/copystr.c
file arch/powerpc/powerpc/cpu_subr.c
diff --git a/sys/arch/powerpc/include/pcb.h b/sys/arch/powerpc/include/pcb.h
index a49d03f1488..7560dee7b17 100644
--- a/sys/arch/powerpc/include/pcb.h
+++ b/sys/arch/powerpc/include/pcb.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcb.h,v 1.10 2007/03/20 20:59:53 kettenis Exp $ */
+/* $OpenBSD: pcb.h,v 1.11 2007/10/10 15:53:52 art Exp $ */
/* $NetBSD: pcb.h,v 1.1 1996/09/30 16:34:29 ws Exp $ */
/*-
@@ -49,7 +49,6 @@ struct pcb {
struct pmap *pcb_pm; /* pmap of our vmspace */
struct pmap *pcb_pmreal; /* real address of above */
register_t pcb_sp; /* saved SP */
- int pcb_spl; /* saved SPL */
faultbuf *pcb_onfault; /* For use during copyin/copyout */
int pcb_flags;
#define PCB_FPU 1 /* Process had FPU initialized */
diff --git a/sys/arch/powerpc/powerpc/vm_machdep.c b/sys/arch/powerpc/powerpc/vm_machdep.c
index 5a7d92622de..89755b7c774 100644
--- a/sys/arch/powerpc/powerpc/vm_machdep.c
+++ b/sys/arch/powerpc/powerpc/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.44 2007/06/20 17:29:36 miod Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.45 2007/10/10 15:53:52 art Exp $ */
/* $NetBSD: vm_machdep.c,v 1.1 1996/09/30 16:34:57 ws Exp $ */
/*
@@ -123,7 +123,6 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize,
sf->sp = (int)cf;
sf->user_sr = pmap_kernel()->pm_sr[PPC_USER_SR]; /* just in case */
pcb->pcb_sp = (int)stktop2;
- pcb->pcb_spl = 0;
}
/*
@@ -155,8 +154,8 @@ cpu_exit(struct proc *p)
pool_put(&ppc_vecpl, pcb->pcb_vr);
#endif /* ALTIVEC */
- (void)splsched();
- switchexit(p);
+ pmap_deactivate(p);
+ sched_exit(p);
}
/*
diff --git a/sys/arch/sgi/localbus/macebus.c b/sys/arch/sgi/localbus/macebus.c
index f02bafba377..4e981dac5ef 100644
--- a/sys/arch/sgi/localbus/macebus.c
+++ b/sys/arch/sgi/localbus/macebus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: macebus.c,v 1.26 2007/07/09 21:40:24 jasper Exp $ */
+/* $OpenBSD: macebus.c,v 1.27 2007/10/10 15:53:52 art Exp $ */
/*
* Copyright (c) 2000-2004 Opsycon AB (www.opsycon.se)
@@ -780,7 +780,6 @@ macebus_iointr(intrmask_t hwpend, struct trap_frame *cf)
intrmask_t
macebus_aux(intrmask_t hwpend, struct trap_frame *cf)
{
- extern char idle[], e_idle[];
u_int64_t mask;
mask = bus_space_read_8(&macebus_tag, mace_h, MACE_ISA_MISC_REG);
@@ -791,7 +790,8 @@ macebus_aux(intrmask_t hwpend, struct trap_frame *cf)
/* RED - User Mode */
if (cf->sr & SR_KSU_USER) {
mask &= ~MACE_ISA_MISC_RLED_OFF;
- } else if (cf->pc >= (long)idle && cf->pc < (long)e_idle) {
+ } else if (curproc == NULL ||
+ curproc == curcpu()->ci_schedstate.spc_idleproc) {
mask &= ~MACE_ISA_MISC_GLED_OFF;
} else {
mask &= ~(MACE_ISA_MISC_RLED_OFF | MACE_ISA_MISC_GLED_OFF);
diff --git a/sys/arch/sgi/sgi/genassym.cf b/sys/arch/sgi/sgi/genassym.cf
index a57571199d8..2e5ac9202f8 100644
--- a/sys/arch/sgi/sgi/genassym.cf
+++ b/sys/arch/sgi/sgi/genassym.cf
@@ -1,4 +1,4 @@
-# $OpenBSD: genassym.cf,v 1.9 2007/06/18 20:25:55 miod Exp $
+# $OpenBSD: genassym.cf,v 1.10 2007/10/10 15:53:52 art Exp $
#
# Copyright (c) 1997 Per Fogelstrom / Opsycon AB
#
@@ -38,9 +38,7 @@ include <machine/cpu.h>
export SONPROC
struct proc
-member p_forw
-member p_back
-member p_priority
+#member p_priority
member p_stat
member p_addr
#member P_UPTE p_md.md_upte
diff --git a/sys/arch/sh/include/cpu.h b/sys/arch/sh/include/cpu.h
index b29d7247ce0..8b43e78767b 100644
--- a/sys/arch/sh/include/cpu.h
+++ b/sys/arch/sh/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.10 2007/06/06 17:15:12 deraadt Exp $ */
+/* $OpenBSD: cpu.h,v 1.11 2007/10/10 15:53:52 art Exp $ */
/* $NetBSD: cpu.h,v 1.41 2006/01/21 04:24:12 uwe Exp $ */
/*-
@@ -125,6 +125,11 @@ extern int want_resched; /* need_resched() was called */
* We need a machine-independent name for this.
*/
#define DELAY(x) delay(x)
+
+#define cpu_idle_enter() do { /* nothing */ } while (0)
+#define cpu_idle_cycle() __asm volatile("sleep")
+#define cpu_idle_leave() do { /* nothing */ } while (0)
+
#endif /* _KERNEL */
/*
diff --git a/sys/arch/sh/sh/genassym.cf b/sys/arch/sh/sh/genassym.cf
index 9227338a9a3..d864f1397ec 100644
--- a/sys/arch/sh/sh/genassym.cf
+++ b/sys/arch/sh/sh/genassym.cf
@@ -1,4 +1,4 @@
-# $OpenBSD: genassym.cf,v 1.3 2007/05/14 07:05:49 art Exp $
+# $OpenBSD: genassym.cf,v 1.4 2007/10/10 15:53:52 art Exp $
# $NetBSD: genassym.cf,v 1.10 2005/12/11 12:19:00 christos Exp $
#-
@@ -54,8 +54,6 @@ member tf_spc
struct proc
member p_addr
-member p_back
-member p_forw
member p_stat
member p_wchan
member P_MD_UPTE p_md.md_upte
diff --git a/sys/arch/sh/sh/locore_c.c b/sys/arch/sh/sh/locore_c.c
index ede226184c7..d1df8aeef7b 100644
--- a/sys/arch/sh/sh/locore_c.c
+++ b/sys/arch/sh/sh/locore_c.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore_c.c,v 1.5 2007/09/09 11:57:55 miod Exp $ */
+/* $OpenBSD: locore_c.c,v 1.6 2007/10/10 15:53:52 art Exp $ */
/* $NetBSD: locore_c.c,v 1.13 2006/03/04 01:13:35 uwe Exp $ */
/*-
@@ -127,26 +127,14 @@
#include <sh/ubcreg.h>
void (*__sh_switch_resume)(struct proc *);
-struct proc *cpu_switch_search(struct proc *);
-struct proc *cpu_switch_prepare(struct proc *, struct proc *);
-void switch_exit(struct proc *, void (*)(struct proc *));
-void idle(void);
+void cpu_switch_prepare(struct proc *, struct proc *);
int want_resched;
-#ifdef LOCKDEBUG
-#define SCHED_LOCK_IDLE() sched_lock_idle()
-#define SCHED_UNLOCK_IDLE() sched_unlock_idle()
-#else
-#define SCHED_LOCK_IDLE() do {} while (/* CONSTCOND */ 0)
-#define SCHED_UNLOCK_IDLE() do {} while (/* CONSTCOND */ 0)
-#endif
-
-
/*
* Prepare context switch from oproc to nproc.
- * This code is shared by cpu_switch and cpu_switchto.
+ * This code is used by cpu_switchto.
*/
-struct proc *
+void
cpu_switch_prepare(struct proc *oproc, struct proc *nproc)
{
nproc->p_stat = SONPROC;
@@ -154,10 +142,8 @@ cpu_switch_prepare(struct proc *oproc, struct proc *nproc)
if (oproc && (oproc->p_md.md_flags & MDP_STEP))
_reg_write_2(SH_(BBRB), 0);
- if (nproc != oproc) {
- curpcb = nproc->p_md.md_pcb;
- pmap_activate(nproc);
- }
+ curpcb = nproc->p_md.md_pcb;
+ pmap_activate(nproc);
if (nproc->p_md.md_flags & MDP_STEP) {
int pm_asid = nproc->p_vmspace->vm_map.pmap->pm_asid;
@@ -171,34 +157,6 @@ cpu_switch_prepare(struct proc *oproc, struct proc *nproc)
}
curproc = nproc;
- return (nproc);
-}
-
-/*
- * Find the highest priority proc and prepare to switching to it.
- */
-struct proc *
-cpu_switch_search(struct proc *oproc)
-{
- struct prochd *q;
- struct proc *p;
-
- curproc = NULL;
-
- SCHED_LOCK_IDLE();
- while (sched_is_idle()) {
- SCHED_UNLOCK_IDLE();
- idle();
- SCHED_LOCK_IDLE();
- }
-
- q = &qs[ffs(whichqs) - 1];
- p = q->ph_link;
- remrunqueue(p);
- want_resched = 0;
- SCHED_UNLOCK_IDLE();
-
- return (cpu_switch_prepare(oproc, p));
}
void
@@ -207,24 +165,8 @@ cpu_exit(struct proc *p)
if (p->p_md.md_flags & MDP_STEP)
_reg_write_2(SH_(BBRB), 0);
- switch_exit(p, exit2);
-}
-
-/*
- * void idle(void):
- * When no processes are on the run queue, wait for something to come
- * ready. Separated function for profiling.
- */
-void
-idle()
-{
- spl0();
-#if 0
- if (uvm.page_idle_zero)
- uvm_pageidlezero();
-#endif
- __asm volatile("sleep");
- splsched();
+ pmap_deactivate(p);
+ sched_exit(p);
}
#ifndef P1_STACK
diff --git a/sys/arch/sh/sh/locore_subr.S b/sys/arch/sh/sh/locore_subr.S
index de57709a5d5..5543b4870c6 100644
--- a/sys/arch/sh/sh/locore_subr.S
+++ b/sys/arch/sh/sh/locore_subr.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore_subr.S,v 1.6 2007/03/02 06:11:54 miod Exp $ */
+/* $OpenBSD: locore_subr.S,v 1.7 2007/10/10 15:53:52 art Exp $ */
/* $NetBSD: locore_subr.S,v 1.28 2006/01/23 22:52:09 uwe Exp $ */
/*
@@ -180,27 +180,26 @@
.text
.align 5 /* align cache line size (32B) */
/*
- * LINTSTUB: Func: void cpu_switch(struct proc *p, struct proc *XXX_IGNORED)
- * Find a runnable proc and switch to it. Wait if necessary.
+ * LINTSTUB: Func: void cpu_switchto(struct proc *old, struct proc *new)
+ * Switch proc contexts.
*/
-ENTRY(cpu_switch)
- /* Save current proc's context to switchframe */
+ENTRY(cpu_switchto)
+ mov r4, r0
+ cmp/eq #0, r0
+ bt 1f
+
+ /* Save old proc's context to switchframe */
mov.l .L_SF, r0
mov.l @(r0, r4), r1
SAVEPCB(r1)
add #PCB_FP, r1
SAVEFP(r1, r8, r9)
-.L_find_and_switch:
- /* Search next proc. cpu_switch_search may or may not sleep. */
- mov.l .L_cpu_switch_search, r0
+1:
+ mov.l .L_cpu_switch_prepare, r0
jsr @r0
- mov r4, r8 /* save old proc */
-
- /* Skip context switch if same proc. */
- cmp/eq r8, r0
- bt/s 1f
- mov r0, r4 /* new proc */
+ mov r5, r8 /* save new proc */
+ mov r8, r4
/* Setup kernel stack */
mov.l .L_SF, r0
@@ -224,7 +223,7 @@ ENTRY(cpu_switch)
/* Now OK to use kernel stack. */
/* Restore new proc's context from switchframe */
-1: mov.l .L_SF, r0
+ mov.l .L_SF, r0
mov.l @(r0, r4), r1
add #4, r1 /* r15 already restored */
mov.l @r1+, r14
@@ -248,49 +247,9 @@ ENTRY(cpu_switch)
nop
.align 2
.L_SF: .long (P_MD_PCB)
-.L_cpu_switch_search: .long _C_LABEL(cpu_switch_search)
+.L_cpu_switch_prepare: .long _C_LABEL(cpu_switch_prepare)
FUNC_SYMBOL(switch_resume)
-
-/*
- * LINTSTUB: Func: void switch_exit(struct proc *p, void (*exit_func)(struct proc *))
- * Called only from cpu_exit(p). Before we call exit_func to
- * free proc's resources (including kernel stack) we need to
- * switch to the proc0's kernel stack. Then we jump into the
- * middle of cpu_switch to find and switch to a new proc.
- */
-ALTENTRY(switch_exit)
- mov.l .L_switch_exit_proc0_pcb, r1
- mov.l .L_switch_exit_curpcb, r0
- mov.l @r1, r1
- mov.l r1, @r0 /* curpcb = proc0.p_md.md_pcb */
-
- mov.l @(SF_R7_BANK, r1), r0 /* stack top */
- mov.l @(SF_R6_BANK, r1), r2 /* current frame */
- mov.l @(SF_R15, r1), r3 /* current stack */
-
- /* switch to proc0's kernel stack */
- __EXCEPTION_BLOCK(r1, r6)
- ldc r0, r7_bank
- ldc r2, r6_bank
- mov r3, r15
- __EXCEPTION_UNBLOCK(r0, r1)
-
- /* safe to call (*exit_func)(p); now */
- jsr @r5
- nop /* proc is already in r4 */
-
- /* proceed to cpu_switch */
- bra .L_find_and_switch
- mov #0, r4 /* no "previous" proc */
-
- .align 2
-.L_switch_exit_proc0_pcb:
- .long _C_LABEL(proc0) + P_MD_PCB
-.L_switch_exit_curpcb:
- .long _C_LABEL(curpcb)
-
-
#ifdef SH3
/*
* LINTSTUB: Func: void sh3_switch_resume(struct proc *p)
diff --git a/sys/arch/sh/sh/sh_machdep.c b/sys/arch/sh/sh/sh_machdep.c
index d81017ac0f1..0cfcd801825 100644
--- a/sys/arch/sh/sh/sh_machdep.c
+++ b/sys/arch/sh/sh/sh_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sh_machdep.c,v 1.16 2007/06/06 17:15:12 deraadt Exp $ */
+/* $OpenBSD: sh_machdep.c,v 1.17 2007/10/10 15:53:52 art Exp $ */
/* $NetBSD: sh3_machdep.c,v 1.59 2006/03/04 01:13:36 uwe Exp $ */
/*
@@ -716,45 +716,6 @@ setregs(struct proc *p, struct exec_package *pack, u_long stack,
rval[1] = 0;
}
-void
-setrunqueue(struct proc *p)
-{
- int whichq = p->p_priority / PPQ;
- struct prochd *q;
- struct proc *prev;
-
-#ifdef DIAGNOSTIC
- if (p->p_back != NULL || p->p_wchan != NULL || p->p_stat != SRUN)
- panic("setrunqueue");
-#endif
- q = &qs[whichq];
- prev = q->ph_rlink;
- p->p_forw = (struct proc *)q;
- q->ph_rlink = p;
- prev->p_forw = p;
- p->p_back = prev;
- whichqs |= 1 << whichq;
-}
-
-void
-remrunqueue(struct proc *p)
-{
- struct proc *prev, *next;
- int whichq = p->p_priority / PPQ;
-
-#ifdef DIAGNOSTIC
- if (((whichqs & (1 << whichq)) == 0))
- panic("remrunqueue: bit %d not set", whichq);
-#endif
- prev = p->p_back;
- p->p_back = NULL;
- next = p->p_forw;
- prev->p_forw = next;
- next->p_back = prev;
- if (prev == next)
- whichqs &= ~(1 << whichq);
-}
-
/*
* Jump to reset vector.
*/
diff --git a/sys/arch/solbourne/solbourne/locore.s b/sys/arch/solbourne/solbourne/locore.s
index 8ff5842d209..0c8666cb599 100644
--- a/sys/arch/solbourne/solbourne/locore.s
+++ b/sys/arch/solbourne/solbourne/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.8 2006/04/15 17:36:47 miod Exp $ */
+/* $OpenBSD: locore.s,v 1.9 2007/10/10 15:53:52 art Exp $ */
/* OpenBSD: locore.s,v 1.64 2005/04/17 18:47:50 miod Exp */
/*
@@ -3233,291 +3233,52 @@ ENTRY(write_user_windows)
.comm _C_LABEL(masterpaddr), 4
/*
- * Switch statistics (for later tweaking):
- * nswitchdiff = p1 => p2 (i.e., chose different process)
- * nswitchexit = number of calls to switchexit()
- * _cnt.v_swtch = total calls to swtch+swtchexit
+ * cpu_switchto(struct proc *oldproc, struct proc *newproc)
*/
- .comm _C_LABEL(nswitchdiff), 4
- .comm _C_LABEL(nswitchexit), 4
-
-/*
- * REGISTER USAGE IN cpu_switch AND switchexit:
- * This is split into two phases, more or less
- * `before we locate a new proc' and `after'.
- * Some values are the same in both phases.
- * Note that the %o0-registers are not preserved across
- * the psr change when entering a new process, since this
- * usually changes the CWP field (hence heavy usage of %g's).
- *
- * %g1 = oldpsr (excluding ipl bits)
- * %g2 = %hi(_C_LABEL(whichqs)); newpsr
- * %g3 = p
- * %g4 = lastproc
- * %g5 = <free>; newpcb
- * %g6 = %hi(_C_LABEL(cpcb))
- * %g7 = %hi(_C_LABEL(curproc))
- * %o0 = tmp 1
- * %o1 = tmp 2
- * %o2 = tmp 3
- * %o3 = tmp 4; whichqs; vm
- * %o4 = tmp 4; which; sswap
- * %o5 = tmp 5; q; <free>
- */
-
-/*
- * switchexit is called only from cpu_exit() before the current process
- * has freed its kernel stack; we must free it. (curproc is already NULL.)
- *
- * We lay the process to rest by changing to the `idle' kernel stack,
- * and note that the `last loaded process' is nonexistent.
- */
-ENTRY(switchexit)
- mov %o0, %g2 ! save proc for exit2() call
-
- /*
- * Change pcb to idle u. area, i.e., set %sp to top of stack
- * and %psr to PSR_S|PSR_ET, and set cpcb to point to _idle_u.
- * Once we have left the old stack, we can call kmem_free to
- * destroy it. Call it any sooner and the register windows
- * go bye-bye.
- */
- set _C_LABEL(idle_u), %g5
- sethi %hi(_C_LABEL(cpcb)), %g6
- mov 1, %g7
- wr %g0, PSR_S, %psr ! change to window 0, traps off
- nop; nop; nop
- wr %g0, 2, %wim ! and make window 1 the trap window
- st %g5, [%g6 + %lo(_C_LABEL(cpcb))] ! cpcb = &idle_u
- st %g7, [%g5 + PCB_WIM] ! idle_u.pcb_wim = log2(2) = 1
- set _C_LABEL(idle_u) + USPACE-CCFSZ, %sp ! set new %sp
-#ifdef DEBUG
- set _C_LABEL(idle_u), %l6
- SET_SP_REDZONE(%l6, %l5)
-#endif
- wr %g0, PSR_S|PSR_ET, %psr ! and then enable traps
- call _C_LABEL(exit2) ! exit2(p)
- mov %g2, %o0
-
- /*
- * Now fall through to `the last switch'. %g6 was set to
- * %hi(_C_LABEL(cpcb)), but may have been clobbered in kmem_free,
- * so all the registers described below will be set here.
- *
- * REGISTER USAGE AT THIS POINT:
- * %g1 = oldpsr (excluding ipl bits)
- * %g2 = %hi(_C_LABEL(whichqs))
- * %g4 = lastproc
- * %g6 = %hi(_C_LABEL(cpcb))
- * %g7 = %hi(_C_LABEL(curproc))
- * %o0 = tmp 1
- * %o1 = tmp 2
- * %o3 = whichqs
- */
-
- INCR(_C_LABEL(nswitchexit)) ! nswitchexit++;
- INCR(_C_LABEL(uvmexp)+V_SWTCH) ! cnt.v_switch++;
-
- mov PSR_S|PSR_ET, %g1 ! oldpsr = PSR_S | PSR_ET;
- sethi %hi(_C_LABEL(whichqs)), %g2
- clr %g4 ! lastproc = NULL;
+ENTRY(cpu_switchto)
sethi %hi(_C_LABEL(cpcb)), %g6
sethi %hi(_C_LABEL(curproc)), %g7
- /* FALLTHROUGH */
-
-/*
- * When no processes are on the runq, switch
- * idles here waiting for something to come ready.
- * The registers are set up as noted above.
- */
- .globl idle
-idle:
- st %g0, [%g7 + %lo(_C_LABEL(curproc))] ! curproc = NULL;
- wr %g1, 0, %psr ! (void) spl0();
-1: ! spin reading _whichqs until nonzero
- ld [%g2 + %lo(_C_LABEL(whichqs))], %o3
- tst %o3
- bnz,a Lsw_scan
- wr %g1, IPL_CLOCK << 8, %psr ! (void) splclock();
- b,a 1b
-
-Lsw_panic_rq:
- sethi %hi(1f), %o0
- call _C_LABEL(panic)
- or %lo(1f), %o0, %o0
-Lsw_panic_wchan:
- sethi %hi(2f), %o0
- call _C_LABEL(panic)
- or %lo(2f), %o0, %o0
-Lsw_panic_srun:
- sethi %hi(3f), %o0
- call _C_LABEL(panic)
- or %lo(3f), %o0, %o0
-1: .asciz "switch rq"
-2: .asciz "switch wchan"
-3: .asciz "switch SRUN"
- _ALIGN
-
-/*
- * cpu_switch() picks a process to run and runs it, saving the current
- * one away. On the assumption that (since most workstations are
- * single user machines) the chances are quite good that the new
- * process will turn out to be the current process, we defer saving
- * it here until we have found someone to load. If that someone
- * is the current process we avoid both store and load.
- *
- * cpu_switch() is always entered at splstatclock or splhigh.
- *
- * IT MIGHT BE WORTH SAVING BEFORE ENTERING idle TO AVOID HAVING TO
- * SAVE LATER WHEN SOMEONE ELSE IS READY ... MUST MEASURE!
- */
- .globl _C_LABEL(time)
-ENTRY(cpu_switch)
- /*
- * REGISTER USAGE AT THIS POINT:
- * %g1 = oldpsr (excluding ipl bits)
- * %g2 = %hi(_C_LABEL(whichqs))
- * %g3 = p
- * %g4 = lastproc
- * %g5 = tmp 0
- * %g6 = %hi(_C_LABEL(cpcb))
- * %g7 = %hi(_C_LABEL(curproc))
- * %o0 = tmp 1
- * %o1 = tmp 2
- * %o2 = tmp 3
- * %o3 = tmp 4, then at Lsw_scan, whichqs
- * %o4 = tmp 5, then at Lsw_scan, which
- * %o5 = tmp 6, then at Lsw_scan, q
- */
- sethi %hi(_C_LABEL(whichqs)), %g2 ! set up addr regs
- sethi %hi(_C_LABEL(cpcb)), %g6
- ld [%g6 + %lo(_C_LABEL(cpcb))], %o0
- std %o6, [%o0 + PCB_SP] ! cpcb->pcb_<sp,pc> = <sp,pc>;
+ ld [%g6 + %lo(_C_LABEL(cpcb))], %o2
+ std %o6, [%o2 + PCB_SP] ! cpcb->pcb_<sp,pc> = <sp,pc>;
rd %psr, %g1 ! oldpsr = %psr;
- sethi %hi(_C_LABEL(curproc)), %g7
- ld [%g7 + %lo(_C_LABEL(curproc))], %g4 ! lastproc = curproc;
- st %g1, [%o0 + PCB_PSR] ! cpcb->pcb_psr = oldpsr;
+ st %g1, [%o2 + PCB_PSR] ! cpcb->pcb_psr = oldpsr;
andn %g1, PSR_PIL, %g1 ! oldpsr &= ~PSR_PIL;
/*
- * In all the fiddling we did to get this far, the thing we are
- * waiting for might have come ready, so let interrupts in briefly
- * before checking for other processes. Note that we still have
- * curproc set---we have to fix this or we can get in trouble with
- * the run queues below.
- */
- st %g0, [%g7 + %lo(_C_LABEL(curproc))] ! curproc = NULL;
- wr %g1, 0, %psr ! (void) spl0();
- nop; nop; nop ! paranoia
- wr %g1, IPL_CLOCK << 8 , %psr ! (void) splclock();
-
-Lsw_scan:
- nop; nop; nop ! paranoia
- ld [%g2 + %lo(_C_LABEL(whichqs))], %o3
-
- /*
- * Optimized inline expansion of `which = ffs(whichqs) - 1';
- * branches to idle if ffs(whichqs) was 0.
- */
- set ffstab, %o2
- andcc %o3, 0xff, %o1 ! byte 0 zero?
- bz,a 1f ! yes, try byte 1
- srl %o3, 8, %o0
- b 2f ! ffs = ffstab[byte0]; which = ffs - 1;
- ldsb [%o2 + %o1], %o0
-1: andcc %o0, 0xff, %o1 ! byte 1 zero?
- bz,a 1f ! yes, try byte 2
- srl %o0, 8, %o0
- ldsb [%o2 + %o1], %o0 ! which = ffstab[byte1] + 7;
- b 3f
- add %o0, 7, %o4
-1: andcc %o0, 0xff, %o1 ! byte 2 zero?
- bz,a 1f ! yes, try byte 3
- srl %o0, 8, %o0
- ldsb [%o2 + %o1], %o0 ! which = ffstab[byte2] + 15;
- b 3f
- add %o0, 15, %o4
-1: ldsb [%o2 + %o0], %o0 ! ffs = ffstab[byte3] + 24
- addcc %o0, 24, %o0 ! (note that ffstab[0] == -24)
- bz idle ! if answer was 0, go idle
- EMPTY
-2: sub %o0, 1, %o4 ! which = ffs(whichqs) - 1
-3: /* end optimized inline expansion */
-
- /*
- * We found a nonempty run queue. Take its first process.
- */
- set _C_LABEL(qs), %o5 ! q = &qs[which];
- sll %o4, 3, %o0
- add %o0, %o5, %o5
- ld [%o5], %g3 ! p = q->ph_link;
- cmp %g3, %o5 ! if (p == q)
- be Lsw_panic_rq ! panic("switch rq");
- EMPTY
- ld [%g3], %o0 ! tmp0 = p->p_forw;
- st %o0, [%o5] ! q->ph_link = tmp0;
- st %o5, [%o0 + 4] ! tmp0->p_back = q;
- cmp %o0, %o5 ! if (tmp0 == q)
- bne 1f
- EMPTY
- mov 1, %o1 ! whichqs &= ~(1 << which);
- sll %o1, %o4, %o1
- andn %o3, %o1, %o3
- st %o3, [%g2 + %lo(_C_LABEL(whichqs))]
-1:
- /*
- * PHASE TWO: NEW REGISTER USAGE:
+ * REGISTER USAGE:
* %g1 = oldpsr (excluding ipl bits)
* %g2 = newpsr
- * %g3 = p
- * %g4 = lastproc
* %g5 = newpcb
* %g6 = %hi(_C_LABEL(cpcb))
* %g7 = %hi(_C_LABEL(curproc))
- * %o0 = tmp 1
- * %o1 = tmp 2
+ * %o0 = oldproc
+ * %o1 = newproc
* %o2 = tmp 3
* %o3 = vm
* %o4 = sswap
* %o5 = <free>
*/
- /* firewalls */
- ld [%g3 + P_WCHAN], %o0 ! if (p->p_wchan)
- tst %o0
- bne Lsw_panic_wchan ! panic("switch wchan");
- EMPTY
- ldsb [%g3 + P_STAT], %o0 ! if (p->p_stat != SRUN)
- cmp %o0, SRUN
- bne Lsw_panic_srun ! panic("switch SRUN");
- EMPTY
-
/*
- * Committed to running process p.
- * It may be the same as the one we were running before.
+ * Committed to running process p (in o1).
*/
+ mov %o1, %g3
+
mov SONPROC, %o0 ! p->p_stat = SONPROC
stb %o0, [%g3 + P_STAT]
sethi %hi(_C_LABEL(want_resched)), %o0
st %g0, [%o0 + %lo(_C_LABEL(want_resched))] ! want_resched = 0;
ld [%g3 + P_ADDR], %g5 ! newpcb = p->p_addr;
- st %g0, [%g3 + 4] ! p->p_back = NULL;
ld [%g5 + PCB_PSR], %g2 ! newpsr = newpcb->pcb_psr;
st %g3, [%g7 + %lo(_C_LABEL(curproc))] ! curproc = p;
- cmp %g3, %g4 ! p == lastproc?
- be,a Lsw_sameproc ! yes, go return 0
- wr %g2, 0, %psr ! (after restoring ipl)
-
/*
- * Not the old process. Save the old process, if any;
- * then load p.
+ * Save the old process, if any; then load p.
*/
- tst %g4
+ tst %o0
be,a Lsw_load ! if no old process, go load
wr %g1, (IPL_CLOCK << 8) | PSR_ET, %psr
- INCR(_C_LABEL(nswitchdiff)) ! clobbers %o0,%o1
/*
* save: write back all windows (including the current one).
* XXX crude; knows nwindows <= 8
@@ -3659,16 +3420,17 @@ badstack:
*/
retl
- EMPTY
-1:
+ nop
-Lsw_sameproc:
- /*
- * We are resuming the process that was running at the
- * call to switch(). Just set psr ipl and return.
- */
-! wr %g2, 0 %psr ! %psr = newpsr; (done earlier)
- nop
+ENTRY(cpu_idle_enter)
+ retl
+ nop
+
+ENTRY(cpu_idle_cycle)
+ retl
+ nop
+
+ENTRY(cpu_idle_leave)
retl
nop
diff --git a/sys/arch/sparc/conf/files.sparc b/sys/arch/sparc/conf/files.sparc
index 00110dace96..1e4de8736a5 100644
--- a/sys/arch/sparc/conf/files.sparc
+++ b/sys/arch/sparc/conf/files.sparc
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sparc,v 1.78 2007/05/29 09:54:03 sobrado Exp $
+# $OpenBSD: files.sparc,v 1.79 2007/10/10 15:53:52 art Exp $
# $NetBSD: files.sparc,v 1.44 1997/08/31 21:29:16 pk Exp $
# @(#)files.sparc 8.1 (Berkeley) 7/19/93
@@ -291,7 +291,6 @@ file arch/sparc/sparc/emul.c
file arch/sparc/sparc/in_cksum.c inet
file arch/sparc/sparc/intr.c
file arch/sparc/sparc/kgdb_machdep.c kgdb
-file arch/sparc/sparc/locore2.c
file arch/sparc/sparc/machdep.c !solbourne
file arch/sparc/sparc/mem.c !solbourne
file arch/sparc/sparc/mutex.c
diff --git a/sys/arch/sparc/sparc/locore.s b/sys/arch/sparc/sparc/locore.s
index 580d51bf563..ac109ebffeb 100644
--- a/sys/arch/sparc/sparc/locore.s
+++ b/sys/arch/sparc/sparc/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.72 2007/05/29 09:54:01 sobrado Exp $ */
+/* $OpenBSD: locore.s,v 1.73 2007/10/10 15:53:52 art Exp $ */
/* $NetBSD: locore.s,v 1.73 1997/09/13 20:36:48 pk Exp $ */
/*
@@ -4383,290 +4383,52 @@ ENTRY(write_user_windows)
.comm _C_LABEL(masterpaddr), 4
/*
- * Switch statistics (for later tweaking):
- * nswitchdiff = p1 => p2 (i.e., chose different process)
- * nswitchexit = number of calls to switchexit()
- * _cnt.v_swtch = total calls to swtch+swtchexit
+ * cpu_switchto(struct proc *oldproc, struct proc *newproc)
*/
- .comm _C_LABEL(nswitchdiff), 4
- .comm _C_LABEL(nswitchexit), 4
-
-/*
- * REGISTER USAGE IN cpu_switch AND switchexit:
- * This is split into two phases, more or less
- * `before we locate a new proc' and `after'.
- * Some values are the same in both phases.
- * Note that the %o0-registers are not preserved across
- * the psr change when entering a new process, since this
- * usually changes the CWP field (hence heavy usage of %g's).
- *
- * %g1 = oldpsr (excluding ipl bits)
- * %g2 = %hi(_C_LABEL(whichqs)); newpsr
- * %g3 = p
- * %g4 = lastproc
- * %g5 = <free>; newpcb
- * %g6 = %hi(_C_LABEL(cpcb))
- * %g7 = %hi(_C_LABEL(curproc))
- * %o0 = tmp 1
- * %o1 = tmp 2
- * %o2 = tmp 3
- * %o3 = tmp 4; whichqs; vm
- * %o4 = tmp 4; which; sswap
- * %o5 = tmp 5; q; <free>
- */
-
-/*
- * switchexit is called only from cpu_exit() before the current process
- * has freed its kernel stack; we must free it. (curproc is already NULL.)
- *
- * We lay the process to rest by changing to the `idle' kernel stack,
- * and note that the `last loaded process' is nonexistent.
- */
-ENTRY(switchexit)
- mov %o0, %g2 ! save proc for exit2() call
-
- /*
- * Change pcb to idle u. area, i.e., set %sp to top of stack
- * and %psr to PSR_S|PSR_ET, and set cpcb to point to _idle_u.
- * Once we have left the old stack, we can call kmem_free to
- * destroy it. Call it any sooner and the register windows
- * go bye-bye.
- */
- set _C_LABEL(idle_u), %g5
- sethi %hi(_C_LABEL(cpcb)), %g6
- mov 1, %g7
- wr %g0, PSR_S, %psr ! change to window 0, traps off
- wr %g0, 2, %wim ! and make window 1 the trap window
- st %g5, [%g6 + %lo(_C_LABEL(cpcb))] ! cpcb = &idle_u
- st %g7, [%g5 + PCB_WIM] ! idle_u.pcb_wim = log2(2) = 1
- set _C_LABEL(idle_u) + USPACE-CCFSZ, %sp ! set new %sp
-#ifdef DEBUG
- set _C_LABEL(idle_u), %l6
- SET_SP_REDZONE(%l6, %l5)
-#endif
- wr %g0, PSR_S|PSR_ET, %psr ! and then enable traps
- call _C_LABEL(exit2) ! exit2(p)
- mov %g2, %o0
-
- /*
- * Now fall through to `the last switch'. %g6 was set to
- * %hi(_C_LABEL(cpcb)), but may have been clobbered in kmem_free,
- * so all the registers described below will be set here.
- *
- * REGISTER USAGE AT THIS POINT:
- * %g1 = oldpsr (excluding ipl bits)
- * %g2 = %hi(_C_LABEL(whichqs))
- * %g4 = lastproc
- * %g6 = %hi(_C_LABEL(cpcb))
- * %g7 = %hi(_C_LABEL(curproc))
- * %o0 = tmp 1
- * %o1 = tmp 2
- * %o3 = whichqs
- */
-
- INCR(_C_LABEL(nswitchexit)) ! nswitchexit++;
- INCR(_C_LABEL(uvmexp)+V_SWTCH) ! cnt.v_switch++;
-
- mov PSR_S|PSR_ET, %g1 ! oldpsr = PSR_S | PSR_ET;
- sethi %hi(_C_LABEL(whichqs)), %g2
- clr %g4 ! lastproc = NULL;
+ENTRY(cpu_switchto)
sethi %hi(_C_LABEL(cpcb)), %g6
sethi %hi(_C_LABEL(curproc)), %g7
- /* FALLTHROUGH */
-
-/*
- * When no processes are on the runq, switch
- * idles here waiting for something to come ready.
- * The registers are set up as noted above.
- */
- .globl idle
-idle:
- st %g0, [%g7 + %lo(_C_LABEL(curproc))] ! curproc = NULL;
- wr %g1, 0, %psr ! (void) spl0();
-1: ! spin reading _whichqs until nonzero
- ld [%g2 + %lo(_C_LABEL(whichqs))], %o3
- tst %o3
- bnz,a Lsw_scan
- wr %g1, IPL_CLOCK << 8, %psr ! (void) splclock();
- b,a 1b
-
-Lsw_panic_rq:
- sethi %hi(1f), %o0
- call _C_LABEL(panic)
- or %lo(1f), %o0, %o0
-Lsw_panic_wchan:
- sethi %hi(2f), %o0
- call _C_LABEL(panic)
- or %lo(2f), %o0, %o0
-Lsw_panic_srun:
- sethi %hi(3f), %o0
- call _C_LABEL(panic)
- or %lo(3f), %o0, %o0
-1: .asciz "switch rq"
-2: .asciz "switch wchan"
-3: .asciz "switch SRUN"
- _ALIGN
-
-/*
- * cpu_switch() picks a process to run and runs it, saving the current
- * one away. On the assumption that (since most workstations are
- * single user machines) the chances are quite good that the new
- * process will turn out to be the current process, we defer saving
- * it here until we have found someone to load. If that someone
- * is the current process we avoid both store and load.
- *
- * cpu_switch() is always entered at splstatclock or splhigh.
- *
- * IT MIGHT BE WORTH SAVING BEFORE ENTERING idle TO AVOID HAVING TO
- * SAVE LATER WHEN SOMEONE ELSE IS READY ... MUST MEASURE!
- */
- .globl _C_LABEL(time)
-ENTRY(cpu_switch)
- /*
- * REGISTER USAGE AT THIS POINT:
- * %g1 = oldpsr (excluding ipl bits)
- * %g2 = %hi(_C_LABEL(whichqs))
- * %g3 = p
- * %g4 = lastproc
- * %g5 = tmp 0
- * %g6 = %hi(_C_LABEL(cpcb))
- * %g7 = %hi(_C_LABEL(curproc))
- * %o0 = tmp 1
- * %o1 = tmp 2
- * %o2 = tmp 3
- * %o3 = tmp 4, then at Lsw_scan, whichqs
- * %o4 = tmp 5, then at Lsw_scan, which
- * %o5 = tmp 6, then at Lsw_scan, q
- */
- sethi %hi(_C_LABEL(whichqs)), %g2 ! set up addr regs
- sethi %hi(_C_LABEL(cpcb)), %g6
- ld [%g6 + %lo(_C_LABEL(cpcb))], %o0
- std %o6, [%o0 + PCB_SP] ! cpcb->pcb_<sp,pc> = <sp,pc>;
+ ld [%g6 + %lo(_C_LABEL(cpcb))], %o2
+ std %o6, [%o2 + PCB_SP] ! cpcb->pcb_<sp,pc> = <sp,pc>;
rd %psr, %g1 ! oldpsr = %psr;
- sethi %hi(_C_LABEL(curproc)), %g7
- ld [%g7 + %lo(_C_LABEL(curproc))], %g4 ! lastproc = curproc;
- st %g1, [%o0 + PCB_PSR] ! cpcb->pcb_psr = oldpsr;
+ st %g1, [%o2 + PCB_PSR] ! cpcb->pcb_psr = oldpsr;
andn %g1, PSR_PIL, %g1 ! oldpsr &= ~PSR_PIL;
/*
- * In all the fiddling we did to get this far, the thing we are
- * waiting for might have come ready, so let interrupts in briefly
- * before checking for other processes. Note that we still have
- * curproc set---we have to fix this or we can get in trouble with
- * the run queues below.
- */
- st %g0, [%g7 + %lo(_C_LABEL(curproc))] ! curproc = NULL;
- wr %g1, 0, %psr ! (void) spl0();
- nop; nop; nop ! paranoia
- wr %g1, IPL_CLOCK << 8 , %psr ! (void) splclock();
-
-Lsw_scan:
- nop; nop; nop ! paranoia
- ld [%g2 + %lo(_C_LABEL(whichqs))], %o3
-
- /*
- * Optimized inline expansion of `which = ffs(whichqs) - 1';
- * branches to idle if ffs(whichqs) was 0.
- */
- set ffstab, %o2
- andcc %o3, 0xff, %o1 ! byte 0 zero?
- bz,a 1f ! yes, try byte 1
- srl %o3, 8, %o0
- b 2f ! ffs = ffstab[byte0]; which = ffs - 1;
- ldsb [%o2 + %o1], %o0
-1: andcc %o0, 0xff, %o1 ! byte 1 zero?
- bz,a 1f ! yes, try byte 2
- srl %o0, 8, %o0
- ldsb [%o2 + %o1], %o0 ! which = ffstab[byte1] + 7;
- b 3f
- add %o0, 7, %o4
-1: andcc %o0, 0xff, %o1 ! byte 2 zero?
- bz,a 1f ! yes, try byte 3
- srl %o0, 8, %o0
- ldsb [%o2 + %o1], %o0 ! which = ffstab[byte2] + 15;
- b 3f
- add %o0, 15, %o4
-1: ldsb [%o2 + %o0], %o0 ! ffs = ffstab[byte3] + 24
- addcc %o0, 24, %o0 ! (note that ffstab[0] == -24)
- bz idle ! if answer was 0, go idle
- EMPTY
-2: sub %o0, 1, %o4 ! which = ffs(whichqs) - 1
-3: /* end optimized inline expansion */
-
- /*
- * We found a nonempty run queue. Take its first process.
- */
- set _C_LABEL(qs), %o5 ! q = &qs[which];
- sll %o4, 3, %o0
- add %o0, %o5, %o5
- ld [%o5], %g3 ! p = q->ph_link;
- cmp %g3, %o5 ! if (p == q)
- be Lsw_panic_rq ! panic("switch rq");
- EMPTY
- ld [%g3], %o0 ! tmp0 = p->p_forw;
- st %o0, [%o5] ! q->ph_link = tmp0;
- st %o5, [%o0 + 4] ! tmp0->p_back = q;
- cmp %o0, %o5 ! if (tmp0 == q)
- bne 1f
- EMPTY
- mov 1, %o1 ! whichqs &= ~(1 << which);
- sll %o1, %o4, %o1
- andn %o3, %o1, %o3
- st %o3, [%g2 + %lo(_C_LABEL(whichqs))]
-1:
- /*
- * PHASE TWO: NEW REGISTER USAGE:
+ * REGISTER USAGE:
* %g1 = oldpsr (excluding ipl bits)
* %g2 = newpsr
- * %g3 = p
- * %g4 = lastproc
* %g5 = newpcb
* %g6 = %hi(_C_LABEL(cpcb))
* %g7 = %hi(_C_LABEL(curproc))
- * %o0 = tmp 1
- * %o1 = tmp 2
+ * %o0 = oldproc
+ * %o1 = newproc
* %o2 = tmp 3
* %o3 = vm
* %o4 = sswap
* %o5 = <free>
*/
- /* firewalls */
- ld [%g3 + P_WCHAN], %o0 ! if (p->p_wchan)
- tst %o0
- bne Lsw_panic_wchan ! panic("switch wchan");
- EMPTY
- ldsb [%g3 + P_STAT], %o0 ! if (p->p_stat != SRUN)
- cmp %o0, SRUN
- bne Lsw_panic_srun ! panic("switch SRUN");
- EMPTY
-
/*
- * Committed to running process p.
- * It may be the same as the one we were running before.
+ * Committed to running process p (in o1).
*/
+ mov %o1, %g3
+
mov SONPROC, %o0 ! p->p_stat = SONPROC
stb %o0, [%g3 + P_STAT]
sethi %hi(_C_LABEL(want_resched)), %o0
st %g0, [%o0 + %lo(_C_LABEL(want_resched))] ! want_resched = 0;
ld [%g3 + P_ADDR], %g5 ! newpcb = p->p_addr;
- st %g0, [%g3 + 4] ! p->p_back = NULL;
ld [%g5 + PCB_PSR], %g2 ! newpsr = newpcb->pcb_psr;
st %g3, [%g7 + %lo(_C_LABEL(curproc))] ! curproc = p;
- cmp %g3, %g4 ! p == lastproc?
- be,a Lsw_sameproc ! yes, go return 0
- wr %g2, 0, %psr ! (after restoring ipl)
-
/*
- * Not the old process. Save the old process, if any;
- * then load p.
+ * Save the old process, if any; then load p.
*/
- tst %g4
+ tst %o0
be,a Lsw_load ! if no old process, go load
wr %g1, (IPL_CLOCK << 8) | PSR_ET, %psr
- INCR(_C_LABEL(nswitchdiff)) ! clobbers %o0,%o1
/*
* save: write back all windows (including the current one).
* XXX crude; knows nwindows <= 8
@@ -4773,16 +4535,17 @@ Lsw_havectx:
sta %o0, [%o1] ASI_SRMMU ! setcontext(vm->vm_map.pmap->pm_ctxnum);
#endif
-Lsw_sameproc:
- /*
- * We are resuming the process that was running at the
- * call to switch(). Just set psr ipl and return.
- */
-! wr %g2, 0 %psr ! %psr = newpsr; (done earlier)
- nop
+ENTRY(cpu_idle_enter)
retl
nop
+ENTRY(cpu_idle_cycle)
+ retl
+ nop
+
+ENTRY(cpu_idle_leave)
+ retl
+ nop
/*
* Snapshot the current process so that stack frames are up to date.
diff --git a/sys/arch/sparc/sparc/locore2.c b/sys/arch/sparc/sparc/locore2.c
index f2b90ed0e4a..e69de29bb2d 100644
--- a/sys/arch/sparc/sparc/locore2.c
+++ b/sys/arch/sparc/sparc/locore2.c
@@ -1,99 +0,0 @@
-/* $OpenBSD: locore2.c,v 1.5 2003/06/02 23:27:55 millert Exp $ */
-/* $NetBSD: locore2.c,v 1.7 1996/11/06 20:19:53 cgd Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * 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. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- * @(#)locore2.c 8.4 (Berkeley) 12/10/93
- */
-
-/*
- * Primitives which are in locore.s on other machines,
- * but which have no reason to be assembly-coded on SPARC.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/resourcevar.h>
-
-#include <machine/cpu.h>
-
-int whichqs;
-
-/*
- * 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(p)
- register struct proc *p;
-{
- register struct prochd *q;
- register struct proc *oldlast;
- register int which = p->p_priority >> 2;
-
- if (p->p_back != NULL)
- panic("setrunqueue");
- q = &qs[which];
- whichqs |= 1 << which;
- 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(p)
- register struct proc *p;
-{
- register int which = p->p_priority >> 2;
- register struct prochd *q;
-
- if ((whichqs & (1 << which)) == 0)
- panic("remrunqueue");
- p->p_forw->p_back = p->p_back;
- p->p_back->p_forw = p->p_forw;
- p->p_back = NULL;
- q = &qs[which];
- if (q->ph_link == (struct proc *)q)
- whichqs &= ~(1 << which);
-}
diff --git a/sys/arch/sparc/sparc/vm_machdep.c b/sys/arch/sparc/sparc/vm_machdep.c
index 73bbdfb1b45..97f5ee4adc1 100644
--- a/sys/arch/sparc/sparc/vm_machdep.c
+++ b/sys/arch/sparc/sparc/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.49 2007/06/20 17:29:36 miod Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.50 2007/10/10 15:53:53 art Exp $ */
/* $NetBSD: vm_machdep.c,v 1.30 1997/03/10 23:55:40 pk Exp $ */
/*
@@ -449,10 +449,9 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
/*
* cpu_exit is called as the last action during exit.
*
- * We clean up a little and then call switchexit() with the old proc
- * as an argument. switchexit() switches to the idle context, schedules
- * the old vmspace and stack to be freed, then selects a new process to
- * run.
+ * We clean up a little and then call sched_exit() with the old proc
+ * as an argument. sched_exit() schedules the old vmspace and stack
+ * to be freed, then selects a new process to run.
*/
void
cpu_exit(p)
@@ -468,8 +467,8 @@ cpu_exit(p)
free((void *)fs, M_SUBPROC);
}
- switchexit(p);
- /* NOTREACHED */
+ pmap_deactivate(p);
+ sched_exit(p);
}
/*
diff --git a/sys/arch/sparc64/conf/files.sparc64 b/sys/arch/sparc64/conf/files.sparc64
index f3463fa8aa8..c9150465f13 100644
--- a/sys/arch/sparc64/conf/files.sparc64
+++ b/sys/arch/sparc64/conf/files.sparc64
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sparc64,v 1.89 2007/09/10 21:33:16 kettenis Exp $
+# $OpenBSD: files.sparc64,v 1.90 2007/10/10 15:53:53 art Exp $
# $NetBSD: files.sparc64,v 1.50 2001/08/10 20:53:50 eeh Exp $
# maxpartitions must be first item in files.${ARCH}
@@ -243,7 +243,6 @@ file arch/sparc64/sparc64/ipifuncs.c multiprocessor
file arch/sparc64/sparc64/kgdb_machdep.c kgdb
# sparc64/sparc64/locore.s is handled specially in the makefile,
# because it must come first in the "ld" command line.
-file arch/sparc64/sparc64/locore2.c
file arch/sparc64/sparc64/machdep.c
file arch/sparc64/sparc64/mem.c
file arch/sparc64/sparc64/mutex.S
diff --git a/sys/arch/sparc64/sparc64/locore.s b/sys/arch/sparc64/sparc64/locore.s
index 07767d70bc5..2456810258e 100644
--- a/sys/arch/sparc64/sparc64/locore.s
+++ b/sys/arch/sparc64/sparc64/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.83 2007/09/30 21:34:20 kettenis Exp $ */
+/* $OpenBSD: locore.s,v 1.84 2007/10/10 15:53:53 art Exp $ */
/* $NetBSD: locore.s,v 1.137 2001/08/13 06:10:10 jdolecek Exp $ */
/*
@@ -5573,350 +5573,39 @@ Lcopyfault:
retl
mov EFAULT, %o0
-
- .data
- _ALIGN
-/*
- * Switch statistics (for later tweaking):
- * nswitchdiff = p1 => p2 (i.e., chose different process)
- * nswitchexit = number of calls to switchexit()
- * _cnt.v_swtch = total calls to swtch+swtchexit
- */
- .comm _C_LABEL(nswitchdiff), 4
- .comm _C_LABEL(nswitchexit), 4
- .text
-/*
- * REGISTER USAGE IN cpu_switch AND switchexit:
- * This is split into two phases, more or less
- * `before we locate a new proc' and `after'.
- * Some values are the same in both phases.
- * Note that the %o0-registers are not preserved across
- * the psr change when entering a new process, since this
- * usually changes the CWP field (hence heavy usage of %g's).
- *
- * %l1 = <free>; newpcb
- * %l2 = %hi(_whichqs); newpsr
- * %l3 = p
- * %l4 = lastproc
- * %l5 = oldpsr (excluding ipl bits)
- * %l6 = %hi(cpcb)
- * %l7 = %hi(curproc)
- * %o0 = tmp 1
- * %o1 = tmp 2
- * %o2 = tmp 3
- * %o3 = tmp 4; whichqs; vm
- * %o4 = tmp 4; which; sswap
- * %o5 = tmp 5; q; <free>
- */
-
-/*
- * switchexit is called only from cpu_exit() before the current process
- * has freed its vmspace and kernel stack; we must schedule them to be
- * freed. (curproc is already NULL.)
- *
- * We lay the process to rest by changing to the `idle' kernel stack,
- * and note that the `last loaded process' is nonexistent.
- */
-ENTRY(switchexit)
- /*
- * Since we're exiting we don't need to save locals or ins, so
- * we won't need the next instruction.
- */
-! save %sp, -CC64FSZ, %sp
- flushw ! We don't have anything else to run, so why not
-#ifdef DEBUG
- save %sp, -CC64FSZ, %sp
- flushw
- restore
-#endif /* DEBUG */
- wrpr %g0, PSTATE_KERN, %pstate ! Make sure we're on the right globals
- mov %o0, %l2 ! save proc arg for exit2() call XXXXX
-
- /*
- * Change pcb to idle u. area, i.e., set %sp to top of stack
- * and %psr to PSR_S|PSR_ET, and set cpcb to point to _idle_u.
- * Once we have left the old stack, we can call kmem_free to
- * destroy it. Call it any sooner and the register windows
- * go bye-bye.
- */
- set _C_LABEL(idle_u), %l1
- sethi %hi(CPCB), %l6
-#if 0
- /* Get rid of the stack */
- rdpr %ver, %o0
- wrpr %g0, 0, %canrestore ! Fixup window state regs
- and %o0, 0x0f, %o0
- wrpr %g0, 0, %otherwin
- wrpr %g0, %o0, %cleanwin ! kernel don't care, but user does
- dec 1, %o0 ! What happens if we don't subtract 2?
- wrpr %g0, %o0, %cansave
- flushw ! DEBUG
-#endif /* 0 */
-
- stx %l1, [%l6 + %lo(CPCB)] ! cpcb = &idle_u
- set _C_LABEL(idle_u) + USPACE - CC64FSZ, %o0 ! set new %sp
- sub %o0, BIAS, %sp ! Maybe this should be a save?
- wrpr %g0, 0, %canrestore
- wrpr %g0, 0, %otherwin
- rdpr %ver, %l7
- and %l7, CWP, %l7
- wrpr %l7, 0, %cleanwin
- dec 1, %l7 ! NWINDOWS-1-1
- wrpr %l7, %cansave
- clr %fp ! End of stack.
-#ifdef DEBUG
- flushw ! DEBUG
- set _C_LABEL(idle_u), %l6
- SET_SP_REDZONE %l6, %l5
-#endif /* DEBUG */
- wrpr %g0, PSTATE_INTR, %pstate ! and then enable traps
- call _C_LABEL(exit2) ! exit2(p)
- mov %l2, %o0
-
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- call _C_LABEL(sched_lock_idle) ! Acquire sched_lock
-#endif /* defined(MULTIPROCESSOR) || defined(LOCKDEBUG) */
- wrpr %g0, PIL_SCHED, %pil ! Set splsched()
-
- /*
- * Now fall through to `the last switch'. %g6 was set to
- * %hi(cpcb), but may have been clobbered in kmem_free,
- * so all the registers described below will be set here.
- *
- * Since the process has exited we can blow its context
- * out of the MMUs now to free up those TLB entries rather
- * than have more useful ones replaced.
- *
- * REGISTER USAGE AT THIS POINT:
- * %l2 = %hi(_whichqs)
- * %l4 = lastproc
- * %l5 = oldpsr (excluding ipl bits)
- * %l6 = %hi(cpcb)
- * %l7 = %hi(curproc)
- * %o0 = tmp 1
- * %o1 = tmp 2
- * %o3 = whichqs
- */
-
- INCR _C_LABEL(nswitchexit) ! nswitchexit++;
- INCR _C_LABEL(uvmexp)+V_SWTCH ! cnt.v_switch++;
-
- mov CTX_SECONDARY, %o0
- sethi %hi(_C_LABEL(whichqs)), %l2
- sethi %hi(CPCB), %l6
- sethi %hi(CURPROC), %l7
- ldxa [%o0] ASI_DMMU, %l1 ! Don't demap the kernel
- ldx [%l6 + %lo(CPCB)], %l5
- clr %l4 ! lastproc = NULL;
- brz,pn %l1, 1f
- set DEMAP_CTX_SECONDARY, %l1 ! Demap secondary context
- stxa %g1, [%l1] ASI_DMMU_DEMAP
- stxa %g1, [%l1] ASI_IMMU_DEMAP
- membar #Sync
-1:
- stxa %g0, [%o0] ASI_DMMU ! Clear out our context
- membar #Sync
- /* FALLTHROUGH */
-
-/*
- * When no processes are on the runq, switch
- * idles here waiting for something to come ready.
- * The registers are set up as noted above.
- */
- .globl idle
-idle:
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- call _C_LABEL(sched_unlock_idle) ! Release sched_lock
-#endif /* defined(MULTIPROCESSOR) || defined(LOCKDEBUG) */
- stx %g0, [%l7 + %lo(CURPROC)] ! curproc = NULL;
-1: ! spin reading _whichqs until nonzero
- wrpr %g0, PSTATE_INTR, %pstate ! Make sure interrupts are enabled
- wrpr %g0, 0, %pil ! (void) spl0();
- ld [%l2 + %lo(_C_LABEL(whichqs))], %o3
- brnz,pt %o3, notidle ! Something to run
- nop
-#ifdef UVM_PAGE_IDLE_ZERO
- ! Check uvm.page_idle_zero
- sethi %hi(_C_LABEL(uvm) + UVM_PAGE_IDLE_ZERO), %o3
- ld [%o3 + %lo(_C_LABEL(uvm) + UVM_PAGE_IDLE_ZERO)], %o3
- brz,pn %o3, 1b
- nop
-
- ! zero some pages
- call _C_LABEL(uvm_pageidlezero)
- nop
-#endif /* UVM_PAGE_IDLE_ZERO */
- ba,a,pt %xcc, 1b
- nop ! spitfire bug
-notidle:
- wrpr %g0, PIL_SCHED, %pil ! (void) splhigh();
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- call _C_LABEL(sched_lock_idle) ! Grab sched_lock
- add %o7, (Lsw_scan-.-4), %o7 ! Return to Lsw_scan directly
-#endif /* defined(MULTIPROCESSOR) || defined(LOCKDEBUG) */
- ba,a,pt %xcc, Lsw_scan
- nop ! spitfire bug
-
-Lsw_panic_rq:
- sethi %hi(1f), %o0
- call _C_LABEL(panic)
- or %lo(1f), %o0, %o0
Lsw_panic_wchan:
- sethi %hi(2f), %o0
- call _C_LABEL(panic)
- or %lo(2f), %o0, %o0
+ sethi %hi(1f), %o0
+ call _C_LABEL(panic)
+ or %lo(1f), %o0, %o0
Lsw_panic_srun:
- sethi %hi(3f), %o0
- call _C_LABEL(panic)
- or %lo(3f), %o0, %o0
- .data
-1: .asciz "switch rq"
-2: .asciz "switch wchan"
-3: .asciz "switch SRUN"
-idlemsg: .asciz "idle %x %x %x %x"
-idlemsg1: .asciz " %x %x %x\r\n"
- _ALIGN
+ sethi %hi(2f), %o0
+ call _C_LABEL(panic)
+ or %lo(2f), %o0, %o0
+ .data
+1: .asciz "switch wchan"
+2: .asciz "switch SRUN"
+
.text
/*
- * cpu_switch() picks a process to run and runs it, saving the current
- * one away. On the assumption that (since most workstations are
- * single user machines) the chances are quite good that the new
- * process will turn out to be the current process, we defer saving
- * it here until we have found someone to load. If that someone
- * is the current process we avoid both store and load.
+ * cpu_switchto(struct proc *old, struct proc *new)
*
- * cpu_switch() is always entered at splstatclock or splhigh.
- *
- * IT MIGHT BE WORTH SAVING BEFORE ENTERING idle TO AVOID HAVING TO
- * SAVE LATER WHEN SOMEONE ELSE IS READY ... MUST MEASURE!
- *
- * Apparently cpu_switch() is called with curproc as the first argument,
- * but no port seems to make use of that parameter.
+ * Save the context of "old" and switch to "new".
*/
- .globl _C_LABEL(time)
-ENTRY(cpu_switch)
+ENTRY(cpu_switchto)
save %sp, -CC64FSZ, %sp
- /*
- * REGISTER USAGE AT THIS POINT:
- * %l1 = tmp 0
- * %l2 = %hi(_C_LABEL(whichqs))
- * %l3 = p
- * %l4 = lastproc
- * %l5 = cpcb
- * %l6 = %hi(CPCB)
- * %l7 = %hi(CURPROC)
- * %o0 = tmp 1
- * %o1 = tmp 2
- * %o2 = tmp 3
- * %o3 = tmp 4, then at Lsw_scan, whichqs
- * %o4 = tmp 5, then at Lsw_scan, which
- * %o5 = tmp 6, then at Lsw_scan, q
- */
-#ifdef DEBUG
- set swdebug, %o1
- ld [%o1], %o1
- brz,pt %o1, 2f
- set 1f, %o0
- call printf
- nop
- .data
-1: .asciz "s"
- _ALIGN
- .globl swdebug
-swdebug: .word 0
- .text
-2:
-#endif /* DEBUG */
flushw ! We don't have anything else to run, so why not flush
-#ifdef DEBUG
- save %sp, -CC64FSZ, %sp
- flushw
- restore
-#endif /* DEBUG */
rdpr %pstate, %o1 ! oldpstate = %pstate;
wrpr %g0, PSTATE_INTR, %pstate ! make sure we're on normal globals
+
+ mov %i0, %l4 ! oldproc
+ mov %i1, %l3 ! newproc
+
sethi %hi(CPCB), %l6
- sethi %hi(_C_LABEL(whichqs)), %l2 ! set up addr regs
ldx [%l6 + %lo(CPCB)], %l5
- sethi %hi(CURPROC), %l7
+ sethi %hi(CURPROC), %l7
stx %o7, [%l5 + PCB_PC] ! cpcb->pcb_pc = pc;
- ldx [%l7 + %lo(CURPROC)], %l4 ! lastproc = curproc;
sth %o1, [%l5 + PCB_PSTATE] ! cpcb->pcb_pstate = oldpstate;
- stx %g0, [%l7 + %lo(CURPROC)] ! curproc = NULL;
-
-Lsw_scan:
- ld [%l2 + %lo(_C_LABEL(whichqs))], %o3
-
-#ifndef POPC
- .globl _C_LABEL(__ffstab)
- /*
- * Optimized inline expansion of `which = ffs(whichqs) - 1';
- * branches to idle if ffs(whichqs) was 0.
- */
- set _C_LABEL(__ffstab), %o2
- andcc %o3, 0xff, %o1 ! byte 0 zero?
- bz,a,pn %icc, 1f ! yes, try byte 1
- srl %o3, 8, %o0
- ba,pt %icc, 2f ! ffs = ffstab[byte0]; which = ffs - 1;
- ldsb [%o2 + %o1], %o0
-1: andcc %o0, 0xff, %o1 ! byte 1 zero?
- bz,a,pn %icc, 1f ! yes, try byte 2
- srl %o0, 8, %o0
- ldsb [%o2 + %o1], %o0 ! which = ffstab[byte1] + 7;
- ba,pt %icc, 3f
- add %o0, 7, %o4
-1: andcc %o0, 0xff, %o1 ! byte 2 zero?
- bz,a,pn %icc, 1f ! yes, try byte 3
- srl %o0, 8, %o0
- ldsb [%o2 + %o1], %o0 ! which = ffstab[byte2] + 15;
- ba,pt %icc, 3f
- add %o0, 15, %o4
-1: ldsb [%o2 + %o0], %o0 ! ffs = ffstab[byte3] + 24
- addcc %o0, 24, %o0 ! (note that ffstab[0] == -24)
- bz,pn %icc, idle ! if answer was 0, go idle
-! XXX check no delay slot
-2: sub %o0, 1, %o4
-3: /* end optimized inline expansion */
-
-#else /* POPC */
- /*
- * Optimized inline expansion of `which = ffs(whichqs) - 1';
- * branches to idle if ffs(whichqs) was 0.
- *
- * This version uses popc.
- *
- * XXXX spitfires and blackbirds don't implement popc.
- *
- */
- brz,pn %o3, idle ! Don't bother if queues are empty
- neg %o3, %o1 ! %o1 = -zz
- xnor %o3, %o1, %o2 ! %o2 = zz ^ ~ -zz
- popc %o2, %o4 ! which = popc(whichqs)
- dec %o4 ! which = ffs(whichqs) - 1
-
-#endif /* POPC */
- /*
- * We found a nonempty run queue. Take its first process.
- */
- set _C_LABEL(qs), %o5 ! q = &qs[which];
- sll %o4, 3+1, %o0
- add %o0, %o5, %o5
- ldx [%o5], %l3 ! p = q->ph_link;
- cmp %l3, %o5 ! if (p == q)
- be,pn %icc, Lsw_panic_rq ! panic("switch rq");
-! XXX check no delay slot
- ldx [%l3], %o0 ! tmp0 = p->p_forw;
- stx %o0, [%o5] ! q->ph_link = tmp0;
- stx %o5, [%o0 + 8] ! tmp0->p_back = q;
- cmp %o0, %o5 ! if (tmp0 == q)
- bne 1f
-! XXX check no delay slot
- mov 1, %o1 ! whichqs &= ~(1 << which);
- sll %o1, %o4, %o1
- andn %o3, %o1, %o3
- st %o3, [%l2 + %lo(_C_LABEL(whichqs))]
-1:
/*
* PHASE TWO: NEW REGISTER USAGE:
* %l1 = newpcb
@@ -5945,7 +5634,6 @@ Lsw_scan:
/*
* Committed to running process p.
- * It may be the same as the one we were running before.
*/
#if defined(MULTIPROCESSOR)
/*
@@ -5958,19 +5646,7 @@ Lsw_scan:
sethi %hi(CPUINFO_VA+CI_WANT_RESCHED), %o0
st %g0, [%o0 + %lo(CPUINFO_VA+CI_WANT_RESCHED)] ! want_resched = 0;
ldx [%l3 + P_ADDR], %l1 ! newpcb = p->p_addr;
- stx %g0, [%l3 + 8] ! p->p_back = NULL;
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- /*
- * Done mucking with the run queues, release the
- * scheduler lock, but keep interrupts out.
- */
- call _C_LABEL(sched_unlock_idle)
-#endif /* defined(MULTIPROCESSOR) || defined(LOCKDEBUG) */
- stx %l4, [%l7 + %lo(CURPROC)] ! restore old proc so we can save it
-
- cmp %l3, %l4 ! p == lastproc?
- be,pt %xcc, Lsw_sameproc ! yes, go return 0
- nop
+ stx %l4, [%l7 + %lo(CURPROC)] ! restore old proc so we can save it
/*
* Not the old process. Save the old process, if any;
@@ -5980,7 +5656,6 @@ Lsw_scan:
brz,pn %l4, Lsw_load ! if no old process, go load
wrpr %g0, PSTATE_KERN, %pstate
- INCR _C_LABEL(nswitchdiff) ! clobbers %o0,%o1,%o2
wb1:
flushw ! save all register windows except this one
stx %i7, [%l5 + PCB_PC] ! Save rpc
@@ -6060,11 +5735,6 @@ Lsw_havectx:
membar #Sync ! Maybe we should use flush here?
flush %sp
-Lsw_sameproc:
- /*
- * We are resuming the process that was running at the
- * call to switch(). Just set psr ipl and return.
- */
! wrpr %g0, 0, %cleanwin ! DEBUG
clr %g4 ! This needs to point to the base of the data segment
wr %g0, ASI_PRIMARY_NOFAULT, %asi ! Restore default ASI
@@ -6072,6 +5742,18 @@ Lsw_sameproc:
ret
restore
+ENTRY(cpu_idle_enter)
+ retl
+ nop
+
+ENTRY(cpu_idle_cycle)
+ retl
+ nop
+
+ENTRY(cpu_idle_leave)
+ retl
+ nop
+
/*
* Snapshot the current process so that stack frames are up to date.
* Only used just before a crash dump.
diff --git a/sys/arch/sparc64/sparc64/vm_machdep.c b/sys/arch/sparc64/sparc64/vm_machdep.c
index 5d46c9eb715..88ba247878a 100644
--- a/sys/arch/sparc64/sparc64/vm_machdep.c
+++ b/sys/arch/sparc64/sparc64/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.15 2007/06/20 17:29:36 miod Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.16 2007/10/10 15:53:53 art Exp $ */
/* $NetBSD: vm_machdep.c,v 1.38 2001/06/30 00:02:20 eeh Exp $ */
/*
@@ -316,8 +316,7 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
* run.
*/
void
-cpu_exit(p)
- struct proc *p;
+cpu_exit(struct proc *p)
{
register struct fpstate64 *fs;
@@ -328,8 +327,9 @@ cpu_exit(p)
}
free((void *)fs, M_SUBPROC);
}
- switchexit(p);
- /* NOTREACHED */
+
+ pmap_deactivate(p);
+ sched_exit(p);
}
/*
diff --git a/sys/arch/vax/include/cpu.h b/sys/arch/vax/include/cpu.h
index 80b05d5d185..dc6ec203a16 100644
--- a/sys/arch/vax/include/cpu.h
+++ b/sys/arch/vax/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.25 2007/05/16 05:19:13 miod Exp $ */
+/* $OpenBSD: cpu.h,v 1.26 2007/10/10 15:53:53 art Exp $ */
/* $NetBSD: cpu.h,v 1.41 1999/10/21 20:01:36 ragge Exp $ */
/*
@@ -129,6 +129,10 @@ extern int want_resched; /* resched() was called */
*/
#define need_proftick(p) mtpr(AST_OK,PR_ASTLVL)
+#define cpu_idle_enter() do { /* nothing */ } while (0)
+#define cpu_idle_cycle() do { /* nothing */ } while (0)
+#define cpu_idle_leave() do { /* nothing */ } while (0)
+
/*
* This defines the I/O device register space size in pages.
*/
diff --git a/sys/arch/vax/include/macros.h b/sys/arch/vax/include/macros.h
index 0c514ff5aa7..87bd942c43a 100644
--- a/sys/arch/vax/include/macros.h
+++ b/sys/arch/vax/include/macros.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: macros.h,v 1.14 2006/11/06 21:31:36 miod Exp $ */
+/* $OpenBSD: macros.h,v 1.15 2007/10/10 15:53:53 art Exp $ */
/* $NetBSD: macros.h,v 1.20 2000/07/19 01:02:52 matt Exp $ */
/*
@@ -232,15 +232,10 @@ skpc(int mask, size_t size, u_char *cp)
return ret;
}
-#define setrunqueue(p) \
- __asm__ __volatile("movl %0,r0;jsb Setrq":: "g"(p):"r0","r1","r2");
-
-#define remrunqueue(p) \
- __asm__ __volatile("movl %0,r0;jsb Remrq":: "g"(p):"r0","r1","r2");
-
-#define cpu_switch(p) \
- __asm__ __volatile("movl %0,r0;movpsl -(sp);jsb Swtch" \
- ::"g"(p):"r0","r1","r2","r3");
+#define cpu_switchto(o, n) \
+ __asm__ __volatile__( \
+ "movl %0,r0; movl %1, r1; movpsl -(sp); jsb __cpu_switchto" \
+ :: "g"(o), "g"(n) : "r0", "r1");
/*
* Interlock instructions. Used both in multiprocessor environments to
diff --git a/sys/arch/vax/vax/subr.s b/sys/arch/vax/vax/subr.s
index 6c669bd47af..b0ca031e3d2 100644
--- a/sys/arch/vax/vax/subr.s
+++ b/sys/arch/vax/vax/subr.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr.s,v 1.26 2007/05/16 05:19:15 miod Exp $ */
+/* $OpenBSD: subr.s,v 1.27 2007/10/10 15:53:53 art Exp $ */
/* $NetBSD: subr.s,v 1.32 1999/03/25 00:41:48 mrg Exp $ */
/*
@@ -240,114 +240,37 @@ ENTRY(longjmp, 0)
#endif
#
-# setrunqueue/remrunqueue fast variants.
+# void
+# cpu_switchto(struct proc *oldproc = r0, struct proc *newproc = r1);
#
-JSBENTRY(Setrq)
-#ifdef DIAGNOSTIC
- tstl 4(r0) # Check that process actually are off the queue
- beql 1f
- pushab setrq
- calls $1,_panic
-setrq: .asciz "setrunqueue"
-#endif
-1: extzv $2,$6,P_PRIORITY(r0),r1 # get priority
- movaq _qs[r1],r2 # get address of queue
- insque (r0),*4(r2) # put proc last in queue
- bbss r1,_whichqs,1f # set queue bit.
-1: rsb
-
-JSBENTRY(Remrq)
- extzv $2,$6,P_PRIORITY(r0),r1
-#ifdef DIAGNOSTIC
- bbs r1,_whichqs,1f
- pushab remrq
- calls $1,_panic
-remrq: .asciz "remrunqueue"
-#endif
-1: remque (r0),r2
- bneq 1f # Not last process on queue
- bbsc r1,_whichqs,1f
-1: clrl 4(r0) # saftey belt
- rsb
-
-#
-# Idle loop. Here we could do something fun, maybe, like calculating
-# pi or something.
-#
-idle: mtpr $0,$PR_IPL # Enable all types of interrupts
-1: tstl _whichqs # Anything ready to run?
- beql 1b # no, continue to loop
- brb Swtch # Yes, goto switch again.
+#define CURPROC _cpu_info_store + CI_CURPROC
-#
-# cpu_switch, cpu_exit and the idle loop implemented in assembler
-# for efficiency. r0 contains pointer to last process.
-#
+JSBENTRY(__cpu_switchto)
+ svpctx
-#define CURPROC _cpu_info_store + CI_CURPROC
+ movb $SONPROC,P_STAT(r1) # p->p_stat = SONPROC
+ movl r1, CURPROC # set new process running
-JSBENTRY(Swtch)
- clrl CURPROC # Stop process accounting
-#bpt
- mtpr $0x1f,$PR_IPL # block all interrupts
- ffs $0,$32,_whichqs,r3 # Search for bit set
- beql idle # no bit set, go to idle loop
-
- movaq _qs[r3],r1 # get address of queue head
- remque *(r1),r2 # remove proc pointed to by queue head
-#ifdef DIAGNOSTIC
- bvc 1f # check if something on queue
- pushab noque
- calls $1,_panic
-noque: .asciz "swtch"
-#endif
-1: bneq 2f # more processes on queue?
- bbsc r3,_whichqs,2f # no, clear bit in whichqs
-2: clrl 4(r2) # clear proc backpointer
- clrl _want_resched # we are now changing process
- movb $SONPROC,P_STAT(r2) # p->p_stat = SONPROC
- movl r2,CURPROC # set new process running
- cmpl r0,r2 # Same process?
- bneq 1f # No, continue
- rsb
-xxd:
-1: movl P_ADDR(r2),r0 # Get pointer to new pcb.
+ movl P_ADDR(r1),r0 # Get pointer to new pcb.
addl3 r0,$IFTRAP,pcbtrap # Save for copy* functions.
-#
-# Nice routine to get physical from virtual addresses.
-#
+ # inline kvtophys
extzv $9,$21,r0,r1 # extract offset
movl *_Sysmap[r1],r2 # get pte
ashl $9,r2,r3 # shift to get phys address.
#
# Do the actual process switch. pc + psl are already on stack, from
-# the calling routine.
+# the beginning of this routine.
#
- svpctx
mtpr r3,$PR_PCBB
- ldpctx
- rei
-
-#
-# the last routine called by a process.
-#
-
-ENTRY(cpu_exit,0)
- movl 4(ap),r6 # Process pointer in r6
- mtpr $0x18,$PR_IPL # Block almost everything
- addl3 $512,_scratch,sp # Change stack, and schedule it to be freed
- pushl r6
- calls $1,_exit2
-
- clrl r0 # No process to switch from
- bicl3 $0xc0000000,_scratch,r1
- mtpr r1,$PR_PCBB
- brw Swtch
+ pushl CURPROC
+ calls $1, _C_LABEL(pmap_activate)
+ ldpctx
+ rei
#
# copy/fetch/store routines.
diff --git a/sys/arch/vax/vax/vm_machdep.c b/sys/arch/vax/vax/vm_machdep.c
index 7205101225d..603bb17e3d3 100644
--- a/sys/arch/vax/vax/vm_machdep.c
+++ b/sys/arch/vax/vax/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.34 2007/06/20 17:29:36 miod Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.35 2007/10/10 15:53:53 art Exp $ */
/* $NetBSD: vm_machdep.c,v 1.67 2000/06/29 07:14:34 mrg Exp $ */
/*
@@ -58,6 +58,16 @@
#include <sys/syscallargs.h>
+void
+cpu_exit(struct proc *p)
+{
+ int s;
+ s = splhigh(); /* splclock(); */
+
+ pmap_deactivate(p);
+ sched_exit(p);
+}
+
/*
* Finish a fork operation, with process p2 nearly set up.
* Copy and update the pcb and trap frame, making the child ready to run.
@@ -110,13 +120,6 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
p2->p_addr->u_pcb.framep = tf;
bcopy(p1->p_addr->u_pcb.framep, tf, sizeof(*tf));
- /*
- * Activate address space for the new process. The PTEs have
- * already been allocated by way of pmap_create().
- * This writes the page table registers to the PCB.
- */
- pmap_activate(p2);
-
/* Mark guard page invalid in kernel stack */
*kvtopte((u_int)p2->p_addr + REDZONEADDR) &= ~PG_V;
diff --git a/sys/conf/files b/sys/conf/files
index 2ab1b985dde..8487299b53d 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1,4 +1,4 @@
-# $OpenBSD: files,v 1.410 2007/09/12 12:59:55 mglocker Exp $
+# $OpenBSD: files,v 1.411 2007/10/10 15:53:53 art Exp $
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@@ -645,6 +645,7 @@ file kern/kern_physio.c
file kern/kern_proc.c
file kern/kern_prot.c
file kern/kern_resource.c
+file kern/kern_sched.c
file kern/kern_sensors.c !small_kernel
file kern/kern_sig.c
file kern/kern_subr.c
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index e3047847f8f..98c75f5e618 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: init_main.c,v 1.144 2007/09/10 18:49:45 miod Exp $ */
+/* $OpenBSD: init_main.c,v 1.145 2007/10/10 15:53:53 art Exp $ */
/* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */
/*
@@ -327,7 +327,9 @@ main(void *framep)
(void)chgproccnt(0, 1);
/* Initialize run queues */
- rqinit();
+ sched_init_runqueues();
+ sleep_queue_init();
+ sched_init_cpu(curcpu());
/* Initialize work queues */
workq_init();
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index f4e18101952..27c7bb79b74 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_clock.c,v 1.64 2007/05/16 17:27:30 art Exp $ */
+/* $OpenBSD: kern_clock.c,v 1.65 2007/10/10 15:53:53 art Exp $ */
/* $NetBSD: kern_clock.c,v 1.34 1996/06/09 04:51:03 briggs Exp $ */
/*-
@@ -546,7 +546,7 @@ statclock(struct clockframe *frame)
if (p != NULL)
p->p_iticks++;
spc->spc_cp_time[CP_INTR]++;
- } else if (p != NULL) {
+ } else if (p != NULL && p != spc->spc_idleproc) {
p->p_sticks++;
spc->spc_cp_time[CP_SYS]++;
} else
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 4c85dd84543..fa68a37f72a 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_exit.c,v 1.71 2007/04/12 22:14:15 tedu Exp $ */
+/* $OpenBSD: kern_exit.c,v 1.72 2007/10/10 15:53:53 art Exp $ */
/* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */
/*
@@ -315,16 +315,8 @@ exit1(struct proc *p, int rv, int flags)
sigactsfree(p);
/*
- * Clear curproc after we've done all operations
- * that could block, and before tearing down the rest
- * of the process state that might be used from clock, etc.
- * Also, can't clear curproc while we're still runnable,
- * as we're not on a run queue (we are current, just not
- * a proper proc any longer!).
- *
- * Other substructures are freed from wait().
+ * Other substructures are freed from reaper and wait().
*/
- curproc = NULL;
/*
* If emulation has process exit hook, call it now.
@@ -373,15 +365,11 @@ struct proclist deadproc = LIST_HEAD_INITIALIZER(deadproc);
void
exit2(struct proc *p)
{
- int s;
-
mtx_enter(&deadproc_mutex);
LIST_INSERT_HEAD(&deadproc, p, p_hash);
mtx_leave(&deadproc_mutex);
wakeup(&deadproc);
-
- SCHED_LOCK(s);
}
/*
@@ -396,6 +384,8 @@ reaper(void)
KERNEL_PROC_UNLOCK(curproc);
+ SCHED_ASSERT_UNLOCKED();
+
for (;;) {
mtx_enter(&deadproc_mutex);
p = LIST_FIRST(&deadproc);
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index d54932106d7..8a048fd5f65 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_fork.c,v 1.92 2007/07/25 23:11:52 art Exp $ */
+/* $OpenBSD: kern_fork.c,v 1.93 2007/10/10 15:53:53 art Exp $ */
/* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */
/*
@@ -224,7 +224,6 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize,
p2->p_stat = SIDL; /* protect against others */
p2->p_exitsig = exitsig;
- p2->p_forw = p2->p_back = NULL;
#ifdef RTHREADS
if (flags & FORK_THREAD) {
@@ -501,7 +500,12 @@ proc_trampoline_mp(void)
p = curproc;
+ SCHED_ASSERT_LOCKED();
+ __mp_unlock(&sched_lock);
+ spl0();
SCHED_ASSERT_UNLOCKED();
+ KASSERT(__mp_lock_held(&kernel_lock) == 0);
+
KERNEL_PROC_LOCK(p);
}
#endif
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index ef16630f108..66d8a8bb5ac 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_proc.c,v 1.35 2007/09/07 15:00:20 art Exp $ */
+/* $OpenBSD: kern_proc.c,v 1.36 2007/10/10 15:53:53 art Exp $ */
/* $NetBSD: kern_proc.c,v 1.14 1996/02/09 18:59:41 christos Exp $ */
/*
@@ -377,8 +377,8 @@ proc_printit(struct proc *p, const char *modif, int (*pr)(const char *, ...))
p->p_comm, p->p_pid, pst, p->p_flag, P_BITS);
(*pr)(" pri=%u, usrpri=%u, nice=%d\n",
p->p_priority, p->p_usrpri, p->p_nice);
- (*pr)(" forw=%p, back=%p, list=%p,%p\n",
- p->p_forw, p->p_back, p->p_list.le_next, p->p_list.le_prev);
+ (*pr)(" forw=%p, list=%p,%p\n",
+ TAILQ_NEXT(p, p_runq), p->p_list.le_next, p->p_list.le_prev);
(*pr)(" user=%p, vmspace=%p\n",
p->p_addr, p->p_vmspace);
(*pr)(" estcpu=%u, cpticks=%d, pctcpu=%u.%u%, swtime=%u\n",
diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c
new file mode 100644
index 00000000000..83c7240c739
--- /dev/null
+++ b/sys/kern/kern_sched.c
@@ -0,0 +1,242 @@
+/* $OpenBSD: kern_sched.c,v 1.1 2007/10/10 15:53:53 art Exp $ */
+/*
+ * Copyright (c) 2007 Artur Grabowski <art@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+
+#include <sys/sched.h>
+#include <sys/proc.h>
+#include <sys/kthread.h>
+#include <sys/systm.h>
+#include <sys/resourcevar.h>
+#include <sys/signalvar.h>
+#include <sys/mutex.h>
+
+#include <uvm/uvm_extern.h>
+
+struct proc *sched_chooseproc(void);
+void sched_kthreads_create(void *);
+void sched_idle(void *);
+
+/*
+ * A few notes about cpu_switchto that is implemented in MD code.
+ *
+ * cpu_switchto takes two arguments, the old proc and the proc
+ * it should switch to. The new proc will never be NULL, so we always have
+ * a saved state that we need to switch to. The old proc however can
+ * be NULL if the process is exiting. NULL for the old proc simply
+ * means "don't bother saving old state".
+ *
+ * cpu_switchto is supposed to atomically load the new state of the process
+ * including the pcb, pmap and setting curproc, the p_cpu pointer in the
+ * proc and p_stat to SONPROC. Atomically with respect to interrupts, other
+ * cpus in the system must not depend on this state being consistent.
+ * Therefore no locking is necessary in cpu_switchto other than blocking
+ * interrupts during the context switch.
+ */
+
+/*
+ * sched_init_cpu is called from main() for the boot cpu, then it's the
+ * responsibility of the MD code to call it for all other cpus.
+ */
+void
+sched_init_cpu(struct cpu_info *ci)
+{
+ struct schedstate_percpu *spc = &ci->ci_schedstate;
+
+ spc->spc_idleproc = NULL;
+
+ kthread_create_deferred(sched_kthreads_create, ci);
+
+ LIST_INIT(&spc->spc_deadproc);
+}
+
+void
+sched_kthreads_create(void *v)
+{
+ struct cpu_info *ci = v;
+ struct schedstate_percpu *spc = &ci->ci_schedstate;
+ static int num;
+
+ if (kthread_create(sched_idle, ci, &spc->spc_idleproc, "idle%d", num))
+ panic("fork idle");
+
+ num++;
+}
+
+void
+sched_idle(void *v)
+{
+ struct proc *p = curproc;
+ struct cpu_info *ci = v;
+ int s;
+
+ KERNEL_PROC_UNLOCK(p);
+
+ /*
+ * First time we enter here, we're not supposed to idle,
+ * just go away for a while.
+ */
+ SCHED_LOCK(s);
+ p->p_stat = SSLEEP;
+ mi_switch();
+ SCHED_UNLOCK(s);
+
+ while (1) {
+ KASSERT(ci == curcpu());
+ KASSERT(curproc == ci->ci_schedstate.spc_idleproc);
+
+ while (!sched_is_idle()) {
+ struct schedstate_percpu *spc = &ci->ci_schedstate;
+ struct proc *dead;
+
+ SCHED_LOCK(s);
+ p->p_stat = SSLEEP;
+ mi_switch();
+ SCHED_UNLOCK(s);
+
+ while ((dead = LIST_FIRST(&spc->spc_deadproc))) {
+ LIST_REMOVE(dead, p_hash);
+ exit2(dead);
+ }
+ }
+
+ cpu_idle_enter();
+ while (sched_is_idle())
+ cpu_idle_cycle();
+ cpu_idle_leave();
+ }
+}
+
+/*
+ * To free our address space we have to jump through a few hoops.
+ * The freeing is done by the reaper, but until we have one reaper
+ * per cpu, we have no way of putting this proc on the deadproc list
+ * and waking up the reaper without risking having our address space and
+ * stack torn from under us before we manage to switch to another proc.
+ * Therefore we have a per-cpu list of dead processes where we put this
+ * proc and have idle clean up that list and move it to the reaper list.
+ * All this will be unnecessary once we can bind the reaper this cpu
+ * and not risk having it switch to another in case it sleeps.
+ */
+void
+sched_exit(struct proc *p)
+{
+ struct schedstate_percpu *spc = &curcpu()->ci_schedstate;
+ struct timeval tv;
+ struct proc *idle;
+ int s;
+
+ microuptime(&tv);
+ timersub(&tv, &spc->spc_runtime, &tv);
+ timeradd(&p->p_rtime, &tv, &p->p_rtime);
+
+ LIST_INSERT_HEAD(&spc->spc_deadproc, p, p_hash);
+
+#ifdef MULTIPROCESSOR
+ KASSERT(__mp_lock_held(&kernel_lock) == 0);
+#endif
+
+ SCHED_LOCK(s);
+ idle = spc->spc_idleproc;
+ idle->p_stat = SRUN;
+ cpu_switchto(NULL, idle);
+}
+
+/*
+ * Run queue management.
+ *
+ * The run queue management is just like before, except that it's with
+ * a bit more modern queue handling.
+ */
+
+TAILQ_HEAD(prochead, proc) sched_qs[NQS];
+volatile int sched_whichqs;
+
+void
+sched_init_runqueues(void)
+{
+ int i;
+
+ for (i = 0; i < NQS; i++)
+ TAILQ_INIT(&sched_qs[i]);
+
+#ifdef MULTIPROCESSOR
+ SIMPLE_LOCK_INIT(&sched_lock);
+#endif
+}
+
+void
+setrunqueue(struct proc *p)
+{
+ int queue = p->p_priority >> 2;
+
+ SCHED_ASSERT_LOCKED();
+
+ TAILQ_INSERT_TAIL(&sched_qs[queue], p, p_runq);
+ sched_whichqs |= (1 << queue);
+}
+
+void
+remrunqueue(struct proc *p)
+{
+ int queue = p->p_priority >> 2;
+
+ SCHED_ASSERT_LOCKED();
+
+ TAILQ_REMOVE(&sched_qs[queue], p, p_runq);
+ if (TAILQ_EMPTY(&sched_qs[queue]))
+ sched_whichqs &= ~(1 << queue);
+}
+
+struct proc *
+sched_chooseproc(void)
+{
+ struct proc *p;
+ int queue;
+
+ SCHED_ASSERT_LOCKED();
+
+again:
+ if (sched_whichqs == 0) {
+ p = curcpu()->ci_schedstate.spc_idleproc;
+ if (p == NULL) {
+ int s;
+ /*
+ * We get here if someone decides to switch during
+ * boot before forking kthreads, bleh.
+ * This is kind of like a stupid idle loop.
+ */
+#ifdef MULTIPROCESSOR
+ __mp_unlock(&sched_lock);
+#endif
+ spl0();
+ delay(10);
+ SCHED_LOCK(s);
+ goto again;
+ }
+ KASSERT(p);
+ p->p_stat = SRUN;
+ } else {
+ queue = ffs(sched_whichqs) - 1;
+ p = TAILQ_FIRST(&sched_qs[queue]);
+ TAILQ_REMOVE(&sched_qs[queue], p, p_runq);
+ if (TAILQ_EMPTY(&sched_qs[queue]))
+ sched_whichqs &= ~(1 << queue);
+ }
+
+ return (p);
+}
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 849dffefc57..8cd4a4285e1 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_synch.c,v 1.80 2007/05/16 17:27:30 art Exp $ */
+/* $OpenBSD: kern_synch.c,v 1.81 2007/10/10 15:53:53 art Exp $ */
/* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
/*
@@ -67,10 +67,17 @@ void endtsleep(void *);
*/
#define TABLESIZE 128
#define LOOKUP(x) (((long)(x) >> 8) & (TABLESIZE - 1))
-struct slpque {
- struct proc *sq_head;
- struct proc **sq_tailp;
-} slpque[TABLESIZE];
+TAILQ_HEAD(slpque,proc) slpque[TABLESIZE];
+
+void
+sleep_queue_init(void)
+{
+ int i;
+
+ for (i = 0; i < TABLESIZE; i++)
+ TAILQ_INIT(&slpque[i]);
+}
+
/*
* During autoconfiguration or after a panic, a sleep will simply
@@ -133,15 +140,12 @@ void
sleep_setup(struct sleep_state *sls, void *ident, int prio, const char *wmesg)
{
struct proc *p = curproc;
- struct slpque *qp;
#ifdef DIAGNOSTIC
if (ident == NULL)
panic("tsleep: no ident");
if (p->p_stat != SONPROC)
panic("tsleep: not SONPROC");
- if (p->p_back != NULL)
- panic("tsleep: p_back not NULL");
#endif
#ifdef KTRACE
@@ -159,12 +163,7 @@ sleep_setup(struct sleep_state *sls, void *ident, int prio, const char *wmesg)
p->p_wmesg = wmesg;
p->p_slptime = 0;
p->p_priority = prio & PRIMASK;
- qp = &slpque[LOOKUP(ident)];
- if (qp->sq_head == 0)
- qp->sq_head = p;
- else
- *qp->sq_tailp = p;
- *(qp->sq_tailp = &p->p_forw) = NULL;
+ TAILQ_INSERT_TAIL(&slpque[LOOKUP(ident)], p, p_runq);
}
void
@@ -179,11 +178,12 @@ sleep_finish(struct sleep_state *sls, int do_sleep)
mi_switch();
} else if (!do_sleep) {
unsleep(p);
+ }
+
#ifdef DIAGNOSTIC
- if (p->p_stat != SONPROC)
- panic("sleep_finish !SONPROC");
+ if (p->p_stat != SONPROC)
+ panic("sleep_finish !SONPROC");
#endif
- }
p->p_cpu->ci_schedstate.spc_curpriority = p->p_usrpri;
SCHED_UNLOCK(sls->sls_s);
@@ -296,17 +296,9 @@ endtsleep(void *arg)
void
unsleep(struct proc *p)
{
- struct slpque *qp;
- struct proc **hp;
-
if (p->p_wchan) {
- hp = &(qp = &slpque[LOOKUP(p->p_wchan)])->sq_head;
- while (*hp != p)
- hp = &(*hp)->p_forw;
- *hp = p->p_forw;
- if (qp->sq_tailp == &p->p_forw)
- qp->sq_tailp = hp;
- p->p_wchan = 0;
+ TAILQ_REMOVE(&slpque[LOOKUP(p->p_wchan)], p, p_runq);
+ p->p_wchan = NULL;
}
}
@@ -317,25 +309,22 @@ void
wakeup_n(void *ident, int n)
{
struct slpque *qp;
- struct proc *p, **q;
+ struct proc *p;
+ struct proc *pnext;
int s;
SCHED_LOCK(s);
qp = &slpque[LOOKUP(ident)];
-restart:
- for (q = &qp->sq_head; (p = *q) != NULL; ) {
+ for (p = TAILQ_FIRST(qp); p != NULL && n != 0; p = pnext) {
+ pnext = TAILQ_NEXT(p, p_runq);
#ifdef DIAGNOSTIC
- if (p->p_back)
- panic("wakeup: p_back not NULL");
if (p->p_stat != SSLEEP && p->p_stat != SSTOP)
panic("wakeup: p_stat is %d", (int)p->p_stat);
#endif
if (p->p_wchan == ident) {
--n;
p->p_wchan = 0;
- *q = p->p_forw;
- if (qp->sq_tailp == &p->p_forw)
- qp->sq_tailp = q;
+ TAILQ_REMOVE(qp, p, p_runq);
if (p->p_stat == SSLEEP) {
/* OPTIMIZED EXPANSION OF setrunnable(p); */
if (p->p_slptime > 1)
@@ -357,13 +346,8 @@ restart:
need_resched(p->p_cpu);
/* END INLINE EXPANSION */
- if (n != 0)
- goto restart;
- else
- break;
}
- } else
- q = &p->p_forw;
+ }
}
SCHED_UNLOCK(s);
}
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index bdc9d6850a2..c9b12d50fab 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.157 2007/09/07 15:00:20 art Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.158 2007/10/10 15:53:53 art Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -1280,9 +1280,7 @@ fill_kproc2(struct proc *p, struct kinfo_proc2 *ki)
ki->p_vm_tsize = vm->vm_tsize;
ki->p_vm_dsize = vm->vm_dused;
ki->p_vm_ssize = vm->vm_ssize;
-
- ki->p_forw = PTRTOINT64(p->p_forw);
- ki->p_back = PTRTOINT64(p->p_back);
+ ki->p_forw = ki->p_back = 0;
ki->p_addr = PTRTOINT64(p->p_addr);
ki->p_stat = p->p_stat;
ki->p_swtime = p->p_swtime;
diff --git a/sys/kern/sched_bsd.c b/sys/kern/sched_bsd.c
index 047207b1d39..aafcbb9eeb4 100644
--- a/sys/kern/sched_bsd.c
+++ b/sys/kern/sched_bsd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sched_bsd.c,v 1.12 2007/05/18 16:10:15 art Exp $ */
+/* $OpenBSD: sched_bsd.c,v 1.13 2007/10/10 15:53:53 art Exp $ */
/* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
/*-
@@ -57,9 +57,6 @@
int lbolt; /* once a second sleep address */
int rrticks_init; /* # of hardclock ticks per roundrobin() */
-int whichqs; /* Bit mask summary of non-empty Q's. */
-struct prochd qs[NQS];
-
struct SIMPLELOCK sched_lock;
void scheduler_start(void);
@@ -359,29 +356,26 @@ preempt(struct proc *newp)
SCHED_UNLOCK(s);
}
-
-/*
- * Must be called at splstatclock() or higher.
- */
void
mi_switch(void)
{
- struct proc *p = curproc; /* XXX */
+ struct schedstate_percpu *spc = &curcpu()->ci_schedstate;
+ struct proc *p = curproc;
+ struct proc *nextproc;
struct rlimit *rlim;
struct timeval tv;
-#if defined(MULTIPROCESSOR)
+#ifdef MULTIPROCESSOR
int hold_count;
int sched_count;
#endif
- struct schedstate_percpu *spc = &p->p_cpu->ci_schedstate;
+
+ KASSERT(p->p_stat != SONPROC);
SCHED_ASSERT_LOCKED();
-#if defined(MULTIPROCESSOR)
+#ifdef MULTIPROCESSOR
/*
* Release the kernel_lock, as we are about to yield the CPU.
- * The scheduler lock is still held until cpu_switch()
- * selects a new process and removes it from the run queue.
*/
sched_count = __mp_release_all_but_one(&sched_lock);
if (p->p_flag & P_BIGLOCK)
@@ -391,7 +385,6 @@ mi_switch(void)
/*
* Compute the amount of time during which the current
* process was running, and add that to its total so far.
- * XXX - use microuptime here to avoid strangeness.
*/
microuptime(&tv);
if (timercmp(&tv, &spc->spc_runtime, <)) {
@@ -427,16 +420,27 @@ mi_switch(void)
*/
spc->spc_schedflags &= ~SPCF_SWITCHCLEAR;
- /*
- * Pick a new current process and record its start time.
- */
- uvmexp.swtch++;
- cpu_switch(p);
+ nextproc = sched_chooseproc();
+
+ if (p != nextproc) {
+ uvmexp.swtch++;
+ cpu_switchto(p, nextproc);
+ } else {
+ p->p_stat = SONPROC;
+ }
+
+ SCHED_ASSERT_LOCKED();
/*
- * Make sure that MD code released the scheduler lock before
- * resuming us.
+ * To preserve lock ordering, we need to release the sched lock
+ * and grab it after we grab the big lock.
+ * In the future, when the sched lock isn't recursive, we'll
+ * just release it here.
*/
+#ifdef MULTIPROCESSOR
+ __mp_unlock(&sched_lock);
+#endif
+
SCHED_ASSERT_UNLOCKED();
/*
@@ -444,11 +448,11 @@ mi_switch(void)
* be running on a new CPU now, so don't use the cache'd
* schedstate_percpu pointer.
*/
- KDASSERT(p->p_cpu != NULL);
- KDASSERT(p->p_cpu == curcpu());
+ KASSERT(p->p_cpu == curcpu());
+
microuptime(&p->p_cpu->ci_schedstate.spc_runtime);
-#if defined(MULTIPROCESSOR)
+#ifdef MULTIPROCESSOR
/*
* Reacquire the kernel_lock now. We do this after we've
* released the scheduler lock to avoid deadlock, and before
@@ -460,20 +464,6 @@ mi_switch(void)
#endif
}
-/*
- * Initialize the (doubly-linked) run queues
- * to be empty.
- */
-void
-rqinit(void)
-{
- int i;
-
- for (i = 0; i < NQS; i++)
- qs[i].ph_link = qs[i].ph_rlink = (struct proc *)&qs[i];
- SIMPLE_LOCK_INIT(&sched_lock);
-}
-
static __inline void
resched_proc(struct proc *p, u_char pri)
{
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 125978d8a74..a4d4a12fa62 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.100 2007/07/25 23:11:53 art Exp $ */
+/* $OpenBSD: proc.h,v 1.101 2007/10/10 15:53:53 art Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -148,8 +148,7 @@ struct process;
#endif
struct proc {
- struct proc *p_forw; /* Doubly-linked run/sleep queue. */
- struct proc *p_back;
+ TAILQ_ENTRY(proc) p_runq;
LIST_ENTRY(proc) p_list; /* List of all processes. */
struct process *p_p; /* The process of this thread. */
@@ -401,14 +400,6 @@ extern struct pool ucred_pool; /* memory pool for ucreds */
extern struct pool session_pool; /* memory pool for sessions */
extern struct pool pcred_pool; /* memory pool for pcreds */
-#define NQS 32 /* 32 run queues. */
-extern int whichqs; /* Bit mask summary of non-empty Q's. */
-struct prochd {
- struct proc *ph_link; /* Linked list of running processes. */
- struct proc *ph_rlink;
-};
-extern struct prochd qs[NQS];
-
struct simplelock;
struct proc *pfind(pid_t); /* Find process by id. */
@@ -423,17 +414,10 @@ int inferior(struct proc *p);
int leavepgrp(struct proc *p);
void yield(void);
void preempt(struct proc *);
-void mi_switch(void);
void pgdelete(struct pgrp *pgrp);
void procinit(void);
-#if !defined(remrunqueue)
-void remrunqueue(struct proc *);
-#endif
void resetpriority(struct proc *);
void setrunnable(struct proc *);
-#if !defined(setrunqueue)
-void setrunqueue(struct proc *);
-#endif
void unsleep(struct proc *);
void wakeup_n(void *chan, int);
void wakeup(void *chan);
@@ -441,17 +425,13 @@ void wakeup(void *chan);
void reaper(void);
void exit1(struct proc *, int, int);
void exit2(struct proc *);
+void cpu_exit(struct proc *);
int fork1(struct proc *, int, int, void *, size_t, void (*)(void *),
void *, register_t *, struct proc **);
-void rqinit(void);
int groupmember(gid_t, struct ucred *);
-#if !defined(cpu_switch)
-void cpu_switch(struct proc *);
-#endif
#if !defined(cpu_wait)
void cpu_wait(struct proc *);
#endif
-void cpu_exit(struct proc *);
void child_return(void *);
@@ -471,6 +451,7 @@ void sleep_setup_signal(struct sleep_state *, int);
void sleep_finish(struct sleep_state *, int);
int sleep_finish_timeout(struct sleep_state *);
int sleep_finish_signal(struct sleep_state *);
+void sleep_queue_init(void);
int tsleep(void *, int, const char *, int);
#define ltsleep(c, p, w, t, l) tsleep(c, p, w, t)
diff --git a/sys/sys/sched.h b/sys/sys/sched.h
index 407ec09f651..62b7f568637 100644
--- a/sys/sys/sched.h
+++ b/sys/sys/sched.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sched.h,v 1.16 2007/05/18 14:41:55 art Exp $ */
+/* $OpenBSD: sched.h,v 1.17 2007/10/10 15:53:53 art Exp $ */
/* $NetBSD: sched.h,v 1.2 1999/02/28 18:14:58 ross Exp $ */
/*-
@@ -76,6 +76,8 @@
#ifndef _SYS_SCHED_H_
#define _SYS_SCHED_H_
+#include <sys/queue.h>
+
/*
* Posix defines a <sched.h> which may want to include <sys/sched.h>
*/
@@ -105,6 +107,11 @@ struct schedstate_percpu {
int spc_rrticks; /* ticks until roundrobin() */
int spc_pscnt; /* prof/stat counter */
int spc_psdiv; /* prof/stat divisor */
+ struct proc *spc_idleproc; /* idle proc for this cpu */
+#ifdef notyet
+ struct proc *spc_reaper; /* dead proc reaper */
+#endif
+ LIST_HEAD(,proc) spc_deadproc;
};
#ifdef _KERNEL
@@ -114,6 +121,8 @@ struct schedstate_percpu {
#define SPCF_SHOULDYIELD 0x0002 /* process should yield the CPU */
#define SPCF_SWITCHCLEAR (SPCF_SEENRR|SPCF_SHOULDYIELD)
+
+#define NQS 32 /* 32 run queues. */
#define PPQ (128 / NQS) /* priorities per queue */
#define NICE_WEIGHT 2 /* priorities per nice level */
#define ESTCPULIM(e) min((e), NICE_WEIGHT * PRIO_MAX - PPQ)
@@ -126,7 +135,21 @@ void schedclock(struct proc *);
struct cpu_info;
void roundrobin(struct cpu_info *);
-#define sched_is_idle() (whichqs == 0)
+void sched_init_cpu(struct cpu_info *);
+void sched_exit(struct proc *);
+void mi_switch(void);
+void cpu_switchto(struct proc *, struct proc *);
+struct proc *sched_chooseproc(void);
+void cpu_idle_enter(void);
+void cpu_idle_cycle(void);
+void cpu_idle_leave(void);
+
+extern volatile int sched_whichqs;
+#define sched_is_idle() (sched_whichqs == 0)
+
+void sched_init_runqueues(void);
+void setrunqueue(struct proc *);
+void remrunqueue(struct proc *);
/* Inherit the parent's scheduler history */
#define scheduler_fork_hook(parent, child) do { \
diff --git a/sys/uvm/uvm_meter.c b/sys/uvm/uvm_meter.c
index 85265e684de..007921d85a2 100644
--- a/sys/uvm/uvm_meter.c
+++ b/sys/uvm/uvm_meter.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_meter.c,v 1.22 2007/02/14 00:53:48 jsg Exp $ */
+/* $OpenBSD: uvm_meter.c,v 1.23 2007/10/10 15:53:53 art Exp $ */
/* $NetBSD: uvm_meter.c,v 1.21 2001/07/14 06:36:03 matt Exp $ */
/*
@@ -109,8 +109,10 @@ uvm_loadav(avg)
continue;
/* FALLTHROUGH */
case SRUN:
- case SIDL:
case SONPROC:
+ if (p == p->p_cpu->ci_schedstate.spc_idleproc)
+ continue;
+ case SIDL:
nrun++;
}
}