summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorTakuya ASADA <syuu@cvs.openbsd.org>2009-10-30 08:13:58 +0000
committerTakuya ASADA <syuu@cvs.openbsd.org>2009-10-30 08:13:58 +0000
commit7b2ee8a540c68bc249a4734323bb044e004e7bd0 (patch)
tree0254ef28bec4f8b9a50f9d123bb7907e7e80d12d /sys/arch
parent95686a4205e4b4f0e746d26a3ad510beaa475f29 (diff)
Support IP30 secondary cpu bootup. ok miod@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/mips64/include/cpu.h4
-rw-r--r--sys/arch/mips64/mips64/cpu.c19
-rw-r--r--sys/arch/sgi/include/autoconf.h3
-rw-r--r--sys/arch/sgi/include/cpu.h8
-rw-r--r--sys/arch/sgi/sgi/ip30.h24
-rw-r--r--sys/arch/sgi/sgi/ip30_machdep.c156
-rw-r--r--sys/arch/sgi/sgi/locore.S16
-rw-r--r--sys/arch/sgi/sgi/mainbus.c15
8 files changed, 226 insertions, 19 deletions
diff --git a/sys/arch/mips64/include/cpu.h b/sys/arch/mips64/include/cpu.h
index a1eb25d6591..25c16aee8c5 100644
--- a/sys/arch/mips64/include/cpu.h
+++ b/sys/arch/mips64/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.41 2009/10/22 22:08:52 miod Exp $ */
+/* $OpenBSD: cpu.h,v 1.42 2009/10/30 08:13:57 syuu Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -403,6 +403,8 @@ extern struct cpuset cpus_running;
extern struct cpu_info *cpu_info[];
void cpu_unidle(struct cpu_info *);
void cpu_boot_secondary_processors(void);
+#define cpu_boot_secondary(ci) hw_cpu_boot_secondary(ci)
+#define cpu_hatch(ci) hw_cpu_hatch(ci)
#include <sys/mplock.h>
#else
diff --git a/sys/arch/mips64/mips64/cpu.c b/sys/arch/mips64/mips64/cpu.c
index 428285ee1ef..8d14587e6ec 100644
--- a/sys/arch/mips64/mips64/cpu.c
+++ b/sys/arch/mips64/mips64/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.15 2009/10/26 20:14:40 miod Exp $ */
+/* $OpenBSD: cpu.c,v 1.16 2009/10/30 08:13:57 syuu Exp $ */
/*
* Copyright (c) 1997-2004 Opsycon AB (www.opsycon.se)
@@ -99,13 +99,11 @@ cpuattach(struct device *parent, struct device *dev, void *aux)
int isr16k = 0;
int displayver;
-#ifdef MULTIPROCESSOR
- cpuset_add(&cpus_running, ci);
-#endif
if (cpuno == 0) {
ci = &cpu_info_primary;
#ifdef MULTIPROCESSOR
ci->ci_flags |= CPUF_RUNNING | CPUF_PRESENT | CPUF_PRIMARY;
+ cpuset_add(&cpus_running, ci);
#endif
bcopy(dev, &ci->ci_dev, sizeof *dev);
}
@@ -315,6 +313,19 @@ cpuattach(struct device *parent, struct device *dev, void *aux)
void
cpu_boot_secondary_processors(void)
{
+ struct cpu_info *ci;
+ u_long i;
+
+ for (i = 0; i < MAXCPUS; i++) {
+ ci = cpu_info[i];
+ if (ci == NULL)
+ continue;
+ if ((ci->ci_flags & CPUF_PRESENT) == 0)
+ continue;
+ if (ci->ci_flags & CPUF_PRIMARY)
+ continue;
+ cpu_boot_secondary(ci);
+ }
}
void
diff --git a/sys/arch/sgi/include/autoconf.h b/sys/arch/sgi/include/autoconf.h
index d7003f4157e..a68295c3d4b 100644
--- a/sys/arch/sgi/include/autoconf.h
+++ b/sys/arch/sgi/include/autoconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.h,v 1.22 2009/10/26 20:14:42 miod Exp $ */
+/* $OpenBSD: autoconf.h,v 1.23 2009/10/30 08:13:57 syuu Exp $ */
/*
* Copyright (c) 2001-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -83,6 +83,7 @@ struct device;
void ip27_setup(void);
void ip27_autoconf(struct device *);
void ip30_setup(void);
+void ip30_autoconf(struct device *);
void ip32_setup(void);
extern char osloadpartition[256];
diff --git a/sys/arch/sgi/include/cpu.h b/sys/arch/sgi/include/cpu.h
index 18e457c2c5a..42b85d8e549 100644
--- a/sys/arch/sgi/include/cpu.h
+++ b/sys/arch/sgi/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.3 2009/09/30 06:22:00 syuu Exp $ */
+/* $OpenBSD: cpu.h,v 1.4 2009/10/30 08:13:57 syuu Exp $ */
/* Use Mips generic include file */
@@ -16,3 +16,9 @@
#endif/* _KERNEL */
#include <mips64/cpu.h>
+
+#if defined(_KERNEL) && defined(MULTIPROCESSOR) && !defined(_LOCORE)
+void hw_cpu_boot_secondary(struct cpu_info *);
+void hw_cpu_hatch(struct cpu_info *);
+void hw_cpu_spinup_trampoline(struct cpu_info *);
+#endif/* _KERNEL && MULTIPROCESSOR && !_LOCORE */
diff --git a/sys/arch/sgi/sgi/ip30.h b/sys/arch/sgi/sgi/ip30.h
index 033e2b316b7..9013b8f5d85 100644
--- a/sys/arch/sgi/sgi/ip30.h
+++ b/sys/arch/sgi/sgi/ip30.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip30.h,v 1.3 2009/10/15 23:40:54 miod Exp $ */
+/* $OpenBSD: ip30.h,v 1.4 2009/10/30 08:13:57 syuu Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
@@ -51,3 +51,25 @@
#define IP30_FLASH_BASE 0xc00000
#define IP30_FLASH_SIZE 0x200000
#define IP30_FLASH_ALT 0xe00000
+
+/*
+ * Multiprocessor configuration area
+ */
+
+#define MPCONF_BASE 0x0000000000000600UL
+#define MPCONF_LEN 0x80
+
+#define MPCONF_MAGIC(i) ((i) * MPCONF_LEN + 0x00)
+#define MPCONF_PRID(i) ((i) * MPCONF_LEN + 0x04)
+#define MPCONF_PHYSID(i) ((i) * MPCONF_LEN + 0x08)
+#define MPCONF_VIRTID(i) ((i) * MPCONF_LEN + 0x0c)
+#define MPCONF_SCACHESZ(i) ((i) * MPCONF_LEN + 0x10)
+#define MPCONF_FANLOADS(i) ((i) * MPCONF_LEN + 0x14)
+#define MPCONF_LAUNCH(i) ((i) * MPCONF_LEN + 0x18)
+#define MPCONF_RNDVZ(i) ((i) * MPCONF_LEN + 0x20)
+#define MPCONF_STACKADDR(i) ((i) * MPCONF_LEN + 0x40)
+#define MPCONF_LPARAM(i) ((i) * MPCONF_LEN + 0x48)
+#define MPCONF_RPARAM(i) ((i) * MPCONF_LEN + 0x50)
+#define MPCONF_IDLEFLAG(i) ((i) * MPCONF_LEN + 0x58)
+
+#define MPCONF_MAGIC_VAL 0xbaddeed2
diff --git a/sys/arch/sgi/sgi/ip30_machdep.c b/sys/arch/sgi/sgi/ip30_machdep.c
index ac05828741e..2708b6d6baa 100644
--- a/sys/arch/sgi/sgi/ip30_machdep.c
+++ b/sys/arch/sgi/sgi/ip30_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip30_machdep.c,v 1.13 2009/10/22 22:08:54 miod Exp $ */
+/* $OpenBSD: ip30_machdep.c,v 1.14 2009/10/30 08:13:57 syuu Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
@@ -45,11 +45,20 @@
extern char *hw_prod;
+extern int mbprint(void *, const char *);
+
paddr_t ip30_widget_short(int16_t, u_int);
paddr_t ip30_widget_long(int16_t, u_int);
paddr_t ip30_widget_map(int16_t, u_int, bus_addr_t *, bus_size_t *);
int ip30_widget_id(int16_t, u_int, uint32_t *);
+#ifdef MULTIPROCESSOR
+static const paddr_t mpconf =
+ PHYS_TO_XKPHYS(MPCONF_BASE, CCA_COHERENT_EXCLWRITE);
+
+static int ip30_cpu_exists(int);
+#endif
+
void
ip30_setup()
{
@@ -141,6 +150,33 @@ ip30_setup()
}
/*
+ * Autoconf enumeration
+ */
+
+void
+ip30_autoconf(struct device *parent)
+{
+ struct mainbus_attach_args maa;
+
+ bzero(&maa, sizeof maa);
+ maa.maa_nasid = masternasid;
+ maa.maa_name = "cpu";
+ config_found(parent, &maa, mbprint);
+#ifdef MULTIPROCESSOR
+ int cpuid;
+ for(cpuid = 1; cpuid < MAX_CPUS; cpuid++)
+ if (ip30_cpu_exists(cpuid) == 0)
+ config_found(parent, &maa, mbprint);
+#endif
+ maa.maa_name = "clock";
+ config_found(parent, &maa, mbprint);
+ maa.maa_name = "xbow";
+ config_found(parent, &maa, mbprint);
+ maa.maa_name = "power";
+ config_found(parent, &maa, mbprint);
+}
+
+/*
* Widget mapping. IP30 only has one processor board node, so the nasid
* parameter is ignored.
*/
@@ -198,3 +234,121 @@ ip30_widget_id(int16_t nasid, u_int widget, uint32_t *wid)
return 0;
}
+
+#ifdef MULTIPROCESSOR
+static int
+ip30_cpu_exists(int cpuid)
+{
+ uint32_t magic =
+ *(volatile uint32_t *)(mpconf + MPCONF_MAGIC(cpuid));
+ if (magic == MPCONF_MAGIC_VAL)
+ return 0;
+ else
+ return 1;
+}
+
+void
+hw_cpu_boot_secondary(struct cpu_info *ci)
+{
+ int cpuid = ci->ci_cpuid;
+
+#ifdef DEBUG
+ uint64_t stackaddr =
+ *(volatile uint64_t *)(mpconf + MPCONF_STACKADDR(cpuid));
+ uint64_t lparam =
+ *(volatile uint64_t *)(mpconf + MPCONF_LPARAM(cpuid));
+ uint64_t launch =
+ *(volatile uint64_t *)(mpconf + MPCONF_LAUNCH(cpuid));
+ uint32_t magic =
+ *(volatile uint32_t *)(mpconf + MPCONF_MAGIC(cpuid));
+ uint32_t prid =
+ *(volatile uint32_t *)(mpconf + MPCONF_PRID(cpuid));
+ uint32_t physid =
+ *(volatile uint32_t *)(mpconf + MPCONF_PHYSID(cpuid));
+ uint32_t virtid =
+ *(volatile uint32_t *)(mpconf + MPCONF_VIRTID(cpuid));
+ uint32_t scachesz =
+ *(volatile uint32_t *)(mpconf + MPCONF_SCACHESZ(cpuid));
+ uint16_t fanloads =
+ *(volatile uint16_t *)(mpconf + MPCONF_FANLOADS(cpuid));
+ uint64_t rndvz =
+ *(volatile uint64_t *)(mpconf + MPCONF_RNDVZ(cpuid));
+ uint64_t rparam =
+ *(volatile uint64_t *)(mpconf + MPCONF_RPARAM(cpuid));
+ uint32_t idleflag =
+ *(volatile uint32_t *)(mpconf + MPCONF_IDLEFLAG(cpuid));
+
+ printf("ci:%p cpuid:%d magic:%x prid:%x physid:%x virtid:%x\n"
+ "scachesz:%u fanloads:%x launch:%llx rndvz:%llx\n"
+ "stackaddr:%llx lparam:%llx rparam:%llx idleflag:%x\n",
+ ci, cpuid, magic, prid, physid, virtid,
+ scachesz, fanloads, launch, rndvz,
+ stackaddr, lparam, rparam, idleflag);
+#endif
+ vaddr_t kstack;
+ kstack = uvm_km_alloc(kernel_map, USPACE);
+ if (kstack == 0) {
+ panic("prom_boot_secondary: unable to allocate idle stack");
+ return;
+ }
+
+ *(volatile uint64_t *)(mpconf + MPCONF_STACKADDR(cpuid)) =
+ (uint64_t)(kstack + USPACE);
+ *(volatile uint64_t *)(mpconf + MPCONF_LPARAM(cpuid)) =
+ (uint64_t)ci;
+ *(volatile uint64_t *)(mpconf + MPCONF_LAUNCH(cpuid)) =
+ (uint64_t)hw_cpu_spinup_trampoline;
+
+ while(!cpuset_isset(&cpus_running, ci))
+ ;
+}
+
+void
+hw_cpu_hatch(struct cpu_info *ci)
+{
+ int cpuid = ci->ci_cpuid;
+
+ /*
+ * Make sure we can access the extended address space.
+ * Note that r10k and later do not allow XUSEG accesses
+ * from kernel mode unless SR_UX is set.
+ */
+ setsr(getsr() | SR_KX | SR_UX);
+
+ /*
+ * Determine system type and set up configuration record data.
+ */
+ sys_config.cpu[cpuid].clock = sys_config.cpu[0].clock;
+ sys_config.cpu[cpuid].type = (cp0_get_prid() >> 8) & 0xff;
+ sys_config.cpu[cpuid].vers_maj = (cp0_get_prid() >> 4) & 0x0f;
+ sys_config.cpu[cpuid].vers_min = cp0_get_prid() & 0x0f;
+ sys_config.cpu[cpuid].fptype = (cp1_get_prid() >> 8) & 0xff;
+ sys_config.cpu[cpuid].fpvers_maj = (cp1_get_prid() >> 4) & 0x0f;
+ sys_config.cpu[cpuid].fpvers_min = cp1_get_prid() & 0x0f;
+ sys_config.cpu[cpuid].tlbsize = 64;
+
+ Mips10k_ConfigCache();
+
+ sys_config.cpu[cpuid].tlbwired = UPAGES / 2;
+ tlb_set_wired(0);
+ tlb_flush(sys_config.cpu[cpuid].tlbsize);
+ tlb_set_wired(sys_config.cpu[cpuid].tlbwired);
+
+ tlb_set_pid(1);
+
+ /*
+ * Turn off bootstrap exception vectors.
+ */
+ setsr(getsr() & ~SR_BOOT_EXC_VEC);
+
+ /*
+ * Clear out the I and D caches.
+ */
+ Mips_SyncCache();
+
+ cpuset_add(&cpus_running, ci);
+
+ for (;;)
+ ;
+}
+#endif
diff --git a/sys/arch/sgi/sgi/locore.S b/sys/arch/sgi/sgi/locore.S
index 22c28b4b9b7..9e638e72b5b 100644
--- a/sys/arch/sgi/sgi/locore.S
+++ b/sys/arch/sgi/sgi/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.9 2009/05/22 20:37:54 miod Exp $ */
+/* $OpenBSD: locore.S,v 1.10 2009/10/30 08:13:57 syuu Exp $ */
/*
* Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -61,3 +61,17 @@ start:
jal main # main(regs)
move a0, zero
PANIC("Startup failed!")
+
+#if defined(MULTIPROCESSOR)
+LEAF(hw_cpu_spinup_trampoline, 0)
+ mfc0 v0, COP_0_STATUS_REG
+ li v1, ~SR_INT_ENAB
+ and v0, v1
+ ori v0, SR_KX | SR_UX
+ mtc0 v0, COP_0_STATUS_REG # disable all interrupts
+ mtc0 zero, COP_0_CAUSE_REG # Clear soft interrupts
+ LA gp, _gp
+ jal hw_cpu_hatch
+ nop
+END(hw_cpu_spinup_trampoline)
+#endif /* MULTIPROCESSOR */
diff --git a/sys/arch/sgi/sgi/mainbus.c b/sys/arch/sgi/sgi/mainbus.c
index bcc43a4358f..a66c1e256ca 100644
--- a/sys/arch/sgi/sgi/mainbus.c
+++ b/sys/arch/sgi/sgi/mainbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mainbus.c,v 1.4 2009/10/26 20:14:42 miod Exp $ */
+/* $OpenBSD: mainbus.c,v 1.5 2009/10/30 08:13:57 syuu Exp $ */
/*
* Copyright (c) 2001-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -79,6 +79,11 @@ mbattach(struct device *parent, struct device *self, void *aux)
ip27_autoconf(self);
return;
#endif
+#ifdef TGT_OCTANE
+ case SGI_OCTANE:
+ ip30_autoconf(self);
+ return;
+#endif
default:
break;
}
@@ -104,14 +109,6 @@ mbattach(struct device *parent, struct device *self, void *aux)
config_found(self, &maa, mbprint);
break;
#endif
-#ifdef TGT_OCTANE
- case SGI_OCTANE:
- maa.maa_name = "xbow";
- config_found(self, &maa, mbprint);
- maa.maa_name = "power";
- config_found(self, &maa, mbprint);
- break;
-#endif
default:
break;
}