summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/sgi/gio/gio.c208
-rw-r--r--sys/arch/sgi/gio/giovar.h11
-rw-r--r--sys/arch/sgi/gio/grtwo.c26
-rw-r--r--sys/arch/sgi/gio/impact_gio.c16
-rw-r--r--sys/arch/sgi/gio/light.c24
-rw-r--r--sys/arch/sgi/gio/newport.c32
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,
- &reg) != 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;
}