summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDale S. Rahn <rahnds@cvs.openbsd.org>2000-09-06 02:12:16 +0000
committerDale S. Rahn <rahnds@cvs.openbsd.org>2000-09-06 02:12:16 +0000
commit718bc35a3f6871a578a50f52a9ddc382d4be6a7d (patch)
treec525a5c21d4782932817d545040509f5e5e3efc6
parentcf7329ef2a79c45d2fd0312719e16fafb8360649 (diff)
Add machine specific vga framebuffer code. Probably should be machine
independant, but not now.
-rw-r--r--sys/arch/powerpc/pci/vgafb.c469
-rw-r--r--sys/arch/powerpc/pci/vgafb_pci.c442
-rw-r--r--sys/arch/powerpc/pci/vgafb_pcivar.h41
-rw-r--r--sys/arch/powerpc/pci/vgafbvar.h67
4 files changed, 1019 insertions, 0 deletions
diff --git a/sys/arch/powerpc/pci/vgafb.c b/sys/arch/powerpc/pci/vgafb.c
new file mode 100644
index 00000000000..4cda4b33275
--- /dev/null
+++ b/sys/arch/powerpc/pci/vgafb.c
@@ -0,0 +1,469 @@
+/* $OpenBSD: vgafb.c,v 1.1 2000/09/06 02:12:14 rahnds Exp $ */
+/* $NetBSD: vga.c,v 1.3 1996/12/02 22:24:54 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <machine/bus.h>
+#include <dev/cons.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/wscons/wscons_raster.h>
+#include <dev/rcons/raster.h>
+
+#include <arch/powerpc/pci/vgafbvar.h>
+
+/* parameters set by OF to detect console */
+extern int cons_displaytype;
+extern bus_space_tag_t cons_membus;
+extern bus_space_handle_t cons_display_mem_h;
+extern bus_space_handle_t cons_display_ctl_h;
+extern int cons_width;
+extern int cons_linebytes;
+extern int cons_height;
+extern int cons_depth;
+
+struct cfdriver vgafb_cd = {
+ NULL, "vgafb", DV_DULL,
+};
+
+void vgafb_cursor __P((void *, int, int, int));
+void vgafb_putchar __P((void *, int, int, u_int, long));
+void vgafb_copycols __P((void *, int, int, int, int));
+void vgafb_erasecols __P((void *, int, int, int));
+void vgafb_copyrows __P((void *, int, int, int));
+void vgafb_eraserows __P((void *, int, int));
+void vgafb_alloc_attr __P((void *c, int fg, int bg, int flags, long *));
+
+static void drawChar ( struct vgafb_config *vc, char ch, int cx,
+ int cy, char at);
+static void setPixel( struct vgafb_config *vc, int x, int y, int v);
+static void vgafb_invert_char ( struct vgafb_config *vc, int cx, int cy);
+extern const char fontdata_8x16[];
+
+struct vgafb_devconfig {
+ struct rcons dc_ri;
+};
+struct raster vgafb_raster;
+
+
+struct vgafb_devconfig vgafb_console_dc;
+
+struct wsscreen_descr vgafb_stdscreen = {
+ "std",
+ 0, 0, /* will be filled in -- XXX shouldn't, it's global */
+ 0,
+ 0, 0,
+ WSSCREEN_REVERSE
+};
+const struct wsscreen_descr *vgafb_scrlist[] = {
+ &vgafb_stdscreen,
+ /* XXX other formats, graphics screen? */
+};
+
+struct wsscreen_list vgafb_screenlist = {
+ sizeof(vgafb_scrlist) / sizeof(struct wsscreen_descr *), vgafb_scrlist
+};
+
+
+struct wsdisplay_emulops vgafb_emulops = {
+ rcons_cursor,
+ rcons_mapchar,
+ rcons_putchar,
+ rcons_copycols,
+ rcons_erasecols,
+ rcons_copyrows,
+ rcons_eraserows,
+ rcons_alloc_attr
+};
+
+int vgafb_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
+int vgafb_mmap __P((void *, off_t, int));
+int vgafb_alloc_screen __P((void *, const struct wsscreen_descr *,
+ void **, int *, int *, long *));
+void vgafb_free_screen __P((void *, void *));
+int vgafb_show_screen __P((void *, void *, int,
+ void (*) (void *, int, int), void *));
+
+struct wsdisplay_accessops vgafb_accessops = {
+ vgafb_ioctl,
+ vgafb_mmap,
+ vgafb_alloc_screen,
+ vgafb_free_screen,
+ vgafb_show_screen,
+ 0 /* load_font */
+};
+
+
+int vgafb_print __P((void *, const char *));
+
+#define FONT_WIDTH 8
+#define FONT_HEIGHT 16
+
+/*
+ * The following functions implement back-end configuration grabbing
+ * and attachment.
+ */
+int
+vgafb_common_probe(iot, memt, iobase, iosize, membase, memsize, mmiobase, mmiosize)
+ bus_space_tag_t iot, memt;
+ u_int32_t iobase, membase, mmiobase;
+ size_t iosize, memsize, mmiosize;
+{
+ bus_space_handle_t ioh_b, ioh_c, ioh_d, memh, mmioh;
+ u_int16_t vgadata;
+ int gotio_b, gotio_c, gotio_d, gotmem, gotmmio, rv;
+ int width;
+
+ gotio_b = gotio_c = gotio_d = gotmem = gotmmio = rv = 0;
+
+ if (iosize != 0) {
+ if (bus_space_map(iot, iobase+0x3b0, 0xc, 0, &ioh_b))
+ goto bad;
+ gotio_b = 1;
+ if (bus_space_map(iot, iobase+0x3c0, 0x10, 0, &ioh_c))
+ goto bad;
+ gotio_c = 1;
+ if (bus_space_map(iot, iobase+0x3d0, 0x10, 0, &ioh_d))
+ goto bad;
+ gotio_d = 1;
+ }
+ if (mmiosize != 0) {
+ printf("vgafb_common_probe, mmio base %x size %x\n",
+ mmiobase, mmiosize);
+ if (bus_space_map(iot, mmiobase, mmiosize, 0, &mmioh))
+ goto bad;
+ printf("vgafb_common_probe, mmio done\n");
+ gotmmio = 1;
+ }
+ /* hack */
+ if (memsize > 0x00010000) {
+ memsize = 0x00010000;
+ }
+ printf("vgafb_common_probe, mem base %x size %x memt %x\n",
+ membase, memsize, memt);
+
+ if (bus_space_map(memt, membase, memsize, 0, &memh))
+ goto bad;
+ printf("vgafb_common_probe, mmio done\n");
+ gotmem = 1;
+
+#if 0
+ /* CR1 - Horiz. Display End */
+ bus_space_write_1(iot, ioh_d, 4, 0x1);
+ width = bus_space_read_1(iot, ioh_d, 5);
+ /* this is not bit width yet */
+
+ /* use CR17 - mode control for this?? */
+ if ((width != 0xff) && (width < 600)) {
+ /* not accessable or in graphics mode? */
+ goto bad;
+ }
+#endif
+
+ #if 0
+ vgadata = bus_space_read_2(memt, memh, 0);
+ bus_space_write_2(memt, memh, 0, 0xa55a);
+ rv = (bus_space_read_2(memt, memh, 0) == 0xa55a);
+ bus_space_write_2(memt, memh, 0, vgadata);
+ #else
+ rv = 1;
+ #endif
+
+
+bad:
+ if (gotio_b)
+ bus_space_unmap(iot, ioh_b, 0xc);
+ if (gotio_c)
+ bus_space_unmap(iot, ioh_c, 0x10);
+ if (gotio_d)
+ bus_space_unmap(iot, ioh_d, 0x10);
+ if (gotmmio)
+ bus_space_unmap(memt, mmioh, mmiosize);
+ if (gotmem)
+ bus_space_unmap(memt, memh, memsize);
+
+ return (rv);
+}
+
+void
+vgafb_common_setup(iot, memt, vc, iobase, iosize, membase, memsize, mmiobase, mmiosize)
+ bus_space_tag_t iot, memt;
+ struct vgafb_config *vc;
+ u_int32_t iobase, membase, mmiobase;
+ size_t iosize, memsize, mmiosize;
+{
+ int cpos;
+ int width, height;
+
+ vc->vc_iot = iot;
+ vc->vc_memt = memt;
+ printf("vgafb_common_setup\n");
+
+ if (iosize != 0) {
+ if (bus_space_map(vc->vc_iot, iobase+0x3b0, 0xc, 0, &vc->vc_ioh_b))
+ panic("vgafb_common_setup: couldn't map io b");
+ if (bus_space_map(vc->vc_iot, iobase+0x3c0, 0x10, 0, &vc->vc_ioh_c))
+ panic("vgafb_common_setup: couldn't map io c");
+ if (bus_space_map(vc->vc_iot, iobase+0x3d0, 0x10, 0, &vc->vc_ioh_d))
+ panic("vgafb_common_setup: couldn't map io d");
+ }
+ if (mmiosize != 0) {
+ if (bus_space_map(vc->vc_memt, mmiobase, mmiosize, 0, &vc->vc_mmioh))
+ panic("vgafb_common_setup: couldn't map mmio");
+ }
+ printf("commons setup mapping mem base %x size %x\n", membase, memsize);
+ if (bus_space_map(vc->vc_memt, membase, memsize, 0, &vc->vc_memh))
+ panic("vgafb_common_setup: couldn't map memory");
+ cons_display_mem_h = vc->vc_memh;
+ printf("display_mem_h %x\n", cons_display_mem_h );
+
+#if 0
+ if (iosize != 0) {
+ /* CR1 - Horiz. Display End */
+ bus_space_write_1(iot, vc->vc_ioh_d, 4, 0x1);
+ width = bus_space_read_1(iot, vc->vc_ioh_d, 5);
+ /* (stored value + 1) * depth -> pixel width */
+ width = ( width + 1 ) * 8;
+
+ /* CR1 - Horiz. Display End */
+ bus_space_write_1(iot, vc->vc_ioh_d, 4, 0x12);
+ {
+ u_int8_t t1, t2, t3;
+ bus_space_write_1(iot, vc->vc_ioh_d, 4, 0x12);
+ t1 = bus_space_read_1(iot, vc->vc_ioh_d, 5);
+
+ bus_space_write_1(iot, vc->vc_ioh_d, 4, 0x7);
+ t2 = bus_space_read_1(iot, vc->vc_ioh_d, 5);
+ height = t1 + ((t2&0x40) << 3)
+ + ((t2&0x02) << 7) + 1;
+ bus_space_write_1(iot, vc->vc_ioh_d, 4, 0x17);
+ t3 = bus_space_read_1(iot, vc->vc_ioh_d, 5);
+ if (t3 & 0x04) {
+ height *= 2;
+ }
+ if (t1 == 0xff && t2 == 0xff && t3 == 0xff) {
+ /* iospace not working??? */
+ /* hope, better guess than 2048x2048 */
+ width = 640;
+ height = 480;
+ }
+ }
+ vc->vc_ncol = width / FONT_WIDTH;
+ vc->vc_nrow = height / FONT_HEIGHT;
+ } else {
+ /* iosize == 0
+ * default to 640x480 and hope
+ */
+ vc->vc_ncol = 640 / FONT_WIDTH;
+ vc->vc_nrow = 480 / FONT_HEIGHT;
+ }
+ vc->vc_ncol = cons_width / FONT_WIDTH;
+ vc->vc_nrow = cons_height / FONT_HEIGHT;
+ printf(", %dx%d", vc->vc_ncol, vc->vc_nrow);
+#endif
+
+ vc->vc_crow = vc->vc_ccol = 0; /* Has to be some onscreen value */
+ vc->vc_so = 0;
+
+ /* clear screen, frob cursor, etc.? */
+ rcons_eraserows(vc, 0, vc->vc_nrow, 0);
+
+#if defined(alpha)
+ /*
+ * XXX DEC HAS SWITCHED THE CODES FOR BLUE AND RED!!!
+ * XXX Therefore, though the comments say "blue bg", the code uses
+ * XXX the value for a red background!
+ */
+ vc->vc_at = 0x40 | 0x0f; /* blue bg|white fg */
+ vc->vc_so_at = 0x40 | 0x0f | 0x80; /* blue bg|white fg|blink */
+#else
+ vc->vc_at = 0x00 | 0xf; /* black bg|white fg */
+ vc->vc_so_at = 0x00 | 0xf | 0x80; /* black bg|white fg|blink */
+#endif
+}
+
+void
+vgafb_wsdisplay_attach(parent, vc, console)
+ struct device *parent;
+ struct vgafb_config *vc;
+ int console;
+{
+ struct wsemuldisplaydev_attach_args aa;
+ struct wscons_odev_spec *wo;
+
+ aa.console = console;
+ aa.scrdata = &vgafb_screenlist;
+ aa.accessops = &vgafb_accessops;
+ aa.accesscookie = vc;
+
+ config_found(parent, &aa, wsemuldisplaydevprint);
+}
+
+
+int
+vgafb_print(aux, pnp)
+ void *aux;
+ const char *pnp;
+{
+
+ if (pnp)
+ printf("wsdisplay at %s", pnp);
+ return (UNCONF);
+}
+
+int
+vgafb_ioctl(v, cmd, data, flag, p)
+ void *v;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ /*struct vgafb_config *vc = v;*/
+
+ /* XXX */
+ return -1;
+}
+
+int
+vgafb_mmap(v, offset, prot)
+ void *v;
+ off_t offset;
+ int prot;
+{
+ struct vgafb_config *vc = v;
+ bus_space_handle_t h;
+ u_int32_t *port;
+
+ /* memsize... */
+ if (offset >= 0x00000 && offset < 0x800000) /* 8MB of mem??? */
+ h = vc->vc_memh + offset;
+ else if (offset >= 0x10000000 && offset < 0x10040000 )
+ /* 256KB of iohb */
+ h = vc->vc_ioh_b;
+ else if (offset >= 0x10040000 && offset < 0x10080000)
+ /* 256KB of iohc */
+ h = vc->vc_ioh_c;
+ else if (offset >= 0x18880000 && offset < 0x100c0000)
+ /* 256KB of iohd */
+ h = vc->vc_ioh_d;
+ else if (offset >= 0x20000000 && offset < 0x30000000)
+ /* mmiosize... */
+ h = vc->vc_mmioh + (offset - 0x20000000);
+ else
+ return (-1);
+
+#ifdef alpha
+ port = (u_int32_t *)(h << 5);
+ return alpha_btop(port); /* XXX */
+#elif defined(i386)
+ port = (u_int32_t *)(h << 5);
+ return i386_btop(port);
+#elif defined(__powerpc__)
+ {
+ /* huh ??? */
+ return h;
+ /*
+ return powerpc_btop(port);
+ */
+ }
+#endif
+}
+
+
+void
+vgafb_cnprobe(cp)
+ struct consdev *cp;
+{
+ int i, j;
+ if (cons_displaytype != 1) {
+ cp->cn_pri = CN_DEAD;
+ return;
+ }
+
+ cp->cn_pri = CN_REMOTE;
+ #if 0
+ for (j = 0; j < 2; j++) {
+ for (i = 0; i < cons_width * cons_height; i++) {
+ bus_space_write_1(cons_membus,
+ cons_display_mem_h, i, j);
+
+ }
+ }
+ #endif
+
+}
+
+extern struct raster_font fontdata8x16;
+void
+vgafb_cnattach(iot, memt, pc, bus, device, function)
+ void * pc;
+ bus_space_tag_t iot, memt;
+ int bus, device, function;
+{
+ long defattr;
+
+ struct vgafb_devconfig *dc = &vgafb_console_dc;
+ struct rcons *ri = &dc->dc_ri;
+ ri->rc_sp = &vgafb_raster;
+
+ printf("vgafb_cnattach called\n");
+
+ ri->rc_sp->width = cons_width;
+ ri->rc_sp->height = cons_height;
+ ri->rc_sp->depth = cons_depth;
+ ri->rc_sp->linelongs = cons_linebytes /4; /* XXX */
+ ri->rc_sp->pixels = (void *)cons_display_mem_h;
+
+ rcons_init(ri, 160, 160);
+
+ vgafb_stdscreen.nrows = ri->rc_maxrow;
+ vgafb_stdscreen.ncols = ri->rc_maxcol;
+ vgafb_stdscreen.textops = &vgafb_emulops;
+ rcons_alloc_attr(ri, 0, 0, 0, &defattr);
+ printf("vgafb_cnattach screen paint start\n");
+ printf("membus %x mem_h %x\n",
+ cons_membus->bus_base, cons_display_mem_h);
+ #if 0
+ {
+ int i;
+ for (i = 0; i < cons_width * cons_height; i++) {
+ bus_space_write_1(cons_membus,
+ cons_display_mem_h, i, 0x1);
+
+ }
+ }
+ #endif
+ printf("vgafb_cnattach screen painted\n");
+ wsdisplay_cnattach(&vgafb_stdscreen, ri, 0, 0, defattr);
+}
diff --git a/sys/arch/powerpc/pci/vgafb_pci.c b/sys/arch/powerpc/pci/vgafb_pci.c
new file mode 100644
index 00000000000..8787289a360
--- /dev/null
+++ b/sys/arch/powerpc/pci/vgafb_pci.c
@@ -0,0 +1,442 @@
+/* $OpenBSD: vgafb_pci.c,v 1.1 2000/09/06 02:12:15 rahnds Exp $ */
+/* $NetBSD: vga_pci.c,v 1.4 1996/12/05 01:39:38 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+
+#ifndef i386
+#include <machine/autoconf.h>
+#endif
+#include <machine/pte.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <dev/rcons/raster.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wscons_raster.h>
+
+#include <arch/powerpc/pci/vgafbvar.h>
+#include <arch/powerpc/pci/vgafb_pcivar.h>
+
+#define PCI_VENDORID(x) ((x) & 0xFFFF)
+#define PCI_CHIPID(x) (((x) >> 16) & 0xFFFF)
+
+struct vgafb_pci_softc {
+ struct device sc_dev;
+
+ pcitag_t sc_pcitag; /* PCI tag, in case we need it. */
+ struct vgafb_config *sc_vc; /* VGA configuration */
+ int nscreens;
+};
+
+#ifdef __BROKEN_INDIRECT_CONFIG
+int vgafb_pci_match __P((struct device *, void *, void *));
+#else
+int vgafb_pci_match __P((struct device *, struct cfdata *, void *));
+#endif
+void vgafb_pci_attach __P((struct device *, struct device *, void *));
+
+int vgafbpcimmap __P((void *, off_t, int));
+int vgafbpciioctl __P((void *, u_long, caddr_t, int, struct proc *));
+
+struct cfattach vgafb_pci_ca = {
+ sizeof(struct vgafb_pci_softc), (cfmatch_t)vgafb_pci_match, vgafb_pci_attach,
+};
+
+pcitag_t vgafb_pci_console_tag;
+struct vgafb_config vgafb_pci_console_vc;
+
+#if 0
+#define DEBUG_VGAFB
+#endif
+
+int
+vgafb_pci_probe(pa, id, ioaddr, iosize, memaddr, memsize, cacheable, mmioaddr, mmiosize)
+ struct pci_attach_args *pa;
+ int id;
+ u_int32_t *ioaddr, *iosize;
+ u_int32_t *memaddr, *memsize, *cacheable;
+ u_int32_t *mmioaddr, *mmiosize;
+{
+ u_int32_t addr, size, tcacheable;
+ pci_chipset_tag_t pc = pa->pa_pc;
+ int retval;
+ int i;
+
+ *iosize = 0x0;
+ *memsize = 0x0;
+ *mmiosize = 0x0;
+ for (i = 0x10; i < 0x18; i += 4) {
+#ifdef DEBUG_VGAFB
+ printf("vgafb confread %x %x\n",
+ i, pci_conf_read(pc, pa->pa_tag, i));
+#endif
+ /* need to check more than just two base addresses? */
+ if (0x1 & pci_conf_read(pc, pa->pa_tag, i) ) {
+ retval = pci_io_find(pc, pa->pa_tag, i,
+ &addr, &size);
+ if (retval) {
+ printf("vgafb_pci_probe: io %x addr %x size %x\n", i, addr, size);
+ return 0;
+ }
+ if (*iosize == 0) {
+ *ioaddr = addr;
+ *iosize = size;
+ }
+
+ } else {
+ retval = pci_mem_find(pc, pa->pa_tag, i,
+ &addr, &size, &tcacheable);
+#ifdef DEBUG_VGAFB
+ printf("vgafb_pci_probe: mem %x addr %x size %x\n", i, addr, size);
+#endif
+
+ if (retval) {
+ printf("vgafb_pci_probe: mem %x addr %x size %x\n", i, addr, size);
+ return 0;
+ }
+ if (size == 0) {
+ /* ignore this entry */
+ }else if (size <= (64 * 1024)) {
+#ifdef DEBUG_VGAFB
+ printf("vgafb_pci_probe: mem %x addr %x size %x iosize %x\n",
+ i, addr, size, *iosize);
+#endif
+ if (*mmiosize == 0) {
+ /* this is mmio, not memory */
+ *mmioaddr = addr;
+ *mmiosize = size;
+ /* need skew in here for io memspace */
+ }
+ } else {
+ if (*memsize == 0) {
+ *memaddr = addr;
+ *memsize = size;
+ *cacheable = tcacheable;
+ }
+ }
+ }
+ }
+#ifdef DEBUG_VGAFB
+ printf("vgafb_pci_probe: id %x ioaddr %x, iosize %x, memaddr %x,\n memsize %x, mmioaddr %x, mmiosize %x\n",
+ id, *ioaddr, *iosize, *memaddr, *memsize, *mmioaddr, *mmiosize);
+#endif
+ if (*iosize == 0) {
+ if (id == 0) {
+#ifdef powerpc
+ /* this is only used if on openfirmware system and
+ * the device does not have a iobase config register,
+ * eg CirrusLogic 5434 VGA. (they hardcode iobase to 0
+ * thus giving standard PC addresses for the registers)
+ */
+ int s;
+ u_int32_t sizedata;
+
+ /*
+ * Open Firmware (yuck) shuts down devices before
+ * entering a program so we need to bring them back
+ * 'online' to respond to bus accesses... so far
+ * this is true on the power.4e.
+ */
+ s = splhigh();
+ sizedata = pci_conf_read(pc, pa->pa_tag,
+ PCI_COMMAND_STATUS_REG);
+ sizedata |= (PCI_COMMAND_MASTER_ENABLE |
+ PCI_COMMAND_IO_ENABLE |
+ PCI_COMMAND_PARITY_ENABLE |
+ PCI_COMMAND_SERR_ENABLE);
+ pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
+ sizedata);
+ splx(s);
+
+#endif
+ /* if this is the first card, allow it
+ * to be accessed in vga iospace
+ */
+ *ioaddr = 0;
+ *iosize = 0x10000; /* 64k, good as any */
+ } else {
+ /* iospace not available, assume 640x480, pray */
+ *ioaddr = 0;
+ *iosize=0;
+ }
+ }
+#ifdef DEBUG_VGAFB
+ printf("vgafb_pci_probe: id %x ioaddr %x, iosize %x, memaddr %x,\n memsize %x, mmioaddr %x, mmiosize %x\n",
+ id, *ioaddr, *iosize, *memaddr, *memsize, *mmioaddr, *mmiosize);
+#endif
+ return 1;
+}
+int
+vgafb_pci_match(parent, match, aux)
+ struct device *parent;
+#ifdef __BROKEN_INDIRECT_CONFIG
+ void *match;
+#else
+ struct cfdata *match;
+#endif
+ void *aux;
+{
+ struct pci_attach_args *pa = aux;
+ u_int32_t memaddr, memsize, cacheable;
+ u_int32_t ioaddr, iosize;
+ u_int32_t mmioaddr, mmiosize;
+ int potential;
+ int retval;
+ static int id = 0;
+ int myid;
+
+ myid = id;
+
+ potential = 0;
+
+ /*
+ * If it's prehistoric/vga or display/vga, we might match.
+ * For the console device, this is jut a sanity check.
+ */
+ if (PCI_CLASS(pa->pa_class) == PCI_CLASS_PREHISTORIC &&
+ PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_PREHISTORIC_VGA)
+ potential = 1;
+ if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY &&
+ PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA)
+ potential = 1;
+
+ if (!potential)
+ return (0);
+
+ /* If it's the console, we have a winner! */
+ if (!bcmp(&pa->pa_tag, &vgafb_pci_console_tag, sizeof(pa->pa_tag))) {
+ id++;
+ return (1);
+ }
+
+#ifdef DEBUG_VGAFB
+ {
+ int i;
+ pci_chipset_tag_t pc = pa->pa_pc;
+ for (i = 0x10; i < 0x24; i+=4) {
+ printf("vgafb confread %x %x\n",
+ i, pci_conf_read(pc, pa->pa_tag, i));
+ }
+ }
+#endif
+
+ memaddr=0xb8000; /* default to isa addresses? */
+ ioaddr = 0; /* default to isa addresses? */
+
+ retval = vgafb_pci_probe(pa, myid, &ioaddr, &iosize,
+ &memaddr, &memsize, &cacheable, &mmioaddr, &mmiosize);
+ if (retval == 0) {
+ return 0;
+ }
+#if 1
+ printf("ioaddr %x, iosize %x, memaddr %x, memsize %x mmioaddr %x mmiosize %x\n",
+ ioaddr, iosize, memaddr, memsize, mmioaddr, mmiosize);
+#endif
+
+ if (!vgafb_common_probe(pa->pa_iot, pa->pa_memt, ioaddr, iosize, memaddr, memsize, mmioaddr, mmiosize))
+ {
+ printf("vgafb_pci_match: common_probe failed\n");
+ return (0);
+ }
+ id++;
+
+ return (1);
+}
+
+void
+vgafb_pci_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct pci_attach_args *pa = aux;
+ struct vgafb_pci_softc *sc = (struct vgafb_pci_softc *)self;
+ struct vgafb_config *vc;
+ u_int32_t memaddr, memsize, cacheable;
+ u_int32_t ioaddr, iosize;
+ u_int32_t mmioaddr, mmiosize;
+ int console;
+ static int id = 0;
+ int myid;
+
+ myid = id;
+
+ vgafb_pci_probe(pa, myid, &ioaddr, &iosize,
+ &memaddr, &memsize, &cacheable, &mmioaddr, &mmiosize);
+
+ console = (!bcmp(&pa->pa_tag, &vgafb_pci_console_tag, sizeof(pa->pa_tag)));
+ if (console)
+ vc = sc->sc_vc = &vgafb_pci_console_vc;
+ else {
+ vc = sc->sc_vc = (struct vgafb_config *)
+ malloc(sizeof(struct vgafb_config), M_DEVBUF, M_WAITOK);
+
+ /* set up bus-independent VGA configuration */
+ vgafb_common_setup(pa->pa_iot, pa->pa_memt, vc,
+ ioaddr, iosize, memaddr, memsize, mmioaddr, mmiosize);
+ }
+ vc->vc_mmap = vgafbpcimmap;
+ vc->vc_ioctl = vgafbpciioctl;
+
+ sc->sc_pcitag = pa->pa_tag;
+
+ if (iosize == 0) {
+ printf (", no io");
+ }
+ if (mmiosize != 0) {
+ printf (", mmio");
+ }
+ printf("\n");
+
+ vgafb_wsdisplay_attach(self, vc, console);
+ id++;
+}
+
+void
+vgafb_pci_console(iot, ioaddr, iosize, memt, memaddr, memsize,
+ pc, bus, device, function)
+ bus_space_tag_t iot, memt;
+ u_int32_t memaddr, memsize;
+ u_int32_t ioaddr, iosize;
+ pci_chipset_tag_t pc;
+ int bus, device, function;
+{
+ extern bus_space_handle_t cons_display_mem_h;
+ struct vgafb_config *vc = &vgafb_pci_console_vc;
+ u_int32_t mmioaddr;
+ u_int32_t mmiosize;
+ int retval;
+ u_int32_t cacheable;
+ static struct pci_attach_args spa;
+ struct pci_attach_args *pa = &spa;
+
+ /* for later recognition */
+ vgafb_pci_console_tag = pci_make_tag(pc, bus, device, function);
+
+ pa->pa_iot = iot;
+ pa->pa_memt = memt;
+ pa->pa_tag = vgafb_pci_console_tag;
+ /*
+ pa->pa_pc = XXX;
+ */
+
+/* XXX probe pci before pci bus config? */
+
+ mmioaddr =0;
+ mmiosize =0;
+#if 0
+ vgafb_pci_probe(pa, 0, &ioaddr, &iosize,
+ &memaddr, &memsize, &cacheable, mmioaddr, mmiosize);
+#endif
+
+
+ /* set up bus-independent VGA configuration */
+ vgafb_common_setup(iot, memt, vc,
+ ioaddr, iosize, memaddr, memsize, mmioaddr, mmiosize);
+
+ vgafb_cnattach(iot, memt, pc, bus, device, function);
+}
+
+int
+vgafbpciioctl(v, cmd, data, flag, p)
+ void *v;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ struct vgafb_pci_softc *sc = v;
+
+ return (vgafb_ioctl(sc->sc_vc, cmd, data, flag, p));
+}
+
+int
+vgafbpcimmap(v, offset, prot)
+ void *v;
+ off_t offset;
+ int prot;
+{
+ struct vgafb_pci_softc *sc = v;
+
+ return (vgafb_mmap(sc->sc_vc, offset, prot));
+}
+
+int
+vgafb_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
+ void *v;
+ const struct wsscreen_descr *type;
+ void **cookiep;
+ int *curxp, *curyp;
+ long *attrp;
+{
+ struct vgafb_pci_softc *sc = v;
+ long defattr;
+
+ if (sc->nscreens > 0)
+ return (ENOMEM);
+
+ *cookiep = &sc->sc_vc->dc_rcons; /* one and only for now */
+ *curxp = 0;
+ *curyp = 0;
+ rcons_alloc_attr(&sc->sc_vc->dc_rcons, 0, 0, 0, &defattr);
+ *attrp = defattr;
+ sc->nscreens++;
+ return (0);
+}
+
+void
+vgafb_free_screen(v, cookie)
+ void *v;
+ void *cookie;
+{
+ struct vgafb_pci_softc *sc = v;
+
+ if (sc->sc_vc == &vgafb_pci_console_vc)
+ panic("vgafb_free_screen: console");
+
+ sc->nscreens--;
+}
+
+int
+vgafb_show_screen(v, cookie, waitok, cb, cbarg)
+ void *v;
+ void *cookie;
+ int waitok;
+ void (*cb) __P((void *, int, int));
+ void *cbarg;
+{
+
+ return (0);
+}
diff --git a/sys/arch/powerpc/pci/vgafb_pcivar.h b/sys/arch/powerpc/pci/vgafb_pcivar.h
new file mode 100644
index 00000000000..ac6d110e893
--- /dev/null
+++ b/sys/arch/powerpc/pci/vgafb_pcivar.h
@@ -0,0 +1,41 @@
+/* $OpenBSD: vgafb_pcivar.h,v 1.1 2000/09/06 02:12:15 rahnds Exp $ */
+/* $NetBSD: vga_pcivar.h,v 1.1 1996/11/19 04:38:36 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#define DEVICE_IS_VGA_PCI(class, id) \
+ (((PCI_CLASS(class) == PCI_CLASS_DISPLAY && \
+ PCI_SUBCLASS(class) == PCI_SUBCLASS_DISPLAY_VGA) || \
+ (PCI_CLASS(class) == PCI_CLASS_PREHISTORIC && \
+ PCI_SUBCLASS(class) == PCI_SUBCLASS_PREHISTORIC_VGA)) ? 1 : 0)
+
+void vgafb_pci_console __P((bus_space_tag_t,
+ u_int32_t ioaddr, u_int32_t iosize,
+ bus_space_tag_t,
+ u_int32_t memaddr, u_int32_t memsize,
+ pci_chipset_tag_t, int, int, int));
diff --git a/sys/arch/powerpc/pci/vgafbvar.h b/sys/arch/powerpc/pci/vgafbvar.h
new file mode 100644
index 00000000000..6c6d41437da
--- /dev/null
+++ b/sys/arch/powerpc/pci/vgafbvar.h
@@ -0,0 +1,67 @@
+/* $OpenBSD: vgafbvar.h,v 1.1 2000/09/06 02:12:15 rahnds Exp $ */
+/* $NetBSD: vgavar.h,v 1.2 1996/11/23 06:06:43 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+struct vgafb_config {
+ /*
+ * Filled in by front-ends.
+ */
+ bus_space_tag_t vc_iot, vc_memt;
+ bus_space_handle_t vc_ioh_b, vc_ioh_c, vc_ioh_d, vc_memh, vc_mmioh;
+
+ /*
+ * Private to back-end.
+ */
+ int vc_ncol, vc_nrow; /* screen width & height */
+ int vc_ccol, vc_crow; /* current cursor position */
+
+ char vc_so; /* in standout mode? */
+ char vc_at; /* normal attributes */
+ char vc_so_at; /* standout attributes */
+
+ int (*vc_ioctl) __P((void *, u_long,
+ caddr_t, int, struct proc *));
+ int (*vc_mmap) __P((void *, off_t, int));
+ #if 0
+ struct raster dc_raster; /* raster description */
+ #endif
+ struct rcons dc_rcons; /* raster blitter control info */
+
+
+};
+
+int vgafb_common_probe __P((bus_space_tag_t, bus_space_tag_t,
+ u_int32_t, size_t, u_int32_t, size_t, u_int32_t, size_t ));
+void vgafb_common_setup __P((bus_space_tag_t, bus_space_tag_t,
+ struct vgafb_config *, u_int32_t, size_t, u_int32_t, size_t,
+ u_int32_t, size_t));
+void vgafb_wscons_attach __P((struct device *, struct vgafb_config *, int));
+void vgafb_wscons_console __P((struct vgafb_config *));
+int vgafbioctl __P((void *, u_long, caddr_t, int, struct proc *));
+int vgafbmmap __P((void *, off_t, int));