summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/sgi/conf/GENERIC-IP303
-rw-r--r--sys/arch/sgi/conf/files.sgi9
-rw-r--r--sys/arch/sgi/dev/power.c106
-rw-r--r--sys/arch/sgi/pci/ioc.c50
-rw-r--r--sys/arch/sgi/sgi/intr_template.c4
-rw-r--r--sys/arch/sgi/sgi/mainbus.c4
-rw-r--r--sys/arch/sgi/xbow/xbridge.c22
7 files changed, 142 insertions, 56 deletions
diff --git a/sys/arch/sgi/conf/GENERIC-IP30 b/sys/arch/sgi/conf/GENERIC-IP30
index 4cde85db51a..739d170a94e 100644
--- a/sys/arch/sgi/conf/GENERIC-IP30
+++ b/sys/arch/sgi/conf/GENERIC-IP30
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC-IP30,v 1.13 2009/10/22 19:55:45 miod Exp $
+# $OpenBSD: GENERIC-IP30,v 1.14 2009/10/26 18:13:31 miod Exp $
#
# THIS KERNEL IS FOR Octane and Octane 2 (IP30) SYSTEMS ONLY.
#
@@ -38,6 +38,7 @@ config bsd swap generic
mainbus0 at root
cpu* at mainbus0
clock0 at mainbus0
+power0 at mainbus0
#### Main local buses
xbow0 at mainbus0
diff --git a/sys/arch/sgi/conf/files.sgi b/sys/arch/sgi/conf/files.sgi
index d4e242378bb..5925463c3e5 100644
--- a/sys/arch/sgi/conf/files.sgi
+++ b/sys/arch/sgi/conf/files.sgi
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sgi,v 1.35 2009/10/26 18:00:04 miod Exp $
+# $OpenBSD: files.sgi,v 1.36 2009/10/26 18:13:31 miod Exp $
#
# maxpartitions must be first item in files.${ARCH}
#
@@ -148,8 +148,11 @@ file arch/sgi/dev/mkbc.c mkbc needs-flag
# Power button
device power
-attach power at macebus
-file arch/sgi/dev/power.c power
+attach power at macebus with power_macebus
+attach power at mainbus with power_mainbus
+file arch/sgi/dev/power.c power |
+ power_macebus | power_mainbus
+ needs-flag
# Raster operations
include "dev/rasops/files.rasops"
diff --git a/sys/arch/sgi/dev/power.c b/sys/arch/sgi/dev/power.c
index 87b4dbc1976..fbf00c1a846 100644
--- a/sys/arch/sgi/dev/power.c
+++ b/sys/arch/sgi/dev/power.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: power.c,v 1.10 2009/10/26 18:00:06 miod Exp $ */
+/* $OpenBSD: power.c,v 1.11 2009/10/26 18:13:34 miod Exp $ */
/*
* Copyright (c) 2007 Jasper Lievisse Adriaanse <jasper@openbsd.org>
@@ -22,65 +22,107 @@
#include <sys/proc.h>
#include <sys/signalvar.h>
-#include <dev/ic/ds1687reg.h>
-
#include <machine/autoconf.h>
+#include <mips64/archtype.h>
+
+#include <dev/ic/ds1687reg.h>
#include <sgi/dev/dsrtcvar.h>
-#include <sgi/localbus/macebus.h>
-#include <sgi/localbus/macebusvar.h>
+#include "power.h"
/*
- * Power button driver for the SGI O2.
+ * Power button driver for the SGI O2 and Octane.
*/
-struct power_softc {
- struct device sc_dev;
- bus_space_tag_t sc_st;
- bus_space_handle_t sc_sh;
-};
-
-void power_attach(struct device *, struct device *, void *);
-int power_match(struct device *, void *, void *);
int power_intr(void *);
struct cfdriver power_cd = {
NULL, "power", DV_DULL
};
+#if NPOWER_MACEBUS > 0
+
+#include <sgi/localbus/macebusvar.h>
+
+void power_macebus_attach(struct device *, struct device *, void *);
+int power_macebus_match(struct device *, void *, void *);
+
+struct cfattach power_macebus_ca = {
+ sizeof(struct device), power_macebus_match, power_macebus_attach
+};
+
int
-power_match(struct device *parent, void *match, void *aux)
+power_macebus_match(struct device *parent, void *match, void *aux)
{
return (1);
}
-struct cfattach power_ca = {
- sizeof(struct power_softc), power_match, power_attach
-};
-
void
-power_attach(struct device *parent, struct device *self, void *aux)
+power_macebus_attach(struct device *parent, struct device *self, void *aux)
{
- struct power_softc *sc = (void *)self;
struct macebus_attach_args *maa = aux;
- extern bus_space_handle_t mace_h;
- sc->sc_st = maa->maa_iot;
-
- /* Map subregion to ISA control registers. */
- if (bus_space_subregion(sc->sc_st, mace_h, 0, 0x80, &sc->sc_sh)) {
- printf(": failed to map ISA control registers!\n");
- return;
- }
-
/* Establish interrupt handler. */
if (macebus_intr_establish(maa->maa_intr, maa->maa_mace_intr,
- IST_EDGE, IPL_TTY, power_intr, sc, sc->sc_dev.dv_xname))
+ IST_EDGE, IPL_TTY, power_intr, self, self->dv_xname))
printf("\n");
else
printf(": unable to establish interrupt!\n");
}
+#endif
+
+#if NPOWER_MAINBUS > 0
+
+#include <sgi/xbow/xbow.h>
+#include <sgi/xbow/xheartreg.h>
+
+void power_mainbus_attach(struct device *, struct device *, void *);
+int power_mainbus_match(struct device *, void *, void *);
+int power_mainbus_intr(void *);
+
+struct cfattach power_mainbus_ca = {
+ sizeof(struct device), power_mainbus_match, power_mainbus_attach
+};
+
+int
+power_mainbus_match(struct device *parent, void *match, void *aux)
+{
+ struct confargs *ca = aux;
+
+ if (strcmp(ca->ca_name, power_cd.cd_name) != 0)
+ return 0;
+
+ return sys_config.system_type == SGI_OCTANE ? 1 : 0;
+}
+
+void
+power_mainbus_attach(struct device *parent, struct device *self, void *aux)
+{
+ /* Establish interrupt handler. */
+ if (xbow_intr_establish(power_mainbus_intr, self, HEART_ISR_POWER,
+ IPL_TTY, self->dv_xname) != 0) {
+ printf(": unable to establish interrupt!\n");
+ return;
+ }
+
+ printf("\n");
+}
+
+int
+power_mainbus_intr(void *v)
+{
+ /*
+ * Clear interrupt condition; debouncing the kickstart bit will not
+ * suffice.
+ */
+ xbow_intr_clear(HEART_ISR_POWER);
+
+ return power_intr(v);
+}
+
+#endif
+
int
power_intr(void *unused)
{
@@ -94,6 +136,8 @@ power_intr(void *unused)
val = dsrtc_register_read(DS1687_EXT_CTRL);
if (val == -1)
return 1; /* no rtc attached */
+
+ /* debounce condition */
dsrtc_register_write(DS1687_EXT_CTRL, val & ~DS1687_KICKSTART);
if (kbd_reset == 1) {
diff --git a/sys/arch/sgi/pci/ioc.c b/sys/arch/sgi/pci/ioc.c
index 24ad8611ede..a5d681b9071 100644
--- a/sys/arch/sgi/pci/ioc.c
+++ b/sys/arch/sgi/pci/ioc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ioc.c,v 1.21 2009/08/18 19:32:47 miod Exp $ */
+/* $OpenBSD: ioc.c,v 1.22 2009/10/26 18:13:34 miod Exp $ */
/*
* Copyright (c) 2008 Joel Sing.
@@ -124,7 +124,8 @@ ioc_print(void *aux, const char *iocname)
if (iocname != NULL)
printf("%s at %s", iaa->iaa_name, iocname);
- if ((int)iaa->iaa_base > 0) /* no base for onewire */
+ /* no base for onewire, and don't display it for rtc */
+ if ((int)iaa->iaa_base > 0 && (int)iaa->iaa_base < IOC3_BYTEBUS_0)
printf(" base 0x%x", iaa->iaa_base);
return (UNCONF);
@@ -141,7 +142,9 @@ ioc_attach(struct device *parent, struct device *self, void *aux)
bus_size_t memsize;
uint32_t data;
int dev;
- int dual_irq, shared_handler, has_ethernet, has_ps2, has_serial;
+ int dual_irq, shared_handler;
+ int device_mask;
+ bus_addr_t rtcbase;
struct device *child;
if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_MEM, 0,
@@ -205,27 +208,33 @@ ioc_attach(struct device *parent, struct device *self, void *aux)
printf("%s: ", self->dv_xname);
dual_irq = shared_handler = 0;
- has_ethernet = has_ps2 = has_serial = 0;
+ device_mask = 0;
if (sc->sc_owserial != NULL) {
if (strncmp(sc->sc_owserial->sc_product, "030-0873-", 9) == 0) {
/* MENET board */
- has_ethernet = has_serial = 1;
+ device_mask = (1 << IOCDEV_SERIAL_A) |
+ (1 << IOCDEV_SERIAL_B) | (1 << IOCDEV_EF);
shared_handler = 1;
} else
if (strncmp(sc->sc_owserial->sc_product, "030-0891-", 9) == 0) {
/* IP30 on-board IOC3 */
- has_ethernet = has_ps2 = has_serial = 1;
+ device_mask = (1 << IOCDEV_SERIAL_A) |
+ (1 << IOCDEV_SERIAL_B) | (1 << IOCDEV_LPT) |
+ (1 << IOCDEV_KBC) | (1 << IOCDEV_RTC) |
+ (1 << IOCDEV_EF);
+ rtcbase = IOC3_BYTEBUS_1;
dual_irq = 1;
} else
if (strncmp(sc->sc_owserial->sc_product, "030-1155-", 9) == 0) {
/* CADDuo board */
- has_ps2 = has_ethernet = 1;
+ device_mask = (1 << IOCDEV_KBC) | (1 << IOCDEV_EF);
shared_handler = 1;
} else
if (strncmp(sc->sc_owserial->sc_product, "030-1657-", 9) == 0 ||
strncmp(sc->sc_owserial->sc_product, "030-1664-", 9) == 0) {
/* PCI_SIO_UFC dual serial board */
- has_serial = 1;
+ device_mask = (1 << IOCDEV_SERIAL_A) |
+ (1 << IOCDEV_SERIAL_B);
} else {
goto unknown;
}
@@ -237,7 +246,11 @@ ioc_attach(struct device *parent, struct device *self, void *aux)
*/
if (sys_config.system_type == SGI_O200 ||
sys_config.system_type == SGI_O300) {
- has_ethernet = has_ps2 = has_serial = 1;
+ device_mask = (1 << IOCDEV_SERIAL_A) |
+ (1 << IOCDEV_SERIAL_B) | (1 << IOCDEV_LPT) |
+ (1 << IOCDEV_KBC) | (1 << IOCDEV_RTC) |
+ (1 << IOCDEV_EF);
+ rtcbase = IOC3_BYTEBUS_0;
dual_irq = 1;
/*
* XXX On IP35 class machines, there are no
@@ -370,13 +383,20 @@ establish:
* Attach other sub-devices.
*/
- if (has_serial) {
+ if (ISSET(device_mask, 1 << IOCDEV_SERIAL_A)) {
+ /*
+ * Put serial ports in passthrough mode,
+ * to use the MI com(4) 16550 support.
+ */
+ bus_space_write_4(sc->sc_memt, sc->sc_memh, IOC3_UARTA_SSCR, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_memh, IOC3_UARTB_SSCR, 0);
+
ioc_attach_child(self, "com", IOC3_UARTA_BASE, IOCDEV_SERIAL_A);
ioc_attach_child(self, "com", IOC3_UARTB_BASE, IOCDEV_SERIAL_B);
}
- if (has_ps2)
+ if (ISSET(device_mask, 1 << IOCDEV_KBC))
ioc_attach_child(self, "iockbc", IOC3_KBC_BASE, IOCDEV_KBC);
- if (has_ethernet) {
+ if (ISSET(device_mask, 1 << IOCDEV_EF)) {
child = ioc_attach_child(self, "iec", IOC3_EF_BASE, IOCDEV_EF);
if (dual_irq != 0 && child == NULL) {
/*
@@ -389,8 +409,10 @@ establish:
pci_intr_disestablish(sc->sc_pc, sc->sc_ih1);
}
}
- /* XXX what about the parallel port? */
- ioc_attach_child(self, "dsrtc", 0 /* IOC3_RTC_BASE */, IOCDEV_RTC);
+ if (ISSET(device_mask, 1 << IOCDEV_LPT))
+ ioc_attach_child(self, "lpt", IOC3_LPT_BASE, IOCDEV_LPT);
+ if (ISSET(device_mask, 1 << IOCDEV_RTC))
+ ioc_attach_child(self, "dsrtc", rtcbase, IOCDEV_RTC);
return;
diff --git a/sys/arch/sgi/sgi/intr_template.c b/sys/arch/sgi/sgi/intr_template.c
index 539c41590f7..4640bbb3927 100644
--- a/sys/arch/sgi/sgi/intr_template.c
+++ b/sys/arch/sgi/sgi/intr_template.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr_template.c,v 1.2 2009/10/26 18:00:06 miod Exp $ */
+/* $OpenBSD: intr_template.c,v 1.3 2009/10/26 18:13:34 miod Exp $ */
/*
* Copyright (c) 2009 Miodrag Vallat.
@@ -82,7 +82,7 @@ INTR_FUNCTIONNAME(uint32_t hwpend, struct trap_frame *frame)
tmpisr = isr & (INTR_IMASK(lvl) ^ INTR_IMASK(lvl - 1));
if (tmpisr == 0)
continue;
- for (bitno = bit, mask = 1UL << bitno; tmpisr != 0;
+ for (bitno = bit, mask = 1UL << bitno; mask != 0;
bitno--, mask >>= 1) {
if ((tmpisr & mask) == 0)
continue;
diff --git a/sys/arch/sgi/sgi/mainbus.c b/sys/arch/sgi/sgi/mainbus.c
index 7780da007a9..442724ace43 100644
--- a/sys/arch/sgi/sgi/mainbus.c
+++ b/sys/arch/sgi/sgi/mainbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mainbus.c,v 1.2 2009/10/14 20:21:16 miod Exp $ */
+/* $OpenBSD: mainbus.c,v 1.3 2009/10/26 18:13:34 miod Exp $ */
/*
* Copyright (c) 2001-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -108,6 +108,8 @@ mbattach(struct device *parent, struct device *self, void *aux)
case SGI_OCTANE:
nca.ca_name = "xbow";
config_found(self, &nca, mbprint);
+ nca.ca_name = "power";
+ config_found(self, &nca, mbprint);
break;
#endif
default:
diff --git a/sys/arch/sgi/xbow/xbridge.c b/sys/arch/sgi/xbow/xbridge.c
index 6f2600cce69..b7c3d652214 100644
--- a/sys/arch/sgi/xbow/xbridge.c
+++ b/sys/arch/sgi/xbow/xbridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xbridge.c,v 1.56 2009/10/26 18:11:27 miod Exp $ */
+/* $OpenBSD: xbridge.c,v 1.57 2009/10/26 18:13:34 miod Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
@@ -2136,17 +2136,31 @@ xbridge_setup(struct xbpci_softc *xb)
/*
* Setup interrupt handling.
+ *
* Note that, on PIC, the `lower address' register is a 64 bit
* register and thus need to be initialized with the whole 64 bit
* address; the `upper address' register is hardwired to zero and
* ignores writes, so we can use the same logic on Bridge and PIC.
+ *
+ * Also, on Octane, we need to keep otherwise unused interrupt source
+ * #6 enabled on the obio widget, as it controls routing of the
+ * power button interrupt (and to make things more complicated than
+ * necessary, this pin is wired to a particular Heart interrupt
+ * register bit, so interrupts on this pin will never be seen at the
+ * Bridge level.
*/
- int_addr = ((uint64_t)xbow_intr_widget << 48) |
- (xbow_intr_widget_register & ((1UL << 48) - 1));
- xbridge_write_reg(xb, BRIDGE_IER, 0);
+#ifdef TGT_OCTANE
+ if (sys_config.system_type == SGI_OCTANE &&
+ xb->xb_widget == IP30_BRIDGE_WIDGET)
+ xbridge_write_reg(xb, BRIDGE_IER, 1 << 6);
+ else
+#endif
+ xbridge_write_reg(xb, BRIDGE_IER, 0);
xbridge_write_reg(xb, BRIDGE_INT_MODE, 0);
xbridge_write_reg(xb, BRIDGE_INT_DEV, 0);
+ int_addr = ((uint64_t)xbow_intr_widget << 48) |
+ (xbow_intr_widget_register & ((1UL << 48) - 1));
xbridge_write_reg(xb, WIDGET_INTDEST_ADDR_LOWER, int_addr);
xbridge_write_reg(xb, WIDGET_INTDEST_ADDR_UPPER, int_addr >> 32);