diff options
-rw-r--r-- | sys/arch/sgi/dev/com_ioc.c | 16 | ||||
-rw-r--r-- | sys/arch/sgi/dev/gbe.c | 4 | ||||
-rw-r--r-- | sys/arch/sgi/dev/iockbc.c | 322 | ||||
-rw-r--r-- | sys/arch/sgi/dev/iockbcvar.h | 19 | ||||
-rw-r--r-- | sys/arch/sgi/pci/ioc.c | 7 | ||||
-rw-r--r-- | sys/arch/sgi/pci/iocvar.h | 6 | ||||
-rw-r--r-- | sys/arch/sgi/pci/iof.c | 7 | ||||
-rw-r--r-- | sys/arch/sgi/pci/iofvar.h | 6 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/ip27_machdep.c | 44 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/ip30.h | 6 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/ip30_machdep.c | 81 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/wscons_machdep.c | 215 | ||||
-rw-r--r-- | sys/arch/sgi/xbow/odyssey.c | 150 | ||||
-rw-r--r-- | sys/arch/sgi/xbow/odysseyvar.h | 19 |
14 files changed, 759 insertions, 143 deletions
diff --git a/sys/arch/sgi/dev/com_ioc.c b/sys/arch/sgi/dev/com_ioc.c index 1f5a838f20b..066900d0c11 100644 --- a/sys/arch/sgi/dev/com_ioc.c +++ b/sys/arch/sgi/dev/com_ioc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: com_ioc.c,v 1.7 2009/10/16 00:15:46 miod Exp $ */ +/* $OpenBSD: com_ioc.c,v 1.8 2010/03/07 13:44:24 miod Exp $ */ /* * Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com) @@ -58,13 +58,14 @@ com_ioc_probe(struct device *parent, void *match, void *aux) struct ioc_attach_args *iaa = aux; bus_space_tag_t iot = iaa->iaa_memt; bus_space_handle_t ioh; - int rv = 0, console; + int rv = 0, console = 0; if (strcmp(iaa->iaa_name, com_cd.cd_name) != 0) return 0; - console = iaa->iaa_memh + iaa->iaa_base == - comconsiot->bus_base + comconsaddr; + if (comconsiot != NULL) + console = iaa->iaa_memh + iaa->iaa_base == + comconsiot->bus_base + comconsaddr; /* if it's in use as console, it's there. */ if (!(console && !comconsattached)) { @@ -87,10 +88,11 @@ com_ioc_attach(struct device *parent, struct device *self, void *aux) struct com_softc *sc = (void *)self; struct ioc_attach_args *iaa = aux; bus_space_handle_t ioh; - int console; + int console = 0; - console = iaa->iaa_memh + iaa->iaa_base == - comconsiot->bus_base + comconsaddr; + if (comconsiot != NULL) + console = iaa->iaa_memh + iaa->iaa_base == + comconsiot->bus_base + comconsaddr; sc->sc_hwflags = 0; sc->sc_swflags = 0; diff --git a/sys/arch/sgi/dev/gbe.c b/sys/arch/sgi/dev/gbe.c index 4c2abf3529d..bb1d77865cb 100644 --- a/sys/arch/sgi/dev/gbe.c +++ b/sys/arch/sgi/dev/gbe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gbe.c,v 1.10 2009/10/26 20:14:42 miod Exp $ */ +/* $OpenBSD: gbe.c,v 1.11 2010/03/07 13:44:24 miod Exp $ */ /* * Copyright (c) 2007, 2008, 2009 Joel Sing <jsing@openbsd.org> @@ -1375,5 +1375,5 @@ gbe_cnattach(bus_space_tag_t iot, bus_addr_t addr) wsdisplay_cnattach(&gbe_stdscreen, &gbe_consdata.ri, 0, 0, attr); gbe_console = 1; - return (1); + return (0); } diff --git a/sys/arch/sgi/dev/iockbc.c b/sys/arch/sgi/dev/iockbc.c index ff7a3872158..14dbafbf3a7 100644 --- a/sys/arch/sgi/dev/iockbc.c +++ b/sys/arch/sgi/dev/iockbc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: iockbc.c,v 1.4 2009/11/18 19:03:27 miod Exp $ */ +/* $OpenBSD: iockbc.c,v 1.5 2010/03/07 13:44:24 miod Exp $ */ /* * Copyright (c) 2006, 2007, 2009 Joel Sing <jsing@openbsd.org> * @@ -65,8 +65,6 @@ #include <mips64/archtype.h> -#include <sgi/dev/iockbcreg.h> - #include <sgi/pci/iocreg.h> #include <sgi/pci/iocvar.h> #include <sgi/pci/iofreg.h> @@ -75,6 +73,12 @@ #include <dev/ic/pckbcvar.h> #include <dev/pckbc/pckbdvar.h> +#include <dev/pci/pcireg.h> +#include <dev/pci/pcidevs.h> + +#include <sgi/dev/iockbcreg.h> +#include <sgi/dev/iockbcvar.h> + #include "iockbc.h" const char *iockbc_slot_names[] = { "kbd", "mouse" }; @@ -89,13 +93,19 @@ const char *iockbc_slot_names[] = { "kbd", "mouse" }; #define DPRINTF(x...) #endif -struct iockbc_softc { - struct pckbc_softc sc_pckbc; - bus_space_tag_t iot; - bus_space_handle_t ioh; - bus_addr_t rx[PCKBC_NSLOTS]; - bus_addr_t tx[PCKBC_NSLOTS]; +struct iockbc_reginfo { + bus_addr_t rx; + bus_addr_t tx; bus_addr_t cs; + uint32_t busy; +}; + +struct iockbc_softc { + struct pckbc_softc sc_pckbc; + bus_space_tag_t iot; + bus_space_handle_t ioh; + const struct iockbc_reginfo *reginfo; + int console; }; int iockbc_match(struct device *, void *, void *); @@ -138,16 +148,20 @@ struct pckbc_slotdata { struct pckbc_devcmd cmds[NCMD]; int rx_queue[3]; int rx_index; + const struct iockbc_reginfo *reginfo; }; #define CMD_IN_QUEUE(q) (TAILQ_FIRST(&(q)->cmdqueue) != NULL) -static int iockbc_console; +struct pckbc_internal iockbc_consdata; -void iockbc_attach_common(struct iockbc_softc *, bus_addr_t); +int iockbc_is_ioc_console(struct ioc_attach_args *); +int iockbc_is_iof_console(struct iof_attach_args *); +void iockbc_attach_common(struct iockbc_softc *, bus_addr_t, int); void iockbc_start(struct pckbc_internal *, pckbc_slot_t); int iockbc_attach_slot(struct iockbc_softc *, pckbc_slot_t); -void iockbc_init_slotdata(struct pckbc_slotdata *); +void iockbc_init_slotdata(struct pckbc_slotdata *, + const struct iockbc_reginfo *); int iockbc_submatch(struct device *, void *, void *); int iockbcprint(void *, const char *); int iockbcintr(void *); @@ -165,12 +179,46 @@ int iockbc_match(struct device *parent, void *cf, void *aux) { /* - * We expect ioc and iof NOT to attach us on if there are no PS/2 ports. + * We expect ioc and iof NOT to attach us if there are no PS/2 ports. */ return 1; } #if NIOCKBC_IOC > 0 +/* + * Register assignments + */ + +const struct iockbc_reginfo iockbc_ioc_normal[PCKBC_NSLOTS] = { + [PCKBC_KBD_SLOT] = { + .rx = IOC3_KBC_KBD_RX, + .tx = IOC3_KBC_KBD_TX, + .cs = IOC3_KBC_CTRL_STATUS, + .busy = IOC3_KBC_STATUS_KBD_WRITE_PENDING + }, + [PCKBC_AUX_SLOT] = { + .rx = IOC3_KBC_AUX_RX, + .tx = IOC3_KBC_AUX_TX, + .cs = IOC3_KBC_CTRL_STATUS, + .busy = IOC3_KBC_STATUS_AUX_WRITE_PENDING + } +}; + +const struct iockbc_reginfo iockbc_ioc_inverted[PCKBC_NSLOTS] = { + [PCKBC_KBD_SLOT] = { + .rx = IOC3_KBC_AUX_RX, + .tx = IOC3_KBC_AUX_TX, + .cs = IOC3_KBC_CTRL_STATUS, + .busy = IOC3_KBC_STATUS_AUX_WRITE_PENDING + }, + [PCKBC_AUX_SLOT] = { + .rx = IOC3_KBC_KBD_RX, + .tx = IOC3_KBC_KBD_TX, + .cs = IOC3_KBC_CTRL_STATUS, + .busy = IOC3_KBC_STATUS_KBD_WRITE_PENDING + } +}; + void iockbc_ioc_attach(struct device *parent, struct device *self, void *aux) { @@ -182,18 +230,10 @@ iockbc_ioc_attach(struct device *parent, struct device *self, void *aux) */ if (ISSET(iaa->iaa_flags, IOC_FLAGS_OBIO) && - sys_config.system_type == SGI_IP35) { - isc->rx[PCKBC_KBD_SLOT] = IOC3_KBC_AUX_RX; - isc->rx[PCKBC_AUX_SLOT] = IOC3_KBC_KBD_RX; - isc->tx[PCKBC_KBD_SLOT] = IOC3_KBC_AUX_TX; - isc->tx[PCKBC_AUX_SLOT] = IOC3_KBC_KBD_TX; - } else { - isc->rx[PCKBC_KBD_SLOT] = IOC3_KBC_KBD_RX; - isc->rx[PCKBC_AUX_SLOT] = IOC3_KBC_AUX_RX; - isc->tx[PCKBC_KBD_SLOT] = IOC3_KBC_KBD_TX; - isc->tx[PCKBC_AUX_SLOT] = IOC3_KBC_AUX_TX; - } - isc->cs = IOC3_KBC_CTRL_STATUS; + sys_config.system_type == SGI_IP35) + isc->reginfo = iockbc_ioc_inverted; + else + isc->reginfo = iockbc_ioc_normal; /* Setup bus space mapping. */ isc->iot = iaa->iaa_memt; @@ -206,22 +246,37 @@ iockbc_ioc_attach(struct device *parent, struct device *self, void *aux) else printf(": unable to establish interrupt\n"); - iockbc_attach_common(isc, iaa->iaa_base); + iockbc_attach_common(isc, iaa->iaa_base, iockbc_is_ioc_console(iaa)); } #endif #if NIOCKBC_IOF > 0 +/* + * Register assignments + */ + +const struct iockbc_reginfo iockbc_iof[PCKBC_NSLOTS] = { + [PCKBC_KBD_SLOT] = { + .rx = IOC4_KBC_KBD_RX, + .tx = IOC4_KBC_KBD_TX, + .cs = IOC4_KBC_CTRL_STATUS, + .busy = IOC3_KBC_STATUS_KBD_WRITE_PENDING + }, + [PCKBC_AUX_SLOT] = { + .rx = IOC4_KBC_AUX_RX, + .tx = IOC4_KBC_AUX_TX, + .cs = IOC4_KBC_CTRL_STATUS, + .busy = IOC3_KBC_STATUS_AUX_WRITE_PENDING + } +}; + void iockbc_iof_attach(struct device *parent, struct device *self, void *aux) { struct iockbc_softc *isc = (void*)self; struct iof_attach_args *iaa = aux; - isc->rx[PCKBC_KBD_SLOT] = IOC4_KBC_KBD_RX; - isc->rx[PCKBC_AUX_SLOT] = IOC4_KBC_AUX_RX; - isc->tx[PCKBC_KBD_SLOT] = IOC4_KBC_KBD_TX; - isc->tx[PCKBC_AUX_SLOT] = IOC4_KBC_AUX_TX; - isc->cs = IOC4_KBC_CTRL_STATUS; + isc->reginfo = iockbc_iof; /* Setup bus space mapping. */ isc->iot = iaa->iaa_memt; @@ -234,12 +289,13 @@ iockbc_iof_attach(struct device *parent, struct device *self, void *aux) else printf(": unable to establish interrupt\n"); - iockbc_attach_common(isc, iaa->iaa_base); + iockbc_attach_common(isc, iaa->iaa_base, iockbc_is_iof_console(iaa)); } #endif void -iockbc_init_slotdata(struct pckbc_slotdata *q) +iockbc_init_slotdata(struct pckbc_slotdata *q, + const struct iockbc_reginfo *reginfo) { int i; TAILQ_INIT(&q->cmdqueue); @@ -250,6 +306,8 @@ iockbc_init_slotdata(struct pckbc_slotdata *q) q->polling = 0; q->rx_index = -1; + + q->reginfo = reginfo; } int @@ -277,10 +335,10 @@ iockbc_submatch(struct device *parent, void *match, void *aux) } int -iockbc_attach_slot(struct iockbc_softc *sc, pckbc_slot_t slot) +iockbc_attach_slot(struct iockbc_softc *isc, pckbc_slot_t slot) { - struct pckbc_softc *isc = &sc->sc_pckbc; - struct pckbc_internal *t = isc->id; + struct pckbc_softc *sc = &isc->sc_pckbc; + struct pckbc_internal *t = sc->id; struct pckbc_attach_args pa; int found; @@ -292,7 +350,7 @@ iockbc_attach_slot(struct iockbc_softc *sc, pckbc_slot_t slot) printf("Failed to allocate slot data!\n"); return 0; } - iockbc_init_slotdata(t->t_slotdata[slot]); + iockbc_init_slotdata(t->t_slotdata[slot], &isc->reginfo[slot]); } pa.pa_tag = t; @@ -304,37 +362,45 @@ iockbc_attach_slot(struct iockbc_softc *sc, pckbc_slot_t slot) } void -iockbc_attach_common(struct iockbc_softc *isc, bus_addr_t addr) +iockbc_attach_common(struct iockbc_softc *isc, bus_addr_t addr, int console) { struct pckbc_softc *sc = &isc->sc_pckbc; struct pckbc_internal *t; + bus_addr_t cs; uint32_t csr; - /* - * Setup up controller: do not force pull clock and data lines low, - * clamp clocks after three bytes received. - */ - csr = bus_space_read_4(isc->iot, isc->ioh, isc->cs); - csr &= ~(IOC3_KBC_CTRL_KBD_PULL_DATA_LOW | - IOC3_KBC_CTRL_KBD_PULL_CLOCK_LOW | - IOC3_KBC_CTRL_AUX_PULL_DATA_LOW | - IOC3_KBC_CTRL_AUX_PULL_CLOCK_LOW | - IOC3_KBC_CTRL_KBD_CLAMP_1 | IOC3_KBC_CTRL_AUX_CLAMP_1); - csr |= IOC3_KBC_CTRL_KBD_CLAMP_3 | IOC3_KBC_CTRL_AUX_CLAMP_3; - bus_space_write_4(isc->iot, isc->ioh, isc->cs, csr); - - /* Setup pckbc_internal structure. */ - t = malloc(sizeof(struct pckbc_internal), M_DEVBUF, - M_WAITOK | M_ZERO); - t->t_iot = isc->iot; - t->t_ioh_d = isc->ioh; - t->t_ioh_c = isc->ioh; - t->t_addr = addr; - t->t_sc = sc; - sc->id = t; - - timeout_set(&t->t_cleanup, iockbc_cleanup, t); - timeout_set(&t->t_poll, iockbc_poll, t); + if (console) { + iockbc_consdata.t_sc = sc; + sc->id = &iockbc_consdata; + isc->console = 1; + } else { + /* + * Setup up controller: do not force pull clock and data lines + * low, clamp clocks after three bytes received. + */ + cs = isc->reginfo[0].cs; + csr = bus_space_read_4(isc->iot, isc->ioh, cs); + csr &= ~(IOC3_KBC_CTRL_KBD_PULL_DATA_LOW | + IOC3_KBC_CTRL_KBD_PULL_CLOCK_LOW | + IOC3_KBC_CTRL_AUX_PULL_DATA_LOW | + IOC3_KBC_CTRL_AUX_PULL_CLOCK_LOW | + IOC3_KBC_CTRL_KBD_CLAMP_1 | IOC3_KBC_CTRL_AUX_CLAMP_1); + csr |= IOC3_KBC_CTRL_KBD_CLAMP_3 | IOC3_KBC_CTRL_AUX_CLAMP_3; + bus_space_write_4(isc->iot, isc->ioh, cs, csr); + + /* Setup pckbc_internal structure. */ + t = malloc(sizeof(struct pckbc_internal), M_DEVBUF, + M_WAITOK | M_ZERO); + t->t_iot = isc->iot; + t->t_ioh_d = isc->ioh; + t->t_ioh_c = isc->ioh; + t->t_addr = addr; + t->t_sc = sc; + sc->id = t; + + timeout_set(&t->t_cleanup, iockbc_cleanup, t); + timeout_set(&t->t_poll, iockbc_poll, t); + } /* * Attach "slots". @@ -368,7 +434,6 @@ iockbcintr(void *vsc) int iockbcintr_internal(struct pckbc_internal *t, struct pckbc_softc *sc) { - struct iockbc_softc *isc = (void *)sc; pckbc_slot_t slot; struct pckbc_slotdata *q; int served = 0; @@ -398,7 +463,7 @@ iockbcintr_internal(struct pckbc_internal *t, struct pckbc_softc *sc) } val = bus_space_read_4(t->t_iot, t->t_ioh_d, - isc->rx[slot]); + q->reginfo->rx); if ((val & IOC3_KBC_DATA_VALID) == 0) break; @@ -447,21 +512,17 @@ iockbc_process_input(struct pckbc_softc *sc, struct pckbc_internal *t, int iockbc_poll_write(struct pckbc_internal *t, pckbc_slot_t slot, int val) { - struct iockbc_softc *isc = (void *)t->t_sc; + struct pckbc_slotdata *q = t->t_slotdata[slot]; bus_space_tag_t iot = t->t_iot; bus_space_handle_t ioh = t->t_ioh_d; - u_int64_t stat, offset, busy; + u_int64_t stat; int timeout = 10000; - offset = isc->tx[slot]; - busy = slot == PCKBC_AUX_SLOT ? IOC3_KBC_STATUS_AUX_WRITE_PENDING : - IOC3_KBC_STATUS_KBD_WRITE_PENDING; - /* Attempt to write a value to the controller. */ while (timeout--) { - stat = bus_space_read_4(iot, ioh, isc->cs); - if ((stat & busy) == 0) { - bus_space_write_4(iot, ioh, offset, val & 0xff); + stat = bus_space_read_4(iot, ioh, q->reginfo->cs); + if ((stat & q->reginfo->busy) == 0) { + bus_space_write_4(iot, ioh, q->reginfo->tx, val & 0xff); return 0; } delay(50); @@ -474,7 +535,6 @@ iockbc_poll_write(struct pckbc_internal *t, pckbc_slot_t slot, int val) int iockbc_poll_read(struct pckbc_internal *t, pckbc_slot_t slot) { - struct iockbc_softc *isc = (void *)t->t_sc; struct pckbc_slotdata *q = t->t_slotdata[slot]; int timeout = 10000; u_int32_t val; @@ -485,7 +545,7 @@ iockbc_poll_read(struct pckbc_internal *t, pckbc_slot_t slot) /* Poll input from controller. */ while (timeout--) { - val = bus_space_read_4(t->t_iot, t->t_ioh_d, isc->rx[slot]); + val = bus_space_read_4(t->t_iot, t->t_ioh_d, q->reginfo->rx); if (val & IOC3_KBC_DATA_VALID) break; delay(50); @@ -855,6 +915,7 @@ pckbc_set_inputhandler(pckbc_tag_t self, pckbc_slot_t slot, pckbc_inputfcn func, { struct pckbc_internal *t = (struct pckbc_internal *)self; struct pckbc_softc *sc = t->t_sc; + struct iockbc_softc *isc = (struct iockbc_softc *)sc; if (slot >= PCKBC_NSLOTS) panic("iockbc_set_inputhandler: bad slot %d", slot); @@ -863,7 +924,7 @@ pckbc_set_inputhandler(pckbc_tag_t self, pckbc_slot_t slot, pckbc_inputfcn func, sc->inputarg[slot] = arg; sc->subname[slot] = name; - if (iockbc_console && slot == PCKBC_KBD_SLOT) + if ((isc == NULL || isc->console) && slot == PCKBC_KBD_SLOT) timeout_add_sec(&t->t_poll, 1); } @@ -903,3 +964,110 @@ pckbc_set_poll(pckbc_tag_t self, pckbc_slot_t slot, int on) } } } + +/* + * Console support. + * + * There might multiple IOC3 and/or IOC4 devices in the system; the kernel + * will currently only use the one the debug serial console would be attached + * to as the console input device, regardless of the ConsoleIn variable. + */ + +static int16_t iockbc_console_nasid; +static int iockbc_console_widget; +static int iockbc_console_npci; +static uint32_t iockbc_console_type; + +static struct pckbc_slotdata iockbc_cons_slotdata; + +int +iockbc_cnattach(int16_t nasid, int widget, int npci, uint32_t type, + pckbc_slot_t slot) +{ + bus_space_tag_t iot = &sys_config.console_io; + bus_space_handle_t ioh = (bus_space_handle_t)iot->bus_base; + struct pckbc_internal *t = &iockbc_consdata; + const struct iockbc_reginfo *reginfo = NULL; + uint32_t csr; + int is_ioc; + int rc; + + is_ioc = type == PCI_ID_CODE(PCI_VENDOR_SGI, PCI_PRODUCT_SGI_IOC3); + if (is_ioc) { +#if NIOCKBC_IOC > 0 + if (sys_config.system_type == SGI_IP35) + reginfo = &iockbc_ioc_inverted[slot]; + else + reginfo = &iockbc_ioc_normal[slot]; +#endif + } else { +#if NIOCKBC_IOF > 0 + reginfo = &iockbc_iof[slot]; +#endif + } + if (reginfo == NULL) + return ENXIO; + + /* + * Setup up controller: do not force pull clock and data lines + * low, clamp clocks after three bytes received. + */ + csr = bus_space_read_4(iot, ioh, reginfo->cs); + csr &= ~(IOC3_KBC_CTRL_KBD_PULL_DATA_LOW | + IOC3_KBC_CTRL_KBD_PULL_CLOCK_LOW | + IOC3_KBC_CTRL_AUX_PULL_DATA_LOW | + IOC3_KBC_CTRL_AUX_PULL_CLOCK_LOW | + IOC3_KBC_CTRL_KBD_CLAMP_1 | IOC3_KBC_CTRL_AUX_CLAMP_1); + csr |= IOC3_KBC_CTRL_KBD_CLAMP_3 | IOC3_KBC_CTRL_AUX_CLAMP_3; + bus_space_write_4(iot, ioh, reginfo->cs, csr); + + /* Setup pckbc_internal structure. */ + t->t_iot = iot; + t->t_ioh_d = (bus_space_handle_t)iot->bus_base; + t->t_addr = 0; /* unused */ + + timeout_set(&t->t_cleanup, iockbc_cleanup, t); + timeout_set(&t->t_poll, iockbc_poll, t); + + iockbc_init_slotdata(&iockbc_cons_slotdata, reginfo); + t->t_slotdata[slot] = &iockbc_cons_slotdata; + + rc = pckbd_cnattach(t, slot); + + /* + * Upon success, remember our configuration to be able to + * recognize the console input device during autoconf. + */ + if (rc == 0) { + iockbc_console_nasid = nasid; + iockbc_console_widget = widget; + iockbc_console_npci = npci; + iockbc_console_type = type; + } + + return rc; +} + +#if NIOCKBC_IOC > 0 +int +iockbc_is_ioc_console(struct ioc_attach_args *iaa) +{ + return iaa->iaa_nasid == iockbc_console_nasid && + iaa->iaa_widget == iockbc_console_widget && + iaa->iaa_npci == iockbc_console_npci && + iockbc_console_type == + PCI_ID_CODE(PCI_VENDOR_SGI, PCI_PRODUCT_SGI_IOC3); +} +#endif + +#if NIOCKBC_IOF > 0 +int +iockbc_is_iof_console(struct iof_attach_args *iaa) +{ + return iaa->iaa_nasid == iockbc_console_nasid && + iaa->iaa_widget == iockbc_console_widget && + iaa->iaa_npci == iockbc_console_npci && + iockbc_console_type == + PCI_ID_CODE(PCI_VENDOR_SGI, PCI_PRODUCT_SGI_IOC4); +} +#endif diff --git a/sys/arch/sgi/dev/iockbcvar.h b/sys/arch/sgi/dev/iockbcvar.h new file mode 100644 index 00000000000..e0a8ecc2910 --- /dev/null +++ b/sys/arch/sgi/dev/iockbcvar.h @@ -0,0 +1,19 @@ +/* $OpenBSD: iockbcvar.h,v 1.1 2010/03/07 13:44:24 miod Exp $ */ + +/* + * Copyright (c) 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +int iockbc_cnattach(int16_t, int, int, uint32_t, pckbc_slot_t); diff --git a/sys/arch/sgi/pci/ioc.c b/sys/arch/sgi/pci/ioc.c index 24f64f2adaa..e1aa1afe2fb 100644 --- a/sys/arch/sgi/pci/ioc.c +++ b/sys/arch/sgi/pci/ioc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ioc.c,v 1.31 2009/11/11 15:56:42 miod Exp $ */ +/* $OpenBSD: ioc.c,v 1.32 2010/03/07 13:44:26 miod Exp $ */ /* * Copyright (c) 2008 Joel Sing. @@ -66,6 +66,7 @@ struct ioc_intr { struct ioc_softc { struct device sc_dev; + int sc_npci; struct mips_bus_space *sc_mem_bus_space; @@ -170,6 +171,7 @@ ioc_attach(struct device *parent, struct device *self, void *aux) } sc->sc_pc = pa->pa_pc; + sc->sc_npci = pa->pa_device; sc->sc_dmat = pa->pa_dmat; /* @@ -443,6 +445,9 @@ ioc_attach_child(struct ioc_softc *sc, const char *name, bus_addr_t base, memset(&iaa, 0, sizeof iaa); iaa.iaa_name = name; + iaa.iaa_nasid = pci_get_nasid(sc->sc_pc); + iaa.iaa_widget = pci_get_widget(sc->sc_pc); + iaa.iaa_npci = sc->sc_npci; iaa.iaa_memt = sc->sc_memt; iaa.iaa_memh = sc->sc_memh; iaa.iaa_dmat = sc->sc_dmat; diff --git a/sys/arch/sgi/pci/iocvar.h b/sys/arch/sgi/pci/iocvar.h index 172e533e54e..6071e2bd24f 100644 --- a/sys/arch/sgi/pci/iocvar.h +++ b/sys/arch/sgi/pci/iocvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: iocvar.h,v 1.4 2009/11/11 15:56:42 miod Exp $ */ +/* $OpenBSD: iocvar.h,v 1.5 2010/03/07 13:44:26 miod Exp $ */ /* * Copyright (c) 2008 Miodrag Vallat. @@ -19,6 +19,10 @@ struct ioc_attach_args { const char *iaa_name; + int16_t iaa_nasid; + int iaa_widget; + int iaa_npci; + bus_space_tag_t iaa_memt; bus_space_handle_t iaa_memh; bus_dma_tag_t iaa_dmat; diff --git a/sys/arch/sgi/pci/iof.c b/sys/arch/sgi/pci/iof.c index 7d6a6631f7a..bf95cddb66d 100644 --- a/sys/arch/sgi/pci/iof.c +++ b/sys/arch/sgi/pci/iof.c @@ -1,4 +1,4 @@ -/* $OpenBSD: iof.c,v 1.4 2009/10/13 21:17:13 miod Exp $ */ +/* $OpenBSD: iof.c,v 1.5 2010/03/07 13:44:26 miod Exp $ */ /* * Copyright (c) 2009 Miodrag Vallat. @@ -56,6 +56,7 @@ struct iof_intr { struct iof_softc { struct device sc_dev; + int sc_npci; struct mips_bus_space *sc_mem_bus_space; @@ -126,6 +127,7 @@ iof_attach(struct device *parent, struct device *self, void *aux) } sc->sc_pc = pa->pa_pc; + sc->sc_npci = pa->pa_device; sc->sc_dmat = pa->pa_dmat; /* @@ -210,6 +212,9 @@ iof_attach_child(struct device *iof, const char *name, bus_addr_t base, struct iof_attach_args iaa; iaa.iaa_name = name; + iaa.iaa_nasid = pci_get_nasid(sc->sc_pc); + iaa.iaa_widget = pci_get_widget(sc->sc_pc); + iaa.iaa_npci = sc->sc_npci; iaa.iaa_memt = sc->sc_memt; iaa.iaa_memh = sc->sc_memh; iaa.iaa_dmat = sc->sc_dmat; diff --git a/sys/arch/sgi/pci/iofvar.h b/sys/arch/sgi/pci/iofvar.h index 5e8d7a09c93..97a3d00598f 100644 --- a/sys/arch/sgi/pci/iofvar.h +++ b/sys/arch/sgi/pci/iofvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: iofvar.h,v 1.2 2009/10/13 21:17:13 miod Exp $ */ +/* $OpenBSD: iofvar.h,v 1.3 2010/03/07 13:44:26 miod Exp $ */ /* * Copyright (c) 2009 Miodrag Vallat. @@ -19,6 +19,10 @@ struct iof_attach_args { const char *iaa_name; + int16_t iaa_nasid; + int iaa_widget; + int iaa_npci; + bus_space_tag_t iaa_memt; bus_space_handle_t iaa_memh; bus_dma_tag_t iaa_dmat; diff --git a/sys/arch/sgi/sgi/ip27_machdep.c b/sys/arch/sgi/sgi/ip27_machdep.c index a9e4db2563b..fa4aeee8f48 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.42 2010/01/09 20:33:16 miod Exp $ */ +/* $OpenBSD: ip27_machdep.c,v 1.43 2010/03/07 13:44:26 miod Exp $ */ /* * Copyright (c) 2008, 2009 Miodrag Vallat. @@ -29,6 +29,7 @@ #include <sys/reboot.h> #include <sys/tty.h> +#include <mips64/arcbios.h> #include <mips64/archtype.h> #include <machine/autoconf.h> @@ -58,6 +59,7 @@ paddr_t ip27_widget_short(int16_t, u_int); paddr_t ip27_widget_long(int16_t, u_int); paddr_t ip27_widget_map(int16_t, u_int,bus_addr_t *, bus_size_t *); int ip27_widget_id(int16_t, u_int, uint32_t *); +int ip27_widget_id_early(int16_t, u_int, uint32_t *); void ip27_halt(int); @@ -159,7 +161,7 @@ ip27_setup() xbow_widget_base = ip27_widget_short; xbow_widget_map = ip27_widget_map; - xbow_widget_id = ip27_widget_id; + xbow_widget_id = ip27_widget_id_early; md_halt = ip27_halt; @@ -219,11 +221,10 @@ ip27_setup() cons = kl_get_console(); xbow_build_bus_space(&sys_config.console_io, 0, 8 /* whatever nonzero */); - /* Constrain to the correct window */ + /* point to devio base */ sys_config.console_io.bus_base = - cons->uart_base & 0xffffffffff000000UL; - - comconsaddr = cons->uart_base & 0x0000000000ffffffUL; + cons->uart_base & 0xfffffffffff00000UL; + comconsaddr = cons->uart_base & 0x00000000000fffffUL; comconsrate = cons->baud; if (comconsrate < 50 || comconsrate > 115200) comconsrate = 9600; @@ -236,10 +237,11 @@ ip27_setup() paddr_t ioc4_base; /* - * IOC4 clocks are derived from the PCI clock, so we need to - * figure out whether this is an 66MHz or a 33MHz bus. + * IOC4 clocks are derived from the PCI clock, + * so we need to figure out whether this is an 66MHz + * or a 33MHz bus. */ - ioc4_base = cons->uart_base & ~0xfffffUL; /* point to devio */ + ioc4_base = sys_config.console_io.bus_base; ioc4_mcr = *(volatile uint32_t *)(ioc4_base + IOC4_MCR); if (ioc4_mcr & IOC4_MCR_PCI_66MHZ) comconsfreq = 66666667; @@ -314,6 +316,8 @@ ip27_autoconf(struct device *parent) struct cpu_attach_args caa; uint node; + xbow_widget_id = ip27_widget_id; + /* * Attach the CPU we are running on early; other processors, * if any, will get attached as they are discovered. @@ -505,6 +509,28 @@ ip27_widget_id(int16_t nasid, u_int widget, uint32_t *wid) } /* + * Same as the above, but usable before we can handle faults. + * Expects the caller to only use valid widget numbers... + */ +int +ip27_widget_id_early(int16_t nasid, u_int widget, uint32_t *wid) +{ + paddr_t wpa; + + if (widget != 0) + { + if (widget < WIDGET_MIN || widget > WIDGET_MAX) + return EINVAL; + } + + wpa = ip27_widget_short(nasid, widget); + if (wid != NULL) + *wid = *(uint32_t *)(wpa + (WIDGET_ID | 4)); + + return 0; +} + +/* * Reboot code */ diff --git a/sys/arch/sgi/sgi/ip30.h b/sys/arch/sgi/sgi/ip30.h index b9b561ad99b..af851668db5 100644 --- a/sys/arch/sgi/sgi/ip30.h +++ b/sys/arch/sgi/sgi/ip30.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip30.h,v 1.8 2010/01/19 19:54:24 miod Exp $ */ +/* $OpenBSD: ip30.h,v 1.9 2010/03/07 13:44:26 miod Exp $ */ /* * Copyright (c) 2008, 2009 Miodrag Vallat. @@ -34,6 +34,8 @@ #define IP30_HEART_WIDGET 8 #define IP30_BRIDGE_WIDGET 15 +#define IP30_IOC_SLOTNO 2 + /* * On-board IOC3 specific GPIO registers wiring */ @@ -93,4 +95,6 @@ struct ip30_gda { void *tlb_handlers[3]; uint64_t nmi_count; }; + +int ip30_find_video(void); #endif diff --git a/sys/arch/sgi/sgi/ip30_machdep.c b/sys/arch/sgi/sgi/ip30_machdep.c index 75cb72af464..29c19aab1f9 100644 --- a/sys/arch/sgi/sgi/ip30_machdep.c +++ b/sys/arch/sgi/sgi/ip30_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip30_machdep.c,v 1.36 2010/02/28 18:01:39 miod Exp $ */ +/* $OpenBSD: ip30_machdep.c,v 1.37 2010/03/07 13:44:26 miod Exp $ */ /* * Copyright (c) 2008, 2009 Miodrag Vallat. @@ -38,6 +38,7 @@ #include <sgi/sgi/ip30.h> #include <sgi/xbow/widget.h> #include <sgi/xbow/xbow.h> +#include <sgi/xbow/xbowdevs.h> #include <sgi/xbow/xbridgereg.h> /* BRIDGE_PCI0_MEM_SPACE_BASE */ #include <sgi/xbow/xheartreg.h> @@ -169,7 +170,7 @@ ip30_setup() /* * Initialize the early console parameters. - * On Octane, the BRIDGE is always widet 15, and IOC3 is always + * On Octane, the BRIDGE is always widget 15, and IOC3 is always * mapped in memory space at address 0x500000. * * Also, note that by using a direct widget bus_space, there is @@ -180,9 +181,9 @@ ip30_setup() xbow_build_bus_space(&sys_config.console_io, 0, 15); sys_config.console_io.bus_base = ip30_widget_long(0, 15) + - BRIDGE_PCI0_MEM_SPACE_BASE; + BRIDGE_PCI0_MEM_SPACE_BASE + 0x500000; - comconsaddr = 0x500000 + IOC3_UARTA_BASE; + comconsaddr = IOC3_UARTA_BASE; comconsfreq = 22000000 / 3; comconsiot = &sys_config.console_io; comconsrate = bios_getenvint("dbaud"); @@ -202,7 +203,7 @@ ip30_setup() * Octane and Octane2 can be told apart with a GPIO source bit * in the onboard IOC3. */ - ip30_iocbase = sys_config.console_io.bus_base + 0x500000; + ip30_iocbase = sys_config.console_io.bus_base; if (*(volatile uint32_t *) (ip30_iocbase + IOC3_GPPR(IP30_GPIO_CLASSIC)) != 0) hw_prod = "Octane"; @@ -320,6 +321,76 @@ ip30_widget_id(int16_t nasid, u_int widget, uint32_t *wid) } /* + * Figure out which video widget to use. + * + * If we are running with glass console, ConsoleOut will be `video(#)' with + * the optional number being the number of the video device in the ARCBios + * component tree. + * + * Unfortunately, we do not know how to match an ARCBios component to a + * given widget (the PROM can... it's just not sharing this with us). + * + * So simply walk the available widget space and count video devices. + */ + +int +ip30_find_video() +{ + uint widid, head; + uint32_t id, vendor, product; + char *p; + + if (strncmp(bios_console, "video", 5) != 0) + return 0; /* not graphics console */ + + p = bios_console + 5; + switch (*p) { + case '(': + /* 8 widgets max -> single digit */ + p++; + if (*p == ')') + head = 0; + else { + if (*p < '0' || *p > '9') + return 0; + head = *p++ - '0'; + if (*p != ')') + return 0; + } + break; + case '\0': + head = 0; + break; + default: + return 0; + } + + for (widid = WIDGET_MIN; widid <= WIDGET_MAX; widid++) { + if (ip30_widget_id(0, widid, &id) != 0) + continue; + + vendor = (id & WIDGET_ID_VENDOR_MASK) >> + WIDGET_ID_VENDOR_SHIFT; + product = (id & WIDGET_ID_PRODUCT_MASK) >> + WIDGET_ID_PRODUCT_SHIFT; + + if ((vendor == XBOW_VENDOR_SGI2 && + product == XBOW_PRODUCT_SGI2_ODYSSEY) || + (vendor == XBOW_VENDOR_SGI5 && + product == XBOW_PRODUCT_SGI5_IMPACT) || + (vendor == XBOW_VENDOR_SGI5 && + product == XBOW_PRODUCT_SGI5_KONA)) { + /* found a video device */ + if (head == 0) + return widid; + head--; + } + } + + return 0; +} + +/* * Fun with the lightbar */ uint32_t diff --git a/sys/arch/sgi/sgi/wscons_machdep.c b/sys/arch/sgi/sgi/wscons_machdep.c index 9c8575864d9..bd12e4725d3 100644 --- a/sys/arch/sgi/sgi/wscons_machdep.c +++ b/sys/arch/sgi/sgi/wscons_machdep.c @@ -1,6 +1,21 @@ -/* $OpenBSD: wscons_machdep.c,v 1.4 2009/10/26 18:00:06 miod Exp $ */ +/* $OpenBSD: wscons_machdep.c,v 1.5 2010/03/07 13:44:26 miod Exp $ */ /* + * Copyright (c) 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* * Copyright (c) 2001 Aaron Campbell * All rights reserved. * @@ -35,31 +50,57 @@ #include <machine/autoconf.h> #include <machine/bus.h> +#if defined(TGT_ORIGIN) +#include <machine/mnode.h> +#endif #include <mips64/arcbios.h> #include <mips64/archtype.h> #include <sgi/localbus/crimebus.h> +#include <sgi/localbus/macebus.h> #include <sgi/localbus/macebusvar.h> -#include <sgi/dev/gbereg.h> -#include <sgi/dev/mkbcreg.h> - #include <dev/cons.h> #include <dev/ic/pckbcvar.h> #include <dev/usb/ukbdvar.h> #include <dev/wscons/wskbdvar.h> #include <dev/wscons/wsconsio.h> +#include <dev/wscons/wsdisplayvar.h> -#include "gbe.h" -#include "mkbc.h" +#include <sgi/dev/gbereg.h> +#include <sgi/dev/iockbcvar.h> +#include <sgi/dev/mkbcreg.h> +#include <sgi/xbow/odysseyvar.h> -#include "wsdisplay.h" -#if NWSDISPLAY > 0 -#include <dev/wscons/wsdisplayvar.h> +#if defined(TGT_OCTANE) +#include <sgi/sgi/ip30.h> +#include <dev/pci/pcireg.h> +#include <dev/pci/pcidevs.h> #endif +#include "gbe.h" +#include "iockbc.h" +#include "mkbc.h" +#include "odyssey.h" +#include "ukbd.h" + cons_decl(ws); +extern bus_addr_t comconsaddr; + +#if defined(TGT_OCTANE) || defined(TGT_ORIGIN) +int16_t output_widget_nasid; +int output_widget_id; +int (*output_widget_cninit)(int16_t, int) = NULL; + +int16_t input_widget_nasid; +int input_widget_id; +int input_widget_npci; +uint32_t input_widget_type; + +int widget_cnprobe(void); +void widget_cnattach(void); +#endif void wscnprobe(struct consdev *cp) @@ -81,9 +122,10 @@ wscnprobe(struct consdev *cp) cp->cn_pri = CN_DEAD; switch (sys_config.system_type) { +#if defined(TGT_O2) case SGI_O2: #if NGBE > 0 - if (gbe_cnprobe(&crimebus_tag, GBE_BASE)) { + if (gbe_cnprobe(&crimebus_tag, GBE_BASE) != 0) { if (strncmp(bios_console, "video", 5) == 0) cp->cn_pri = CN_FORCED; else @@ -91,6 +133,32 @@ wscnprobe(struct consdev *cp) } #endif break; +#endif + +#if defined(TGT_ORIGIN) + case SGI_IP27: + case SGI_IP35: + if (widget_cnprobe() != 0) { + if (strncmp(bios_console, + "/dev/graphics/textport", 22) == 0) + cp->cn_pri = CN_FORCED; + else + cp->cn_pri = CN_MIDPRI; + } + break; +#endif + +#if defined(TGT_OCTANE) + case SGI_OCTANE: + if (widget_cnprobe() != 0) { + if (strncmp(bios_console, "video", 5) == 0) + cp->cn_pri = CN_FORCED; + else + cp->cn_pri = CN_MIDPRI; + } + break; +#endif + default: break; } @@ -106,14 +174,37 @@ static int initted; initted = 1; + switch (sys_config.system_type) { +#if defined(TGT_O2) + case SGI_O2: #if NGBE > 0 - if (!gbe_cnattach(&crimebus_tag, GBE_BASE)) - return; + if (gbe_cnattach(&crimebus_tag, GBE_BASE) != 0) + return; #endif + #if NMKBC > 0 - if (!mkbc_cnattach(&macebus_tag, 0x00320000, PCKBC_KBD_SLOT)) - return; + if (mkbc_cnattach(&macebus_tag, MACE_IO_KBC_OFFS, + PCKBC_KBD_SLOT) == 0) + return; /* console keyboard found */ #endif +#if NUKBD > 0 + /* fallback keyboard console attachment if the others failed */ + ukbd_cnattach(); +#endif + break; +#endif + +#if defined(TGT_OCTANE) || defined(TGT_ORIGIN) + case SGI_IP27: + case SGI_IP35: + case SGI_OCTANE: + widget_cnattach(); + break; +#endif + + default: + break; + } } void @@ -139,3 +230,99 @@ wscnpollc(dev_t dev, int on) { wskbd_cnpollc(dev, on); } + +/* + * Try to figure out if we have a glass console widget, and if we have + * a driver for it. + */ + +#if defined(TGT_OCTANE) || defined(TGT_ORIGIN) +int +widget_cnprobe() +{ +#ifdef TGT_ORIGIN + console_t *cons; +#endif + + switch (sys_config.system_type) { +#ifdef TGT_ORIGIN + case SGI_IP27: + case SGI_IP35: + /* + * Our first pass over the KL configuration data has figured + * out which component is the glass console, if any. + */ + if (kl_glass_console == NULL) + return 0; + output_widget_nasid = kl_glass_console->nasid; + output_widget_id = kl_glass_console->widid; + + cons = kl_get_console(); + input_widget_nasid = cons->nasid; + input_widget_id = cons->wid; + input_widget_npci = cons->npci; + input_widget_type = (uint32_t)cons->type; + break; +#endif +#ifdef TGT_OCTANE + case SGI_OCTANE: + output_widget_nasid = masternasid; + output_widget_id = ip30_find_video(); + if (output_widget_id == 0) + return 0; + + input_widget_nasid = masternasid; + input_widget_id = IP30_BRIDGE_WIDGET; + input_widget_npci = IP30_IOC_SLOTNO; + input_widget_type = + PCI_ID_CODE(PCI_VENDOR_SGI, PCI_PRODUCT_SGI_IOC3); + break; +#endif + default: + return 0; + } + + /* + * Try supported frame buffers in no particular order. + */ + +#if NODYSSEY > 0 + if (odyssey_cnprobe(output_widget_nasid, output_widget_id) != 0) { + output_widget_cninit = odyssey_cnattach; + goto success; + } +#endif + + return 0; + +success: + /* + * At this point, we are commited to setup a glass console, + * so prevent serial console from winning over. + */ + comconsaddr = 0; + + return 1; +} + +void +widget_cnattach() +{ + /* should not happen */ + if (output_widget_cninit == NULL) + return; + + if ((*output_widget_cninit)(output_widget_nasid, output_widget_id) != 0) + return; + +#if NIOCKBC > 0 + if (iockbc_cnattach(input_widget_nasid, input_widget_id, + input_widget_npci, input_widget_type, PCKBC_KBD_SLOT) == 0) + return; /* console keyboard found */ +#endif +#if NUKBD > 0 + /* fallback keyboard console attachment if the others failed */ + ukbd_cnattach(); +#endif +} +#endif diff --git a/sys/arch/sgi/xbow/odyssey.c b/sys/arch/sgi/xbow/odyssey.c index b7cc082de55..f425da0ef19 100644 --- a/sys/arch/sgi/xbow/odyssey.c +++ b/sys/arch/sgi/xbow/odyssey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: odyssey.c,v 1.1 2010/03/04 14:50:35 jsing Exp $ */ +/* $OpenBSD: odyssey.c,v 1.2 2010/03/07 13:44:26 miod Exp $ */ /* * Copyright (c) 2009, 2010 Joel Sing <jsing@openbsd.org> * @@ -36,9 +36,11 @@ #include <mips64/arcbios.h> +#include <sgi/xbow/odysseyreg.h> +#include <sgi/xbow/odysseyvar.h> +#include <sgi/xbow/widget.h> #include <sgi/xbow/xbow.h> #include <sgi/xbow/xbowdevs.h> -#include <sgi/xbow/odysseyreg.h> #include <dev/wscons/wsconsio.h> #include <dev/wscons/wsdisplayvar.h> @@ -86,6 +88,8 @@ struct odyssey_softc { int odyssey_match(struct device *, void *, void *); void odyssey_attach(struct device *, struct device *, void *); +int odyssey_is_console(struct xbow_attach_args *); + void odyssey_cmd_wait(struct odyssey_softc *); void odyssey_data_wait(struct odyssey_softc *); void odyssey_cmd_flush(struct odyssey_softc *, int); @@ -126,6 +130,9 @@ int odyssey_show_screen(void *, void *, int, void (*)(void *, int, int), void *); void odyssey_burner(void *, u_int, u_int); +static struct odyssey_screen odyssey_consdata; +static struct odyssey_softc odyssey_cons_sc; + struct wsscreen_descr odyssey_stdscreen = { "std", /* Screen name. */ }; @@ -192,36 +199,47 @@ odyssey_attach(struct device *parent, struct device *self, void *aux) bcopy(xaa->xaa_iot, &sc->iot_store, sizeof(struct mips_bus_space)); sc->iot = &sc->iot_store; - /* - * Setup screen data. - */ - sc->curscr = malloc(sizeof(struct odyssey_screen), M_DEVBUF, M_NOWAIT); - if (sc->curscr == NULL) { - printf("failed to allocate screen memory!\n"); - return; - } - sc->curscr->sc = (void *)sc; - screen = sc->curscr; - /* Setup bus space mappings. */ if (bus_space_map(sc->iot, ODYSSEY_REG_OFFSET, ODYSSEY_REG_SIZE, BUS_SPACE_MAP_LINEAR, &sc->ioh)) { - printf("failed to map framebuffer bus space!\n"); + printf("failed to map bus space!\n"); return; } - /* Setup hardware and clear screen. */ - odyssey_setup(sc); - odyssey_fillrect(sc, 0, 0, 1280, 1024, 0x000000); - odyssey_cmd_flush(sc, 0); + if (odyssey_is_console(xaa)) { + /* + * Setup has already been done via odyssey_cnattach(). + */ + screen = &odyssey_consdata; + sc->curscr = screen; + sc->curscr->sc = (void *)sc; + sc->console = 1; + } else { + /* + * Setup screen data. + */ + sc->curscr = malloc(sizeof(struct odyssey_screen), M_DEVBUF, + M_NOWAIT); + if (sc->curscr == NULL) { + printf("failed to allocate screen memory!\n"); + return; + } + sc->curscr->sc = (void *)sc; + screen = sc->curscr; - /* Set screen defaults. */ - screen->width = 1280; - screen->height = 1024; - screen->depth = 32; - screen->linebytes = screen->width * screen->depth / 8; + /* Setup hardware and clear screen. */ + odyssey_setup(sc); + odyssey_fillrect(sc, 0, 0, 1280, 1024, 0x000000); + odyssey_cmd_flush(sc, 0); - odyssey_init_screen(screen); + /* Set screen defaults. */ + screen->width = 1280; + screen->height = 1024; + screen->depth = 32; + screen->linebytes = screen->width * screen->depth / 8; + + odyssey_init_screen(screen); + } waa.console = sc->console; waa.scrdata = &odyssey_screenlist; @@ -1046,3 +1064,87 @@ ieee754_sp(int32_t v) return (sign << 31) | (exp << 23) | ((v << (23 - i)) & 0x7fffff); } + +/* + * Console support. + */ + +static int16_t odyssey_console_nasid; +static int odyssey_console_widget; + +int +odyssey_cnprobe(int16_t nasid, int widget) +{ + u_int32_t wid, vendor, product; + + /* Probe for Odyssey graphics card. */ + if (xbow_widget_id(nasid, widget, &wid) != 0) + return 0; + + vendor = (wid & WIDGET_ID_VENDOR_MASK) >> WIDGET_ID_VENDOR_SHIFT; + product = (wid & WIDGET_ID_PRODUCT_MASK) >> WIDGET_ID_PRODUCT_SHIFT; + + if (vendor != XBOW_VENDOR_SGI2 || product != XBOW_PRODUCT_SGI2_ODYSSEY) + return 0; + + if (strncmp(bios_graphics, "alive", 5) != 0) + return 0; + + return 1; +} + +int +odyssey_cnattach(int16_t nasid, int widget) +{ + struct odyssey_softc *sc; + struct odyssey_screen *screen; + long attr; + int rc; + + sc = &odyssey_cons_sc; + screen = &odyssey_consdata; + sc->curscr = screen; + sc->curscr->sc = (void *)sc; + + /* Build bus space accessor. */ + xbow_build_bus_space(&sc->iot_store, nasid, widget); + sc->iot = &sc->iot_store; + + /* Setup bus space mappings. */ + rc = bus_space_map(sc->iot, ODYSSEY_REG_OFFSET, ODYSSEY_REG_SIZE, + BUS_SPACE_MAP_LINEAR, &sc->ioh); + if (rc != 0) + return rc; + + /* Setup hardware and clear screen. */ + odyssey_setup(sc); + odyssey_fillrect(sc, 0, 0, 1280, 1024, 0x000000); + odyssey_cmd_flush(sc, 0); + + /* Set screen defaults. */ + screen->width = 1280; + screen->height = 1024; + screen->depth = 32; + screen->linebytes = screen->width * screen->depth / 8; + + odyssey_init_screen(screen); + + /* + * Attach wsdisplay. + */ + odyssey_consdata.ri.ri_ops.alloc_attr(&odyssey_consdata.ri, + 0, 0, 0, &attr); + wsdisplay_cnattach(&odyssey_stdscreen, &odyssey_consdata.ri, + 0, 0, attr); + odyssey_console_nasid = nasid; + odyssey_console_widget = widget; + + return 0; +} + +int +odyssey_is_console(struct xbow_attach_args *xaa) +{ + return xaa->xaa_nasid == odyssey_console_nasid && + xaa->xaa_widget == odyssey_console_widget; +} diff --git a/sys/arch/sgi/xbow/odysseyvar.h b/sys/arch/sgi/xbow/odysseyvar.h new file mode 100644 index 00000000000..f11567a12a9 --- /dev/null +++ b/sys/arch/sgi/xbow/odysseyvar.h @@ -0,0 +1,19 @@ +/* $OpenBSD: odysseyvar.h,v 1.1 2010/03/07 13:44:26 miod Exp $ */ +/* + * Copyright (c) 2010 Joel Sing <jsing@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +int odyssey_cnprobe(int16_t, int); +int odyssey_cnattach(int16_t, int); |