diff options
-rw-r--r-- | sys/arch/sgi/gio/gio.c | 208 | ||||
-rw-r--r-- | sys/arch/sgi/gio/giovar.h | 11 | ||||
-rw-r--r-- | sys/arch/sgi/gio/grtwo.c | 26 | ||||
-rw-r--r-- | sys/arch/sgi/gio/impact_gio.c | 16 | ||||
-rw-r--r-- | sys/arch/sgi/gio/light.c | 24 | ||||
-rw-r--r-- | sys/arch/sgi/gio/newport.c | 32 |
6 files changed, 149 insertions, 168 deletions
diff --git a/sys/arch/sgi/gio/gio.c b/sys/arch/sgi/gio/gio.c index e2d42e50ff4..b223234ebbc 100644 --- a/sys/arch/sgi/gio/gio.c +++ b/sys/arch/sgi/gio/gio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gio.c,v 1.5 2012/04/18 17:28:24 miod Exp $ */ +/* $OpenBSD: gio.c,v 1.6 2012/04/24 20:11:26 miod Exp $ */ /* $NetBSD: gio.c,v 1.32 2011/07/01 18:53:46 dyoung Exp $ */ /* @@ -61,7 +61,10 @@ #include <sgi/gio/giovar.h> #include <sgi/gio/giodevs.h> #include <sgi/gio/giodevs_data.h> + #include <sgi/gio/grtworeg.h> +#include <sgi/gio/lightreg.h> +#include <sgi/gio/newportreg.h> #include <sgi/localbus/imcvar.h> #include <sgi/localbus/intreg.h> @@ -93,6 +96,7 @@ int gio_print_fb(void *, const char *); int gio_search(struct device *, void *, void *); int gio_submatch(struct device *, void *, void *); uint32_t gio_id(vaddr_t, paddr_t, int); +int gio_is_framebuffer_id(uint32_t); struct gio_softc { struct device sc_dev; @@ -111,6 +115,8 @@ struct cfdriver gio_cd = { /* Address of the console frame buffer registers, if applicable */ paddr_t giofb_consaddr; +/* Id of the console frame buffer */ +uint32_t giofb_consid; /* Names of the frame buffers, as obtained by ARCBios */ const char *giofb_names[GIO_MAX_FB]; @@ -121,9 +127,6 @@ struct gio_probe { uint32_t mach_subtype; }; -/* an invalid GIO ID value used to report the device might be a frame buffer */ -#define GIO_FAKE_FB_ID (0xffffff7f) - /* * Expansion Slot Base Addresses * @@ -197,7 +200,7 @@ gio_attach(struct device *parent, struct device *self, void *aux) struct gio_softc *sc = (struct gio_softc *)self; struct imc_attach_args *iaa = (struct imc_attach_args *)aux; struct gio_attach_args ga; - uint32_t gfx[GIO_MAX_FB]; + uint32_t gfx[GIO_MAX_FB], id; uint i, j, ngfx; printf("\n"); @@ -217,10 +220,6 @@ gio_attach(struct device *parent, struct device *self, void *aux) * we do not confuse them with expansion slots, should the * addresses coincide. * - * Unfortunately graphics devices for which we have no configured - * driver, which address matches a regular slot number, will show - * up as rogue devices attached to real slots. - * * If only the ARCBios component tree would be so kind as to give * us the address of the frame buffer components... */ @@ -240,14 +239,23 @@ gio_attach(struct device *parent, struct device *self, void *aux) ga.ga_ioh = PHYS_TO_XKPHYS(ga.ga_addr, CCA_NC); /* no need to probe a glass console again */ - if (ga.ga_addr != giofb_consaddr && - gio_id(ga.ga_ioh, ga.ga_addr, 1) != GIO_FAKE_FB_ID) - continue; + if (ga.ga_addr == giofb_consaddr) + id = giofb_consid; + else { + id = gio_id(ga.ga_ioh, ga.ga_addr, 1); + if (!gio_is_framebuffer_id(id)) + continue; + } ga.ga_iot = sc->sc_iot; ga.ga_dmat = sc->sc_dmat; ga.ga_slot = -1; - ga.ga_product = -1; + ga.ga_product = id; + /* + * Note that this relies upon ARCBios listing frame + * buffers in ascending address order, which seems + * to be the case so far on multihead Indigo2 systems. + */ if (ngfx < GIO_MAX_FB) ga.ga_descr = giofb_names[ngfx]; else @@ -331,12 +339,17 @@ gio_id(vaddr_t va, paddr_t pa, int maybe_gfx) /* * If the address doesn't match a base slot address, then we are - * only probing for a frame buffer. + * only probing for a light(4) frame buffer. */ - if (pa != GIO_ADDR_GFX && pa != GIO_ADDR_EXP0 && pa != GIO_ADDR_EXP1 && - maybe_gfx == 0) - return 0; + if (pa != GIO_ADDR_GFX && pa != GIO_ADDR_EXP0 && pa != GIO_ADDR_EXP1) { + if (maybe_gfx == 0) + return 0; + else { + if (pa == LIGHT_ADDR_0 || pa == LIGHT_ADDR_1) + return GIO_PRODUCT_FAKEID_LIGHT; + } + } /* * If there is a real GIO device at this address (as opposed to @@ -355,36 +368,46 @@ gio_id(vaddr_t va, paddr_t pa, int maybe_gfx) */ if (guarded_read_4(va + HQ2_MYSTERY, &mystery) == 0 && mystery == HQ2_MYSTERY_VALUE) - return maybe_gfx ? GIO_FAKE_FB_ID : 0; + return maybe_gfx ? GIO_PRODUCT_FAKEID_GRTWO : 0; if (GIO_PRODUCT_32BIT_ID(id8)) { if (id16 == (id32 & 0xffff)) return id32; } else { - if (id8 != 0) - return id8; + if (id8 != 0) { + if (id8 != GIO_PRODUCT_IMPACT || maybe_gfx) + return id8; + else + return 0; + } } } /* * If there is a frame buffer device, then either we have hit a - * device register (light, grtwo), or we did not fault because - * the slot is pipelined (newport). - * In the latter case, we attempt to probe a known register - * offset. + * device register (grtwo), or we did not fault because the slot + * is pipelined (newport). + * In the latter case, we attempt to probe a known register offset. */ if (maybe_gfx) { - if (id32 != 4 || id16 != 2 || id8 != 1) - return GIO_FAKE_FB_ID; + if (id32 != 4 || id16 != 2 || id8 != 1) { + if (guarded_read_4(va + HQ2_MYSTERY, &mystery) == 0 && + mystery == HQ2_MYSTERY_VALUE) + return GIO_PRODUCT_FAKEID_GRTWO; + else + return 0; + } /* could be newport(4) */ - va += 0xf0000; - if (guarded_read_4(va, &id32) == 0 && - guarded_read_2(va | 2, &id16) == 0 && - guarded_read_1(va | 3, &id8) == 0) { - if (id32 != 4 || id16 != 2 || id8 != 1) - return GIO_FAKE_FB_ID; + if (pa == GIO_ADDR_GFX || pa == GIO_ADDR_EXP0) { + va += NEWPORT_REX3_OFFSET; + if (guarded_read_4(va, &id32) == 0 && + guarded_read_2(va | 2, &id16) == 0 && + guarded_read_1(va | 3, &id8) == 0) { + if (id32 != 4 || id16 != 2 || id8 != 1) + return GIO_PRODUCT_FAKEID_NEWPORT; + } } return 0; @@ -434,12 +457,30 @@ int gio_print_fb(void *aux, const char *pnp) { struct gio_attach_args *ga = aux; + const char *fbname; - if (pnp != NULL) - printf("framebuffer at %s", pnp); + if (pnp != NULL) { + switch (ga->ga_product) { + case GIO_PRODUCT_FAKEID_GRTWO: + fbname = "grtwo"; + break; + case GIO_PRODUCT_IMPACT: + fbname = "impact"; + break; + case GIO_PRODUCT_FAKEID_LIGHT: + fbname = "light"; + break; + case GIO_PRODUCT_FAKEID_NEWPORT: + fbname = "newport"; + break; + default: /* should never happen */ + fbname = "framebuffer"; + break; + } + printf("%s at %s", fbname, pnp); + } - if (ga->ga_addr != (uint64_t)-1) - printf(" addr 0x%lx", ga->ga_addr); + printf(" addr 0x%lx", ga->ga_addr); return UNCONF; } @@ -492,6 +533,7 @@ int giofb_cnprobe() { struct gio_attach_args ga; + uint32_t id; int i; for (i = 0; gfx_bases[i].base != 0; i++) { @@ -512,10 +554,14 @@ giofb_cnprobe() ga.ga_ioh = PHYS_TO_XKPHYS(ga.ga_addr, CCA_NC); ga.ga_dmat = &imc_bus_dma_tag; ga.ga_slot = -1; - ga.ga_product = -1; ga.ga_descr = NULL; - switch (gio_id(ga.ga_ioh, ga.ga_addr, 1)) { + id = gio_id(ga.ga_ioh, ga.ga_addr, 1); + if (!gio_is_framebuffer_id(id)) + continue; + + ga.ga_product = giofb_consid = id; + switch (id) { case GIO_PRODUCT_IMPACT: #if NIMPACT_GIO > 0 ga.ga_product = GIO_PRODUCT_IMPACT; @@ -523,15 +569,19 @@ giofb_cnprobe() return 0; #endif break; - case GIO_FAKE_FB_ID: + case GIO_PRODUCT_FAKEID_GRTWO: #if NGRTWO > 0 if (grtwo_cnprobe(&ga) != 0) return 0; #endif + break; + case GIO_PRODUCT_FAKEID_LIGHT: #if NLIGHT > 0 if (light_cnprobe(&ga) != 0) return 0; #endif + break; + case GIO_PRODUCT_FAKEID_NEWPORT: #if NNEWPORT > 0 if (newport_cnprobe(&ga) != 0) return 0; @@ -547,64 +597,60 @@ int giofb_cnattach() { struct gio_attach_args ga; - int i; - - for (i = 0; gfx_bases[i].base != 0; i++) { - if (giofb_consaddr != 0 && - gfx_bases[i].base != giofb_consaddr) - continue; - - /* skip bases that don't apply to us */ - if (gfx_bases[i].mach_type != sys_config.system_type) - continue; - if (gfx_bases[i].mach_subtype != -1 && - gfx_bases[i].mach_subtype != sys_config.system_subtype) - continue; - - ga.ga_addr = gfx_bases[i].base; - ga.ga_iot = &imcbus_tag; - ga.ga_ioh = PHYS_TO_XKPHYS(ga.ga_addr, CCA_NC); - ga.ga_dmat = &imc_bus_dma_tag; - ga.ga_slot = -1; - ga.ga_product = -1; - ga.ga_descr = NULL; + ga.ga_addr = giofb_consaddr; + ga.ga_iot = &imcbus_tag; + ga.ga_ioh = PHYS_TO_XKPHYS(ga.ga_addr, CCA_NC); + ga.ga_dmat = &imc_bus_dma_tag; + ga.ga_slot = -1; + ga.ga_product = giofb_consid; + ga.ga_descr = NULL; - switch (gio_id(ga.ga_ioh, ga.ga_addr, 1)) { - case GIO_PRODUCT_IMPACT: + switch (giofb_consid) { + case GIO_PRODUCT_IMPACT: #if NIMPACT_GIO > 0 - if (impact_gio_cnattach(&ga) == 0) - return 0; + if (impact_gio_cnattach(&ga) == 0) + return 0; #endif - break; - case GIO_FAKE_FB_ID: - /* - * We still need to probe before attach since we don't - * know the frame buffer type here. - */ + break; + case GIO_PRODUCT_FAKEID_GRTWO: #if NGRTWO > 0 - if (grtwo_cnprobe(&ga) != 0 && - grtwo_cnattach(&ga) == 0) - return 0; + if (grtwo_cnattach(&ga) == 0) + return 0; #endif + break; + case GIO_PRODUCT_FAKEID_LIGHT: #if NLIGHT > 0 - if (light_cnprobe(&ga) != 0 && - light_cnattach(&ga) == 0) - return 0; + if (light_cnattach(&ga) == 0) + return 0; #endif + break; + case GIO_PRODUCT_FAKEID_NEWPORT: #if NNEWPORT > 0 - if (newport_cnprobe(&ga) != 0 && - newport_cnattach(&ga) == 0) - return 0; + if (newport_cnattach(&ga) == 0) + return 0; #endif - break; - } + break; } giofb_consaddr = 0; return ENXIO; } +int +gio_is_framebuffer_id(uint32_t id) +{ + switch (id) { + case GIO_PRODUCT_IMPACT: + case GIO_PRODUCT_FAKEID_GRTWO: + case GIO_PRODUCT_FAKEID_LIGHT: + case GIO_PRODUCT_FAKEID_NEWPORT: + return 1; + default: + return 0; + } +} + /* * Devices living in the expansion slots must enable or disable some * GIO arbiter settings. This is accomplished via imc(4) registers. diff --git a/sys/arch/sgi/gio/giovar.h b/sys/arch/sgi/gio/giovar.h index 60382b3411b..5bffeafdbaf 100644 --- a/sys/arch/sgi/gio/giovar.h +++ b/sys/arch/sgi/gio/giovar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: giovar.h,v 1.2 2012/04/16 22:28:13 miod Exp $ */ +/* $OpenBSD: giovar.h,v 1.3 2012/04/24 20:11:26 miod Exp $ */ /* $NetBSD: giovar.h,v 1.10 2011/07/01 18:53:46 dyoung Exp $ */ /* @@ -85,3 +85,12 @@ int giofb_cnprobe(void); extern paddr_t giofb_consaddr; extern const char *giofb_names[GIO_MAX_FB]; + +/* + * Fake GIO device IDs to identify frame buffers without GIO IDs. + * These are built as 32-bit GIO IDs without the `32-bit ID' bit set. + */ + +#define GIO_PRODUCT_FAKEID_LIGHT 0xff010000 +#define GIO_PRODUCT_FAKEID_NEWPORT 0xff020000 +#define GIO_PRODUCT_FAKEID_GRTWO 0xff030000 diff --git a/sys/arch/sgi/gio/grtwo.c b/sys/arch/sgi/gio/grtwo.c index 8fa4bee9730..f608b7214b6 100644 --- a/sys/arch/sgi/gio/grtwo.c +++ b/sys/arch/sgi/gio/grtwo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: grtwo.c,v 1.2 2012/04/18 17:20:54 miod Exp $ */ +/* $OpenBSD: grtwo.c,v 1.3 2012/04/24 20:11:26 miod Exp $ */ /* $NetBSD: grtwo.c,v 1.11 2009/11/22 19:09:15 mbalmer Exp $ */ /* @@ -163,7 +163,6 @@ static struct grtwo_devconfig grtwo_console_dc; /* console backing store, worst cast font selection */ static struct wsdisplay_charcell grtwo_console_bs[(GRTWO_WIDTH / 8) * (GRTWO_HEIGHT / 16)]; -static int grtwo_is_console = 0; void grtwo_wait_gfifo(struct grtwo_devconfig *dc) @@ -340,26 +339,8 @@ int grtwo_match(struct device *parent, void *vcf, void *aux) { struct gio_attach_args *ga = aux; - uint32_t mystery; - /* not looking for a frame buffer */ - if (ga->ga_slot != -1) - return 0; - - if (ga->ga_addr != GIO_ADDR_GFX && ga->ga_addr != GIO_ADDR_EXP0 && - ga->ga_addr != GIO_ADDR_EXP1) - return 0; - - /* - * GR2 doesn't have anything that even vaguely resembles a product - * ID. Instead, we determine presence by looking at the HQ2 "mystery" - * register, which contains a magic number. - */ - - if (guarded_read_4(ga->ga_ioh + HQ2_MYSTERY, &mystery) != 0) - return 0; - - if (mystery != HQ2_MYSTERY_VALUE) + if (ga->ga_product != GIO_PRODUCT_FAKEID_GRTWO) return 0; return 1; @@ -379,7 +360,7 @@ grtwo_attach(struct device *parent, struct device *self, void *aux) descr = "GR2"; printf(": %s", descr); - if (grtwo_is_console && ga->ga_addr == grtwo_console_dc.dc_addr) { + if (ga->ga_addr == grtwo_console_dc.dc_addr) { waa.console = 1; dc = &grtwo_console_dc; sc->sc_nscreens = 1; @@ -465,7 +446,6 @@ grtwo_cnattach(struct gio_attach_args *ga) cell->attr = defattr; wsdisplay_cnattach(&grtwo_console_dc.dc_wsd, ri, 0, 0, defattr); - grtwo_is_console = 1; return 0; } diff --git a/sys/arch/sgi/gio/impact_gio.c b/sys/arch/sgi/gio/impact_gio.c index 4fb2f2b6ee3..f745843c0d6 100644 --- a/sys/arch/sgi/gio/impact_gio.c +++ b/sys/arch/sgi/gio/impact_gio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: impact_gio.c,v 1.1 2012/04/18 17:28:24 miod Exp $ */ +/* $OpenBSD: impact_gio.c,v 1.2 2012/04/24 20:11:26 miod Exp $ */ /* * Copyright (c) 2012 Miodrag Vallat. @@ -53,20 +53,6 @@ impact_gio_match(struct device *parent, void *match, void *aux) { struct gio_attach_args *ga = aux; - /* Impact only exists on Indigo 2 systems */ - if (sys_config.system_type != SGI_IP22 || - sys_config.system_subtype != IP22_INDIGO2) - return 0; - - /* not looking for a frame buffer */ - if (ga->ga_slot != -1) - return 0; - - /* EXP1 does not exist on Indigo2 */ - if (ga->ga_addr != GIO_ADDR_GFX && ga->ga_addr != GIO_ADDR_EXP0) - return 0; - - /* Impact has a real GIO ID */ if (ga->ga_product != GIO_PRODUCT_IMPACT) return 0; diff --git a/sys/arch/sgi/gio/light.c b/sys/arch/sgi/gio/light.c index 05240d604cb..036171567ea 100644 --- a/sys/arch/sgi/gio/light.c +++ b/sys/arch/sgi/gio/light.c @@ -1,4 +1,4 @@ -/* $OpenBSD: light.c,v 1.1 2012/04/17 15:36:55 miod Exp $ */ +/* $OpenBSD: light.c,v 1.2 2012/04/24 20:11:26 miod Exp $ */ /* $NetBSD: light.c,v 1.5 2007/03/04 06:00:39 christos Exp $ */ /* @@ -159,7 +159,6 @@ void light_attach_common(struct light_devconfig *, struct gio_attach_args *); void light_init_screen(struct light_devconfig *); static struct light_devconfig light_console_dc; -static int light_is_console = 0; #define LIGHT_IS_LG1(_rev) ((_rev) < 2) /* else LG2 */ @@ -277,23 +276,11 @@ int light_match(struct device *parent, void *vcf, void *aux) { struct gio_attach_args *ga = aux; - uint32_t reg; - /* not looking for a frame buffer */ - if (ga->ga_slot != -1) - return (0); - - if (ga->ga_addr != LIGHT_ADDR_0 && ga->ga_addr != LIGHT_ADDR_1) - return (0); - - if (guarded_read_4(ga->ga_ioh + REX_PAGE1_SET + REX_P1REG_XYOFFSET, - ®) != 0) - return (0); - - if (reg != 0x08000800) - return (0); + if (ga->ga_product != GIO_PRODUCT_FAKEID_LIGHT) + return 0; - return (1); + return 1; } void @@ -304,7 +291,7 @@ light_attach(struct device *parent, struct device *self, void *aux) struct light_devconfig *dc; struct wsemuldisplaydev_attach_args waa; - if (light_is_console && ga->ga_addr == light_console_dc.dc_addr) { + if (ga->ga_addr == light_console_dc.dc_addr) { waa.console = 1; dc = &light_console_dc; sc->sc_nscreens = 1; @@ -356,7 +343,6 @@ light_cnattach(struct gio_attach_args *ga) ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr); wsdisplay_cnattach(&light_console_dc.dc_wsd, ri, 0, 0, defattr); - light_is_console = 1; return 0; } diff --git a/sys/arch/sgi/gio/newport.c b/sys/arch/sgi/gio/newport.c index c70347cb65a..049cbef3481 100644 --- a/sys/arch/sgi/gio/newport.c +++ b/sys/arch/sgi/gio/newport.c @@ -1,4 +1,4 @@ -/* $OpenBSD: newport.c,v 1.1 2012/04/16 22:31:36 miod Exp $ */ +/* $OpenBSD: newport.c,v 1.2 2012/04/24 20:11:26 miod Exp $ */ /* $NetBSD: newport.c,v 1.15 2009/05/12 23:51:25 macallan Exp $ */ /* @@ -171,7 +171,6 @@ void newport_init_screen(struct newport_devconfig *); void newport_setup_hw(struct newport_devconfig *); static struct newport_devconfig newport_console_dc; -static int newport_is_console = 0; /**** Low-level hardware register groveling functions ****/ static __inline__ void @@ -489,32 +488,8 @@ int newport_match(struct device *parent, void *vcf, void *aux) { struct gio_attach_args *ga = aux; - uint32_t dummy; - /* not looking for a frame buffer */ - if (ga->ga_slot != -1) - return 0; - - if (ga->ga_addr != GIO_ADDR_GFX && ga->ga_addr != GIO_ADDR_EXP0) - return 0; - - /* Don't do the destructive probe if we're already attached */ - if (newport_is_console && ga->ga_addr == newport_console_dc.dc_addr) - return 1; - - if (guarded_read_4(ga->ga_ioh + NEWPORT_REX3_OFFSET + REX3_REG_XSTARTI, - &dummy) != 0) - return 0; - if (guarded_read_4(ga->ga_ioh + NEWPORT_REX3_OFFSET + REX3_REG_XSTART, - &dummy) != 0) - return 0; - - /* Ugly, this probe is destructive, blame SGI... */ - bus_space_write_4(ga->ga_iot, ga->ga_ioh, - NEWPORT_REX3_OFFSET + REX3_REG_XSTARTI, 0x12345678); - if (bus_space_read_4(ga->ga_iot, ga->ga_ioh, - NEWPORT_REX3_OFFSET + REX3_REG_XSTART) != - ((0x12345678 & 0xffff) << 11)) + if (ga->ga_product != GIO_PRODUCT_FAKEID_NEWPORT) return 0; return 1; @@ -529,7 +504,7 @@ newport_attach(struct device *parent, struct device *self, void *aux) struct wsemuldisplaydev_attach_args waa; const char *descr; - if (newport_is_console && ga->ga_addr == newport_console_dc.dc_addr) { + if (ga->ga_addr == newport_console_dc.dc_addr) { waa.console = 1; dc = &newport_console_dc; sc->sc_nscreens = 1; @@ -581,7 +556,6 @@ newport_cnattach(struct gio_attach_args *ga) ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr); wsdisplay_cnattach(&newport_console_dc.dc_wsd, ri, 0, 0, defattr); - newport_is_console = 1; return 0; } |