Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch Detect and spin up non-boot CPUs.
details: https://anonhg.NetBSD.org/src/rev/8627a2948edc
branches: trunk
changeset: 761320:8627a2948edc
user: skrll <skrll%NetBSD.org@localhost>
date: Sun Jan 23 21:53:39 2011 +0000
description:
Detect and spin up non-boot CPUs.
Mostly from OpenBSD.
diffstat:
sys/arch/hp700/dev/cpu.c | 149 +++++++++++++++++++++++++++++++++++---
sys/arch/hp700/hp700/genassym.cf | 4 +-
sys/arch/hp700/hp700/locore.S | 137 +++++++++++++++++++++++++++++++++++-
sys/arch/hp700/hp700/machdep.c | 14 +++-
sys/arch/hp700/hp700/mainbus.c | 22 ++---
sys/arch/hp700/include/cpu.h | 22 ++++-
sys/arch/hppa/hppa/machdep.h | 5 +-
7 files changed, 315 insertions(+), 38 deletions(-)
diffs (truncated from 573 to 300 lines):
diff -r 9158df1c72f1 -r 8627a2948edc sys/arch/hp700/dev/cpu.c
--- a/sys/arch/hp700/dev/cpu.c Sun Jan 23 21:29:52 2011 +0000
+++ b/sys/arch/hp700/dev/cpu.c Sun Jan 23 21:53:39 2011 +0000
@@ -1,6 +1,6 @@
-/* $NetBSD: cpu.c,v 1.16 2010/12/08 09:48:27 skrll Exp $ */
+/* $NetBSD: cpu.c,v 1.17 2011/01/23 21:53:39 skrll Exp $ */
-/* $OpenBSD: cpu.c,v 1.28 2004/12/28 05:18:25 mickey Exp $ */
+/* $OpenBSD: cpu.c,v 1.29 2009/02/08 18:33:28 miod Exp $ */
/*
* Copyright (c) 1998-2003 Michael Shalayeff
@@ -29,13 +29,17 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.16 2010/12/08 09:48:27 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.17 2011/01/23 21:53:39 skrll Exp $");
+
+#include "opt_multiprocessor.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/reboot.h>
+#include <uvm/uvm.h>
+
#include <machine/cpufunc.h>
#include <machine/pdc.h>
#include <machine/iomod.h>
@@ -53,6 +57,9 @@
#ifdef MULTIPROCESSOR
int hppa_ncpus;
+
+struct cpu_info *cpu_hatch_info;
+static volatile int start_secondary_cpu;
#endif
int cpumatch(device_t, cfdata_t, void *);
@@ -61,20 +68,19 @@
CFATTACH_DECL_NEW(cpu, sizeof(struct cpu_softc),
cpumatch, cpuattach, NULL, NULL);
-static int cpu_attached;
-
int
cpumatch(device_t parent, cfdata_t cf, void *aux)
{
struct confargs *ca = aux;
- /* there will be only one for now XXX */
/* probe any 1.0, 1.1 or 2.0 */
- if (cpu_attached ||
- ca->ca_type.iodc_type != HPPA_TYPE_NPROC ||
+ if (ca->ca_type.iodc_type != HPPA_TYPE_NPROC ||
ca->ca_type.iodc_sv_model != HPPA_NPROC_HPPA)
return 0;
+ if (cf->cf_unit >= MAXCPUS)
+ return 0;
+
return 1;
}
@@ -89,11 +95,22 @@
struct cpu_softc *sc = device_private(self);
struct confargs *ca = aux;
- const char lvls[4][4] = { "0", "1", "1.5", "2" };
+ struct cpu_info *ci;
+ static const char lvls[4][4] = { "0", "1", "1.5", "2" };
u_int mhz = 100 * cpu_ticksnum / cpu_ticksdenom;
+ int cpuno = device_unit(self);
+
+#ifdef MULTIPROCESSOR
+ struct pglist mlist;
+ struct vm_page *m;
+ int error;
+#endif
sc->sc_dev = self;
- cpu_attached = 1;
+
+ ci = &cpus[cpuno];
+ ci->ci_cpuid = cpuno;
+ ci->ci_hpa = ca->ca_hpa;
/* Print the CPU chip name, nickname, and rev. */
aprint_normal(": %s", hppa_cpu_info->hci_chip_name);
@@ -151,13 +168,43 @@
aprint_normal("\n");
/* sanity against luser amongst config editors */
- if (ca->ca_irq == 31) {
- sc->sc_ih = hp700_intr_establish(IPL_CLOCK, clock_intr,
- NULL /*clockframe*/, &int_reg_cpu, ca->ca_irq);
+ if (ca->ca_irq != 31) {
+ aprint_error_dev(self, "bad irq number %d\n", ca->ca_irq);
+ return;
+ }
+
+ sc->sc_ih = hp700_intr_establish(IPL_CLOCK, clock_intr,
+ NULL /*clockframe*/, &int_reg_cpu, 31);
+
+#ifdef MULTIPROCESSOR
+
+ /* Allocate stack for spin up and FPU emulation. */
+ TAILQ_INIT(&mlist);
+ error = uvm_pglistalloc(PAGE_SIZE, 0, -1L, PAGE_SIZE, 0, &mlist, 1,
+ 0);
+
+ if (error) {
+ aprint_error(": unable to allocate CPU stack!\n");
+ return;
+ }
+ m = TAILQ_FIRST(&mlist);
+ ci->ci_stack = VM_PAGE_TO_PHYS(m);
+
+ if (ci->ci_hpa == hppa_mcpuhpa) {
+ ci->ci_flags |= CPUF_PRIMARY|CPUF_RUNNING;
} else {
- aprint_error_dev(self, "bad irq number %d\n", ca->ca_irq);
+ int err;
+
+ err = mi_cpu_attach(ci);
+ if (err) {
+ aprint_error_dev(self,
+ "mi_cpu_attach failed with %d\n", err);
+ return;
+ }
}
+#endif
+
/*
* Set the allocatable bits in the CPU interrupt registers.
* These should only be used by major chipsets, like ASP and
@@ -168,3 +215,77 @@
int_reg_cpu.int_reg_allocatable_bits =
(1 << 28) | (1 << 27) | (1 << 26);
}
+
+
+#ifdef MULTIPROCESSOR
+void
+cpu_boot_secondary_processors(void)
+{
+ struct cpu_info *ci;
+ struct iomod *cpu;
+ int i, j;
+
+ for (i = 0; i < HPPA_MAXCPUS; i++) {
+
+ ci = &cpus[i];
+ if (ci->ci_cpuid == 0)
+ continue;
+
+ if (ci->ci_data.cpu_idlelwp == NULL)
+ continue;
+
+ if (ci->ci_flags & CPUF_PRIMARY)
+ continue;
+
+ /* Release the specified CPU by triggering an EIR{0}. */
+ cpu_hatch_info = ci;
+ cpu = (struct iomod *)(ci->ci_hpa);
+ cpu->io_eir = 0;
+ membar_sync();
+
+ /* Wait for CPU to wake up... */
+ j = 0;
+ while (!(ci->ci_flags & CPUF_RUNNING) && j++ < 10000)
+ delay(1000);
+ if (!(ci->ci_flags & CPUF_RUNNING))
+ printf("failed to hatch cpu %i!\n", ci->ci_cpuid);
+ }
+
+ /* Release secondary CPUs. */
+ start_secondary_cpu = 1;
+ membar_sync();
+}
+
+void
+cpu_hw_init(void)
+{
+ struct cpu_info *ci = curcpu();
+
+ /* Purge TLB and flush caches. */
+ ptlball();
+ fcacheall();
+
+ /* Enable address translations. */
+ ci->ci_psw = PSW_I | PSW_Q | PSW_P | PSW_C | PSW_D;
+ ci->ci_psw |= (cpus[0].ci_psw & PSW_O);
+
+ ci->ci_curlwp = ci->ci_data.cpu_idlelwp;
+}
+
+void
+cpu_hatch(void)
+{
+ struct cpu_info *ci = curcpu();
+
+ ci->ci_flags |= CPUF_RUNNING;
+
+ /* Wait for additional CPUs to spinup. */
+ while (!start_secondary_cpu)
+ ;
+
+ /* Spin for now */
+ for (;;)
+ ;
+
+}
+#endif
diff -r 9158df1c72f1 -r 8627a2948edc sys/arch/hp700/hp700/genassym.cf
--- a/sys/arch/hp700/hp700/genassym.cf Sun Jan 23 21:29:52 2011 +0000
+++ b/sys/arch/hp700/hp700/genassym.cf Sun Jan 23 21:53:39 2011 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.30 2011/01/23 09:44:58 skrll Exp $
+# $NetBSD: genassym.cf,v 1.31 2011/01/23 21:53:39 skrll Exp $
# $OpenBSD: genassym.cf,v 1.18 2001/09/20 18:31:14 mickey Exp $
@@ -101,9 +101,9 @@
define CI_FPU_STATE offsetof(struct cpu_info, ci_fpu_state)
ifdef MULTIPROCESSOR
define CI_CURLWP offsetof(struct cpu_info, ci_curlwp)
+define CI_STACK offsetof(struct cpu_info, ci_stack)
endif
-
define MTX_IPL offsetof(struct kmutex, mtx_ipl)
define MTX_LOCK offsetof(struct kmutex, mtx_lock)
define MTX_OWNER offsetof(struct kmutex, mtx_owner)
diff -r 9158df1c72f1 -r 8627a2948edc sys/arch/hp700/hp700/locore.S
--- a/sys/arch/hp700/hp700/locore.S Sun Jan 23 21:29:52 2011 +0000
+++ b/sys/arch/hp700/hp700/locore.S Sun Jan 23 21:53:39 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.S,v 1.52 2011/01/23 09:44:58 skrll Exp $ */
+/* $NetBSD: locore.S,v 1.53 2011/01/23 21:53:39 skrll Exp $ */
/* $OpenBSD: locore.S,v 1.158 2008/07/28 19:08:46 miod Exp $ */
/*
@@ -258,6 +258,18 @@
*/
mtctl %r0, %ccr
+#ifdef MULTIPROCESSOR
+
+#define PZ_MEM_RENDEZ 0x10
+#define PZ_MEM_RENDEZ_HI 0x28
+
+ /* Setup SMP rendezvous address. */
+ ldil L%hw_cpu_spinup_trampoline, %r1
+ ldo R%hw_cpu_spinup_trampoline(%r1), %r1
+ stw %r1, PZ_MEM_RENDEZ(%r0)
+ stw %r0, PZ_MEM_RENDEZ_HI(%r0)
+#endif
+
/*
* We need to set the Q bit so that we can take TLB misses after we
* turn on virtual memory.
@@ -411,6 +423,129 @@
nop
EXIT(kernel_setup)
+
+#ifdef MULTIPROCESSOR
+/*
+ * Trampoline to spin up secondary processors.
+ */
+LEAF_ENTRY_NOPROFILE(hw_cpu_spinup_trampoline)
+
+ /*
+ * disable interrupts and turn off all bits in the psw so that
+ * we start in a known state.
+ */
+ rsm RESET_PSW, %r0
+ nop ! nop ! nop ! nop ! nop ! nop
+
+ /* go to virtual mode...
+ /* get things ready for the kernel to run in virtual mode */
+ ldi HPPA_PID_KERNEL, %r1
+ mtctl %r1, %pidr1
+ mtctl %r1, %pidr2
+#if pbably_not_worth_it
+ mtctl %r0, %pidr3
+ mtctl %r0, %pidr4
+#endif
+ mtsp %r0, %sr0
+ mtsp %r0, %sr1
+ mtsp %r0, %sr2
+ mtsp %r0, %sr3
+ mtsp %r0, %sr4
+ mtsp %r0, %sr5
+ mtsp %r0, %sr6
+ mtsp %r0, %sr7
Home |
Main Index |
Thread Index |
Old Index