Now that we have the kthread mechanism, massively clean up the way

additional processors are spun up on multiprocessor Alpha systems.
Now, each processor gets its own idle thread (the primary processor
uses proc0).  This idle thread is used in switch_exit(), rather than
explicitly referencing proc0.

Also, make `curproc', `fpcurproc', and `curpcb' per-cpu values.  This
required some data structure rearrangement; cpu info is now statically
allocated in the BSS, rather than via malloc(), and cpu_softc is gone.
(Modeled somewhat after NetBSD/sparc's multiprocessor info structures.)
This commit is contained in:
thorpej 1999-02-23 03:20:00 +00:00
parent 5bc723973e
commit 76e4555f2c
17 changed files with 469 additions and 341 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: autoconf.c,v 1.32 1998/11/25 19:58:47 mjacob Exp $ */
/* $NetBSD: autoconf.c,v 1.33 1999/02/23 03:20:00 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
@ -46,9 +46,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.32 1998/11/25 19:58:47 mjacob Exp $");
#include "opt_multiprocessor.h"
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.33 1999/02/23 03:20:00 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -108,13 +106,6 @@ configure()
* to do restarts.
*/
hwrpb_restart_setup();
#if defined(MULTIPROCESSOR)
/*
* Spin up any secondary CPUs.
*/
cpu_run_spinup_queue();
#endif
}
void

View File

@ -1,4 +1,4 @@
/* $NetBSD: compat_13_machdep.c,v 1.3 1998/11/19 01:59:39 ross Exp $ */
/* $NetBSD: compat_13_machdep.c,v 1.4 1999/02/23 03:20:00 thorpej Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@ -29,7 +29,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: compat_13_machdep.c,v 1.3 1998/11/19 01:59:39 ross Exp $");
__KERNEL_RCSID(0, "$NetBSD: compat_13_machdep.c,v 1.4 1999/02/23 03:20:00 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -44,6 +44,8 @@ __KERNEL_RCSID(0, "$NetBSD: compat_13_machdep.c,v 1.3 1998/11/19 01:59:39 ross E
#include <machine/reg.h>
#include <machine/alpha.h>
#include <alpha/alpha/cpuvar.h>
/*
* System call to cleanup state after a signal
* has been taken. Reset signal mask and
@ -65,7 +67,6 @@ compat_13_sys_sigreturn(p, v, retval)
syscallarg(struct sigcontext13 *) sigcntxp;
} */ *uap = v;
struct sigcontext13 *scp, ksc;
extern struct proc *fpcurproc;
sigset13_t mask13;
sigset_t mask;

View File

@ -1,7 +1,7 @@
/* $NetBSD: cpu.c,v 1.33 1998/11/19 01:59:39 ross Exp $ */
/* $NetBSD: cpu.c,v 1.34 1999/02/23 03:20:01 thorpej Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -66,14 +66,13 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.33 1998/11/19 01:59:39 ross Exp $");
__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.34 1999/02/23 03:20:01 thorpej Exp $");
#include "opt_multiprocessor.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/user.h>
@ -88,17 +87,22 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.33 1998/11/19 01:59:39 ross Exp $");
#include <alpha/alpha/cpuvar.h>
#if defined(MULTIPROCESSOR)
TAILQ_HEAD(, cpu_softc) cpu_spinup_queue =
TAILQ_HEAD_INITIALIZER(cpu_spinup_queue);
#include <sys/malloc.h>
#include <sys/kthread.h>
/* Map CPU ID to cpu_softc; allocate in cpu_attach(). */
struct cpu_softc **cpus;
/* Quick access to the primary CPU. */
struct cpu_softc *primary_cpu;
/*
* Array of CPU info structures. Must be statically-allocated because
* curproc, etc. are used early.
*/
struct cpu_info cpu_info[ALPHA_MAXPROCS];
/* Bitmask of CPUs currently running. */
u_long cpus_running;
void cpu_create_idle_thread __P((void *));
#else
paddr_t curpcb; /* PA of our current context */
struct proc *fpcurproc; /* current owner of FPU */
#endif /* MULTIPROCESSOR */
/* Definition of the driver for autoconfig. */
@ -106,7 +110,7 @@ static int cpumatch(struct device *, struct cfdata *, void *);
static void cpuattach(struct device *, struct device *, void *);
struct cfattach cpu_ca = {
sizeof(struct cpu_softc), cpumatch, cpuattach
sizeof(struct device), cpumatch, cpuattach
};
extern struct cfdriver cpu_cd;
@ -152,25 +156,21 @@ struct cputable_struct {
* works.
*
* As we find processors during the autoconfiguration sequence, all
* processors that are available and not the primary are placed on
* a "spin-up queue". Once autoconfiguration has completed, this
* queue is run to spin up the secondary processors.
* processors that are available and not the primary are set up to
* have a kernel thread created for them. This kernel thread will
* be that CPUs "idle thread" (analog of proc0). These threads are
* created after init(8) is created.
*
* cpu_run_spinup_queue() pulls each processor off the list, switches
* it to OSF/1 PALcode, sets the entry point to the cpu_spinup_trampoline,
* and then sends a "START" command to the secondary processor's console.
* cpu_create_idle_thread() creates one idle thread, and starts that
* thread's prcessor, switches it to OSF/1 PALcode, sets the entry point
* to cpu_spinup_trampoline, and then sends a "START" command to the
* secondary processor's console.
*
* Upon successful processor bootup, the cpu_spinup_trampoline will call
* cpu_hatch(), which will print a message indicating that the processor
* is running, and will set the "hatched" flag in its softc. At the end
* of cpu_hatch() is a spin-forever loop; we do not yet attempt to schedule
* anything on secondary CPUs.
*
* To summarize:
*
* [primary cpu] cpu_run_spinup_queue -> return
*
* [secondary cpus] cpu_spinup_trampoline -> cpu_hatch -> spin-loop
*/
static int
@ -197,7 +197,6 @@ cpuattach(parent, dev, aux)
struct device *dev;
void *aux;
{
struct cpu_softc *sc = (struct cpu_softc *)dev;
struct mainbus_attach_args *ma = aux;
int i;
char **s;
@ -206,15 +205,14 @@ cpuattach(parent, dev, aux)
int needcomma;
#endif
u_int32_t major, minor;
#if defined(MULTIPROCESSOR)
struct cpu_info *ci;
#endif
p = LOCATE_PCS(hwrpb, ma->ma_slot);
major = PCS_CPU_MAJORTYPE(p);
minor = PCS_CPU_MINORTYPE(p);
simple_lock_init(&sc->sc_slock);
sc->sc_cpuid = ma->ma_slot;
printf(": ID %d%s, ", ma->ma_slot,
ma->ma_slot == hwrpb->rpb_primary_cpu_id ? " (primary)" : "");
@ -263,21 +261,14 @@ recognized:
#if defined(MULTIPROCESSOR)
if (ma->ma_slot > ALPHA_WHAMI_MAXID) {
printf("%s: procssor ID too large, ignoring\n",
sc->sc_dev.dv_xname);
printf("%s: procssor ID too large, ignoring\n", dev->dv_xname);
return;
}
if (cpus == NULL) {
size_t size = sizeof(struct cpu_softc *) * hwrpb->rpb_pcs_cnt;
cpus = malloc(size, M_DEVBUF, M_NOWAIT);
if (cpus == NULL)
panic("cpu_attach: unable to allocate cpus array");
memset(cpus, 0, size);
}
cpus[ma->ma_slot] = sc;
ci = &cpu_info[ma->ma_slot];
simple_lock_init(&ci->ci_slock);
ci->ci_cpuid = ma->ma_slot;
ci->ci_dev = dev;
#endif /* MULTIPROCESSOR */
/*
@ -295,157 +286,139 @@ recognized:
if (ma->ma_slot == hwrpb->rpb_primary_cpu_id) {
u_long cpumask = (1UL << ma->ma_slot);
sc->sc_flags |= CPUF_PRIMARY;
ci->ci_flags |= CPUF_PRIMARY;
ci->ci_idle_thread = &proc0;
alpha_atomic_setbits_q(&cpus_running, cpumask);
primary_cpu = sc;
return;
}
/*
* Not the primary CPU; need to queue this processor to be
* started after autoconfiguration is finished.
* Not the primary CPU; need to queue a kernel thread to be created
* to be this processor's idle thread. The creation of the kernel
* thread will also spin up the processor.
*/
if ((p->pcs_flags & PCS_PA) == 0) {
printf("%s: processor not available for use\n",
sc->sc_dev.dv_xname);
printf("%s: processor not available for use\n", dev->dv_xname);
return;
}
/*
* Place this processor on the cpu-spinup queue. No locking is
* necessary; only the primary CPU will access this list.
*/
TAILQ_INSERT_TAIL(&cpu_spinup_queue, sc, sc_q);
kthread_create_deferred(cpu_create_idle_thread, ci);
#endif /* MULTIPROCESSOR */
}
#if defined(MULTIPROCESSOR)
void
cpu_run_spinup_queue()
cpu_create_idle_thread(arg)
void *arg;
{
struct cpu_softc *sc;
struct cpu_info *ci = arg;
struct proc *p;
long timeout;
struct pcs *pcsp, *primary_pcsp;
struct pcb *pcb;
u_long cpumask;
primary_pcsp = LOCATE_PCS(hwrpb, hwrpb->rpb_primary_cpu_id);
pcsp = LOCATE_PCS(hwrpb, ci->ci_cpuid);
cpumask = (1UL << ci->ci_cpuid);
while ((sc = TAILQ_FIRST(&cpu_spinup_queue)) != NULL) {
TAILQ_REMOVE(&cpu_spinup_queue, sc, sc_q);
pcsp = LOCATE_PCS(hwrpb, sc->sc_cpuid);
cpumask = (1UL << sc->sc_cpuid);
/* Make sure the processor has valid PALcode. */
if ((pcsp->pcs_flags & PCS_PV) == 0) {
printf("%s: PALcode not valid\n", sc->sc_dev.dv_xname);
continue;
}
/*
* XXX This really should fork honest idleprocs (a'la proc0)
* XXX but we aren't called via MI code yet, so we can't
* XXX really fork.
*/
/* Allocate the idle stack. */
sc->sc_idle_stack = malloc(USPACE, M_TEMP, M_NOWAIT);
if (sc->sc_idle_stack == NULL) {
printf("%s: unable to allocate idle stack\n",
sc->sc_dev.dv_xname);
continue;
}
memset(sc->sc_idle_stack, 0, USPACE);
#if 0
printf("%s: idle stack = %p\n", sc->sc_dev.dv_xname,
sc->sc_idle_stack);
#endif
/*
* Initialize the PCB and copy it to the PCS.
* XXX We don't yet use the trapframe. Will we ever?
*/
pcb = (struct pcb *)sc->sc_idle_stack;
pcb->pcb_hw.apcb_ksp =
(u_int64_t)sc->sc_idle_stack + USPACE -
sizeof(struct trapframe);
pcb->pcb_hw.apcb_backup_ksp = pcb->pcb_hw.apcb_ksp;
pcb->pcb_hw.apcb_asn = proc0.p_addr->u_pcb.pcb_hw.apcb_asn;
pcb->pcb_hw.apcb_ptbr = proc0.p_addr->u_pcb.pcb_hw.apcb_ptbr;
memcpy(pcsp->pcs_hwpcb, &pcb->pcb_hw, sizeof(pcb->pcb_hw));
#if 0
printf("%s: hwpcb ksp = 0x%lx\n", sc->sc_dev.dv_xname,
pcb->pcb_hw.apcb_ksp);
printf("%s: hwpcb ptbr = 0x%lx\n", sc->sc_dev.dv_xname,
pcb->pcb_hw.apcb_ptbr);
#endif
/*
* Set up the HWRPB to restart the secondary processor
* with our spin-up trampoline.
*/
hwrpb->rpb_restart = (u_int64_t) cpu_spinup_trampoline;
hwrpb->rpb_restart_val = (u_int64_t) sc;
hwrpb->rpb_checksum = hwrpb_checksum();
/*
* Configure the CPU to start in OSF/1 PALcode by copying
* the primary CPU's PALcode revision info to the secondary
* CPUs PCS.
*/
/*
* XXX Until I can update the boot block on my test system.
* XXX --thorpej
*/
#if 0
memcpy(&pcsp->pcs_pal_rev, &primary_pcsp->pcs_pal_rev,
sizeof(pcsp->pcs_pal_rev));
#else
memcpy(&pcsp->pcs_pal_rev,
&pcsp->pcs_palrevisions[PALvar_OSF1],
sizeof(pcsp->pcs_pal_rev));
#endif
pcsp->pcs_flags |= (PCS_CV|PCS_RC);
pcsp->pcs_flags &= ~PCS_BIP;
/* Make sure the secondary console sees all this. */
alpha_mb();
/* Send a "START" command to the secondary CPU's console. */
if (cpu_iccb_send(sc->sc_cpuid, "START\r\n")) {
printf("%s: unable to issue `START' command\n",
sc->sc_dev.dv_xname);
continue;
}
/* Wait for the processor to boot. */
for (timeout = 10000; timeout != 0; timeout--) {
alpha_mb();
if (pcsp->pcs_flags & PCS_BIP)
break;
delay(1000);
}
if (timeout == 0)
printf("%s: processor failed to boot\n",
sc->sc_dev.dv_xname);
/*
* ...and now wait for verification that it's running kernel
* code.
*/
for (timeout = 10000; timeout != 0; timeout--) {
alpha_mb();
if ((volatile u_long)cpus_running & cpumask)
break;
delay(1000);
}
if (timeout == 0)
printf("%s: processor failed to hatch\n",
sc->sc_dev.dv_xname);
/* Make sure the processor has valid PALcode. */
if ((pcsp->pcs_flags & PCS_PV) == 0) {
printf("%s: PALcode not valid\n", ci->ci_dev->dv_xname);
return;
}
/*
* Create the CPU's idle thread. Note, the thread entry point
* and argument is effectively ignored in this case; we set up
* the entry point below, when we set up the CPU's HWPCB.
*/
if (kthread_create(NULL, NULL, &ci->ci_idle_thread, "%s idle",
ci->ci_dev->dv_xname)) {
printf("%s: unable to create idle thread\n",
ci->ci_dev->dv_xname);
return;
}
p = ci->ci_idle_thread;
/*
* Initialize the idle thread's PCB. Note we initialize the
* ASN and PTBR now, but we're going to call pmap_activate()
* immediately once the CPU is hatched.
*/
pcb = &p->p_addr->u_pcb;
pcb->pcb_hw.apcb_backup_ksp = pcb->pcb_hw.apcb_ksp;
pcb->pcb_hw.apcb_asn = proc0.p_addr->u_pcb.pcb_hw.apcb_asn;
pcb->pcb_hw.apcb_ptbr = proc0.p_addr->u_pcb.pcb_hw.apcb_ptbr;
memcpy(pcsp->pcs_hwpcb, &pcb->pcb_hw, sizeof(pcb->pcb_hw));
#if 0
printf("%s: hwpcb ksp = 0x%lx\n", sc->sc_dev.dv_xname,
pcb->pcb_hw.apcb_ksp);
printf("%s: hwpcb ptbr = 0x%lx\n", sc->sc_dev.dv_xname,
pcb->pcb_hw.apcb_ptbr);
#endif
/*
* Set up the HWRPB to restart the secondary processor
* with our spin-up trampoline.
*/
hwrpb->rpb_restart = (u_int64_t) cpu_spinup_trampoline;
hwrpb->rpb_restart_val = (u_int64_t) ci;
hwrpb->rpb_checksum = hwrpb_checksum();
/*
* Configure the CPU to start in OSF/1 PALcode by copying
* the primary CPU's PALcode revision info to the secondary
* CPUs PCS.
*/
/*
* XXX Until I can update the boot block on my test system.
* XXX --thorpej
*/
#if 0
memcpy(&pcsp->pcs_pal_rev, &primary_pcsp->pcs_pal_rev,
sizeof(pcsp->pcs_pal_rev));
#else
memcpy(&pcsp->pcs_pal_rev, &pcsp->pcs_palrevisions[PALvar_OSF1],
sizeof(pcsp->pcs_pal_rev));
#endif
pcsp->pcs_flags |= (PCS_CV|PCS_RC);
pcsp->pcs_flags &= ~PCS_BIP;
/* Make sure the secondary console sees all this. */
alpha_mb();
/* Send a "START" command to the secondary CPU's console. */
if (cpu_iccb_send(ci->ci_cpuid, "START\r\n")) {
printf("%s: unable to issue `START' command\n",
ci->ci_dev->dv_xname);
return;
}
/* Wait for the processor to boot. */
for (timeout = 10000; timeout != 0; timeout--) {
alpha_mb();
if (pcsp->pcs_flags & PCS_BIP)
break;
delay(1000);
}
if (timeout == 0)
printf("%s: processor failed to boot\n", ci->ci_dev->dv_xname);
/*
* ...and now wait for verification that it's running kernel
* code.
*/
for (timeout = 10000; timeout != 0; timeout--) {
alpha_mb();
if ((volatile u_long)cpus_running & cpumask)
break;
delay(1000);
}
if (timeout == 0)
printf("%s: processor failed to hatch\n", ci->ci_dev->dv_xname);
}
void
@ -454,10 +427,10 @@ cpu_halt_secondary(cpu_id)
{
long timeout;
u_long cpumask = (1UL << cpu_id);
struct cpu_softc *sc;
#ifdef DIAGNOSTIC
if (cpu_id >= hwrpb->rpb_pcs_cnt || (sc = cpus[cpu_id]) == NULL)
if (cpu_id >= hwrpb->rpb_pcs_cnt ||
cpu_info[cpu_id].ci_dev == NULL)
panic("cpu_halt_secondary: bogus cpu_id");
#endif
@ -480,20 +453,26 @@ cpu_halt_secondary(cpu_id)
/* Erk, secondary failed to halt. */
printf("WARNING: %s (ID %lu) failed to halt\n",
sc->sc_dev.dv_xname, cpu_id);
cpu_info[cpu_id].ci_dev->dv_xname, cpu_id);
}
void
cpu_hatch(sc)
struct cpu_softc *sc;
cpu_hatch(ci)
struct cpu_info *ci;
{
u_long cpumask = (1UL << sc->sc_cpuid);
u_long cpumask = (1UL << ci->ci_cpuid);
/* Set our `curpcb' to reflect our context. */
curpcb = (paddr_t)ci->ci_idle_thread->p_md.md_pcbpaddr;
/* Fully activate our address space. */
pmap_activate(ci->ci_idle_thread);
/* Initialize trap vectors for this processor. */
trap_init();
/* Yahoo! We're running kernel code! Announce it! */
printf("%s: processor ID %lu running\n", sc->sc_dev.dv_xname,
printf("%s: processor ID %lu running\n", ci->ci_dev->dv_xname,
alpha_pal_whami());
alpha_atomic_setbits_q(&cpus_running, cpumask);

View File

@ -1,7 +1,7 @@
/* $NetBSD: cpuvar.h,v 1.3 1998/09/29 07:05:30 thorpej Exp $ */
/* $NetBSD: cpuvar.h,v 1.4 1999/02/23 03:20:01 thorpej Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -37,22 +37,47 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/lock.h>
#ifndef _ALPHA_ALPHA_CPUVAR_H_
#define _ALPHA_ALPHA_CPUVAR_H_
struct cpu_softc {
struct device sc_dev; /* generic device glue */
struct simplelock sc_slock; /* spin lock */
u_long sc_cpuid; /* CPU ID */
caddr_t sc_idle_stack; /* our idle stack */
u_long sc_flags; /* flags; see below */
u_long sc_ipis; /* interprocessor interrupts pending */
TAILQ_ENTRY(cpu_softc) sc_q; /* processing queue */
};
#include <sys/lock.h>
#define CPUF_PRIMARY 0x00000001 /* CPU is primary CPU */
struct cpu_info {
struct proc *ci_curproc; /* current owner of the processor */
struct proc *ci_fpcurproc; /* current owner of the FPU */
paddr_t ci_curpcb; /* PA of current HW context */
struct simplelock ci_slock; /* spin lock */
u_long ci_cpuid; /* CPU ID */
struct proc *ci_idle_thread; /* our idle thread */
u_long ci_flags; /* flags; see below */
u_long ci_ipis; /* interprocessor interrupts pending */
struct device *ci_dev; /* pointer to our device */
};
#ifdef _KERNEL
extern unsigned long cpus_running;
extern struct cpu_softc **cpus;
extern struct cpu_softc *primary_cpu;
#ifndef _LKM
#include "opt_multiprocessor.h"
#endif
#ifdef MULTIPROCESSOR
extern unsigned long cpus_running;
extern struct cpu_info cpu_info[];
/*
* Map per-cpu variables to the cpu_info structure.
* XXX alpha_pal_whami() might be expensive, here!
*/
#define curproc cpu_info[alpha_pal_whami()].ci_curproc
#define fpcurproc cpu_info[alpha_pal_whami()].ci_fpcurproc
#define curpcb cpu_info[alpha_pal_whami()].ci_curpcb
#else
extern struct proc *fpcurproc; /* current owner of FPU */
extern paddr_t curpcb; /* PA of current HW context */
#endif /* MULTIPROCESSOR */
#endif /* _KERNEL */
#endif /* _ALPHA_ALPHA_CPUVAR_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: genassym.c,v 1.19 1998/09/29 06:22:09 thorpej Exp $ */
/* $NetBSD: genassym.c,v 1.20 1999/02/23 03:20:01 thorpej Exp $ */
/*
* Copyright (c) 1994, 1995 Gordon W. Ross
@ -62,7 +62,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__RCSID("$NetBSD: genassym.c,v 1.19 1998/09/29 06:22:09 thorpej Exp $");
__RCSID("$NetBSD: genassym.c,v 1.20 1999/02/23 03:20:01 thorpej Exp $");
#include <sys/param.h>
#include <sys/buf.h>
@ -80,6 +80,8 @@ __RCSID("$NetBSD: genassym.c,v 1.19 1998/09/29 06:22:09 thorpej Exp $");
#include <machine/rpb.h>
#include <machine/vmparam.h>
#include <alpha/alpha/cpuvar.h>
#include <vm/vm.h>
/* Note: Avoid /usr/include for cross compilation! */
@ -213,6 +215,14 @@ struct nv assyms[] = {
/* Syscalls called from sigreturn. */
def1(SYS___sigreturn14),
def1(SYS_exit),
/* CPU info */
def1(ALPHA_MAXPROCS),
def(SIZEOF_CPU_INFO, sizeof(struct cpu_info)),
off(CPU_INFO_CURPROC, struct cpu_info, ci_curproc),
off(CPU_INFO_FPCURPROC, struct cpu_info, ci_fpcurproc),
off(CPU_INFO_CURPCB, struct cpu_info, ci_curpcb),
off(CPU_INFO_IDLE_THREAD, struct cpu_info, ci_idle_thread),
};
int nassyms = sizeof(assyms)/sizeof(assyms[0]);

View File

@ -1,4 +1,4 @@
/* $NetBSD: interrupt.c,v 1.35 1999/02/23 02:56:04 ross Exp $ */
/* $NetBSD: interrupt.c,v 1.36 1999/02/23 03:20:01 thorpej Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@ -37,7 +37,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: interrupt.c,v 1.35 1999/02/23 02:56:04 ross Exp $");
__KERNEL_RCSID(0, "$NetBSD: interrupt.c,v 1.36 1999/02/23 03:20:01 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -80,24 +80,23 @@ interrupt(a0, a1, a2, framep)
case ALPHA_INTR_XPROC: /* interprocessor interrupt */
#if defined(MULTIPROCESSOR)
{
struct cpu_softc *sc;
struct cpu_info *ci;
u_long pending_ipis, bit;
#if 1
printf("CPU %lu got IPI\n", cpu_id);
#endif
sc = cpus[cpu_id];
#ifdef DIAGNOSTIC
if (sc == NULL) {
if (cpu_info[cpu_id].ci_dev == NULL) {
/* XXX panic? */
printf("WARNING: no cpu_softc for ID %lu\n",
printf("WARNING: no device for ID %lu\n",
cpu_id);
return;
}
#endif
pending_ipis = alpha_atomic_loadlatch_q(&sc->sc_ipis, 0);
pending_ipis = alpha_atomic_loadlatch_q(&ci->ci_ipis, 0);
for (bit = 0; bit < ALPHA_NIPIS; bit++)
if (pending_ipis & (1UL << bit))
(*ipifuncs[bit])();

View File

@ -1,4 +1,4 @@
/* $NetBSD: ipifuncs.c,v 1.3 1998/09/29 19:40:33 thorpej Exp $ */
/* $NetBSD: ipifuncs.c,v 1.4 1999/02/23 03:20:01 thorpej Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -39,7 +39,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.3 1998/09/29 19:40:33 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.4 1999/02/23 03:20:01 thorpej Exp $");
/*
* Interprocessor interrupt handlers.
@ -75,19 +75,19 @@ void
alpha_send_ipi(cpu_id, ipinum)
u_long cpu_id, ipinum;
{
struct cpu_softc *sc;
u_long ipimask;
#ifdef DIAGNOSTIC
if (ipinum >= ALPHA_NIPIS)
panic("alpha_sched_ipi: bogus ipinum");
if (cpu_id >= hwrpb->rpb_pcs_cnt || (sc = cpus[cpu_id]) == NULL)
if (cpu_id >= hwrpb->rpb_pcs_cnt ||
cpu_info[cpu_id].ci_dev == NULL)
panic("alpha_sched_ipi: bogus cpu_id");
#endif
ipimask = (1UL << ipinum);
alpha_atomic_setbits_q(&sc->sc_ipis, ipimask);
alpha_atomic_setbits_q(&cpu_info[cpu_id].ci_ipis, ipimask);
printf("SENDING IPI TO %lu\n", cpu_id);
alpha_pal_wripir(cpu_id);
printf("IPI SENT\n");
@ -98,12 +98,11 @@ alpha_ipi_halt()
{
u_long cpu_id = alpha_pal_whami();
struct pcs *pcsp = LOCATE_PCS(hwrpb, cpu_id);
struct cpu_softc *sc = cpus[cpu_id];
/* Disable interrupts. */
(void) splhigh();
printf("%s: shutting down...\n", sc->sc_dev.dv_xname);
printf("%s: shutting down...\n", cpu_info[cpu_id].ci_dev->dv_xname);
alpha_atomic_clearbits_q(&cpus_running, (1UL << cpu_id));
pcsp->pcs_flags &= ~(PCS_RC | PCS_HALT_REQ);

View File

@ -1,4 +1,41 @@
/* $NetBSD: locore.s,v 1.56 1998/11/26 20:26:52 thorpej Exp $ */
/* $NetBSD: locore.s,v 1.57 1999/02/23 03:20:02 thorpej Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center.
*
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@ -39,7 +76,7 @@
#include <machine/asm.h>
__KERNEL_RCSID(0, "$NetBSD: locore.s,v 1.56 1998/11/26 20:26:52 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: locore.s,v 1.57 1999/02/23 03:20:02 thorpej Exp $");
#ifndef EVCNT_COUNTERS
#include <machine/intrcnt.h>
@ -48,18 +85,63 @@ __KERNEL_RCSID(0, "$NetBSD: locore.s,v 1.56 1998/11/26 20:26:52 thorpej Exp $");
.stabs __FILE__,132,0,0,kernel_text
#if defined(MULTIPROCESSOR)
IMPORT(cpu_info, SIZEOF_CPU_INFO * ALPHA_MAXPROCS)
/*
* The physical address of the current HWPCB.
* Get pointer to our cpu_info structure. Clobbers v0, t0, t8...t11.
*/
BSS(curpcb, 8)
#define GET_CPUINFO(reg) \
/* Get our processor ID. */ \
call_pal PAL_OSF1_whami ; \
\
/* Compute offset of our cpu_info. */ \
ldiq reg, SIZEOF_CPU_INFO ; \
mulq reg, v0, v0 ; \
\
/* Get the address of cpu_info, and add the offset. */ \
lda reg, cpu_info ; \
addq reg, v0, reg
#define GET_CURPROC(reg) \
GET_CPUINFO(reg) ; \
addq reg, CPU_INFO_CURPROC, reg
#define GET_FPCURPROC(reg) \
GET_CPUINFO(reg) ; \
addq reg, CPU_INFO_FPCURPROC, reg
#define GET_CURPCB(reg) \
GET_CPUINFO(reg) ; \
addq reg, CPU_INFO_CURPCB, reg
#define GET_IDLE_THREAD(reg) \
GET_CPUINFO(reg) ; \
addq reg, CPU_INFO_IDLE_THREAD, reg ; \
ldq reg, 0(reg)
#else
IMPORT(curproc, 8)
IMPORT(fpcurproc, 8)
IMPORT(curpcb, 8)
#define GET_CURPROC(reg) lda reg, curproc
#define GET_FPCURPROC(reg) lda reg, fpcurproc
#define GET_CURPCB(reg) lda reg, curpcb
#define GET_IDLE_THREAD(reg) lda reg, proc0
#endif
/*
* Perform actions necessary to switch to a new context. The
* hwpcb should be in a0.
* hwpcb should be in a0. Clobbers v0, t0.
*/
#define SWITCH_CONTEXT \
/* Make a note of the context we're running on. */ \
stq a0, curpcb ; \
GET_CURPCB(t0) ; \
stq a0, 0(t0) ; \
\
/* Swap in the new context. */ \
call_pal PAL_OSF1_swpctx
@ -122,10 +204,10 @@ Lstart1: LDGP(pv)
call_pal PAL_OSF1_wrvptptr /* clobbers a0, t0, t8-t11 */
/*
* Switch to proc0's PCB, which is at U_PCB off of proc0paddr.
* Switch to proc0's PCB.
*/
lda t0,proc0 /* get phys addr of pcb */
ldq a0,P_MD_PCBPADDR(t0)
lda a0, proc0
ldq a0, P_MD_PCBPADDR(a0) /* phys addr of PCB */
SWITCH_CONTEXT
/*
@ -323,12 +405,17 @@ Lchkast:
CALL(ast)
Lsetfpenable:
/* enable FPU based on whether the current proc is fpcurproc */
ldq t0, curproc
ldq t1, fpcurproc
cmpeq t0, t1, t0
/*
* enable FPU based on whether the current proc is fpcurproc.
* Note: GET_*() clobbers v0, t0, t8...t11.
*/
GET_CURPROC(t1)
ldq t1, 0(t1)
GET_FPCURPROC(t2)
ldq t2, 0(t2)
cmpeq t1, t2, t1
mov zero, a0
cmovne t0, 1, a0
cmovne t1, 1, a0
call_pal PAL_OSF1_wrfen
Lrestoreregs:
@ -685,7 +772,9 @@ IMPORT(kernel_lev1map, 8)
LEAF(idle, 0)
br pv, Lidle1
Lidle1: LDGP(pv)
stq zero, curproc /* curproc <- NULL for stats */
/* Note: GET_CURPROC() clobbers v0, t0, t8...t11. */
GET_CURPROC(t1)
stq zero, 0(t1) /* curproc <- NULL for stats */
mov zero, a0 /* enable all interrupts */
call_pal PAL_OSF1_swpipl
Lidle2:
@ -702,8 +791,12 @@ Lidle2:
*/
LEAF(cpu_switch, 0)
LDGP(pv)
/* do an inline savectx(), to save old context */
ldq a0, curproc
/*
* do an inline savectx(), to save old context
* Note: GET_CURPROC() clobbers v0, t0, t8...t11.
*/
GET_CURPROC(a0)
ldq a0, 0(a0)
ldq a1, P_ADDR(a0)
/* NOTE: ksp is stored by the swpctx */
stq s0, U_PCB_CONTEXT+(0 * 8)(a1) /* store s0 - s6 */
@ -817,8 +910,11 @@ Lcs7:
* globals. We must do this even if switching to ourselves
* because we might have re-entered cpu_switch() from idle(),
* in which case curproc would be NULL.
*
* Note: GET_CURPROC() clobbers v0, t0, t8...t11.
*/
stq s2, curproc /* curproc = p */
GET_CURPROC(t1)
stq s2, 0(t1) /* curproc = p */
stq zero, want_resched /* we've rescheduled */
/*
@ -863,9 +959,9 @@ LEAF(switch_trampoline, 0)
/*
* switch_exit(struct proc *p)
* Make a the named process exit. Partially switch to proc0 (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
* 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)
@ -874,18 +970,13 @@ LEAF(switch_exit, 1)
/* save the exiting proc pointer */
mov a0, s2
/* Switch to proc0. */
lda t4, proc0 /* t4 = &proc0 */
ldq t5, P_MD_PCBPADDR(t4) /* t5 = p->p_md.md_pcbpaddr */
/*
* Do the actual context swap.
*/
mov t5, a0
/* Switch to our idle thread. */
GET_IDLE_THREAD(a0) /* clobbers v0, t0, t8-t11 */
ldq a0, P_MD_PCBPADDR(a0) /* phys addr of PCB */
SWITCH_CONTEXT
/*
* Now running as proc0, except for the value of 'curproc' and
* Now running as idle thread, except for the value of 'curproc' and
* the saved regs.
*/
@ -947,50 +1038,58 @@ Lcopystr4:
RET
END(copystr)
NESTED(copyinstr, 4, 16, ra, 0, 0)
NESTED(copyinstr, 4, 16, ra, IM_RA|IM_S0, 0)
LDGP(pv)
lda sp, -16(sp) /* set up stack frame */
stq ra, (16-8)(sp) /* save ra */
stq s0, (16-16)(sp) /* save s0 */
ldiq t0, VM_MAX_ADDRESS /* make sure that src addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, copyerr /* if it's not, error out. */
/* Note: GET_CURPROC() clobbers v0, t0, t8...t11. */
GET_CURPROC(s0)
lda v0, copyerr /* set up fault handler. */
.set noat
ldq at_reg, curproc
ldq at_reg, 0(s0)
ldq at_reg, P_ADDR(at_reg)
stq v0, U_PCB_ONFAULT(at_reg)
.set at
CALL(copystr) /* do the copy. */
.set noat
ldq at_reg, curproc /* kill the fault handler. */
ldq at_reg, 0(s0) /* kill the fault handler. */
ldq at_reg, P_ADDR(at_reg)
stq zero, U_PCB_ONFAULT(at_reg)
.set at
ldq ra, (16-8)(sp) /* restore ra. */
ldq s0, (16-16)(sp) /* restore s0. */
lda sp, 16(sp) /* kill stack frame. */
RET /* v0 left over from copystr */
END(copyinstr)
NESTED(copyoutstr, 4, 16, ra, 0, 0)
NESTED(copyoutstr, 4, 16, ra, IM_RA|IM_S0, 0)
LDGP(pv)
lda sp, -16(sp) /* set up stack frame */
stq ra, (16-8)(sp) /* save ra */
stq s0, (16-16)(sp) /* save s0 */
ldiq t0, VM_MAX_ADDRESS /* make sure that dest addr */
cmpult a1, t0, t1 /* is in user space. */
beq t1, copyerr /* if it's not, error out. */
/* Note: GET_CURPROC() clobbers v0, t0, t8...t11. */
GET_CURPROC(s0)
lda v0, copyerr /* set up fault handler. */
.set noat
ldq at_reg, curproc
ldq at_reg, 0(s0)
ldq at_reg, P_ADDR(at_reg)
stq v0, U_PCB_ONFAULT(at_reg)
.set at
CALL(copystr) /* do the copy. */
.set noat
ldq at_reg, curproc /* kill the fault handler. */
ldq at_reg, 0(s0) /* kill the fault handler. */
ldq at_reg, P_ADDR(at_reg)
stq zero, U_PCB_ONFAULT(at_reg)
.set at
ldq ra, (16-8)(sp) /* restore ra. */
ldq s0, (16-16)(sp) /* restore s0. */
lda sp, 16(sp) /* kill stack frame. */
RET /* v0 left over from copystr */
END(copyoutstr)
@ -1240,27 +1339,31 @@ bcopy_ov_short:
* called by uiomove(), which may be in the path of servicing a non-fatal
* page fault.
*/
NESTED(kcopy, 3, 16, ra, 0, 0)
NESTED(kcopy, 3, 32, ra, IM_RA|IM_S0|IM_S1, 0)
LDGP(pv)
lda sp, -16(sp) /* set up stack frame */
stq ra, (16-16)(sp) /* save ra */
stq s0, (16-8)(sp) /* save s0 */
lda sp, -32(sp) /* set up stack frame */
stq ra, (32-8)(sp) /* save ra */
stq s0, (32-16)(sp) /* save s0 */
stq s1, (32-24)(sp) /* save s1 */
/* Note: GET_CURPROC() clobbers v0, t0, t8...t11. */
GET_CURPROC(s1)
lda v0, kcopyerr /* set up fault handler. */
.set noat
ldq at_reg, curproc
ldq at_reg, 0(s1)
ldq at_reg, P_ADDR(at_reg)
ldq s0, U_PCB_ONFAULT(at_reg) /* save old handler. */
stq v0, U_PCB_ONFAULT(at_reg)
.set at
CALL(bcopy) /* do the copy. */
.set noat
ldq at_reg, curproc /* restore the old handler. */
ldq at_reg, 0(s1) /* restore the old handler. */
ldq at_reg, P_ADDR(at_reg)
stq s0, U_PCB_ONFAULT(at_reg)
.set at
ldq ra, (16-16)(sp) /* restore ra. */
ldq s0, (16-8)(sp) /* restore s0. */
lda sp, 16(sp) /* kill stack frame. */
ldq ra, (32-8)(sp) /* restore ra. */
ldq s0, (32-16)(sp) /* restore s0. */
ldq s1, (32-24)(sp) /* restore s1. */
lda sp, 32(sp) /* kill stack frame. */
mov zero, v0 /* return 0. */
RET
END(kcopy)
@ -1268,63 +1371,72 @@ NESTED(kcopy, 3, 16, ra, 0, 0)
LEAF(kcopyerr, 0)
LDGP(pv)
.set noat
ldq at_reg, curproc /* restore the old handler. */
ldq at_reg, 0(s1) /* restore the old handler. */
ldq at_reg, P_ADDR(at_reg)
stq s0, U_PCB_ONFAULT(at_reg)
.set at
ldq ra, (16-16)(sp) /* restore ra. */
ldq s0, (16-8)(sp) /* restore s0. */
lda sp, 16(sp) /* kill stack frame. */
ldq ra, (32-8)(sp) /* restore ra. */
ldq s0, (32-16)(sp) /* restore s0. */
ldq s1, (32-24)(sp) /* restore s1. */
lda sp, 32(sp) /* kill stack frame. */
ldiq v0, EFAULT /* return EFAULT. */
RET
END(kcopyerr)
#endif /* UVM */
NESTED(copyin, 3, 16, ra, 0, 0)
NESTED(copyin, 3, 16, ra, IM_RA|IM_S0, 0)
LDGP(pv)
lda sp, -16(sp) /* set up stack frame */
stq ra, (16-8)(sp) /* save ra */
stq s0, (16-16)(sp) /* save s0 */
ldiq t0, VM_MAX_ADDRESS /* make sure that src addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, copyerr /* if it's not, error out. */
/* Note: GET_CURPROC() clobbers v0, t0, t8...t11. */
GET_CURPROC(s0)
lda v0, copyerr /* set up fault handler. */
.set noat
ldq at_reg, curproc
ldq at_reg, 0(s0)
ldq at_reg, P_ADDR(at_reg)
stq v0, U_PCB_ONFAULT(at_reg)
.set at
CALL(bcopy) /* do the copy. */
.set noat
ldq at_reg, curproc /* kill the fault handler. */
ldq at_reg, 0(s0) /* kill the fault handler. */
ldq at_reg, P_ADDR(at_reg)
stq zero, U_PCB_ONFAULT(at_reg)
.set at
ldq ra, (16-8)(sp) /* restore ra. */
ldq s0, (16-16)(sp) /* restore s0. */
lda sp, 16(sp) /* kill stack frame. */
mov zero, v0 /* return 0. */
RET
END(copyin)
NESTED(copyout, 3, 16, ra, 0, 0)
NESTED(copyout, 3, 16, ra, IM_RA|IM_S0, 0)
LDGP(pv)
lda sp, -16(sp) /* set up stack frame */
stq ra, (16-8)(sp) /* save ra */
stq s0, (16-16)(sp) /* save s0 */
ldiq t0, VM_MAX_ADDRESS /* make sure that dest addr */
cmpult a1, t0, t1 /* is in user space. */
beq t1, copyerr /* if it's not, error out. */
/* Note: GET_CURPROC() clobbers v0, t0, t8...t11. */
GET_CURPROC(s0)
lda v0, copyerr /* set up fault handler. */
.set noat
ldq at_reg, curproc
ldq at_reg, 0(s0)
ldq at_reg, P_ADDR(at_reg)
stq v0, U_PCB_ONFAULT(at_reg)
.set at
CALL(bcopy) /* do the copy. */
.set noat
ldq at_reg, curproc /* kill the fault handler. */
ldq at_reg, 0(s0) /* kill the fault handler. */
ldq at_reg, P_ADDR(at_reg)
stq zero, U_PCB_ONFAULT(at_reg)
.set at
ldq ra, (16-8)(sp) /* restore ra. */
ldq s0, (16-16)(sp) /* restore s0. */
lda sp, 16(sp) /* kill stack frame. */
mov zero, v0 /* return 0. */
RET
@ -1333,6 +1445,7 @@ NESTED(copyout, 3, 16, ra, 0, 0)
LEAF(copyerr, 0)
LDGP(pv)
ldq ra, (16-8)(sp) /* restore ra. */
ldq s0, (16-16)(sp) /* restore s0. */
lda sp, 16(sp) /* kill stack frame. */
ldiq v0, EFAULT /* return EFAULT. */
RET
@ -1353,16 +1466,18 @@ XLEAF(fuiword, 1)
ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswberr /* if it's not, error out. */
/* Note: GET_CURPROC() clobbers v0, t0, t8...t11. */
GET_CURPROC(t1)
lda t0, fswberr
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq t0, U_PCB_ONFAULT(at_reg)
.set at
ldq v0, 0(a0)
zap v0, 0xf0, v0
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq zero, U_PCB_ONFAULT(at_reg)
.set at
@ -1375,15 +1490,17 @@ XLEAF(fuisword, 1)
ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswberr /* if it's not, error out. */
/* Note: GET_CURPROC() clobbers v0, t0, t8...t11. */
GET_CURPROC(t1)
lda t0, fswberr
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq t0, U_PCB_ONFAULT(at_reg)
.set at
/* XXX FETCH IT */
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq zero, U_PCB_ONFAULT(at_reg)
.set at
@ -1396,15 +1513,17 @@ XLEAF(fuibyte, 1)
ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswberr /* if it's not, error out. */
/* Note: GET_CURPROC() clobbers v0, t0, t8...t11. */
GET_CURPROC(t1)
lda t0, fswberr
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq t0, U_PCB_ONFAULT(at_reg)
.set at
/* XXX FETCH IT */
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq zero, U_PCB_ONFAULT(at_reg)
.set at
@ -1417,15 +1536,17 @@ LEAF(suword, 2)
ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswberr /* if it's not, error out. */
/* Note: GET_CURPROC() clobbers v0, t0, t8...t11. */
GET_CURPROC(t1)
lda t0, fswberr
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq t0, U_PCB_ONFAULT(at_reg)
.set at
stq a1, 0(a0) /* do the wtore. */
stq a1, 0(a0) /* do the store. */
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq zero, U_PCB_ONFAULT(at_reg)
.set at
@ -1439,15 +1560,17 @@ LEAF(suiword, 2)
ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswberr /* if it's not, error out. */
/* Note: GET_CURPROC() clobbers v0, t0, t8...t11. */
GET_CURPROC(t1)
lda t0, fswberr
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq t0, U_PCB_ONFAULT(at_reg)
.set at
/* XXX STORE IT */
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq zero, U_PCB_ONFAULT(at_reg)
.set at
@ -1461,15 +1584,17 @@ LEAF(susword, 2)
ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswberr /* if it's not, error out. */
/* Note: GET_CURPROC() clobbers v0, t0, t8...t11. */
GET_CURPROC(t1)
lda t0, fswberr
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq t0, U_PCB_ONFAULT(at_reg)
.set at
/* XXX STORE IT */
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq zero, U_PCB_ONFAULT(at_reg)
.set at
@ -1482,15 +1607,17 @@ LEAF(suisword, 2)
ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswberr /* if it's not, error out. */
/* Note: GET_CURPROC() clobbers v0, t0, t8...t11. */
GET_CURPROC(t1)
lda t0, fswberr
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq t0, U_PCB_ONFAULT(at_reg)
.set at
/* XXX STORE IT */
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq zero, U_PCB_ONFAULT(at_reg)
.set at
@ -1505,9 +1632,11 @@ LEAF(subyte, 2)
ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswberr /* if it's not, error out. */
/* Note: GET_CURPROC() clobbers v0, t0, t8...t11. */
GET_CURPROC(t1)
lda t0, fswberr
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq t0, U_PCB_ONFAULT(at_reg)
.set at
@ -1518,7 +1647,7 @@ LEAF(subyte, 2)
or t0, a1, a1 /* put the result together */
stq_u a1, 0(a0) /* and store it. */
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq zero, U_PCB_ONFAULT(at_reg)
.set at
@ -1531,9 +1660,11 @@ LEAF(suibyte, 2)
ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswberr /* if it's not, error out. */
/* Note: GET_CURPROC() clobbers v0, t0, t8...t11. */
GET_CURPROC(t1)
lda t0, fswberr
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq t0, U_PCB_ONFAULT(at_reg)
.set at
@ -1544,7 +1675,7 @@ LEAF(suibyte, 2)
or t0, a1, a1 /* put the result together */
stq_u a1, 0(a0) /* and store it. */
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq zero, U_PCB_ONFAULT(at_reg)
.set at
@ -1573,16 +1704,18 @@ LEAF(fuswintr, 2)
ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswintrberr /* if it's not, error out. */
/* Note: GET_CURPROC() clobbers v0, t0, t8...t11. */
GET_CURPROC(t1)
lda t0, fswintrberr
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq t0, U_PCB_ONFAULT(at_reg)
stq a0, U_PCB_ACCESSADDR(at_reg)
.set at
/* XXX FETCH IT */
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq zero, U_PCB_ONFAULT(at_reg)
.set at
@ -1594,16 +1727,18 @@ LEAF(suswintr, 2)
ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswintrberr /* if it's not, error out. */
/* Note: GET_CURPROC() clobbers v0, t0, t8...t11. */
GET_CURPROC(t1)
lda t0, fswintrberr
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq t0, U_PCB_ONFAULT(at_reg)
stq a0, U_PCB_ACCESSADDR(at_reg)
.set at
/* XXX STORE IT */
.set noat
ldq at_reg, curproc
ldq at_reg, 0(t1)
ldq at_reg, P_ADDR(at_reg)
stq zero, U_PCB_ONFAULT(at_reg)
.set at

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.160 1999/02/12 06:30:08 thorpej Exp $ */
/* $NetBSD: machdep.c,v 1.161 1999/02/23 03:20:02 thorpej Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -82,7 +82,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.160 1999/02/12 06:30:08 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.161 1999/02/23 03:20:02 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -1337,7 +1337,7 @@ haltsys:
/* Kill off any secondary CPUs. */
for (cpu_id = 0; cpu_id < hwrpb->rpb_pcs_cnt; cpu_id++) {
if (cpu_id == hwrpb->rpb_primary_cpu_id ||
cpus[cpu_id] == NULL)
cpu_info[cpu_id].ci_softc == NULL)
continue;
cpu_halt_secondary(cpu_id);
}
@ -1730,7 +1730,6 @@ sendsig(catcher, sig, mask, code)
struct trapframe *frame;
struct sigacts *psp = p->p_sigacts;
int onstack, fsize, rndfsize;
extern struct proc *fpcurproc;
frame = p->p_md.md_tf;
@ -1869,7 +1868,6 @@ sys___sigreturn14(p, v, retval)
syscallarg(struct sigcontext *) sigcntxp;
} */ *uap = v;
struct sigcontext *scp, ksc;
extern struct proc *fpcurproc;
/*
* The trampoline code hands us the context.
@ -1985,7 +1983,6 @@ setregs(p, pack, stack)
u_long stack;
{
struct trapframe *tfp = p->p_md.md_tf;
extern struct proc *fpcurproc;
#ifdef DEBUG
int i;
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: multiproc.s,v 1.2 1998/09/28 21:48:50 thorpej Exp $ */
/* $NetBSD: multiproc.s,v 1.3 1999/02/23 03:20:03 thorpej Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
__KERNEL_RCSID(5, "$NetBSD: multiproc.s,v 1.2 1998/09/28 21:48:50 thorpej Exp $")
__KERNEL_RCSID(5, "$NetBSD: multiproc.s,v 1.3 1999/02/23 03:20:03 thorpej Exp $")
/*
* Multiprocessor glue code.
@ -53,7 +53,7 @@ inc5: .stabs __FILE__,132,0,0,inc5; .loc 1 __LINE__
* make the function call look right, and call cpu_hatch() to finish
* starting up the processor.
*
* We are provided an argument in $27 (pv) (which will be our cpu_softc).
* We are provided an argument in $27 (pv) (which will be our cpu_info).
*/
NESTED_NOPROFILE(cpu_spinup_trampoline,0,0,ra,0,0)
mov pv, s0 /* squirrel away argument */

View File

@ -1,4 +1,4 @@
/* $NetBSD: process_machdep.c,v 1.11 1998/11/19 02:29:49 ross Exp $ */
/* $NetBSD: process_machdep.c,v 1.12 1999/02/23 03:20:03 thorpej Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
@ -54,7 +54,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.11 1998/11/19 02:29:49 ross Exp $");
__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.12 1999/02/23 03:20:03 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -63,10 +63,13 @@ __KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.11 1998/11/19 02:29:49 ross Ex
#include <sys/user.h>
#include <sys/vnode.h>
#include <sys/ptrace.h>
#include <machine/reg.h>
#include <machine/frame.h>
#include <machine/alpha.h>
#include <alpha/alpha/cpuvar.h>
#define process_frame(p) ((p)->p_md.md_tf)
#define process_pcb(p) (&(p)->p_addr->u_pcb)
#define process_fpframe(p) (&(process_pcb(p)->pcb_fp))
@ -123,7 +126,6 @@ process_read_fpregs(p, regs)
struct proc *p;
struct fpreg *regs;
{
extern struct proc *fpcurproc;
if (p == fpcurproc) {
alpha_pal_wrfen(1);
@ -140,7 +142,6 @@ process_write_fpregs(p, regs)
struct proc *p;
struct fpreg *regs;
{
extern struct proc *fpcurproc;
if (p == fpcurproc)
fpcurproc = NULL;

View File

@ -1,4 +1,4 @@
/* $NetBSD: prom.c,v 1.31 1998/11/19 02:29:49 ross Exp $ */
/* $NetBSD: prom.c,v 1.32 1999/02/23 03:20:03 thorpej Exp $ */
/*
* Copyright (c) 1992, 1994, 1995, 1996 Carnegie Mellon University
@ -27,7 +27,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: prom.c,v 1.31 1998/11/19 02:29:49 ross Exp $");
__KERNEL_RCSID(0, "$NetBSD: prom.c,v 1.32 1999/02/23 03:20:03 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -40,6 +40,8 @@ __KERNEL_RCSID(0, "$NetBSD: prom.c,v 1.31 1998/11/19 02:29:49 ross Exp $");
#define ENABLEPROM
#include <machine/prom.h>
#include <alpha/alpha/cpuvar.h>
#include <dev/cons.h>
/* XXX this is to fake out the console routines, while booting. */
@ -61,7 +63,6 @@ static pt_entry_t *
rom_lev1map()
{
struct alpha_pcb *apcb;
extern u_long curpcb;
extern pt_entry_t *kernel_lev1map;
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.39 1998/11/19 02:29:49 ross Exp $ */
/* $NetBSD: trap.c,v 1.40 1999/02/23 03:20:03 thorpej Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@ -35,7 +35,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.39 1998/11/19 02:29:49 ross Exp $");
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.40 1999/02/23 03:20:03 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -63,8 +63,6 @@ __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.39 1998/11/19 02:29:49 ross Exp $");
#include <compat/osf1/osf1_syscall.h>
#endif
struct proc *fpcurproc; /* current user of the FPU */
void userret __P((struct proc *, u_int64_t, u_quad_t));
unsigned long Sfloat_to_reg __P((unsigned int));

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.41 1998/11/19 02:29:49 ross Exp $ */
/* $NetBSD: vm_machdep.c,v 1.42 1999/02/23 03:20:03 thorpej Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@ -31,7 +31,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.41 1998/11/19 02:29:49 ross Exp $");
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.42 1999/02/23 03:20:03 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -68,7 +68,6 @@ cpu_coredump(p, vp, cred, chdr)
int error;
struct md_coredump cpustate;
struct coreseg cseg;
extern struct proc *fpcurproc;
CORE_SETMAGIC(*chdr, COREMAGIC, MID_MACHINE, 0);
chdr->c_hdrsize = ALIGN(sizeof(*chdr));
@ -117,7 +116,6 @@ void
cpu_exit(p)
struct proc *p;
{
extern struct proc *fpcurproc;
if (p == fpcurproc)
fpcurproc = NULL;
@ -149,7 +147,6 @@ cpu_fork(p1, p2)
{
struct user *up = p2->p_addr;
int i;
extern struct proc *fpcurproc;
p2->p_md.md_tf = p1->p_md.md_tf;
p2->p_md.md_flags = p1->p_md.md_flags & MDP_FPUSED;
@ -314,7 +311,6 @@ void
cpu_swapout(p)
struct proc *p;
{
extern struct proc *fpcurproc;
if (p != fpcurproc)
return;

View File

@ -1,4 +1,4 @@
/* $NetBSD: alpha.h,v 1.1 1998/11/19 01:57:56 ross Exp $ */
/* $NetBSD: alpha.h,v 1.2 1999/02/23 03:20:04 thorpej Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -86,7 +86,6 @@ struct mchkinfo {
};
extern int cold;
extern struct proc *fpcurproc;
struct mchkinfo *cpu_mchkinfo __P((void));
void XentArith __P((u_int64_t, u_int64_t, u_int64_t)); /* MAGIC */
@ -128,11 +127,10 @@ void trap_init __P((void));
void enable_nsio_ide __P((bus_space_tag_t));
/* Multiprocessor glue; cpu.c */
struct cpu_softc;
struct cpu_info;
int cpu_iccb_send __P((long, const char *));
void cpu_iccb_receive __P((void));
void cpu_hatch __P((struct cpu_softc *));
void cpu_run_spinup_queue __P((void));
void cpu_hatch __P((struct cpu_info *));
void cpu_halt_secondary __P((unsigned long));
void cpu_spinup_trampoline __P((void)); /* MAGIC */
void cpu_pause __P((unsigned long));

View File

@ -1,4 +1,4 @@
/* $NetBSD: proc.h,v 1.3 1997/04/06 08:47:36 cgd Exp $ */
/* $NetBSD: proc.h,v 1.4 1999/02/23 03:20:04 thorpej Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@ -27,6 +27,11 @@
* rights to redistribute these changes.
*/
#ifdef _KERNEL
/* For `curproc' multiprocessor glue. */
#include <alpha/alpha/cpuvar.h>
#endif /* _KERNEL */
/*
* Machine-dependent part of the proc struct for the Alpha.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: tlsb.c,v 1.16 1999/02/12 01:45:42 thorpej Exp $ */
/* $NetBSD: tlsb.c,v 1.17 1999/02/23 03:20:04 thorpej Exp $ */
/*
* Copyright (c) 1997 by Matthew Jacob
* NASA AMES Research Center.
@ -39,7 +39,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: tlsb.c,v 1.16 1999/02/12 01:45:42 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: tlsb.c,v 1.17 1999/02/23 03:20:04 thorpej Exp $");
#include "opt_multiprocessor.h"
@ -228,21 +228,14 @@ tlsbattach(parent, self, aux)
* XXX per-CPU interrupt queue?
*/
printf("%s node %d: routing interrupts to %s\n",
self->dv_xname, node,
cpus[hwrpb->rpb_primary_cpu_id]->sc_dev.dv_xname);
self->dv_xname, node,
cpu_info[hwrpb->rpb_primary_cpu_id].ci_dev->dv_xname);
TLSB_PUT_NODEREG(node, TLCPUMASK,
(1UL << hwrpb->rpb_primary_cpu_id));
printf("%s node %d: routing interrupts to %s\n",
self->dv_xname, node,
cpus[hwrpb->rpb_primary_cpu_id]->sc_dev.dv_xname);
#else
/*
* Make sure interrupts are sent to the primary
* CPU.
* Make sure interrupts are sent to the primary CPU.
*/
printf("%s node %d: routing interrupts to cpu id %lu\n",
self->dv_xname, node,
hwrpb->rpb_primary_cpu_id);
TLSB_PUT_NODEREG(node, TLCPUMASK,
(1UL << hwrpb->rpb_primary_cpu_id));
#endif /* MULTIPROCESSOR */