Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/macppc/macppc First attempt to spin up the secondar...
details: https://anonhg.NetBSD.org/src/rev/44e83b0707e4
branches: trunk
changeset: 494314:44e83b0707e4
user: tsubai <tsubai%NetBSD.org@localhost>
date: Wed Jul 05 16:02:38 2000 +0000
description:
First attempt to spin up the secondary processor on 180MP and 200MP.
XXX Need more work.
diffstat:
sys/arch/macppc/macppc/cpu.c | 275 ++++++++++++++++++++++++++++++++++++++-
sys/arch/macppc/macppc/locore.S | 24 +++-
sys/arch/macppc/macppc/machdep.c | 54 +-------
sys/arch/macppc/macppc/mainbus.c | 14 +-
4 files changed, 303 insertions(+), 64 deletions(-)
diffs (truncated from 490 to 300 lines):
diff -r 0f645cbb49b2 -r 44e83b0707e4 sys/arch/macppc/macppc/cpu.c
--- a/sys/arch/macppc/macppc/cpu.c Wed Jul 05 15:45:28 2000 +0000
+++ b/sys/arch/macppc/macppc/cpu.c Wed Jul 05 16:02:38 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.6 2000/02/08 12:49:06 tsubai Exp $ */
+/* $NetBSD: cpu.c,v 1.7 2000/07/05 16:02:38 tsubai Exp $ */
/*-
* Copyright (C) 1998, 1999 Internet Research Institute, Inc.
@@ -31,26 +31,55 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "opt_multiprocessor.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <uvm/uvm_extern.h>
#include <dev/ofw/openfirm.h>
+
#include <machine/autoconf.h>
+#include <machine/bat.h>
+#include <machine/pcb.h>
+#include <machine/pio.h>
-static int cpumatch __P((struct device *, struct cfdata *, void *));
-static void cpuattach __P((struct device *, struct device *, void *));
+int cpumatch(struct device *, struct cfdata *, void *);
+void cpuattach(struct device *, struct device *, void *);
-static void ohare_init __P((void));
-static void display_l2cr __P((void));
+void identifycpu(char *);
+static void ohare_init(void);
+static void display_l2cr(void);
+int cpu_spinup(void);
+void cpu_hatch(void);
+
+void cpu_spinup_trampoline(void);
struct cfattach cpu_ca = {
sizeof(struct device), cpumatch, cpuattach
};
+int ncpus;
+
extern struct cfdriver cpu_cd;
extern int powersave;
+#define HAMMERHEAD 0xf8000000
+#define HH_ARBCONF (HAMMERHEAD + 0x90)
+#define HH_INTR (HAMMERHEAD + 0xc0)
+
+/* XXX for now */
+#undef cpu_number
+static inline int
+cpu_number()
+{
+ int pir;
+
+ asm ("mfspr %0,1023" : "=r"(pir));
+ return pir;
+}
+
int
cpumatch(parent, cf, aux)
struct device *parent;
@@ -58,11 +87,23 @@
void *aux;
{
struct confargs *ca = aux;
+ int *reg = ca->ca_reg;
+ int hammerhead;
if (strcmp(ca->ca_name, cpu_cd.cd_name))
return 0;
- return 1;
+ switch (reg[0]) {
+ case 0: /* master CPU */
+ return 1;
+ case 1: /* secondary CPU */
+ hammerhead = OF_finddevice("/hammerhead");
+ if (hammerhead == -1)
+ return 0;
+ if (in32rb(HH_ARBCONF) & 0x02)
+ return 1;
+ }
+ return 0;
}
#define MPC601 1
@@ -83,7 +124,29 @@
struct device *parent, *self;
void *aux;
{
+ struct confargs *ca = aux;
+ int *reg = ca->ca_reg;
int hid0, pvr;
+ char model[80];
+
+ ncpus++;
+
+ switch (reg[0]) {
+ case 0:
+ asm volatile ("mtspr 1023,%0" :: "r"(0)); /* PIR */
+ identifycpu(model);
+ printf(": %s, ID %d (primary)", model, cpu_number());
+ break;
+/* #ifdef MULTIPROCESSOR */
+ case 1:
+ cpu_spinup();
+ printf("\n");
+ return;
+/* #endif */
+ default:
+ printf(": more than 2 cpus?\n");
+ panic("cpuattach");
+ }
__asm __volatile ("mfpvr %0" : "=r"(pvr));
switch (pvr >> 16) {
@@ -116,6 +179,47 @@
printf("\n");
}
+struct cputab {
+ int version;
+ char *name;
+};
+static struct cputab models[] = {
+ { 1, "601" },
+ { 3, "603" },
+ { 4, "604" },
+ { 5, "602" },
+ { 6, "603e" },
+ { 7, "603ev" },
+ { 8, "750" },
+ { 9, "604ev" },
+ { 12, "7400" },
+ { 20, "620" },
+ { 0, NULL }
+};
+
+void
+identifycpu(cpu_model)
+ char *cpu_model;
+{
+ int pvr, vers, rev;
+ struct cputab *cp = models;
+
+ asm ("mfpvr %0" : "=r"(pvr));
+ vers = pvr >> 16;
+ rev = pvr & 0xffff;
+
+ while (cp->name) {
+ if (cp->version == vers)
+ break;
+ cp++;
+ }
+ if (cp->name)
+ strcpy(cpu_model, cp->name);
+ else
+ sprintf(cpu_model, "Version %x", vers);
+ sprintf(cpu_model + strlen(cpu_model), " (Revision %x)", rev);
+}
+
#define CACHE_REG 0xf8000000
void
@@ -210,3 +314,162 @@
}
printf("\n");
}
+
+/* #ifdef MULTIPROCESSOR */
+struct cpu_hatch_data {
+ int running;
+ int pir;
+ int hid0;
+ int sdr1;
+ int sr[16];
+ int tbu, tbl;
+};
+
+volatile struct cpu_hatch_data *cpu_hatch_data;
+volatile int cpu_hatchstack;
+
+int
+cpu_spinup()
+{
+ volatile struct cpu_hatch_data hatch_data, *h = &hatch_data;
+ int i;
+ struct pcb *pcb;
+ struct pglist mlist;
+ int error;
+
+ /*
+ * Allocate UPAGES contiguous pages for the idle PCB and stack
+ * from the lowest 256MB (because bat0 always maps it va == pa).
+ */
+ TAILQ_INIT(&mlist);
+ error = uvm_pglistalloc(USPACE, 0x0, 0x10000000, 0, 0, &mlist, 1, 1);
+ if (error) {
+ printf(": unable to allocate idle stack");
+ return -1;
+ }
+
+ pcb = (void *)VM_PAGE_TO_PHYS(TAILQ_FIRST(&mlist));
+ bzero(pcb, USPACE);
+
+ /*
+ * Initialize the idle stack pointer, reserving space for an
+ * (empty) trapframe (XXX is the trapframe really necessary?)
+ */
+ pcb->pcb_sp = (paddr_t)pcb + USPACE - sizeof(struct trapframe);
+
+ cpu_hatch_data = h;
+ h->running = 0;
+ h->pir = 1;
+ cpu_hatchstack = pcb->pcb_sp;
+
+ /* copy special registers */
+ asm volatile ("mfspr %0,1008" : "=r"(h->hid0));
+ asm volatile ("mfsdr1 %0" : "=r"(h->sdr1));
+ for (i = 0; i < 16; i++)
+ asm ("mfsrin %0,%1" : "=r"(h->sr[i]) : "r"(i << ADDR_SR_SHFT));
+
+ asm volatile ("sync; isync");
+
+ /* Start secondary cpu and stop timebase. */
+ out32(0xf2800000, (int)cpu_spinup_trampoline);
+ out32(HH_INTR, ~0);
+ out32(HH_INTR, 0);
+
+ /* sync timebase (XXX shouldn't be zero'ed) */
+ asm volatile ("mttbl %0; mttbu %0; mttbl %0" :: "r"(0));
+
+ /*
+ * wait for secondary spin up (1.5ms @ 604/200MHz)
+ * XXX we cannot use delay() here because timebase is not running.
+ */
+ for (i = 0; i < 100000; i++)
+ if (h->running)
+ break;
+
+ /* Start timebase. */
+ out32(0xf2800000, 0x100);
+ out32(HH_INTR, ~0);
+ out32(HH_INTR, 0);
+
+ delay(100000); /* wait for secondary printf */
+
+ if (h->running == 0) {
+ printf(": secondary cpu didn't start");
+ return -1;
+ }
+
+ return 0;
+}
+
+void
+cpu_hatch()
+{
+ volatile struct cpu_hatch_data *h = cpu_hatch_data;
+ u_int msr;
+ int i;
+ char model[80];
+
+ /* Initialize timebase. */
+ asm ("mttbl %0; mttbu %0; mttbl %0" :: "r"(0));
+
+ /* Set PIR (Processor Identification Register). i.e. whoami */
+ asm volatile ("mtspr 1023,%0" :: "r"(h->pir));
+
+ /* Initialize MMU. */
+ asm ("mtibatu 0,%0" :: "r"(0));
+ asm ("mtibatu 1,%0" :: "r"(0));
+ asm ("mtibatu 2,%0" :: "r"(0));
+ asm ("mtibatu 3,%0" :: "r"(0));
+ asm ("mtdbatu 0,%0" :: "r"(0));
+ asm ("mtdbatu 1,%0" :: "r"(0));
+ asm ("mtdbatu 2,%0" :: "r"(0));
+ asm ("mtdbatu 3,%0" :: "r"(0));
+
+ asm ("mtspr 1008,%0" :: "r"(h->hid0));
+
+ asm ("mtibatl 0,%0; mtibatu 0,%1;"
+ "mtdbatl 0,%0; mtdbatu 0,%1;"
+ :: "r"(battable[0].batl), "r"(battable[0].batu));
+
+ /* XXX obio (for now) */
+ asm ("mtibatl 1,%0; mtibatu 1,%1;"
+ "mtdbatl 1,%0; mtdbatu 1,%1;"
+ :: "r"(battable[0xf].batl), "r"(battable[0xf].batu));
+
+ for (i = 0; i < 16; i++)
+ asm ("mtsrin %0,%1" :: "r"(h->sr[i]), "r"(i << ADDR_SR_SHFT));
Home |
Main Index |
Thread Index |
Old Index