diff options
Diffstat (limited to 'sys')
-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; |