more SMP work:
make IPI's work. modify boot_secondary_processors() to clear the startup flag in each cpu. new raise_ipi_wait_and_unlock() that calls raise_ipi(), waits for the cpu to acknowledge it got the message, and then unlocks the msglock. use the new framework in mp_{pause,resume}_cpus(). nmi_soft() takes a `struct trapframe *', to be used by ddb.
This commit is contained in:
parent
ba991d978b
commit
d3b1cc167d
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cpu.c,v 1.118 2001/05/26 21:27:14 chs Exp $ */
|
||||
/* $NetBSD: cpu.c,v 1.119 2001/06/07 17:59:47 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
@ -52,12 +52,14 @@
|
||||
*/
|
||||
|
||||
#include "opt_multiprocessor.h"
|
||||
#include "opt_lockdebug.h"
|
||||
#include "opt_ddb.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/lock.h>
|
||||
|
||||
#include <uvm/uvm.h>
|
||||
|
||||
@ -104,7 +106,6 @@ struct cfattach cpu_ca = {
|
||||
static char *fsrtoname __P((int, int, int));
|
||||
void cache_print __P((struct cpu_softc *));
|
||||
void cpu_setup __P((struct cpu_softc *));
|
||||
void cpu_spinup __P((struct cpu_softc *));
|
||||
void fpu_init __P((struct cpu_info *));
|
||||
|
||||
#define IU_IMPL(psr) ((u_int)(psr) >> 28)
|
||||
@ -114,9 +115,11 @@ void fpu_init __P((struct cpu_info *));
|
||||
#define SRMMU_VERS(mmusr) (((mmusr) >> 24) & 0xf)
|
||||
|
||||
#if defined(MULTIPROCESSOR)
|
||||
void cpu_spinup __P((struct cpu_softc *));
|
||||
struct cpu_info *alloc_cpuinfo_global_va __P((int, vsize_t *));
|
||||
struct cpu_info *alloc_cpuinfo __P((void));
|
||||
|
||||
|
||||
struct cpu_info *
|
||||
alloc_cpuinfo_global_va(ismaster, sizep)
|
||||
int ismaster;
|
||||
@ -203,6 +206,7 @@ alloc_cpuinfo()
|
||||
pmap_update();
|
||||
|
||||
bzero((void *)cpi, sz);
|
||||
cpi->flags = CPUFLG_STARTUP;
|
||||
cpi->eintstack = (void *)((vaddr_t)cpi + sz);
|
||||
cpi->idle_u = (void *)((vaddr_t)cpi + sz - INT_STACK_SIZE - USPACE);
|
||||
|
||||
@ -398,19 +402,31 @@ static struct cpu_softc *bootcpu;
|
||||
void
|
||||
cpu_boot_secondary_processors()
|
||||
{
|
||||
|
||||
/*
|
||||
* XXX This is currently a noop; the CPUs are already running, but
|
||||
* XXX aren't doing anything. Eventually, this will release a
|
||||
* XXX semaphore that all those secondary processors are anxiously
|
||||
* XXX waiting on.
|
||||
*/
|
||||
int n;
|
||||
|
||||
if (cpu_instance != ncpu) {
|
||||
printf("NOTICE: only %d out of %d CPUs were configured\n",
|
||||
cpu_instance, ncpu);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cpus == NULL)
|
||||
return;
|
||||
|
||||
/* Tell the other CPU's to start up. */
|
||||
printf("cpu0: booting secondary processors:");
|
||||
for (n = 0; n < ncpu; n++) {
|
||||
struct cpu_info *cpi = cpus[n];
|
||||
|
||||
if (cpi == NULL || cpuinfo.mid == cpi->mid)
|
||||
continue;
|
||||
|
||||
printf(" cpu%d", cpi->ci_cpuid);
|
||||
|
||||
/* tell it to continue */
|
||||
//cpi->flags &= ~CPUFLG_STARTUP;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif /* MULTIPROCESSOR */
|
||||
|
||||
@ -444,6 +460,7 @@ cpu_setup(sc)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(MULTIPROCESSOR)
|
||||
/*
|
||||
* Allocate per-CPU data, then start up this CPU using PROM.
|
||||
*/
|
||||
@ -451,7 +468,6 @@ void
|
||||
cpu_spinup(sc)
|
||||
struct cpu_softc *sc;
|
||||
{
|
||||
#if defined(MULTIPROCESSOR)
|
||||
struct cpu_info *cpi = sc->sc_cpuinfo;
|
||||
int n;
|
||||
extern void cpu_hatch __P((void)); /* in locore.s */
|
||||
@ -491,13 +507,31 @@ extern void cpu_hatch __P((void)); /* in locore.s */
|
||||
delay(100);
|
||||
}
|
||||
printf("CPU did not spin up\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
raise_ipi_wait_and_unlock(cpi)
|
||||
struct cpu_info *cpi;
|
||||
{
|
||||
int i;
|
||||
|
||||
raise_ipi(cpi);
|
||||
i = 0;
|
||||
while ((cpi->flags & CPUFLG_GOTMSG) == 0) {
|
||||
if (i++ > 10000) {
|
||||
printf("raise_ipi_wait_and_unlock(cpu%d): couldn't ping cpu%d\n",
|
||||
cpuinfo.ci_cpuid, cpi->ci_cpuid);
|
||||
break;
|
||||
}
|
||||
delay(1);
|
||||
cpuinfo.cache_flush((caddr_t)&cpi->flags, sizeof(cpi->flags));
|
||||
}
|
||||
simple_unlock(&cpi->msg.lock);
|
||||
}
|
||||
|
||||
void
|
||||
mp_pause_cpus()
|
||||
{
|
||||
#if defined(MULTIPROCESSOR)
|
||||
int n;
|
||||
|
||||
if (cpus == NULL)
|
||||
@ -505,19 +539,20 @@ mp_pause_cpus()
|
||||
|
||||
for (n = 0; n < ncpu; n++) {
|
||||
struct cpu_info *cpi = cpus[n];
|
||||
|
||||
if (cpi == NULL || cpuinfo.mid == cpi->mid)
|
||||
continue;
|
||||
|
||||
simple_lock(&cpi->msg.lock);
|
||||
cpi->msg.tag = XPMSG_PAUSECPU;
|
||||
raise_ipi(cpi);
|
||||
cpi->flags &= ~CPUFLG_GOTMSG;
|
||||
raise_ipi_wait_and_unlock(cpi);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
mp_resume_cpus()
|
||||
{
|
||||
#if defined(MULTIPROCESSOR)
|
||||
int n;
|
||||
|
||||
if (cpus == NULL)
|
||||
@ -525,15 +560,15 @@ mp_resume_cpus()
|
||||
|
||||
for (n = 0; n < ncpu; n++) {
|
||||
struct cpu_info *cpi = cpus[n];
|
||||
|
||||
if (cpi == NULL || cpuinfo.mid == cpi->mid)
|
||||
continue;
|
||||
|
||||
simple_lock(&cpi->msg.lock);
|
||||
cpi->msg.tag = XPMSG_RESUMECPU;
|
||||
raise_ipi(cpi);
|
||||
/* tell it to continue */
|
||||
cpi->flags &= ~CPUFLG_PAUSED;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif /* MULTIPROCESSOR */
|
||||
|
||||
/*
|
||||
* fpu_init() must be run on associated CPU.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cpuvar.h,v 1.33 2001/06/03 04:03:29 mrg Exp $ */
|
||||
/* $NetBSD: cpuvar.h,v 1.34 2001/06/07 17:59:48 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 The NetBSD Foundation, Inc.
|
||||
@ -393,6 +393,9 @@ void getcpuinfo __P((struct cpu_info *sc, int node));
|
||||
void mmu_install_tables __P((struct cpu_info *));
|
||||
void pmap_alloc_cpu __P((struct cpu_info *));
|
||||
void pmap_globalize_boot_cpu __P((struct cpu_info *));
|
||||
#if defined(MULTIPROCESSOR)
|
||||
void raise_ipi_wait_and_unlock __P((struct cpu_info *));
|
||||
#endif
|
||||
|
||||
extern struct cpu_info **cpus;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: intr.c,v 1.50 2001/03/22 15:56:43 mrg Exp $ */
|
||||
/* $NetBSD: intr.c,v 1.51 2001/06/07 17:59:48 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -159,7 +159,7 @@ soft01intr(fp)
|
||||
|
||||
#if defined(SUN4M)
|
||||
void nmi_hard __P((void));
|
||||
void nmi_soft __P((void));
|
||||
void nmi_soft __P((struct trapframe *));
|
||||
|
||||
int (*memerr_handler) __P((void));
|
||||
int (*sbuserr_handler) __P((void));
|
||||
@ -198,7 +198,7 @@ nmi_hard()
|
||||
* Examine pending system interrupts.
|
||||
*/
|
||||
si = *((u_int32_t *)ICR_SI_PEND);
|
||||
printf("NMI: system interrupts: %s\n",
|
||||
printf("cpu%d: NMI: system interrupts: %s\n", cpu_number(),
|
||||
bitmask_snprintf(si, SINTR_BITS, bits, sizeof(bits)));
|
||||
|
||||
if ((si & SINTR_M) != 0) {
|
||||
@ -227,28 +227,24 @@ nmi_hard()
|
||||
}
|
||||
|
||||
void
|
||||
nmi_soft()
|
||||
nmi_soft(tf)
|
||||
struct trapframe *tf;
|
||||
{
|
||||
|
||||
#ifdef MULTIPROCESSOR
|
||||
switch (cpuinfo.msg.tag) {
|
||||
case XPMSG_SAVEFPU: {
|
||||
savefpstate(cpuinfo.fpproc->p_md.md_fpstate);
|
||||
cpuinfo.fpproc->p_md.md_fpumid = -1;
|
||||
cpuinfo.fpproc = NULL;
|
||||
}
|
||||
break;
|
||||
case XPMSG_PAUSECPU: {
|
||||
cpuinfo.flags |= 0x4000;
|
||||
while (cpuinfo.flags & 0x4000) {
|
||||
simple_unlock(&cpuinfo.msg.lock);
|
||||
delay(1);
|
||||
simple_lock(&cpuinfo.msg.lock);
|
||||
cpuinfo.flags |= CPUFLG_PAUSED|CPUFLG_GOTMSG;
|
||||
while (cpuinfo.flags & CPUFLG_PAUSED)
|
||||
cpuinfo.cache_flush((caddr_t)&cpuinfo.flags, sizeof(cpuinfo.flags));
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XPMSG_RESUMECPU: {
|
||||
cpuinfo.flags &= ~0x4000;
|
||||
}
|
||||
break;
|
||||
case XPMSG_VCACHE_FLUSH_PAGE: {
|
||||
struct xpmsg_flush_page *p = &cpuinfo.msg.u.xpmsg_flush_page;
|
||||
int ctx = getcontext();
|
||||
@ -290,7 +286,6 @@ nmi_soft()
|
||||
}
|
||||
break;
|
||||
}
|
||||
simple_unlock(&cpuinfo.msg.lock);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user