summaryrefslogtreecommitdiffstats
path: root/sys/arch/sgi/dev
diff options
context:
space:
mode:
authormiod <miod@openbsd.org>2012-04-18 17:28:24 +0000
committermiod <miod@openbsd.org>2012-04-18 17:28:24 +0000
commitdafdb93f71b2cfef068c4ec44413b602b3f17f9c (patch)
tree464f343bad7ad5e3dd94579aa98cf4c2fd23fa47 /sys/arch/sgi/dev
parentDon't attach a wsdisplay if not the console device, for part of the device (diff)
downloadwireguard-openbsd-dafdb93f71b2cfef068c4ec44413b602b3f17f9c.tar.xz
wireguard-openbsd-dafdb93f71b2cfef068c4ec44413b602b3f17f9c.zip
Split the existing impact@xbow attachment into generic impact routines, and
bus-specific attachment; impactreg.h and impactvar.h move from sgi/xbow/ to sgi/dev/. Teach the generic impact code how to code with pre-ImpactSR boards, which have a slightly different register layout (information obtained from Peter Fuerst's Linux IP28 patches). Add an impact@gio attachment (unfortunately untested, no Impact GIO boards here). All Indigo 2 graphics options should be supported now (assuming the Extreme/Ultra will actually work with grtwo(4) out of the box). Tested not to disturb operation on IP30. ** ATTENTION! If you are building IP27 or IP30 kernels, be sure to rm impact.d ** before building a new kernel.
Diffstat (limited to 'sys/arch/sgi/dev')
-rw-r--r--sys/arch/sgi/dev/impact.c794
-rw-r--r--sys/arch/sgi/dev/impactreg.h112
-rw-r--r--sys/arch/sgi/dev/impactvar.h36
3 files changed, 942 insertions, 0 deletions
diff --git a/sys/arch/sgi/dev/impact.c b/sys/arch/sgi/dev/impact.c
new file mode 100644
index 00000000000..ca4b9229056
--- /dev/null
+++ b/sys/arch/sgi/dev/impact.c
@@ -0,0 +1,794 @@
+/* $OpenBSD: impact.c,v 1.1 2012/04/18 17:28:24 miod Exp $ */
+
+/*
+ * Copyright (c) 2010 Miodrag Vallat.
+ * Copyright (c) 2009, 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.
+ */
+
+/*
+ * Driver for the SGI Impact and ImpactSR graphics board.
+ */
+
+/*
+ * The details regarding the design and operation of this hardware, along with
+ * the necessary magic numbers, are only available thanks to the reverse
+ * engineering work undertaken by Stanislaw Skowronek <skylark@linux-mips.org>.
+ *
+ * Differences between ImpactSR and Impact researched by Peter Fuerst
+ * <post@pfrst.de>.
+ */
+
+/*
+ * This driver currently lacks support for the HQ3 and HQ4 DMA engines, which
+ * could be used to speed up rasops `copy' operations a lot by doing
+ * framebuffer to memory, then memory to framebuffer operations.
+ *
+ * Of course, in an ideal world, these operations would be done with
+ * framebuffer to framebuffer operations, but according to Skowronek, these
+ * operations are not reliable and IRIX' Xsgi X server does not even try to
+ * use them.
+ *
+ * Thus this driver currently implements rasops `copy' operations by repainting
+ * affected areas with PIO routines. This is unfortunately slower than DMA,
+ * but this will work until I have more time to spend on this. -- miod
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/types.h>
+#include <sys/malloc.h>
+
+#include <machine/bus.h>
+
+#include <sgi/dev/gl.h>
+#include <sgi/dev/impactreg.h>
+#include <sgi/dev/impactvar.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/rasops/rasops.h>
+
+struct cfdriver impact_cd = {
+ NULL, "impact", DV_DULL,
+};
+
+#define IMPACT_WIDTH 1280
+#define IMPACT_HEIGHT 1024
+#define IMPACT_DEPTH 32
+
+struct impact_screen {
+ struct rasops_info ri;
+ long defattr;
+ struct wsdisplay_charcell *bs;
+
+ struct impact_softc *sc;
+ int has_hq4;
+
+ bus_addr_t fifo_status;
+ bus_addr_t cfifo;
+
+ bus_space_tag_t iot;
+ bus_space_handle_t ioh;
+
+ struct wsscreen_descr wsd;
+ struct wsscreen_list wsl;
+ struct wsscreen_descr *scrlist[1];
+};
+
+static inline void
+ impact_cmd_fifo_write(struct impact_screen *, uint64_t, uint32_t, int);
+int impact_cmd_fifo_wait(struct impact_screen *);
+
+void impact_setup(struct impact_screen *, int);
+int impact_init_screen(struct impact_screen *);
+
+/*
+ * Hardware acceleration (sort of) for rasops.
+ */
+void impact_rop(struct impact_screen *, int, int, int, int, int, u_int);
+void impact_fillrect(struct impact_screen *, int, int, int, int, u_int);
+int impact_do_cursor(struct rasops_info *);
+int impact_putchar(void *, int, int, u_int, long);
+int impact_copycols(void *, int, int, int, int);
+int impact_erasecols(void *, int, int, int, long);
+int impact_copyrows(void *, int, int, int);
+int impact_eraserows(void *, int, int, long);
+
+/*
+ * Interfaces for wscons.
+ */
+int impact_ioctl(void *, u_long, caddr_t, int, struct proc *);
+paddr_t impact_mmap(void *, off_t, int);
+int impact_alloc_screen(void *, const struct wsscreen_descr *, void **,
+ int *, int *, long *);
+void impact_free_screen(void *, void *);
+int impact_show_screen(void *, void *, int, void (*)(void *, int, int),
+ void *);
+
+static struct impact_screen impact_cons;
+
+struct wsdisplay_accessops impact_accessops = {
+ impact_ioctl,
+ impact_mmap,
+ impact_alloc_screen,
+ impact_free_screen,
+ impact_show_screen,
+ NULL, /* load_font */
+ NULL, /* scrollback */
+ NULL, /* getchar */
+ NULL, /* burner */
+ NULL /* pollc */
+};
+
+int
+impact_attach_common(struct impact_softc *sc, bus_space_tag_t iot,
+ bus_space_handle_t ioh, int console, int has_hq4)
+{
+ struct wsemuldisplaydev_attach_args waa;
+ struct impact_screen *scr;
+
+ if (console) {
+ /*
+ * Setup has already been done via impact_cnattach().
+ */
+ scr = &impact_cons;
+ scr->sc = sc;
+ sc->curscr = scr;
+ sc->console = 1;
+ } else {
+ /*
+ * Setup screen data.
+ */
+ scr = malloc(sizeof(struct impact_screen), M_DEVBUF,
+ M_NOWAIT | M_ZERO);
+ if (scr == NULL) {
+ printf("failed to allocate screen memory!\n");
+ return ENOMEM;
+ }
+
+ scr->iot = iot;
+ scr->ioh = ioh;
+ scr->sc = sc;
+ sc->curscr = scr;
+
+ /* Setup hardware and clear screen. */
+ impact_setup(scr, has_hq4);
+ if (impact_init_screen(scr) != 0) {
+ printf("failed to allocate memory\n");
+ free(scr, M_DEVBUF);
+ return ENOMEM;
+ }
+ }
+
+ scr->scrlist[0] = &scr->wsd;
+ scr->wsl.nscreens = 1;
+ scr->wsl.screens = (const struct wsscreen_descr **)scr->scrlist;
+
+ waa.console = sc->console;
+ waa.scrdata = &scr->wsl;
+ waa.accessops = &impact_accessops;
+ waa.accesscookie = scr;
+ waa.defaultscreens = 0;
+
+ config_found(&sc->sc_dev, &waa, wsemuldisplaydevprint);
+
+ return 0;
+}
+
+int
+impact_init_screen(struct impact_screen *scr)
+{
+ struct rasops_info *ri = &scr->ri;
+ size_t bssize;
+
+ bzero(ri, sizeof(struct rasops_info));
+
+ ri->ri_flg = RI_CENTER | RI_FULLCLEAR;
+ ri->ri_depth = IMPACT_DEPTH;
+ ri->ri_width = IMPACT_WIDTH;
+ ri->ri_height = IMPACT_HEIGHT;
+ ri->ri_stride = IMPACT_WIDTH * IMPACT_DEPTH / 8;
+
+ rasops_init(ri, 160, 160);
+
+ /*
+ * Allocate backing store to remember character cells, to
+ * be able to fulfill scrolling requests.
+ */
+ if (scr->bs == NULL) {
+ bssize = ri->ri_rows * ri->ri_cols *
+ sizeof(struct wsdisplay_charcell);
+ scr->bs = malloc(bssize, M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (scr->bs == NULL)
+ return ENOMEM;
+ }
+
+ ri->ri_hw = scr;
+
+ ri->ri_ops.putchar = impact_putchar;
+ ri->ri_do_cursor = impact_do_cursor;
+ ri->ri_ops.copyrows = impact_copyrows;
+ ri->ri_ops.copycols = impact_copycols;
+ ri->ri_ops.eraserows = impact_eraserows;
+ ri->ri_ops.erasecols = impact_erasecols;
+
+ /* clear display */
+ impact_fillrect(scr, 0, 0, ri->ri_width, ri->ri_height,
+ ri->ri_devcmap[WSCOL_BLACK]);
+
+ strlcpy(scr->wsd.name, "std", sizeof(scr->wsd.name));
+ scr->wsd.ncols = ri->ri_cols;
+ scr->wsd.nrows = ri->ri_rows;
+ scr->wsd.textops = &ri->ri_ops;
+ scr->wsd.fontwidth = ri->ri_font->fontwidth;
+ scr->wsd.fontheight = ri->ri_font->fontheight;
+ scr->wsd.capabilities = ri->ri_caps;
+
+ return 0;
+}
+
+/*
+ * Hardware initialization.
+ */
+
+void
+impact_setup(struct impact_screen *scr, int has_hq4)
+{
+ bus_addr_t xmap_base;
+ bus_addr_t vc3_base;
+
+ scr->has_hq4 = has_hq4;
+
+ if (has_hq4) {
+ xmap_base = IMPACTSR_XMAP_BASE;
+ vc3_base = IMPACTSR_VC3_BASE;
+ scr->fifo_status = IMPACTSR_FIFOSTATUS;
+ scr->cfifo = IMPACTSR_CFIFO;
+ } else {
+ xmap_base = IMPACT_XMAP_BASE;
+ vc3_base = IMPACT_VC3_BASE;
+ scr->fifo_status = IMPACT_FIFOSTATUS;
+ scr->cfifo = IMPACT_CFIFO;
+ }
+
+ if (has_hq4) {
+ /* HQ4 initialization */
+ bus_space_write_4(scr->iot, scr->ioh, IMPACTSR_CFIFO_HW,
+ 0x00000047);
+ bus_space_write_4(scr->iot, scr->ioh, IMPACTSR_CFIFO_LW,
+ 0x00000014);
+ bus_space_write_4(scr->iot, scr->ioh, IMPACTSR_CFIFO_DELAY,
+ 0x00000064);
+ bus_space_write_4(scr->iot, scr->ioh, IMPACTSR_DFIFO_HW,
+ 0x00000040);
+ bus_space_write_4(scr->iot, scr->ioh, IMPACTSR_DFIFO_LW,
+ 0x00000010);
+ bus_space_write_4(scr->iot, scr->ioh, IMPACTSR_DFIFO_DELAY,
+ 0x00000000);
+ } else {
+ /* HQ3 initialization */
+ bus_space_write_4(scr->iot, scr->ioh, IMPACT_CFIFO_HW,
+ 0x00000020);
+ bus_space_write_4(scr->iot, scr->ioh, IMPACT_CFIFO_LW,
+ 0x00000014);
+ bus_space_write_4(scr->iot, scr->ioh, IMPACT_CFIFO_DELAY,
+ 0x00000064);
+ bus_space_write_4(scr->iot, scr->ioh, IMPACT_DFIFO_HW,
+ 0x00000028);
+ bus_space_write_4(scr->iot, scr->ioh, IMPACT_DFIFO_LW,
+ 0x00000014);
+ bus_space_write_4(scr->iot, scr->ioh, IMPACT_DFIFO_DELAY,
+ 0x00000fff);
+ }
+
+ /* VC3 initialization: disable hardware cursor */
+ bus_space_write_4(scr->iot, scr->ioh,
+ vc3_base + IMPACTSR_VC3_INDEXDATA, 0x1d000100);
+
+ /* RSS initialization */
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_COLORMASKLSBSA, 0xffffff, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_COLORMASKLSBSB, 0xffffff, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_COLORMASKMSBS, 0, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_XFRMASKLO, 0xffffff, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_XFRMASKHI, 0xffffff, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_DRBPOINTERS, 0xc8240, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_CONFIG, 0xcac, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_XYWIN,
+ IMPACTSR_YXCOORDS(0, 0x3ff), 0);
+
+ /* XMAP initialization */
+ bus_space_write_1(scr->iot, scr->ioh,
+ xmap_base + IMPACTSR_XMAP_PP1SELECT, 0x01);
+ bus_space_write_1(scr->iot, scr->ioh,
+ xmap_base + IMPACTSR_XMAP_INDEX, 0x00);
+ bus_space_write_4(scr->iot, scr->ioh,
+ xmap_base + IMPACTSR_XMAP_MAIN_MODE, 0x000007a4);
+}
+
+/*
+ * Write to the command FIFO.
+ */
+static inline void
+impact_cmd_fifo_write(struct impact_screen *scr, uint64_t reg, uint32_t val,
+ int exec)
+{
+ uint64_t cmd;
+
+ cmd = IMPACTSR_CFIFO_WRITE | (reg << IMPACTSR_CFIFO_REG_SHIFT);
+ if (exec)
+ cmd |= IMPACTSR_CFIFO_EXEC;
+ bus_space_write_8(scr->iot, scr->ioh, scr->cfifo, cmd | val);
+}
+
+/*
+ * Wait until the command FIFO is empty.
+ */
+int
+impact_cmd_fifo_wait(struct impact_screen *scr)
+{
+ u_int32_t val, timeout = 1000000;
+#ifdef DIAGNOSTIC
+ struct impact_softc *sc = scr->sc;
+#endif
+
+ val = bus_space_read_4(scr->iot, scr->ioh, scr->fifo_status);
+ while ((val & IMPACTSR_FIFO_MASK) != 0) {
+ delay(1);
+ if (--timeout == 0) {
+#ifdef DIAGNOSTIC
+ if (sc != NULL && sc->console == 0)
+ printf("%s: timeout waiting for command fifo\n",
+ sc != NULL ? sc->sc_dev.dv_xname :
+ impact_cd.cd_name);
+#endif
+ return ETIMEDOUT;
+ }
+ val = bus_space_read_4(scr->iot, scr->ioh, scr->fifo_status);
+ }
+
+ return 0;
+}
+
+/*
+ * Interfaces for wscons.
+ */
+
+int
+impact_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ struct impact_screen *scr = (struct impact_screen *)v;
+ struct rasops_info *ri;
+ struct wsdisplay_fbinfo *fb;
+
+ switch (cmd) {
+ case WSDISPLAYIO_GTYPE:
+ *(u_int *)data = WSDISPLAY_TYPE_IMPACT;
+ break;
+ case WSDISPLAYIO_GINFO:
+ fb = (struct wsdisplay_fbinfo *)data;
+ ri = &scr->ri;
+ fb->height = ri->ri_height;
+ fb->width = ri->ri_width;
+ fb->depth = ri->ri_depth;
+ fb->cmsize = 0;
+ break;
+#if 0
+ case WSDISPLAYIO_LINEBYTES:
+ ri = &scr->ri;
+ *(u_int *)data = ri->ri_stride;
+ break;
+#endif
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+paddr_t
+impact_mmap(void *v, off_t offset, int prot)
+{
+ if (offset < 0 || (offset & PAGE_MASK) != 0)
+ return -1;
+
+ return -1;
+}
+
+int
+impact_alloc_screen(void *v, const struct wsscreen_descr *type,
+ void **cookiep, int *curxp, int *curyp, long *attrp)
+{
+ struct impact_screen *scr = (struct impact_screen *)v;
+ struct rasops_info *ri = &scr->ri;
+ struct impact_softc *sc = (struct impact_softc *)scr->sc;
+
+ /* We do not allow multiple consoles at the moment. */
+ if (sc->nscreens > 0)
+ return ENOMEM;
+
+ sc->nscreens++;
+
+ *cookiep = ri;
+ *curxp = 0;
+ *curyp = 0;
+ ri->ri_ops.alloc_attr(ri, 0, 0, 0, &scr->defattr);
+ *attrp = scr->defattr;
+
+ return 0;
+}
+
+void
+impact_free_screen(void *v, void *cookie)
+{
+ /* We do not allow multiple consoles at the moment. */
+}
+
+int
+impact_show_screen(void *v, void *cookie, int waitok,
+ void (*cb)(void *, int, int), void *cbarg)
+{
+ /* We do not allow multiple consoles at the moment. */
+ return 0;
+}
+
+/*
+ * Hardware accelerated functions.
+ */
+
+void
+impact_rop(struct impact_screen *scr, int x, int y, int w, int h, int op,
+ u_int c)
+{
+ impact_cmd_fifo_wait(scr);
+ if (op == OPENGL_LOGIC_OP_COPY)
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_PP1FILLMODE,
+ IMPACTSR_PP1FILLMODE(0x6300, op), 0);
+ else
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_PP1FILLMODE,
+ IMPACTSR_PP1FILLMODE(0x6304, op), 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_FILLMODE, 0, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_PACKEDCOLOR, c & 0x00ffffff, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_BLOCKXYSTARTI,
+ IMPACTSR_XYCOORDS(x, y), 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_BLOCKXYENDI,
+ IMPACTSR_XYCOORDS(x + w - 1, y + h - 1), 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_IR_ALIAS, 0x18, 1);
+}
+
+void
+impact_fillrect(struct impact_screen *scr, int x, int y, int w, int h, u_int c)
+{
+ impact_rop(scr, x, y, w, h, OPENGL_LOGIC_OP_COPY, c);
+}
+
+int
+impact_do_cursor(struct rasops_info *ri)
+{
+ struct impact_screen *scr = ri->ri_hw;
+ int y, x, w, h, fg, bg;
+
+ w = ri->ri_font->fontwidth;
+ h = ri->ri_font->fontheight;
+ x = ri->ri_xorigin + ri->ri_ccol * w;
+ y = ri->ri_yorigin + ri->ri_crow * h;
+
+ ri->ri_ops.unpack_attr(ri, scr->defattr, &fg, &bg, NULL);
+
+ impact_rop(scr, x, y, w, h, OPENGL_LOGIC_OP_XOR, ri->ri_devcmap[fg]);
+ impact_cmd_fifo_wait(scr);
+
+ return 0;
+}
+
+int
+impact_putchar(void *cookie, int row, int col, u_int uc, long attr)
+{
+ struct rasops_info *ri = cookie;
+ struct impact_screen *scr = ri->ri_hw;
+ struct wsdisplay_font *font = ri->ri_font;
+ int x, y, w, h, bg, fg, ul;
+ u_int8_t *fontbitmap;
+ u_int chunk;
+ struct wsdisplay_charcell *cell;
+
+ /* Update backing store. */
+ cell = scr->bs + row * ri->ri_cols + col;
+ cell->uc = uc;
+ cell->attr = attr;
+
+ w = font->fontwidth;
+ h = font->fontheight;
+ x = ri->ri_xorigin + col * w;
+ y = ri->ri_yorigin + row * h;
+
+ ri->ri_ops.unpack_attr(ri, attr, &fg, &bg, &ul);
+
+ /* Handle spaces with a single fillrect. */
+ if ((uc == ' ' || uc == 0) && ul == 0) {
+ impact_fillrect(scr, x, y, w, h, ri->ri_devcmap[bg]);
+ return 0;
+ }
+
+ fontbitmap = (u_int8_t *)(font->data + (uc - font->firstchar) *
+ ri->ri_fontscale);
+
+ impact_cmd_fifo_wait(scr);
+ if (ri->ri_devcmap[bg] == 0) {
+ /*
+ * 1bpp pixel expansion; fast but background color ends up
+ * being incorrect (white renders as light green, and other
+ * colors end up slightly more greenish), which is why it is
+ * only done for black background.
+ */
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_PP1FILLMODE,
+ IMPACTSR_PP1FILLMODE(0x6300, OPENGL_LOGIC_OP_COPY), 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_FILLMODE,
+ 0x00400018, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_PACKEDCOLOR,
+ ri->ri_devcmap[fg], 0);
+#if 0
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_BKGRD_RG,
+ (ri->ri_devcmap[bg] & 0x0000ffff) << 8, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_BKGRD_BA,
+ (ri->ri_devcmap[bg] & 0x00ff0000) >> 8, 0);
+#else
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_BKGRD_RG, 0, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_BKGRD_BA, 0, 0);
+#endif
+
+ if (w <= 8) {
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_BLOCKXYSTARTI,
+ IMPACTSR_XYCOORDS(x, y), 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_BLOCKXYENDI,
+ IMPACTSR_XYCOORDS(x + w - 1, y + h - 1), 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_IR_ALIAS,
+ 0x18, 1);
+
+ for (; h != 0; h--) {
+ chunk = *fontbitmap;
+ fontbitmap += font->stride;
+
+ /* Handle underline. */
+ if (ul && h == 1)
+ chunk = 0xff;
+
+ impact_cmd_fifo_wait(scr);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_CHAR_H,
+ chunk << 24, 1);
+ }
+ } else {
+ for (; h != 0; h--) {
+ chunk = *(u_int16_t *)fontbitmap;
+ fontbitmap += font->stride;
+
+ /* Handle underline. */
+ if (ul && h == 1)
+ chunk = 0xffff;
+
+ impact_cmd_fifo_write(scr,
+ IMPACTSR_CMD_BLOCKXYSTARTI,
+ IMPACTSR_XYCOORDS(x, y), 0);
+ impact_cmd_fifo_write(scr,
+ IMPACTSR_CMD_BLOCKXYENDI,
+ IMPACTSR_XYCOORDS(x + w - 1, y + 1 - 1), 0);
+ impact_cmd_fifo_write(scr,
+ IMPACTSR_CMD_IR_ALIAS, 0x18, 1);
+
+ impact_cmd_fifo_wait(scr);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_CHAR_H,
+ chunk << 16, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_CHAR_L,
+ chunk << 24, 1);
+
+ y++;
+ }
+ }
+ } else {
+ uint mask;
+ uint32_t data;
+ int i, flip;
+
+ /* slower 8bpp blt; hopefully gives us the correct colors */
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_PP1FILLMODE,
+ IMPACTSR_PP1FILLMODE(0x6300, OPENGL_LOGIC_OP_COPY), 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_BLOCKXYSTARTI,
+ IMPACTSR_XYCOORDS(x, y), 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_BLOCKXYENDI,
+ IMPACTSR_XYCOORDS(x + w - 1, y + h - 1), 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_FILLMODE,
+ 0x00c00000, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_XFRMODE, 0x0080, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_XFRSIZE,
+ IMPACTSR_YXCOORDS(w, h), 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_XFRCOUNTERS,
+ IMPACTSR_YXCOORDS(w, h), 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_GLINE_XSTARTF, 1, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_IR_ALIAS, 0x18, 1);
+ for (i = 0; i < 32 + 1; i++)
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_ALPHA, 0, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_XFRCONTROL, 2, 0);
+
+ flip = 0;
+ for (; h != 0; h--) {
+ if (w > 8)
+ chunk = *(u_int16_t *)fontbitmap;
+ else
+ chunk = *fontbitmap;
+ fontbitmap += font->stride;
+
+ /* Handle underline. */
+ if (ul && h == 1)
+ chunk = 0xffff;
+
+ /* font data is packed towards most significant bit */
+ mask = w > 8 ? 0x8000 : 0x80;
+ for (i = w; i != 0; i--, mask >>= 1) {
+ data = ri->ri_devcmap[(chunk & mask) ? fg : bg];
+ impact_cmd_fifo_write(scr, flip ?
+ IMPACTSR_CMD_CHAR_L : IMPACTSR_CMD_CHAR_H,
+ data, flip);
+ flip ^= 1;
+ }
+ if (flip)
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_CHAR_L,
+ 0, 1);
+ }
+
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_GLINE_XSTARTF, 0, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_RE_TOGGLECNTX, 0, 0);
+ impact_cmd_fifo_write(scr, IMPACTSR_CMD_XFRCOUNTERS,
+ IMPACTSR_YXCOORDS(0, 0), 0);
+ }
+
+ return 0;
+}
+
+int
+impact_copycols(void *cookie, int row, int src, int dst, int num)
+{
+ struct rasops_info *ri = cookie;
+ struct impact_screen *scr = ri->ri_hw;
+ struct wsdisplay_charcell *cell;
+
+ /* Copy columns in backing store. */
+ cell = scr->bs + row * ri->ri_cols;
+ ovbcopy(cell + src, cell + dst,
+ num * sizeof(struct wsdisplay_charcell));
+
+ /* Repaint affected area */
+ cell += dst;
+ for (; num != 0; num--, dst++, cell++)
+ impact_putchar(cookie, row, dst, cell->uc, cell->attr);
+
+ return 0;
+}
+
+int
+impact_erasecols(void *cookie, int row, int col, int num, long attr)
+{
+ struct rasops_info *ri = cookie;
+ struct impact_screen *scr = ri->ri_hw;
+ int bg, fg, i;
+ struct wsdisplay_charcell *cell;
+
+ /* Erase columns in backing store. */
+ cell = scr->bs + row * ri->ri_cols + col;
+ for (i = num; i != 0; i--, cell++) {
+ cell->uc = 0;
+ cell->attr = attr;
+ }
+
+ ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
+
+ row *= ri->ri_font->fontheight;
+ col *= ri->ri_font->fontwidth;
+ num *= ri->ri_font->fontwidth;
+
+ impact_fillrect(scr, ri->ri_xorigin + col, ri->ri_yorigin + row,
+ num, ri->ri_font->fontheight, ri->ri_devcmap[bg]);
+
+ return 0;
+}
+
+int
+impact_copyrows(void *cookie, int src, int dst, int num)
+{
+ struct rasops_info *ri = cookie;
+ struct impact_screen *scr = ri->ri_hw;
+ struct wsdisplay_charcell *cell;
+ int col;
+
+ /* Copy rows in backing store. */
+ cell = scr->bs + dst * ri->ri_cols;
+ ovbcopy(scr->bs + src * ri->ri_cols, cell,
+ num * ri->ri_cols * sizeof(struct wsdisplay_charcell));
+
+ /* Repaint affected area */
+ for (; num != 0; num--, dst++) {
+ for (col = 0; col < ri->ri_cols; col++, cell++)
+ impact_putchar(cookie, dst, col, cell->uc, cell->attr);
+ }
+
+ return 0;
+}
+
+int
+impact_eraserows(void *cookie, int row, int num, long attr)
+{
+ struct rasops_info *ri = cookie;
+ struct impact_screen *scr = ri->ri_hw;
+ int x, y, w, bg, fg;
+ struct wsdisplay_charcell *cell;
+
+ /* Erase rows in backing store. */
+ cell = scr->bs + row * ri->ri_cols;
+ for (x = ri->ri_cols; x != 0; x--, cell++) {
+ cell->uc = 0;
+ cell->attr = attr;
+ }
+ for (y = 1; y < num; y++)
+ ovbcopy(scr->bs + row * ri->ri_cols,
+ scr->bs + (row + y) * ri->ri_cols,
+ ri->ri_cols * sizeof(struct wsdisplay_charcell));
+
+ ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
+
+ if ((num == ri->ri_rows) && ISSET(ri->ri_flg, RI_FULLCLEAR)) {
+ num = ri->ri_height;
+ x = y = 0;
+ w = ri->ri_width;
+ } else {
+ num *= ri->ri_font->fontheight;
+ x = ri->ri_xorigin;
+ y = ri->ri_yorigin + row * ri->ri_font->fontheight;
+ w = ri->ri_emuwidth;
+ }
+
+ impact_fillrect(scr, x, y, w, num, ri->ri_devcmap[bg]);
+ impact_cmd_fifo_wait(scr);
+
+ return 0;
+}
+
+/*
+ * Console support.
+ */
+
+/* console backing store, worst case font selection */
+static struct wsdisplay_charcell
+ impact_cons_bs[(IMPACT_WIDTH / 8) * (IMPACT_HEIGHT / 16)];
+
+int
+impact_cnattach_common(bus_space_tag_t iot, bus_space_handle_t ioh, int has_hq4)
+{
+ struct impact_screen *scr = &impact_cons;
+ struct rasops_info *ri = &scr->ri;
+ int rc;
+
+ scr->iot = iot;
+ scr->ioh = ioh;
+ impact_setup(scr, has_hq4);
+ scr->bs = impact_cons_bs;
+ rc = impact_init_screen(scr);
+ if (rc != 0)
+ return rc;
+
+ ri->ri_ops.alloc_attr(ri, 0, 0, 0, &scr->defattr);
+ wsdisplay_cnattach(&scr->wsd, ri, 0, 0, scr->defattr);
+
+ return 0;
+}
diff --git a/sys/arch/sgi/dev/impactreg.h b/sys/arch/sgi/dev/impactreg.h
new file mode 100644
index 00000000000..15b6f909b2d
--- /dev/null
+++ b/sys/arch/sgi/dev/impactreg.h
@@ -0,0 +1,112 @@
+/* $OpenBSD: impactreg.h,v 1.1 2012/04/18 17:28:24 miod Exp $ */
+/*
+ * Copyright (c) 2010 Miodrag Vallat.
+ * Copyright (c) 2009, 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.
+ */
+
+/*
+ * Impact and ImpactSR registers
+ */
+
+#define IMPACTSR_STATUS 0x020000
+#define IMPACTSR_FIFOSTATUS 0x020008
+#define IMPACTSR_FIFO_MASK 0x000000ff
+#define IMPACTSR_GIOSTATUS 0x020100
+#define IMPACTSR_DMABUSY 0x020200
+#define IMPACTSR_CFIFO 0x020400
+
+#define IMPACT_STATUS 0x070000
+#define IMPACT_FIFOSTATUS 0x070004
+#define IMPACT_GIOSTATUS 0x070100
+#define IMPACT_DMABUSY 0x070104
+#define IMPACT_CFIFO 0x070080
+
+#define IMPACTSR_CFIFO_HW 0x040000
+#define IMPACTSR_CFIFO_LW 0x040008
+#define IMPACTSR_CFIFO_DELAY 0x040010
+#define IMPACTSR_DFIFO_HW 0x040020
+#define IMPACTSR_DFIFO_LW 0x040028
+#define IMPACTSR_DFIFO_DELAY 0x040030
+#define IMPACT_CFIFO_HW 0x050020
+#define IMPACT_CFIFO_LW 0x050024
+#define IMPACT_CFIFO_DELAY 0x050028
+#define IMPACT_DFIFO_HW 0x05002c
+#define IMPACT_DFIFO_LW 0x050030
+#define IMPACT_DFIFO_DELAY 0x050034
+
+#define IMPACTSR_XMAP_BASE 0x071c00
+#define IMPACT_XMAP_BASE 0x061c00
+
+#define IMPACTSR_XMAP_PP1SELECT 0x000008
+#define IMPACTSR_XMAP_INDEX 0x000088
+#define IMPACTSR_XMAP_CONFIG 0x000100
+#define IMPACTSR_XMAP_CONFIGB 0x000108
+#define IMPACTSR_XMAP_BUF_SELECT 0x000180
+#define IMPACTSR_XMAP_MAIN_MODE 0x000200
+#define IMPACTSR_XMAP_OVERLAY_MODE 0x000280
+#define IMPACTSR_XMAP_DIB 0x000300
+#define IMPACTSR_XMAP_DIB_DW 0x000340
+#define IMPACTSR_XMAP_RE_RAC 0x000380
+
+#define IMPACTSR_VC3_BASE 0x072000
+#define IMPACT_VC3_BASE 0x062000
+
+#define IMPACTSR_VC3_INDEX 0x000008
+#define IMPACTSR_VC3_INDEXDATA 0x000038
+#define IMPACTSR_VC3_DATA 0x0000b0
+#define IMPACTSR_VC3_RAM 0x000190
+
+/*
+ * Command FIFO instruction encoding
+ */
+
+#define IMPACTSR_CFIFO_WRITE 0x0018000400000000UL
+#define IMPACTSR_CFIFO_EXEC 0x0004000000000000UL
+#define IMPACTSR_CFIFO_REG_SHIFT 40
+
+/*
+ * Command FIFO registers
+ */
+
+#define IMPACTSR_CMD_GLINE_XSTARTF 0x0c
+#define IMPACTSR_CMD_IR_ALIAS 0x45
+#define IMPACTSR_CMD_BLOCKXYSTARTI 0x46 /* XY coords */
+#define IMPACTSR_CMD_BLOCKXYENDI 0x47 /* XY coords */
+#define IMPACTSR_CMD_PACKEDCOLOR 0x5b
+#define IMPACTSR_CMD_ALPHA 0x5f
+#define IMPACTSR_CMD_CHAR_H 0x70
+#define IMPACTSR_CMD_CHAR_L 0x71
+#define IMPACTSR_CMD_XFRCONTROL 0x102
+#define IMPACTSR_CMD_FILLMODE 0x110
+#define IMPACTSR_CMD_CONFIG 0x112
+#define IMPACTSR_CMD_XYWIN 0x115 /* YX coords */
+#define IMPACTSR_CMD_BKGRD_RG 0x140
+#define IMPACTSR_CMD_BKGRD_BA 0x141
+#define IMPACTSR_CMD_XFRSIZE 0x153 /* YX coords */
+#define IMPACTSR_CMD_XFRMASKLO 0x156
+#define IMPACTSR_CMD_XFRMASKHI 0x157
+#define IMPACTSR_CMD_XFRCOUNTERS 0x158 /* YX coords */
+#define IMPACTSR_CMD_XFRMODE 0x159
+#define IMPACTSR_CMD_RE_TOGGLECNTX 0x15f
+#define IMPACTSR_CMD_PP1FILLMODE 0x161
+#define IMPACTSR_CMD_COLORMASKMSBS 0x162
+#define IMPACTSR_CMD_COLORMASKLSBSA 0x163
+#define IMPACTSR_CMD_COLORMASKLSBSB 0x164
+#define IMPACTSR_CMD_DRBPOINTERS 0x16d
+
+#define IMPACTSR_XYCOORDS(x,y) (((x) << 16) | (y))
+#define IMPACTSR_YXCOORDS(x,y) (((y) << 16) | (x))
+
+#define IMPACTSR_PP1FILLMODE(mode,op) ((mode) | ((op) << 26))
diff --git a/sys/arch/sgi/dev/impactvar.h b/sys/arch/sgi/dev/impactvar.h
new file mode 100644
index 00000000000..cc88b38a44c
--- /dev/null
+++ b/sys/arch/sgi/dev/impactvar.h
@@ -0,0 +1,36 @@
+/* $OpenBSD: impactvar.h,v 1.1 2012/04/18 17:28: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.
+ */
+
+struct impact_screen;
+
+struct impact_softc {
+ struct device sc_dev;
+ struct impact_screen *curscr;
+ int console;
+ int nscreens;
+};
+
+int impact_attach_common(struct impact_softc *, bus_space_tag_t,
+ bus_space_handle_t, int, int);
+int impact_cnattach_common(bus_space_tag_t, bus_space_handle_t, int);
+
+struct gio_attach_args;
+int impact_gio_cnprobe(struct gio_attach_args *);
+int impact_gio_cnattach(struct gio_attach_args *);
+int impact_xbow_cnprobe(void);
+int impact_xbow_cnattach(void);