diff options
-rw-r--r-- | sys/arch/sgi/conf/GENERIC-IP30 | 3 | ||||
-rw-r--r-- | sys/arch/sgi/conf/files.sgi | 9 | ||||
-rw-r--r-- | sys/arch/sgi/dev/power.c | 106 | ||||
-rw-r--r-- | sys/arch/sgi/pci/ioc.c | 50 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/intr_template.c | 4 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/mainbus.c | 4 | ||||
-rw-r--r-- | sys/arch/sgi/xbow/xbridge.c | 22 |
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); |