diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2010-03-20 16:22:56 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2010-03-20 16:22:56 +0000 |
commit | 88e3a5ffe05ba89494884709af8488464f764604 (patch) | |
tree | 20451403a9e5ae696c37b1aeae4eb45ac5d452e3 /sys/arch/sgi | |
parent | e995bd3a29cc2b1c26f169864d4cfeea2c7aee3d (diff) |
Add code to tell Origin 200 and Origin 2000 / Onyx 2 apart.
Use this to correctly handle the onboard IOC3 chip configuration on O2k
(two IOC3 chips to be able to provide four serial ports, and the other
subdevices are split accross the two IOC3 chips).
Diffstat (limited to 'sys/arch/sgi')
-rw-r--r-- | sys/arch/sgi/pci/ioc.c | 115 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/ip27.h | 46 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/ip27_machdep.c | 31 |
3 files changed, 156 insertions, 36 deletions
diff --git a/sys/arch/sgi/pci/ioc.c b/sys/arch/sgi/pci/ioc.c index e1aa1afe2fb..c19fc82b88e 100644 --- a/sys/arch/sgi/pci/ioc.c +++ b/sys/arch/sgi/pci/ioc.c @@ -1,8 +1,8 @@ -/* $OpenBSD: ioc.c,v 1.32 2010/03/07 13:44:26 miod Exp $ */ +/* $OpenBSD: ioc.c,v 1.33 2010/03/20 16:22:53 miod Exp $ */ /* * Copyright (c) 2008 Joel Sing. - * Copyright (c) 2008, 2009 Miodrag Vallat. + * Copyright (c) 2008, 2009, 2010 Miodrag Vallat. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -115,10 +115,10 @@ int iocow_pulse(struct ioc_softc *, int, int); #ifdef TGT_ORIGIN /* * A mask of nodes on which an ioc driver has attached. - * We use this to prevent attaching a pci IOC3 card which NIC has failed, - * as the onboard IOC3. - * - * XXX This obviously will not work in N mode... + * We use this on IP35 systems, to prevent attaching a pci IOC3 card which NIC + * has failed, as the onboard IOC3. + * XXX This obviously will not work in N mode... but then IP35 are supposed to + * XXX always run in M mode. */ static uint64_t ioc_nodemask = 0; #endif @@ -274,32 +274,95 @@ ioc_attach(struct device *parent, struct device *self, void *aux) * very likely that we are the on-board IOC3 found * on IP27 and IP35 systems, unless we have already * found an on-board IOC3 on this node. + * + * Origin 2000 (real IP27) systems are a real annoyance, + * because they actually have two IOC3 on their BASEIO + * board, with the various devices split accross them + * (two IOC3 chips are needed to provide the four serial + * ports). We can rely upon the PCI device numbers (2 and 6) + * to tell onboard IOC3 from PCI IOC3 devices. */ - if ((sys_config.system_type == SGI_IP27 || - sys_config.system_type == SGI_IP35) && - !ISSET(ioc_nodemask, 1UL << currentnasid)) { - SET(ioc_nodemask, 1UL << currentnasid); + switch (sys_config.system_type) { + case SGI_IP27: + switch (sys_config.system_subtype) { + case IP27_O2K: + if (pci_get_widget(sc->sc_pc) == + IP27_O2K_BRIDGE_WIDGET) + switch (pa->pa_device) { + case IP27_IOC_SLOTNO: + subdevice_mask = + (1 << IOCDEV_SERIAL_A) | + (1 << IOCDEV_SERIAL_B) | + (1 << IOCDEV_RTC) | + (1 << IOCDEV_EF); + break; + case IP27_IOC2_SLOTNO: + subdevice_mask = + (1 << IOCDEV_SERIAL_A) | + (1 << IOCDEV_SERIAL_B) | + (1 << IOCDEV_LPT) | +#if 0 /* not worth doing */ + (1 << IOCDEV_RTC) | +#endif + (1 << IOCDEV_KBC); + break; + default: + break; + } + break; + case IP27_O200: + if (pci_get_widget(sc->sc_pc) == + IP27_O200_BRIDGE_WIDGET) + switch (pa->pa_device) { + case IP27_IOC_SLOTNO: + subdevice_mask = + (1 << IOCDEV_SERIAL_A) | + (1 << IOCDEV_SERIAL_B) | + (1 << IOCDEV_LPT) | + (1 << IOCDEV_KBC) | + (1 << IOCDEV_RTC) | + (1 << IOCDEV_EF); + break; + default: + break; + } + break; + default: + break; + } + break; + case SGI_IP35: + if (!ISSET(ioc_nodemask, 1UL << currentnasid)) { + SET(ioc_nodemask, 1UL << currentnasid); - subdevice_mask = (1 << IOCDEV_SERIAL_A) | - (1 << IOCDEV_SERIAL_B) | (1 << IOCDEV_LPT) | - (1 << IOCDEV_KBC) | (1 << IOCDEV_RTC) | - (1 << IOCDEV_EF); - /* - * Origin 300 onboard IOC3 do not have PS/2 ports; - * since they can only be connected to other 300 or - * 350 bricks (the latter using IOC4 devices), - * it is safe to do this regardless of the current - * nasid. - */ - if (sys_config.system_type == SGI_IP35 && - sys_config.system_subtype == IP35_O300) - subdevice_mask &= ~(1 << IOCDEV_KBC); + subdevice_mask = (1 << IOCDEV_SERIAL_A) | + (1 << IOCDEV_SERIAL_B) | (1 << IOCDEV_LPT) | + (1 << IOCDEV_KBC) | (1 << IOCDEV_RTC) | + (1 << IOCDEV_EF); + /* + * Origin 300 onboard IOC3 do not have PS/2 + * ports; since they can only be connected to + * other 300 or 350 bricks (the latter using + * IOC4 devices), it is safe to do this + * regardless of the current nasid. + * XXX What about Onyx 300 though??? + */ + if (sys_config.system_subtype == IP35_O300) + subdevice_mask &= ~(1 << IOCDEV_KBC); + } + break; + default: + break; + } + if (subdevice_mask != 0) { rtcbase = IOC3_BYTEBUS_0; - has_superio = has_enet = 1; + has_superio = 1; + if (ISSET(subdevice_mask, 1 << IOCDEV_EF)) + has_enet = 1; is_obio = 1; } else -#endif +#endif /* TGT_ORIGIN */ { unknown: /* diff --git a/sys/arch/sgi/sgi/ip27.h b/sys/arch/sgi/sgi/ip27.h index 64c30adb224..66c13d253b0 100644 --- a/sys/arch/sgi/sgi/ip27.h +++ b/sys/arch/sgi/sgi/ip27.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip27.h,v 1.2 2009/11/07 14:49:01 miod Exp $ */ +/* $OpenBSD: ip27.h,v 1.3 2010/03/20 16:22:55 miod Exp $ */ /* * Copyright (c) 2009 Miodrag Vallat. @@ -30,8 +30,52 @@ #define IP35_NMI_KREGS_SIZE 0x400 /* per CPU */ #define IP35_NMI_EFRAME_BASE 0xa000 +/* IP27 system types */ + +#define IP27_SN0 0x00 +#define IP27_SN00 0x01 +#define IP27_O200 IP27_SN00 +#define IP27_O2K IP27_SN0 +#define IP27_UNKNOWN 0x02 + /* IP35 Brick types */ #define IP35_O350 0x02 #define IP35_FUEL 0x04 #define IP35_O300 0x08 + +/* + * Specific device assignment + */ + +#define IP27_O200_BRIDGE_WIDGET 8 +#define IP27_O2K_BRIDGE_WIDGET 15 + +#define IP27_IOC_SLOTNO 2 +#define IP27_IOC2_SLOTNO 6 + +/* + * IP27 configuration structure. Used to tell Origin 200 and Origin 2000 + * apart. + */ + +#define IP27_CONFIG_OFFSET 0x60 /* relative to LBOOTBASE */ +#define IP27_CONFIG_MAGIC 0x69703237636f6e66LL /* "ip27conf" */ + +struct ip27_config { + volatile uint32_t time_const; + volatile uint32_t r10k_sysad; + volatile uint64_t magic; + volatile uint64_t cpu_hz; + volatile uint64_t hub_hz; + volatile uint64_t rtc_hz; + volatile uint32_t ecc_enable; + volatile uint32_t fprom_cyc; + volatile uint32_t ip27_subtype; + volatile uint32_t cksum; + volatile uint32_t flash_count; + volatile uint32_t fprom_wr; + volatile uint32_t prom_ver; + volatile uint32_t prom_rev; + volatile uint32_t config_specific; +}; diff --git a/sys/arch/sgi/sgi/ip27_machdep.c b/sys/arch/sgi/sgi/ip27_machdep.c index fa4aeee8f48..ec540df45d3 100644 --- a/sys/arch/sgi/sgi/ip27_machdep.c +++ b/sys/arch/sgi/sgi/ip27_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip27_machdep.c,v 1.43 2010/03/07 13:44:26 miod Exp $ */ +/* $OpenBSD: ip27_machdep.c,v 1.44 2010/03/20 16:22:55 miod Exp $ */ /* * Copyright (c) 2008, 2009 Miodrag Vallat. @@ -114,9 +114,11 @@ ip27_setup() { size_t gsz; uint node; + struct ip27_config *ip27_config; uint64_t synergy0_0; console_t *cons; nmi_t *nmi; + static char unknown_model[20]; uncached_base = PHYS_TO_XKPHYS_UNCACHED(0, SP_NC); io_base = PHYS_TO_XKPHYS_UNCACHED(0, SP_IO); @@ -143,20 +145,31 @@ ip27_setup() hw_prod = "Origin 300"; break; default: - { - static char unknown_model[20]; snprintf(unknown_model, sizeof unknown_model, "Unknown IP35 type %x", sys_config.system_subtype); hw_prod = unknown_model; - } break; } } else { - /* - * XXX need to look for Sn00 type in LBOOT space to tell - * XXX Origin 2000 and Origin 200 apart. - */ - hw_prod = "Origin 200"; + ip27_config = (struct ip27_config *) + IP27_LHSPEC_ADDR(LBOOTBASE_IP27 + IP27_CONFIG_OFFSET); + if (ip27_config->magic == IP27_CONFIG_MAGIC) + sys_config.system_subtype = ip27_config->ip27_subtype; + else + sys_config.system_subtype = IP27_UNKNOWN; + switch (sys_config.system_subtype) { + case IP27_O2K: + hw_prod = "Origin 2000"; + break; + case IP27_O200: + hw_prod = "Origin 200"; + break; + default: + snprintf(unknown_model, sizeof unknown_model, + "Unknown IP27 type %x", sys_config.system_subtype); + hw_prod = unknown_model; + break; + } } xbow_widget_base = ip27_widget_short; |