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