diff options
author | Takuya ASADA <syuu@cvs.openbsd.org> | 2009-10-30 08:13:58 +0000 |
---|---|---|
committer | Takuya ASADA <syuu@cvs.openbsd.org> | 2009-10-30 08:13:58 +0000 |
commit | 7b2ee8a540c68bc249a4734323bb044e004e7bd0 (patch) | |
tree | 0254ef28bec4f8b9a50f9d123bb7907e7e80d12d /sys/arch | |
parent | 95686a4205e4b4f0e746d26a3ad510beaa475f29 (diff) |
Support IP30 secondary cpu bootup. ok miod@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/mips64/include/cpu.h | 4 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/cpu.c | 19 | ||||
-rw-r--r-- | sys/arch/sgi/include/autoconf.h | 3 | ||||
-rw-r--r-- | sys/arch/sgi/include/cpu.h | 8 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/ip30.h | 24 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/ip30_machdep.c | 156 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/locore.S | 16 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/mainbus.c | 15 |
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; } |