diff options
author | 2012-05-17 19:46:52 +0000 | |
---|---|---|
committer | 2012-05-17 19:46:52 +0000 | |
commit | b1650df9c5d1d61bfbe8a6d7b2ee202d819a73a0 (patch) | |
tree | bef2275c644c97f7075c7c8e01a0f1adddb3fc5a | |
parent | Better probes for sq and wdsc in gio-masqueraded-as-hpc expansion boards. (diff) | |
download | wireguard-openbsd-b1650df9c5d1d61bfbe8a6d7b2ee202d819a73a0.tar.xz wireguard-openbsd-b1650df9c5d1d61bfbe8a6d7b2ee202d819a73a0.zip |
Yet another rework of the crucial gio_id() function responsible for correctly
recognizing a GIO device or an id-less frame buffer in a GIO slot.
Turns out that GIO32 devices (at least those with a 32-bit ID register, but
likely all of them) do NOT like accesses to the minimal GIO register area
NOT done on 32-bit boundaries. While frame buffers won't mind, especially
if their slots are pipelined.
This makes it a lot easier to tell them apart.
While there, split gio_intr_establish() into gio_intr_map(), which will return
a logical interrupt number out of a GIO slot number, and gio_intr_establish(),
which will now expect a logical interrupt number, instead of a logical slot
number. These two functions are still unused, but upcoming changes depend on
this work. (Yes, I'm too lazy to make two commits for this tonite)
-rw-r--r-- | sys/arch/sgi/gio/gio.c | 95 | ||||
-rw-r--r-- | sys/arch/sgi/gio/giovar.h | 3 |
2 files changed, 33 insertions, 65 deletions
diff --git a/sys/arch/sgi/gio/gio.c b/sys/arch/sgi/gio/gio.c index 3e6930ee9ac..214bdad8bd5 100644 --- a/sys/arch/sgi/gio/gio.c +++ b/sys/arch/sgi/gio/gio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gio.c,v 1.9 2012/05/10 21:36:11 miod Exp $ */ +/* $OpenBSD: gio.c,v 1.10 2012/05/17 19:46:52 miod Exp $ */ /* $NetBSD: gio.c,v 1.32 2011/07/01 18:53:46 dyoung Exp $ */ /* @@ -325,9 +325,12 @@ gio_id(vaddr_t va, paddr_t pa, int maybe_gfx) /* * First, attempt to read the address with various sizes. - * If the slot is pipelined, and the address does not hit a - * device register, we will not fault but read the transfer - * width back. + * + * - GIO32 devices will only support reads from 32-bit aligned + * addresses, in all sizes (at least for the ID register). + * - frame buffers will support aligned reads from any size at + * any address, but will actually return the access width if + * the slot is pipelined. */ if (guarded_read_4(va, &id32) != 0) @@ -354,52 +357,16 @@ gio_id(vaddr_t va, paddr_t pa, int maybe_gfx) } /* - * 32-bit GIO devices may not like subword accesses to the - * identification register. Don't bail out if any of these - * access fails, it's probably one good sign of real GIO - * hardware (as opposed to a non-Impact frame buffer) being - * there. - */ - if (GIO_PRODUCT_32BIT_ID(id32)) { - if (guarded_read_2(va | 2, &id16) != 0 || - guarded_read_1(va | 3, &id8) != 0) - return id32; - } else { - if (guarded_read_2(va | 2, &id16) != 0 || - guarded_read_1(va | 3, &id8) != 0) - return 0; - } - - /* - * If there is a real GIO device at this address (as opposed to - * a graphics card), then the low-order 8 bits of each read need - * to be consistent... + * GIO32 devices will not answer to addresses not aligned on + * 32 bit boundaries. */ - if (id8 == (id16 & 0xff) && id8 == (id32 & 0xff)) { - /* - * If we are unlucky, this device will actually be a grtwo(4) - * frame buffer, and we have read the first word of its - * shared memory, which will satisfy the above test. - * - * Check its so-called mystery register to prevent matching - * it as an unknown GIO device. - */ - if (guarded_read_4(va + HQ2_MYSTERY, &mystery) == 0 && - mystery == HQ2_MYSTERY_VALUE) - return maybe_gfx ? GIO_PRODUCT_FAKEID_GRTWO : 0; - - if (GIO_PRODUCT_32BIT_ID(id8)) { - if (id16 == (id32 & 0xffff)) - return id32; - } else { - if (id8 != 0) { - if (maybe_gfx) - return id8; - else - return 0; - } - } + if (guarded_read_2(va | 2, &id16) != 0 || + guarded_read_1(va | 3, &id8) != 0) { + if (GIO_PRODUCT_32BIT_ID(id32)) + return id32; + else + return GIO_PRODUCT_PRODUCTID(id32); } /* @@ -706,8 +673,8 @@ gio_arb_config(int slot, uint32_t flags) } /* - * Establish an interrupt handler for expansion boards (not frame buffers!) - * in the specified slot. + * Return the logical interrupt number for an expansion board (not a frame + * buffer!) in the specified slot. * * Indy and Challenge S have a single GIO interrupt per GIO slot, but * distinct slot interrups. Indigo and Indigo2 have three GIO interrupts per @@ -716,36 +683,36 @@ gio_arb_config(int slot, uint32_t flags) * * Expansion boards appear to always use the intermediate level. */ -void * -gio_intr_establish(int slot, int level, int (*func)(void *), void *arg, - const char *what) +int +gio_intr_map(int slot) { - int intr; - switch (sys_config.system_type) { case SGI_IP20: if (slot == GIO_SLOT_GFX) - return NULL; - intr = INT2_L0_INTR(INT2_L0_GIO_LVL1); - break; + return -1; + return INT2_L0_INTR(INT2_L0_GIO_LVL1); case SGI_IP22: case SGI_IP26: case SGI_IP28: if (sys_config.system_subtype == IP22_INDIGO2) { if (slot == GIO_SLOT_EXP1) - return NULL; - intr = INT2_L0_INTR(INT2_L0_GIO_LVL1); + return -1; + return INT2_L0_INTR(INT2_L0_GIO_LVL1); } else { if (slot == GIO_SLOT_GFX) - return NULL; - intr = INT2_MAP1_INTR(slot == GIO_SLOT_EXP0 ? + return -1; + return INT2_MAP1_INTR(slot == GIO_SLOT_EXP0 ? INT2_MAP_GIO_SLOT0 : INT2_MAP_GIO_SLOT1); } - break; default: - return NULL; + return -1; } +} +void * +gio_intr_establish(int intr, int level, int (*func)(void *), void *arg, + const char *what) +{ return int2_intr_establish(intr, level, func, arg, what); } diff --git a/sys/arch/sgi/gio/giovar.h b/sys/arch/sgi/gio/giovar.h index 5bffeafdbaf..3b5b9ca62cf 100644 --- a/sys/arch/sgi/gio/giovar.h +++ b/sys/arch/sgi/gio/giovar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: giovar.h,v 1.3 2012/04/24 20:11:26 miod Exp $ */ +/* $OpenBSD: giovar.h,v 1.4 2012/05/17 19:46:52 miod Exp $ */ /* $NetBSD: giovar.h,v 1.10 2011/07/01 18:53:46 dyoung Exp $ */ /* @@ -76,6 +76,7 @@ struct gio_attach_args { #define GIO_MAX_FB 3 int gio_arb_config(int, uint32_t); +int gio_intr_map(int); void *gio_intr_establish(int, int, int (*)(void *), void *, const char *); const char *gio_product_string(int); |