summaryrefslogtreecommitdiff
path: root/sys/arch/sgi
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/sgi')
-rw-r--r--sys/arch/sgi/pci/ioc.c115
-rw-r--r--sys/arch/sgi/sgi/ip27.h46
-rw-r--r--sys/arch/sgi/sgi/ip27_machdep.c31
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;