diff options
author | Aaron Campbell <aaron@cvs.openbsd.org> | 2000-11-15 20:17:39 +0000 |
---|---|---|
committer | Aaron Campbell <aaron@cvs.openbsd.org> | 2000-11-15 20:17:39 +0000 |
commit | c6b81477957194a276e75a185a4b2e87ac43f413 (patch) | |
tree | a24c07c89b6e504a43f01f148b3fb2f81474904a /sys/dev | |
parent | 459bffc0f4130f9bdbcdbcd9321bf367300f927c (diff) |
Updated VGA driver; from NetBSD. Needed for wscons on i386 and alpha. These
files could probably be updated even a bit further (they are from mid-summer).
In addition, I've added support for console scrollback, somewhat inspired by
Linux's vgacon driver. Basically, instead of allocating our own buffer and
doing lots of copies, we take advantage of Video RAM and just modify the VGA
display origin register as appropriate. This approach has a few advantages:
simple to implement, no wasted KVM, it's fast, and after a boot you can now
scroll back all the way to the BIOS messages (assuming your msgbuf is of a
typical length :). Disadvantages are that the VRAM buffer is relatively
small (only 32k) and we do not support raster devices through this method.
(thanks to mickey@ for pointing this out).
The code for this is fairly unobtrusive, so should we come up with a better
approach to console scrollback at a later time (i.e., even more platform
independent) it should be easy to revert this.
We're one step further in porting nice features of PCVT over to wscons.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ic/vga.c | 1317 | ||||
-rw-r--r-- | sys/dev/ic/vga_subr.c | 161 | ||||
-rw-r--r-- | sys/dev/ic/vgareg.h | 57 | ||||
-rw-r--r-- | sys/dev/ic/vgavar.h | 153 | ||||
-rw-r--r-- | sys/dev/isa/vga_isa.c | 127 | ||||
-rw-r--r-- | sys/dev/isa/vga_isavar.h | 7 | ||||
-rw-r--r-- | sys/dev/pci/vga_pci.c | 104 | ||||
-rw-r--r-- | sys/dev/pci/vga_pcivar.h | 8 |
8 files changed, 1502 insertions, 432 deletions
diff --git a/sys/dev/ic/vga.c b/sys/dev/ic/vga.c index d4212386637..be3a7de3ea5 100644 --- a/sys/dev/ic/vga.c +++ b/sys/dev/ic/vga.c @@ -1,5 +1,5 @@ -/* $OpenBSD: vga.c,v 1.12 1998/09/28 01:07:34 rahnds Exp $ */ -/* $NetBSD: vga.c,v 1.3 1996/12/02 22:24:54 cgd Exp $ */ +/* $OpenBSD: vga.c,v 1.13 2000/11/15 20:17:37 aaron Exp $ */ +/* $NetBSD: vga.c,v 1.28.2.1 2000/06/30 16:27:47 simonb Exp $ */ /* * Copyright (c) 1995, 1996 Carnegie-Mellon University. @@ -30,39 +30,236 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/timeout.h> #include <sys/kernel.h> #include <sys/device.h> +#include <sys/malloc.h> +#include <sys/queue.h> #include <machine/bus.h> -#include <dev/wscons/wsconsvar.h> +#include <dev/ic/mc6845reg.h> +#include <dev/ic/pcdisplayvar.h> +#include <dev/ic/vgareg.h> #include <dev/ic/vgavar.h> -#define VGA_IO_D_6845_ADDR 0x4 -#define VGA_IO_D_6845_DATA 0x5 +#include <dev/wscons/wsdisplayvar.h> +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/unicode.h> -struct cfdriver vga_cd = { - NULL, "vga", DV_DULL, +#include <dev/ic/pcdisplay.h> + +#if 0 +#include "opt_wsdisplay_compat.h" /* for WSCONS_SUPPORT_PCVTFONTS */ +#endif + +static struct vgafont { + char name[16]; + int height; + int encoding; +#ifdef notyet + int firstchar, numchars; +#endif + int slot; +} vga_builtinfont = { + "builtin", + 16, + WSDISPLAY_FONTENC_IBM, +#ifdef notyet + 0, 256, +#endif + 0 +}; + +struct vgascreen { + struct pcdisplayscreen pcs; + + LIST_ENTRY(vgascreen) next; + + struct vga_config *cfg; + + /* videostate */ + struct vgafont *fontset1, *fontset2; + /* font data */ + /* palette */ + + int mindispoffset, maxdispoffset; + int vga_rollover; }; -void vga_cursor __P((void *, int, int, int)); -void vga_putstr __P((void *, int, int, char *, int)); -void vga_copycols __P((void *, int, int, int, int)); -void vga_erasecols __P((void *, int, int, int)); +struct vga_config { + struct vga_handle hdl; + + int nscreens; + LIST_HEAD(, vgascreen) screens; + struct vgascreen *active; /* current display */ + const struct wsscreen_descr *currenttype; + int currentfontset1, currentfontset2; + + int vc_biosmapped; + bus_space_tag_t vc_biostag; + bus_space_handle_t vc_bioshdl; + + struct vgafont *vc_fonts[8]; + + struct vgascreen *wantedscreen; + void (*switchcb) __P((void *, int, int)); + void *switchcbarg; + +#ifdef arc + paddr_t (*vc_mmap) __P((void *, off_t, int)); +#endif + + struct timeout vc_switch_timeout; +}; + +static int vgaconsole, vga_console_type, vga_console_attached; +static struct vgascreen vga_console_screen; +static struct vga_config vga_console_vc; + +int vga_selectfont __P((struct vga_config *, struct vgascreen *, + char *, char *)); +void vga_init_screen __P((struct vga_config *, struct vgascreen *, + const struct wsscreen_descr *, + int, long *)); +void vga_init __P((struct vga_config *, bus_space_tag_t, + bus_space_tag_t)); +static void vga_setfont __P((struct vga_config *, struct vgascreen *)); + +static int vga_mapchar __P((void *, int, unsigned int *)); +static void vga_putchar __P((void *, int, int, u_int, long)); +static int vga_alloc_attr __P((void *, int, int, int, long *)); void vga_copyrows __P((void *, int, int, int)); -void vga_eraserows __P((void *, int, int)); -void vga_set_attr __P((void *, int)); - -struct wscons_emulfuncs vga_emulfuncs = { - vga_cursor, - vga_putstr, - vga_copycols, - vga_erasecols, + +const struct wsdisplay_emulops vga_emulops = { + pcdisplay_cursor, + vga_mapchar, + vga_putchar, + pcdisplay_copycols, + pcdisplay_erasecols, vga_copyrows, - vga_eraserows, - vga_set_attr, + pcdisplay_eraserows, + vga_alloc_attr +}; + +/* + * translate WS(=ANSI) color codes to standard pc ones + */ +static unsigned char fgansitopc[] = { +#ifdef __alpha__ + /* + * XXX DEC HAS SWITCHED THE CODES FOR BLUE AND RED!!! + * XXX We should probably not bother with this + * XXX (reinitialize the palette registers). + */ + FG_BLACK, FG_BLUE, FG_GREEN, FG_CYAN, FG_RED, + FG_MAGENTA, FG_BROWN, FG_LIGHTGREY +#else + FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE, + FG_MAGENTA, FG_CYAN, FG_LIGHTGREY +#endif +}, bgansitopc[] = { +#ifdef __alpha__ + BG_BLACK, BG_BLUE, BG_GREEN, BG_CYAN, BG_RED, + BG_MAGENTA, BG_BROWN, BG_LIGHTGREY +#else + BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE, + BG_MAGENTA, BG_CYAN, BG_LIGHTGREY +#endif +}; + +const struct wsscreen_descr vga_stdscreen = { + "80x25", 80, 25, + &vga_emulops, + 8, 16, + WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_BLINK +}, vga_stdscreen_mono = { + "80x25", 80, 25, + &vga_emulops, + 8, 16, + WSSCREEN_HILIT | WSSCREEN_UNDERLINE | WSSCREEN_BLINK | WSSCREEN_REVERSE +}, vga_stdscreen_bf = { + "80x25bf", 80, 25, + &vga_emulops, + 8, 16, + WSSCREEN_WSCOLORS | WSSCREEN_BLINK +}, vga_40lscreen = { + "80x40", 80, 40, + &vga_emulops, + 8, 10, + WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_BLINK +}, vga_40lscreen_mono = { + "80x40", 80, 40, + &vga_emulops, + 8, 10, + WSSCREEN_HILIT | WSSCREEN_UNDERLINE | WSSCREEN_BLINK | WSSCREEN_REVERSE +}, vga_40lscreen_bf = { + "80x40bf", 80, 40, + &vga_emulops, + 8, 10, + WSSCREEN_WSCOLORS | WSSCREEN_BLINK +}, vga_50lscreen = { + "80x50", 80, 50, + &vga_emulops, + 8, 8, + WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_BLINK +}, vga_50lscreen_mono = { + "80x50", 80, 50, + &vga_emulops, + 8, 8, + WSSCREEN_HILIT | WSSCREEN_UNDERLINE | WSSCREEN_BLINK | WSSCREEN_REVERSE +}, vga_50lscreen_bf = { + "80x50bf", 80, 50, + &vga_emulops, + 8, 8, + WSSCREEN_WSCOLORS | WSSCREEN_BLINK +}; + +#define VGA_SCREEN_CANTWOFONTS(type) (!((type)->capabilities & WSSCREEN_HILIT)) + +const struct wsscreen_descr *_vga_scrlist[] = { + &vga_stdscreen, + &vga_stdscreen_bf, + &vga_40lscreen, + &vga_40lscreen_bf, + &vga_50lscreen, + &vga_50lscreen_bf, + /* XXX other formats, graphics screen? */ +}, *_vga_scrlist_mono[] = { + &vga_stdscreen_mono, + &vga_40lscreen_mono, + &vga_50lscreen_mono, + /* XXX other formats, graphics screen? */ }; -int vgaprint __P((void *, const char *)); +const struct wsscreen_list vga_screenlist = { + sizeof(_vga_scrlist) / sizeof(struct wsscreen_descr *), + _vga_scrlist +}, vga_screenlist_mono = { + sizeof(_vga_scrlist_mono) / sizeof(struct wsscreen_descr *), + _vga_scrlist_mono +}; + +int vga_ioctl __P((void *, u_long, caddr_t, int, struct proc *)); +int vga_mmap __P((void *, off_t, int)); +int vga_alloc_screen __P((void *, const struct wsscreen_descr *, + void **, int *, int *, long *)); +void vga_free_screen __P((void *, void *)); +int vga_show_screen __P((void *, void *, int, + void (*) (void *, int, int), void *)); +int vga_load_font __P((void *, void *, struct wsdisplay_font *)); +void vga_scrollback __P((void *, void *, int)); + +void vga_doswitch __P((struct vga_config *)); + +const struct wsdisplay_accessops vga_accessops = { + vga_ioctl, + vga_mmap, + vga_alloc_screen, + vga_free_screen, + vga_show_screen, + vga_load_font, + vga_scrollback +}; /* * The following functions implement back-end configuration grabbing @@ -72,274 +269,715 @@ int vga_common_probe(iot, memt) bus_space_tag_t iot, memt; { - bus_space_handle_t ioh_b, ioh_c, ioh_d, memh; + bus_space_handle_t ioh_vga, ioh_6845, memh; + u_int8_t regval; u_int16_t vgadata; - int gotio_b, gotio_c, gotio_d, gotmem, rv; + int gotio_vga, gotio_6845, gotmem, mono, rv; + int dispoffset; - gotio_b = gotio_c = gotio_d = gotmem = rv = 0; + gotio_vga = gotio_6845 = gotmem = rv = 0; - if (bus_space_map(iot, 0x3b0, 0xc, 0, &ioh_b)) - goto bad; - gotio_b = 1; - if (bus_space_map(iot, 0x3c0, 0x10, 0, &ioh_c)) + if (bus_space_map(iot, 0x3c0, 0x10, 0, &ioh_vga)) goto bad; - gotio_c = 1; - if (bus_space_map(iot, 0x3d0, 0x10, 0, &ioh_d)) + gotio_vga = 1; + + /* read "misc output register" */ + regval = bus_space_read_1(iot, ioh_vga, 0xc); + mono = !(regval & 1); + + if (bus_space_map(iot, (mono ? 0x3b0 : 0x3d0), 0x10, 0, &ioh_6845)) goto bad; - gotio_d = 1; - if (bus_space_map(memt, 0xb8000, 0x8000, 0, &memh)) + gotio_6845 = 1; + + if (bus_space_map(memt, 0xa0000, 0x20000, 0, &memh)) goto bad; gotmem = 1; - 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); + dispoffset = (mono ? 0x10000 : 0x18000); + + vgadata = bus_space_read_2(memt, memh, dispoffset); + bus_space_write_2(memt, memh, dispoffset, 0xa55a); + if (bus_space_read_2(memt, memh, dispoffset) != 0xa55a) + goto bad; + bus_space_write_2(memt, memh, dispoffset, vgadata); + + /* + * check if this is really a VGA + * (try to write "Color Select" register as XFree86 does) + * XXX check before if at least EGA? + */ + /* reset state */ + (void) bus_space_read_1(iot, ioh_6845, 10); + bus_space_write_1(iot, ioh_vga, VGA_ATC_INDEX, + 20 | 0x20); /* colselect | enable */ + regval = bus_space_read_1(iot, ioh_vga, VGA_ATC_DATAR); + /* toggle the implemented bits */ + bus_space_write_1(iot, ioh_vga, VGA_ATC_DATAW, regval ^ 0x0f); + bus_space_write_1(iot, ioh_vga, VGA_ATC_INDEX, + 20 | 0x20); + /* read back */ + if (bus_space_read_1(iot, ioh_vga, VGA_ATC_DATAR) != (regval ^ 0x0f)) + goto bad; + /* restore contents */ + bus_space_write_1(iot, ioh_vga, VGA_ATC_DATAW, regval); + rv = 1; 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 (gotio_vga) + bus_space_unmap(iot, ioh_vga, 0x10); + if (gotio_6845) + bus_space_unmap(iot, ioh_6845, 0x10); if (gotmem) - bus_space_unmap(memt, memh, 0x8000); + bus_space_unmap(memt, memh, 0x20000); return (rv); } -void -vga_common_setup(iot, memt, vc) - bus_space_tag_t iot, memt; +/* + * We want at least ASCII 32..127 be present in the + * first font slot. + */ +#define vga_valid_primary_font(f) \ + (f->encoding == WSDISPLAY_FONTENC_IBM || \ + f->encoding == WSDISPLAY_FONTENC_ISO) + +int +vga_selectfont(vc, scr, name1, name2) struct vga_config *vc; + struct vgascreen *scr; + char *name1, *name2; /* NULL: take first found */ { - int cpos; + const struct wsscreen_descr *type = scr->pcs.type; + struct vgafont *f1, *f2; + int i; - vc->vc_iot = iot; - vc->vc_memt = memt; - - if (bus_space_map(vc->vc_iot, 0x3b0, 0xc, 0, &vc->vc_ioh_b)) - panic("vga_common_setup: couldn't map io b"); - if (bus_space_map(vc->vc_iot, 0x3c0, 0x10, 0, &vc->vc_ioh_c)) - panic("vga_common_setup: couldn't map io c"); - if (bus_space_map(vc->vc_iot, 0x3d0, 0x10, 0, &vc->vc_ioh_d)) - panic("vga_common_setup: couldn't map io d"); - if (bus_space_map(vc->vc_memt, 0xb8000, 0x8000, 0, &vc->vc_memh)) - panic("vga_common_setup: couldn't map memory"); - - vc->vc_nrow = 25; - vc->vc_ncol = 80; - - bus_space_write_1(iot, vc->vc_ioh_d, VGA_IO_D_6845_ADDR, 14); - cpos = bus_space_read_1(iot, vc->vc_ioh_d, VGA_IO_D_6845_DATA) << 8; - bus_space_write_1(iot, vc->vc_ioh_d, VGA_IO_D_6845_ADDR, 15); - cpos |= bus_space_read_1(iot, vc->vc_ioh_d, VGA_IO_D_6845_DATA); - vc->vc_crow = cpos / vc->vc_ncol; - vc->vc_ccol = cpos % vc->vc_ncol; - - vc->vc_so = 0; -#if 0 - vc->vc_at = 0x00 | 0xf; /* black bg|white fg */ - vc->vc_so_at = 0x00 | 0xf | 0x80; /* black bg|white fg|blink */ + f1 = f2 = 0; + + for (i = 0; i < 8; i++) { + struct vgafont *f = vc->vc_fonts[i]; + if (!f || f->height != type->fontheight) + continue; + if (!f1 && + vga_valid_primary_font(f) && + (!name1 || !strcmp(name1, f->name))) { + f1 = f; + continue; + } + if (!f2 && + VGA_SCREEN_CANTWOFONTS(type) && + (!name2 || !strcmp(name2, f->name))) { + f2 = f; + continue; + } + } - /* clear screen, frob cursor, etc.? */ - pcivga_eraserows(vc, 0, vc->vc_nrow); -#endif /* - * 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! + * The request fails if no primary font was found, + * or if a second font was requested but not found. */ - vc->vc_at = 0x40 | 0x0f; /* blue bg|white fg */ - vc->vc_so_at = 0x40 | 0x0f | 0x80; /* blue bg|white fg|blink */ + if (f1 && (!name2 || f2)) { +#ifdef VGAFONTDEBUG + if (scr != &vga_console_screen || vga_console_attached) { + printf("vga (%s): font1=%s (slot %d)", type->name, + f1->name, f1->slot); + if (f2) + printf(", font2=%s (slot %d)", + f2->name, f2->slot); + printf("\n"); + } +#endif + scr->fontset1 = f1; + scr->fontset2 = f2; + return (0); + } + return (ENXIO); } void -vga_wscons_attach(parent, vc, console) - struct device *parent; +vga_init_screen(vc, scr, type, existing, attrp) struct vga_config *vc; - int console; + struct vgascreen *scr; + const struct wsscreen_descr *type; + int existing; + long *attrp; { - struct wscons_attach_args waa; - struct wscons_odev_spec *wo; + int cpos; + int res; - waa.waa_isconsole = console; - wo = &waa.waa_odev_spec; + scr->cfg = vc; + scr->pcs.hdl = (struct pcdisplay_handle *)&vc->hdl; + scr->pcs.type = type; + scr->pcs.active = 0; + scr->mindispoffset = 0; + scr->maxdispoffset = 0x8000 - type->nrows * type->ncols * 2; - wo->wo_emulfuncs = &vga_emulfuncs; - wo->wo_emulfuncs_cookie = vc; + if (existing) { + cpos = vga_6845_read(&vc->hdl, cursorh) << 8; + cpos |= vga_6845_read(&vc->hdl, cursorl); - wo->wo_ioctl = vc->vc_ioctl; - wo->wo_mmap = vc->vc_mmap; - wo->wo_miscfuncs_cookie = vc; + /* make sure we have a valid cursor position */ + if (cpos < 0 || cpos >= type->nrows * type->ncols) + cpos = 0; - wo->wo_nrows = vc->vc_nrow; - wo->wo_ncols = vc->vc_ncol; - wo->wo_crow = vc->vc_crow; - wo->wo_ccol = vc->vc_ccol; - - config_found(parent, &waa, vgaprint); + scr->pcs.dispoffset = vga_6845_read(&vc->hdl, startadrh) << 9; + scr->pcs.dispoffset |= vga_6845_read(&vc->hdl, startadrl) << 1; + + /* make sure we have a valid memory offset */ + if (scr->pcs.dispoffset < scr->mindispoffset || + scr->pcs.dispoffset > scr->maxdispoffset) + scr->pcs.dispoffset = scr->mindispoffset; + } else { + cpos = 0; + scr->pcs.dispoffset = scr->mindispoffset; + } + scr->pcs.visibleoffset = scr->pcs.dispoffset; + scr->vga_rollover = 0; + + scr->pcs.vc_crow = cpos / type->ncols; + scr->pcs.vc_ccol = cpos % type->ncols; + pcdisplay_cursor_init(&scr->pcs, existing); + +#ifdef __alpha__ + if (!vc->hdl.vh_mono) + /* + * DEC firmware uses a blue background. + */ + res = vga_alloc_attr(scr, WSCOL_WHITE, WSCOL_BLUE, + WSATTR_WSCOLORS, attrp); + else +#endif + res = vga_alloc_attr(scr, 0, 0, 0, attrp); +#ifdef DIAGNOSTIC + if (res) + panic("vga_init_screen: attribute botch"); +#endif + + scr->pcs.mem = NULL; + + scr->fontset1 = scr->fontset2 = 0; + if (vga_selectfont(vc, scr, 0, 0)) { + if (scr == &vga_console_screen) + panic("vga_init_screen: no font"); + else + printf("vga_init_screen: no font\n"); + } + + vc->nscreens++; + LIST_INSERT_HEAD(&vc->screens, scr, next); } void -vga_wscons_console(vc) +vga_init(vc, iot, memt) struct vga_config *vc; + bus_space_tag_t iot, memt; +{ + struct vga_handle *vh = &vc->hdl; + u_int8_t mor; + int i; + + vh->vh_iot = iot; + vh->vh_memt = memt; + + if (bus_space_map(vh->vh_iot, 0x3c0, 0x10, 0, &vh->vh_ioh_vga)) + panic("vga_common_setup: couldn't map vga io"); + + /* read "misc output register" */ + mor = bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, 0xc); + vh->vh_mono = !(mor & 1); + + if (bus_space_map(vh->vh_iot, (vh->vh_mono ? 0x3b0 : 0x3d0), 0x10, 0, + &vh->vh_ioh_6845)) + panic("vga_common_setup: couldn't map 6845 io"); + + if (bus_space_map(vh->vh_memt, 0xa0000, 0x20000, 0, &vh->vh_allmemh)) + panic("vga_common_setup: couldn't map memory"); + + if (bus_space_subregion(vh->vh_memt, vh->vh_allmemh, + (vh->vh_mono ? 0x10000 : 0x18000), 0x8000, + &vh->vh_memh)) + panic("vga_common_setup: mem subrange failed"); + + /* should only reserve the space (no need to map - save KVM) */ + vc->vc_biostag = memt; + if (bus_space_map(vc->vc_biostag, 0xc0000, 0x8000, 0, + &vc->vc_bioshdl)) + vc->vc_biosmapped = 0; + else + vc->vc_biosmapped = 1; + + vc->nscreens = 0; + LIST_INIT(&vc->screens); + vc->active = NULL; + vc->currenttype = vh->vh_mono ? &vga_stdscreen_mono : &vga_stdscreen; +#if 0 + callout_init(&vc->vc_switch_callout); +#endif + + vc->vc_fonts[0] = &vga_builtinfont; + for (i = 1; i < 8; i++) + vc->vc_fonts[i] = 0; + + vc->currentfontset1 = vc->currentfontset2 = 0; +} + +void +vga_common_attach(self, iot, memt, type) + struct device *self; + bus_space_tag_t iot, memt; + int type; { - struct wscons_odev_spec wo; +#ifdef arc + vga_extended_attach(self, iot, memt, type, NULL); +} - wo.wo_emulfuncs = &vga_emulfuncs; - wo.wo_emulfuncs_cookie = vc; +void +vga_extended_attach(self, iot, memt, type, map) + struct device *self; + bus_space_tag_t iot, memt; + int type; + int (*map) __P((void *, vaddr_t, int)); +{ +#endif /* arc */ + int console; + struct vga_config *vc; + struct wsemuldisplaydev_attach_args aa; - /* ioctl and mmap are unused until real attachment. */ + console = vga_is_console(iot, type); - wo.wo_nrows = vc->vc_nrow; - wo.wo_ncols = vc->vc_ncol; - wo.wo_crow = vc->vc_crow; - wo.wo_ccol = vc->vc_ccol; - - wscons_attach_console(&wo); + if (console) { + vc = &vga_console_vc; + vga_console_attached = 1; + } else { + vc = malloc(sizeof(struct vga_config), M_DEVBUF, M_WAITOK); + vga_init(vc, iot, memt); + } + +#ifdef arc + vc->vc_mmap = map; +#endif + + aa.console = console; + aa.scrdata = (vc->hdl.vh_mono ? &vga_screenlist_mono : &vga_screenlist); + aa.accessops = &vga_accessops; + aa.accesscookie = vc; + + config_found(self, &aa, wsemuldisplaydevprint); } int -vgaprint(aux, pnp) - void *aux; - const char *pnp; +vga_cnattach(iot, memt, type, check) + bus_space_tag_t iot, memt; + int type, check; { + long defattr; + const struct wsscreen_descr *scr; + + if (check && !vga_common_probe(iot, memt)) + return (ENXIO); + + /* set up bus-independent VGA configuration */ + vga_init(&vga_console_vc, iot, memt); + scr = vga_console_vc.currenttype; + vga_init_screen(&vga_console_vc, &vga_console_screen, scr, 1, &defattr); + + vga_console_screen.pcs.active = 1; + vga_console_vc.active = &vga_console_screen; - if (pnp) - printf("wscons at %s", pnp); - return (UNCONF); + wsdisplay_cnattach(scr, &vga_console_screen, + vga_console_screen.pcs.vc_ccol, + vga_console_screen.pcs.vc_crow, + defattr); + + vgaconsole = 1; + vga_console_type = type; + return (0); } int -vgaioctl(v, cmd, data, flag, p) +vga_is_console(iot, type) + bus_space_tag_t iot; + int type; +{ + if (vgaconsole && + !vga_console_attached && + iot == vga_console_vc.hdl.vh_iot && + (vga_console_type == -1 || (type == vga_console_type))) + return (1); + return (0); +} + +int +vga_ioctl(v, cmd, data, flag, p) void *v; u_long cmd; caddr_t data; int flag; struct proc *p; { - /*struct vga_config *vc = v;*/ +#if 0 + struct vga_config *vc = v; +#endif + + switch (cmd) { +#if 0 + case WSDISPLAYIO_GTYPE: + *(int *)data = vc->vc_type; + /* XXX should get detailed hardware information here */ + return 0; +#else + case WSDISPLAYIO_GTYPE: + *(int *)data = WSDISPLAY_TYPE_UNKNOWN; + return 0; +#endif + + case WSDISPLAYIO_GINFO: + case WSDISPLAYIO_GETCMAP: + case WSDISPLAYIO_PUTCMAP: + case WSDISPLAYIO_GVIDEO: + case WSDISPLAYIO_SVIDEO: + case WSDISPLAYIO_GCURPOS: + case WSDISPLAYIO_SCURPOS: + case WSDISPLAYIO_GCURMAX: + case WSDISPLAYIO_GCURSOR: + case WSDISPLAYIO_SCURSOR: + /* NONE of these operations are by the generic VGA driver. */ + return ENOTTY; + } - /* XXX */ return -1; } int -vgammap(v, offset, prot) +vga_mmap(v, offset, prot) void *v; off_t offset; int prot; { + +#ifdef arc struct vga_config *vc = v; - bus_space_handle_t h; - u_int32_t *port; - - if (offset >= 0x00000 && offset < 0x100000) /* 1MB of mem */ - h = vc->vc_memh + offset; - else if (offset >= 0x10000 && offset < 0x140000) /* 256KB of iohb */ - h = vc->vc_ioh_b; - else if (offset >= 0x140000 && offset < 0x180000) /* 256KB of iohc */ - h = vc->vc_ioh_c; - else if (offset >= 0x180000 && offset < 0x1c0000) /* 256KB of iohd */ - h = vc->vc_ioh_d; - else - return (-1); - - port = (u_int32_t *)(h << 5); -#ifdef alpha - return alpha_btop(port); /* XXX */ -#elif defined(i386) - return i386_btop(port); -#elif defined(powerpc) - return powerpc_btop(port); + + if (vc->vc_mmap != NULL) + return (*vc->vc_mmap)(v, offset, prot); +#else + /* XXX */ #endif + return -1; } -/* - * The following functions implement the MI ANSI terminal emulation on - * a VGA display. - */ -void -vga_cursor(id, on, row, col) - void *id; - int on, row, col; +int +vga_alloc_screen(v, type, cookiep, curxp, curyp, defattrp) + void *v; + const struct wsscreen_descr *type; + void **cookiep; + int *curxp, *curyp; + long *defattrp; { - struct vga_config *vc = id; - bus_space_tag_t iot = vc->vc_iot; - bus_space_handle_t ioh_d = vc->vc_ioh_d; - int pos; + struct vga_config *vc = v; + struct vgascreen *scr; -#if 0 - printf("vga_cursor: %d %d\n", row, col); -#endif - /* turn the cursor off */ - if (!on) { - /* XXX disable cursor how??? */ - vc->vc_crow = vc->vc_ccol = -1; + if (vc->nscreens == 1) { + /* + * When allocating the second screen, get backing store + * for the first one too. + * XXX We could be more clever and use video RAM. + */ + vc->screens.lh_first->pcs.mem = + malloc(type->ncols * type->nrows * 2, M_DEVBUF, M_WAITOK); + } + + scr = malloc(sizeof(struct vgascreen), M_DEVBUF, M_WAITOK); + vga_init_screen(vc, scr, type, vc->nscreens == 0, defattrp); + + if (vc->nscreens == 1) { + scr->pcs.active = 1; + vc->active = scr; + vc->currenttype = type; } else { - vc->vc_crow = row; - vc->vc_ccol = col; + scr->pcs.mem = malloc(type->ncols * type->nrows * 2, + M_DEVBUF, M_WAITOK); + pcdisplay_eraserows(&scr->pcs, 0, type->nrows, *defattrp); } - pos = row * vc->vc_ncol + col; + *cookiep = scr; + *curxp = scr->pcs.vc_ccol; + *curyp = scr->pcs.vc_crow; - bus_space_write_1(iot, ioh_d, VGA_IO_D_6845_ADDR, 14); - bus_space_write_1(iot, ioh_d, VGA_IO_D_6845_DATA, pos >> 8); - bus_space_write_1(iot, ioh_d, VGA_IO_D_6845_ADDR, 15); - bus_space_write_1(iot, ioh_d, VGA_IO_D_6845_DATA, pos); + return (0); } void -vga_putstr(id, row, col, cp, len) - void *id; - int row, col; - char *cp; - int len; +vga_free_screen(v, cookie) + void *v; + void *cookie; +{ + struct vgascreen *vs = cookie; + struct vga_config *vc = vs->cfg; + + LIST_REMOVE(vs, next); + if (vs != &vga_console_screen) + free(vs, M_DEVBUF); + else + panic("vga_free_screen: console"); + + if (vc->active == vs) + vc->active = 0; +} + +void +vga_setfont(vc, scr) + struct vga_config *vc; + struct vgascreen *scr; +{ + int fontslot1, fontslot2; + + fontslot1 = (scr->fontset1 ? scr->fontset1->slot : 0); + fontslot2 = (scr->fontset2 ? scr->fontset2->slot : fontslot1); + if (vc->currentfontset1 != fontslot1 || + vc->currentfontset2 != fontslot2) { + vga_setfontset(&vc->hdl, fontslot1, fontslot2); + vc->currentfontset1 = fontslot1; + vc->currentfontset2 = fontslot2; + } +} + +int +vga_show_screen(v, cookie, waitok, cb, cbarg) + void *v; + void *cookie; + int waitok; + void (*cb) __P((void *, int, int)); + void *cbarg; { - struct vga_config *vc = id; - bus_space_tag_t memt = vc->vc_memt; - bus_space_handle_t memh = vc->vc_memh; - int i, off; - - off = (row * vc->vc_ncol + col) * 2; - for (i = 0; i < len; i++, cp++, off += 2) { - bus_space_write_1(memt, memh, off, *cp); - bus_space_write_1(memt, memh, off + 1, - vc->vc_so ? vc->vc_so_at : vc->vc_at); + struct vgascreen *scr = cookie, *oldscr; + struct vga_config *vc = scr->cfg; + + oldscr = vc->active; /* can be NULL! */ + if (scr == oldscr) { + return (0); + } + + vc->wantedscreen = cookie; + vc->switchcb = cb; + vc->switchcbarg = cbarg; + if (cb) { + timeout_set(&vc->vc_switch_timeout, + (void(*)(void *))vga_doswitch, vc); + timeout_add(&vc->vc_switch_timeout, 0); + return (EAGAIN); } + + vga_doswitch(vc); + return (0); } void -vga_copycols(id, row, srccol, dstcol, ncols) - void *id; - int row, srccol, dstcol, ncols; +vga_doswitch(vc) + struct vga_config *vc; { - struct vga_config *vc = id; - bus_size_t srcoff, dstoff; + struct vgascreen *scr, *oldscr; + struct vga_handle *vh = &vc->hdl; + const struct wsscreen_descr *type; + + scr = vc->wantedscreen; + if (!scr) { + printf("vga_doswitch: disappeared\n"); + (*vc->switchcb)(vc->switchcbarg, EIO, 0); + return; + } + type = scr->pcs.type; + oldscr = vc->active; /* can be NULL! */ +#ifdef DIAGNOSTIC + if (oldscr) { + if (!oldscr->pcs.active) + panic("vga_show_screen: not active"); + if (oldscr->pcs.type != vc->currenttype) + panic("vga_show_screen: bad type"); + } +#endif + if (scr == oldscr) { + return; + } +#ifdef DIAGNOSTIC + if (scr->pcs.active) + panic("vga_show_screen: active"); +#endif + + scr->vga_rollover = 0; - srcoff = (row * vc->vc_ncol + srccol) * 2; - dstoff = (row * vc->vc_ncol + dstcol) * 2; + if (oldscr) { + const struct wsscreen_descr *oldtype = oldscr->pcs.type; + + oldscr->pcs.active = 0; + bus_space_read_region_2(vh->vh_memt, vh->vh_memh, + oldscr->pcs.dispoffset, oldscr->pcs.mem, + oldtype->ncols * oldtype->nrows); + } + + if (vc->currenttype != type) { + vga_setscreentype(vh, type); + vc->currenttype = type; + } + + vga_setfont(vc, scr); + /* XXX switch colours! */ + + scr->pcs.visibleoffset = scr->pcs.dispoffset = scr->mindispoffset; + if (!oldscr || (scr->pcs.dispoffset != oldscr->pcs.dispoffset)) { + vga_6845_write(vh, startadrh, scr->pcs.dispoffset >> 9); + vga_6845_write(vh, startadrl, scr->pcs.dispoffset >> 1); + } - bus_space_copy_2(vc->vc_memt, vc->vc_memh, srcoff, vc->vc_memh, dstoff, - ncols); + bus_space_write_region_2(vh->vh_memt, vh->vh_memh, + scr->pcs.dispoffset, scr->pcs.mem, + type->ncols * type->nrows); + scr->pcs.active = 1; + + vc->active = scr; + + pcdisplay_cursor(&scr->pcs, scr->pcs.cursoron, + scr->pcs.vc_crow, scr->pcs.vc_ccol); + + vc->wantedscreen = 0; + if (vc->switchcb) + (*vc->switchcb)(vc->switchcbarg, 0, 0); +} + +int +vga_load_font(v, cookie, data) + void *v; + void *cookie; + struct wsdisplay_font *data; +{ + struct vga_config *vc = v; + struct vgascreen *scr = cookie; + char *name2; + int res, slot; + struct vgafont *f; + + if (scr) { + name2 = data->name; + while (*name2 && *name2 != ',') + name2++; + if (name2) + *name2++ = '\0'; + res = vga_selectfont(vc, scr, data->name, name2); + if (!res) + vga_setfont(vc, scr); + return (res); + } + + if (data->fontwidth != 8 || data->stride != 1) + return (EINVAL); /* XXX 1 byte per line */ + if (data->firstchar != 0 || data->numchars != 256) + return (EINVAL); +#ifndef WSCONS_SUPPORT_PCVTFONTS + if (data->encoding == WSDISPLAY_FONTENC_PCVT) { + printf("vga: pcvt font support not built in, see vga(4)\n"); + return (EINVAL); + } +#endif + + for (slot = 0; slot < 8; slot++) + if (!vc->vc_fonts[slot]) + break; + if (slot == 8) + return (ENOSPC); + + f = malloc(sizeof(struct vgafont), M_DEVBUF, M_WAITOK); + strncpy(f->name, data->name, sizeof(f->name)); + f->height = data->fontheight; + f->encoding = data->encoding; +#ifdef notyet + f->firstchar = data->firstchar; + f->numchars = data->numchars; +#endif +#ifdef VGAFONTDEBUG + printf("vga: load %s (8x%d, enc %d) font to slot %d\n", f->name, + f->height, f->encoding, slot); +#endif + vga_loadchars(&vc->hdl, slot, 0, 256, f->height, data->data); + f->slot = slot; + vc->vc_fonts[slot] = f; + + return (0); } void -vga_erasecols(id, row, startcol, ncols) - void *id; - int row, startcol, ncols; +vga_scrollback(v, cookie, lines) + void *v; + void *cookie; + int lines; { - struct vga_config *vc = id; - bus_size_t off; - u_int16_t val; + struct vga_config *vc = v; + struct vgascreen *scr = cookie; + struct vga_handle *vh = &vc->hdl; - off = (row * vc->vc_ncol + startcol) * 2; + if (lines == 0) + scr->pcs.visibleoffset = scr->pcs.dispoffset; /* reset */ + else { + int vga_scr_end; + int margin = scr->pcs.type->ncols * 2; + int ul, we, p, st; - val = (vc->vc_at << 8) | ' '; + vga_scr_end = (scr->pcs.dispoffset + scr->pcs.type->ncols * + scr->pcs.type->nrows * 2); + if (scr->vga_rollover > vga_scr_end + margin) { + ul = vga_scr_end; + we = scr->vga_rollover + scr->pcs.type->ncols * 2; + } else { + ul = 0; + we = 0x8000; + } + p = (scr->pcs.visibleoffset - ul + we) % we + lines * + (scr->pcs.type->ncols * 2); + st = (scr->pcs.dispoffset - ul + we) % we; + if (p < margin) + p = 0; + if (p > st - margin) + p = st; + scr->pcs.visibleoffset = (p + ul) % we; + } + + /* update visible position */ + vga_6845_write(vh, startadrh, scr->pcs.visibleoffset >> 9); + vga_6845_write(vh, startadrl, scr->pcs.visibleoffset >> 1); +} - bus_space_set_region_2(vc->vc_memt, vc->vc_memh, off, val, ncols); +int +vga_alloc_attr(id, fg, bg, flags, attrp) + void *id; + int fg, bg; + int flags; + long *attrp; +{ + struct vgascreen *scr = id; + struct vga_config *vc = scr->cfg; + + if (vc->hdl.vh_mono) { + if (flags & WSATTR_WSCOLORS) + return (EINVAL); + if (flags & WSATTR_REVERSE) + *attrp = 0x70; + else + *attrp = 0x07; + if (flags & WSATTR_UNDERLINE) + *attrp |= FG_UNDERLINE; + if (flags & WSATTR_HILIT) + *attrp |= FG_INTENSE; + } else { + if (flags & (WSATTR_UNDERLINE | WSATTR_REVERSE)) + return (EINVAL); + if (flags & WSATTR_WSCOLORS) + *attrp = fgansitopc[fg] | bgansitopc[bg]; + else + *attrp = 7; + if (flags & WSATTR_HILIT) + *attrp += 8; + } + if (flags & WSATTR_BLINK) + *attrp |= FG_BLINK; + return (0); } void @@ -347,39 +985,274 @@ vga_copyrows(id, srcrow, dstrow, nrows) void *id; int srcrow, dstrow, nrows; { - struct vga_config *vc = id; + struct vgascreen *scr = id; + bus_space_tag_t memt = scr->pcs.hdl->ph_memt; + bus_space_handle_t memh = scr->pcs.hdl->ph_memh; + int ncols = scr->pcs.type->ncols; bus_size_t srcoff, dstoff; - srcoff = (srcrow * vc->vc_ncol + 0) * 2; - dstoff = (dstrow * vc->vc_ncol + 0) * 2; + srcoff = srcrow * ncols + 0; + dstoff = dstrow * ncols + 0; + + if (scr->pcs.active) { + if (dstrow == 0 && (srcrow + nrows == scr->pcs.type->nrows)) { +#ifdef PCDISPLAY_SOFTCURSOR + int cursoron = scr->pcs.cursoron; - bus_space_copy_2(vc->vc_memt, vc->vc_memh, srcoff, vc->vc_memh, dstoff, - nrows * vc->vc_ncol); + if (cursoron) + pcdisplay_cursor(&scr->pcs, 0, + scr->pcs.vc_crow, scr->pcs.vc_ccol); +#endif + /* scroll up whole screen */ + if ((scr->pcs.dispoffset + srcrow * ncols * 2) + <= scr->maxdispoffset) { + scr->pcs.dispoffset += srcrow * ncols * 2; + } else { + bus_space_copy_2(memt, memh, + scr->pcs.dispoffset + srcoff * 2, + memh, scr->mindispoffset, + nrows * ncols); + scr->vga_rollover = scr->pcs.dispoffset; + scr->pcs.dispoffset = scr->mindispoffset; + scr->pcs.visibleoffset = scr->pcs.dispoffset; + memt = memt; + memh = memh; + } + vga_6845_write(&scr->cfg->hdl, startadrh, + scr->pcs.dispoffset >> 9); + vga_6845_write(&scr->cfg->hdl, startadrl, + scr->pcs.dispoffset >> 1); +#ifdef PCDISPLAY_SOFTCURSOR + if (cursoron) + pcdisplay_cursor(&scr->pcs, 1, + scr->pcs.vc_crow, scr->pcs.vc_ccol); +#endif + } else { + bus_space_copy_2(memt, memh, + scr->pcs.dispoffset + srcoff * 2, + memh, scr->pcs.dispoffset + dstoff * 2, + nrows * ncols); + } + } else + bcopy(&scr->pcs.mem[srcoff], &scr->pcs.mem[dstoff], + nrows * ncols * 2); } -void -vga_eraserows(id, startrow, nrows) - void *id; - int startrow, nrows; +#ifdef WSCONS_SUPPORT_PCVTFONTS + +#define NOTYET 0xffff +static u_int16_t pcvt_unichars[0xa0] = { +/* 0 */ _e006U, + NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, + NOTYET, + 0x2409, /* SYMBOL FOR HORIZONTAL TABULATION */ + 0x240a, /* SYMBOL FOR LINE FEED */ + 0x240b, /* SYMBOL FOR VERTICAL TABULATION */ + 0x240c, /* SYMBOL FOR FORM FEED */ + 0x240d, /* SYMBOL FOR CARRIAGE RETURN */ + NOTYET, NOTYET, +/* 1 */ NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, + NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, +/* 2 */ NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, + NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, +/* 3 */ NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, + NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, +/* 4 */ 0x03c1, /* GREEK SMALL LETTER RHO */ + 0x03c8, /* GREEK SMALL LETTER PSI */ + 0x2202, /* PARTIAL DIFFERENTIAL */ + 0x03bb, /* GREEK SMALL LETTER LAMDA */ + 0x03b9, /* GREEK SMALL LETTER IOTA */ + 0x03b7, /* GREEK SMALL LETTER ETA */ + 0x03b5, /* GREEK SMALL LETTER EPSILON */ + 0x03c7, /* GREEK SMALL LETTER CHI */ + 0x2228, /* LOGICAL OR */ + 0x2227, /* LOGICAL AND */ + 0x222a, /* UNION */ + 0x2283, /* SUPERSET OF */ + 0x2282, /* SUBSET OF */ + 0x03a5, /* GREEK CAPITAL LETTER UPSILON */ + 0x039e, /* GREEK CAPITAL LETTER XI */ + 0x03a8, /* GREEK CAPITAL LETTER PSI */ +/* 5 */ 0x03a0, /* GREEK CAPITAL LETTER PI */ + 0x21d2, /* RIGHTWARDS DOUBLE ARROW */ + 0x21d4, /* LEFT RIGHT DOUBLE ARROW */ + 0x039b, /* GREEK CAPITAL LETTER LAMDA */ + 0x0398, /* GREEK CAPITAL LETTER THETA */ + 0x2243, /* ASYMPTOTICALLY EQUAL TO */ + 0x2207, /* NABLA */ + 0x2206, /* INCREMENT */ + 0x221d, /* PROPORTIONAL TO */ + 0x2234, /* THEREFORE */ + 0x222b, /* INTEGRAL */ + 0x2215, /* DIVISION SLASH */ + 0x2216, /* SET MINUS */ + _e00eU, + _e00dU, + _e00bU, +/* 6 */ _e00cU, + _e007U, + _e008U, + _e009U, + _e00aU, + 0x221a, /* SQUARE ROOT */ + 0x03c9, /* GREEK SMALL LETTER OMEGA */ + 0x00a5, /* YEN SIGN */ + 0x03be, /* GREEK SMALL LETTER XI */ + 0x00fd, /* LATIN SMALL LETTER Y WITH ACUTE */ + 0x00fe, /* LATIN SMALL LETTER THORN */ + 0x00f0, /* LATIN SMALL LETTER ETH */ + 0x00de, /* LATIN CAPITAL LETTER THORN */ + 0x00dd, /* LATIN CAPITAL LETTER Y WITH ACUTE */ + 0x00d7, /* MULTIPLICATION SIGN */ + 0x00d0, /* LATIN CAPITAL LETTER ETH */ +/* 7 */ 0x00be, /* VULGAR FRACTION THREE QUARTERS */ + 0x00b8, /* CEDILLA */ + 0x00b4, /* ACUTE ACCENT */ + 0x00af, /* MACRON */ + 0x00ae, /* REGISTERED SIGN */ + 0x00ad, /* SOFT HYPHEN */ + 0x00ac, /* NOT SIGN */ + 0x00a8, /* DIAERESIS */ + 0x2260, /* NOT EQUAL TO */ + _e005U, + _e004U, + _e003U, + _e002U, + _e001U, + 0x03c5, /* GREEK SMALL LETTER UPSILON */ + 0x00f8, /* LATIN SMALL LETTER O WITH STROKE */ +/* 8 */ 0x0153, /* LATIN SMALL LIGATURE OE */ + 0x00f5, /* LATIN SMALL LETTER O WITH TILDE !!!doc bug */ + 0x00e3, /* LATIN SMALL LETTER A WITH TILDE */ + 0x0178, /* LATIN CAPITAL LETTER Y WITH DIAERESIS */ + 0x00db, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ + 0x00da, /* LATIN CAPITAL LETTER U WITH ACUTE */ + 0x00d9, /* LATIN CAPITAL LETTER U WITH GRAVE */ + 0x00d8, /* LATIN CAPITAL LETTER O WITH STROKE */ + 0x0152, /* LATIN CAPITAL LIGATURE OE */ + 0x00d5, /* LATIN CAPITAL LETTER O WITH TILDE */ + 0x00d4, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ + 0x00d3, /* LATIN CAPITAL LETTER O WITH ACUTE */ + 0x00d2, /* LATIN CAPITAL LETTER O WITH GRAVE */ + 0x00cf, /* LATIN CAPITAL LETTER I WITH DIAERESIS */ + 0x00ce, /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ + 0x00cd, /* LATIN CAPITAL LETTER I WITH ACUTE */ +/* 9 */ 0x00cc, /* LATIN CAPITAL LETTER I WITH GRAVE */ + 0x00cb, /* LATIN CAPITAL LETTER E WITH DIAERESIS */ + 0x00ca, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ + 0x00c8, /* LATIN CAPITAL LETTER E WITH GRAVE */ + 0x00c3, /* LATIN CAPITAL LETTER A WITH TILDE */ + 0x00c2, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ + 0x00c1, /* LATIN CAPITAL LETTER A WITH ACUTE */ + 0x00c0, /* LATIN CAPITAL LETTER A WITH GRAVE */ + 0x00b9, /* SUPERSCRIPT ONE */ + 0x00b7, /* MIDDLE DOT */ + 0x03b6, /* GREEK SMALL LETTER ZETA */ + 0x00b3, /* SUPERSCRIPT THREE */ + 0x00a9, /* COPYRIGHT SIGN */ + 0x00a4, /* CURRENCY SIGN */ + 0x03ba, /* GREEK SMALL LETTER KAPPA */ + _e000U +}; + +int vga_pcvt_mapchar __P((int, unsigned int *)); + +int +vga_pcvt_mapchar(uni, index) + int uni; + unsigned int *index; { - struct vga_config *vc = id; - bus_size_t off, count; - u_int16_t val; + int i; + + for (i = 0; i < 0xa0; i++) /* 0xa0..0xff are reserved */ + if (uni == pcvt_unichars[i]) { + *index = i; + return (5); + } + *index = 0x99; /* middle dot */ + return (0); +} + +#endif /* WSCONS_SUPPORT_PCVTFONTS */ - off = (startrow * vc->vc_ncol + 0) * 2; - count = nrows * vc->vc_ncol; +int _vga_mapchar __P((void *, struct vgafont *, int, unsigned int *)); - val = (vc->vc_at << 8) | ' '; +int +_vga_mapchar(id, font, uni, index) + void *id; + struct vgafont *font; + int uni; + unsigned int *index; +{ - bus_space_set_region_2(vc->vc_memt, vc->vc_memh, off, val, count); + switch (font->encoding) { + case WSDISPLAY_FONTENC_ISO: + if (uni < 256) { + *index = uni; + return (5); + } else { + *index = ' '; + return (0); + } + break; + case WSDISPLAY_FONTENC_IBM: + return (pcdisplay_mapchar(id, uni, index)); +#ifdef WSCONS_SUPPORT_PCVTFONTS + case WSDISPLAY_FONTENC_PCVT: + return (vga_pcvt_mapchar(uni, index)); +#endif + default: +#ifdef VGAFONTDEBUG + printf("_vga_mapchar: encoding=%d\n", font->encoding); +#endif + *index = ' '; + return (0); + } } -void -vga_set_attr(id, val) +int +vga_mapchar(id, uni, index) void *id; - int val; + int uni; + unsigned int *index; { - struct vga_config *vc = id; + struct vgascreen *scr = id; + unsigned int idx1, idx2; + int res1, res2; - vc->vc_so = val; + res1 = 0; + idx1 = ' '; /* space */ + if (scr->fontset1) + res1 = _vga_mapchar(id, scr->fontset1, uni, &idx1); + res2 = -1; + if (scr->fontset2) { + KASSERT(VGA_SCREEN_CANTWOFONTS(scr->pcs.type)); + res2 = _vga_mapchar(id, scr->fontset2, uni, &idx2); + } + if (res2 > res1) { + *index = idx2 | 0x0800; /* attribute bit 3 */ + return (res2); + } + *index = idx1; + return (res1); } + +static void +vga_putchar(c, row, col, uc, attr) + void *c; + int row; + int col; + u_int uc; + long attr; +{ + struct vgascreen *scr = c; + + if (scr->pcs.visibleoffset != scr->pcs.dispoffset) + vga_scrollback(scr->cfg, scr, 0); + + pcdisplay_putchar(c, row, col, uc, attr); +} + +struct cfdriver vga_cd = { + NULL, "vga", DV_DULL +}; diff --git a/sys/dev/ic/vga_subr.c b/sys/dev/ic/vga_subr.c new file mode 100644 index 00000000000..0ee1e6f6c98 --- /dev/null +++ b/sys/dev/ic/vga_subr.c @@ -0,0 +1,161 @@ +/* $OpenBSD: vga_subr.c,v 1.1 2000/11/15 20:17:38 aaron Exp $ */ +/* $NetBSD: vga_subr.c,v 1.6 2000/01/25 02:44:03 ad Exp $ */ + +/* + * Copyright (c) 1998 + * Matthias Drochner. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project + * by Matthias Drochner. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> +#include <sys/queue.h> +#include <machine/bus.h> + +#include <dev/ic/mc6845reg.h> +#include <dev/ic/pcdisplayvar.h> +#include <dev/ic/vgareg.h> +#include <dev/ic/vgavar.h> + +#include <dev/wscons/wsdisplayvar.h> + +static void fontram __P((struct vga_handle *)); +static void textram __P((struct vga_handle *)); + +static void +fontram(vh) + struct vga_handle *vh; +{ + /* program sequencer to access character generator */ + + vga_ts_write(vh, syncreset, 0x01); /* synchronous reset */ + vga_ts_write(vh, wrplmask, 0x04); /* write to map 2 */ + vga_ts_write(vh, memmode, 0x07); /* sequential addressing */ + vga_ts_write(vh, syncreset, 0x03); /* clear synchronous reset */ + + /* program graphics controller to access character generator */ + + vga_gdc_write(vh, rdplanesel, 0x02); /* select map 2 for cpu reads */ + vga_gdc_write(vh, mode, 0x00); /* disable odd-even addressing */ + vga_gdc_write(vh, misc, 0x04); /* map starts at 0xA000 */ +} + +static void +textram(vh) + struct vga_handle *vh; +{ + /* program sequencer to access video ram */ + + vga_ts_write(vh, syncreset, 0x01); /* synchronous reset */ + vga_ts_write(vh, wrplmask, 0x03); /* write to map 0 & 1 */ + vga_ts_write(vh, memmode, 0x03); /* odd-even addressing */ + vga_ts_write(vh, syncreset, 0x03); /* clear synchronous reset */ + + /* program graphics controller for text mode */ + + vga_gdc_write(vh, rdplanesel, 0x00); /* select map 0 for cpu reads */ + vga_gdc_write(vh, mode, 0x10); /* enable odd-even addressing */ + /* map starts at 0xb800 or 0xb000 (mono) */ + vga_gdc_write(vh, misc, (vh->vh_mono ? 0x0a : 0x0e)); +} + +void +vga_loadchars(vh, fontset, first, num, lpc, data) + struct vga_handle *vh; + int fontset, first, num; + int lpc; + char *data; +{ + int offset, i, j, s; + + /* fontset number swizzle done in vga_setfontset() */ + offset = (fontset << 13) | (first << 5); + + s = splhigh(); + fontram(vh); + + for (i = 0; i < num; i++) + for (j = 0; j < lpc; j++) + bus_space_write_1(vh->vh_memt, vh->vh_allmemh, + offset + (i << 5) + j, + data[i * lpc + j]); + + textram(vh); + splx(s); +} + +void +vga_setfontset(vh, fontset1, fontset2) + struct vga_handle *vh; + int fontset1, fontset2; +{ + u_int8_t cmap; + static u_int8_t cmaptaba[] = { + 0x00, 0x10, 0x01, 0x11, + 0x02, 0x12, 0x03, 0x13 + }; + static u_int8_t cmaptabb[] = { + 0x00, 0x20, 0x04, 0x24, + 0x08, 0x28, 0x0c, 0x2c + }; + + /* extended font if fontset1 != fontset2 */ + cmap = cmaptaba[fontset1] | cmaptabb[fontset2]; + + vga_ts_write(vh, fontsel, cmap); +} + +void +vga_setscreentype(vh, type) + struct vga_handle *vh; + const struct wsscreen_descr *type; +{ + vga_6845_write(vh, maxrow, type->fontheight - 1); + + /* lo byte */ + vga_6845_write(vh, vde, type->fontheight * type->nrows - 1); + +#ifndef PCDISPLAY_SOFTCURSOR + /* set cursor to last 2 lines */ + vga_6845_write(vh, curstart, type->fontheight - 2); + vga_6845_write(vh, curend, type->fontheight - 1); +#endif + /* + * disable colour plane 3 if needed for font selection + */ + if (type->capabilities & WSSCREEN_HILIT) { + /* + * these are the screens which don't support + * 512-character fonts + */ + vga_attr_write(vh, colplen, 0x0f); + } else + vga_attr_write(vh, colplen, 0x07); +} diff --git a/sys/dev/ic/vgareg.h b/sys/dev/ic/vgareg.h new file mode 100644 index 00000000000..216b22ebdb5 --- /dev/null +++ b/sys/dev/ic/vgareg.h @@ -0,0 +1,57 @@ +/* $OpenBSD: vgareg.h,v 1.1 2000/11/15 20:17:38 aaron Exp $ */ +/* $NetBSD: vgareg.h,v 1.2 1998/05/28 16:48:41 drochner Exp $ */ + +/* + * Copyright (c) 1998 + * Matthias Drochner. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project + * by Matthias Drochner. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +struct reg_vgaattr { /* indexed via port 0x3c0 */ + char palette[16]; + char mode, overscan, colplen, horpixpan; + char colreset, misc; +}; +#define VGA_ATC_INDEX 0 +#define VGA_ATC_DATAW 0 +#define VGA_ATC_DATAR 1 + +struct reg_vgats { /* indexed via port 0x3c4 */ + char syncreset, mode, wrplmask, fontsel, memmode; +}; +#define VGA_TS_INDEX 4 +#define VGA_TS_DATA 5 + +struct reg_vgagdc { /* indexed via port 0x3ce */ + char setres, ensetres, colorcomp, rotfunc; + char rdplanesel, mode, misc, colorcare; + char bitmask; +}; +#define VGA_GDC_INDEX 0xe +#define VGA_GDC_DATA 0xf diff --git a/sys/dev/ic/vgavar.h b/sys/dev/ic/vgavar.h index f7e1d58599d..f024ed7c1ff 100644 --- a/sys/dev/ic/vgavar.h +++ b/sys/dev/ic/vgavar.h @@ -1,5 +1,5 @@ -/* $OpenBSD: vgavar.h,v 1.3 1997/11/06 08:11:57 niklas Exp $ */ -/* $NetBSD: vgavar.h,v 1.2 1996/11/23 06:06:43 cgd Exp $ */ +/* $OpenBSD: vgavar.h,v 1.4 2000/11/15 20:17:38 aaron Exp $ */ +/* $NetBSD: vgavar.h,v 1.4 2000/06/17 07:11:50 soda Exp $ */ /* * Copyright (c) 1995, 1996 Carnegie-Mellon University. @@ -28,33 +28,128 @@ * rights to redistribute these changes. */ -struct vga_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; - - /* - * 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)); - +struct vga_handle { + struct pcdisplay_handle vh_ph; + bus_space_handle_t vh_ioh_vga, vh_allmemh; + int vh_mono; }; +#define vh_iot vh_ph.ph_iot +#define vh_memt vh_ph.ph_memt +#define vh_ioh_6845 vh_ph.ph_ioh_6845 +#define vh_memh vh_ph.ph_memh + +static inline u_int8_t _vga_attr_read __P((struct vga_handle *, int)); +static inline void _vga_attr_write __P((struct vga_handle *, int, u_int8_t)); +static inline u_int8_t _vga_ts_read __P((struct vga_handle *, int)); +static inline void _vga_ts_write __P((struct vga_handle *, int, u_int8_t)); +static inline u_int8_t _vga_gdc_read __P((struct vga_handle *, int)); +static inline void _vga_gdc_write __P((struct vga_handle *, int, u_int8_t)); + +static inline u_int8_t _vga_attr_read(vh, reg) + struct vga_handle *vh; + int reg; +{ + u_int8_t res; + + /* reset state */ + (void) bus_space_read_1(vh->vh_iot, vh->vh_ioh_6845, 10); + + bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_ATC_INDEX, reg); + res = bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, VGA_ATC_DATAR); + + /* reset state XXX unneeded? */ + (void) bus_space_read_1(vh->vh_iot, vh->vh_ioh_6845, 10); + + /* enable */ + bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, 0, 0x20); + + return (res); +} + +static inline void _vga_attr_write(vh, reg, val) + struct vga_handle *vh; + int reg; + u_int8_t val; +{ + /* reset state */ + (void) bus_space_read_1(vh->vh_iot, vh->vh_ioh_6845, 10); + + bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_ATC_INDEX, reg); + bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_ATC_DATAW, val); + + /* reset state XXX unneeded? */ + (void) bus_space_read_1(vh->vh_iot, vh->vh_ioh_6845, 10); + + /* enable */ + bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, 0, 0x20); +} + +static inline u_int8_t _vga_ts_read(vh, reg) + struct vga_handle *vh; + int reg; +{ + bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_TS_INDEX, reg); + return (bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, VGA_TS_DATA)); +} + +static inline void _vga_ts_write(vh, reg, val) + struct vga_handle *vh; + int reg; + u_int8_t val; +{ + bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_TS_INDEX, reg); + bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_TS_DATA, val); +} + +static inline u_int8_t _vga_gdc_read(vh, reg) + struct vga_handle *vh; + int reg; +{ + bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_GDC_INDEX, reg); + return (bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, VGA_GDC_DATA)); +} + +static inline void _vga_gdc_write(vh, reg, val) + struct vga_handle *vh; + int reg; + u_int8_t val; +{ + bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_GDC_INDEX, reg); + bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_GDC_DATA, val); +} + +#define vga_attr_read(vh, reg) \ + _vga_attr_read(vh, offsetof(struct reg_vgaattr, reg)) +#define vga_attr_write(vh, reg, val) \ + _vga_attr_write(vh, offsetof(struct reg_vgaattr, reg), val) +#define vga_ts_read(vh, reg) \ + _vga_ts_read(vh, offsetof(struct reg_vgats, reg)) +#define vga_ts_write(vh, reg, val) \ + _vga_ts_write(vh, offsetof(struct reg_vgats, reg), val) +#define vga_gdc_read(vh, reg) \ + _vga_gdc_read(vh, offsetof(struct reg_vgagdc, reg)) +#define vga_gdc_write(vh, reg, val) \ + _vga_gdc_write(vh, offsetof(struct reg_vgagdc, reg), val) + +#define vga_6845_read(vh, reg) \ + pcdisplay_6845_read(&(vh)->vh_ph, reg) +#define vga_6845_write(vh, reg, val) \ + pcdisplay_6845_write(&(vh)->vh_ph, reg, val) int vga_common_probe __P((bus_space_tag_t, bus_space_tag_t)); -void vga_common_setup __P((bus_space_tag_t, bus_space_tag_t, - struct vga_config *)); -void vga_wscons_attach __P((struct device *, struct vga_config *, int)); -void vga_wscons_console __P((struct vga_config *)); -int vgaioctl __P((void *, u_long, caddr_t, int, struct proc *)); -int vgammap __P((void *, off_t, int)); +void vga_common_attach __P((struct device *, bus_space_tag_t, + bus_space_tag_t, int)); +#ifdef arc +void vga_extended_attach __P((struct device *, bus_space_tag_t, + bus_space_tag_t, int, + int (*) __P((void *, off_t, int)))); +#endif +int vga_is_console __P((bus_space_tag_t, int)); + +int vga_cnattach __P((bus_space_tag_t, bus_space_tag_t, int, int)); + +struct wsscreen_descr; +void vga_loadchars __P((struct vga_handle *, int, int, int, int, char *)); +void vga_setfontset __P((struct vga_handle *, int, int)); +void vga_setscreentype __P((struct vga_handle *, + const struct wsscreen_descr *)); diff --git a/sys/dev/isa/vga_isa.c b/sys/dev/isa/vga_isa.c index 3e4b6973cfb..67b1d1cc9c1 100644 --- a/sys/dev/isa/vga_isa.c +++ b/sys/dev/isa/vga_isa.c @@ -1,5 +1,5 @@ -/* $OpenBSD: vga_isa.c,v 1.6 1997/11/06 12:26:55 niklas Exp $ */ -/* $NetBSD: vga_isa.c,v 1.4 1996/12/05 01:39:32 cgd Exp $ */ +/* $OpenBSD: vga_isa.c,v 1.7 2000/11/15 20:17:38 aaron Exp $ */ +/* $NetBSD: vga_isa.c,v 1.3 1998/06/12 18:45:48 drochner Exp $ */ /* * Copyright (c) 1995, 1996 Carnegie-Mellon University. @@ -34,71 +34,56 @@ #include <sys/device.h> #include <sys/malloc.h> -#include <machine/autoconf.h> -#include <machine/pte.h> - #include <dev/isa/isavar.h> + +#include <dev/ic/mc6845reg.h> +#include <dev/ic/pcdisplayvar.h> +#include <dev/ic/vgareg.h> #include <dev/ic/vgavar.h> #include <dev/isa/vga_isavar.h> +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wsdisplayvar.h> + struct vga_isa_softc { struct device sc_dev; - - struct vga_config *sc_vc; /* VGA configuration */ +#if 0 + struct vga_config *sc_vc; /* VGA configuration */ +#endif }; -#ifdef __BROKEN_INDIRECT_CONFIG int vga_isa_match __P((struct device *, void *, void *)); -#else -int vga_isa_match __P((struct device *, struct cfdata *, void *)); -#endif void vga_isa_attach __P((struct device *, struct device *, void *)); -int vgaisammap __P((void *, off_t, int)); -int vgaisaioctl __P((void *, u_long, caddr_t, int, struct proc *)); - struct cfattach vga_isa_ca = { sizeof(struct vga_isa_softc), vga_isa_match, vga_isa_attach, }; -int vga_isa_console_tag; /* really just a boolean. */ -struct vga_config vga_isa_console_vc; - int vga_isa_match(parent, match, aux) struct device *parent; -#ifdef __BROKEN_INDIRECT_CONFIG void *match; -#else - struct cfdata *match; -#endif void *aux; { struct isa_attach_args *ia = aux; - int rv; - static int matched; - - /* There can be only one. */ - if (matched) - return (0); /* If values are hardwired to something that they can't be, punt. */ - if (ia->ia_iobase != IOBASEUNK || /* ia->ia_iosize != 0 || XXX isa.c */ - (ia->ia_maddr != MADDRUNK && ia->ia_maddr != 0xb8000) || - (ia->ia_msize != 0 && ia->ia_msize != 0x8000) || + if ((ia->ia_iobase != IOBASEUNK && ia->ia_iobase != 0x3b0) || + /* ia->ia_iosize != 0 || XXX isa.c */ + (ia->ia_maddr != MADDRUNK && ia->ia_maddr != 0xa0000) || + (ia->ia_msize != 0 && ia->ia_msize != 0x20000) || ia->ia_irq != IRQUNK || ia->ia_drq != DRQUNK) return (0); - rv = vga_isa_console_tag || vga_common_probe(ia->ia_iot, ia->ia_memt); + if (!vga_is_console(ia->ia_iot, WSDISPLAY_TYPE_ISAVGA) && + !vga_common_probe(ia->ia_iot, ia->ia_memt)) + return (0); - if (rv) { - ia->ia_iobase = 0x3b0; - ia->ia_iosize = 0x30; - ia->ia_maddr = 0xb8000; - ia->ia_msize = 0x8000; - matched = 1; - } - return (rv); + ia->ia_iobase = 0x3b0; /* XXX mono 0x3b0 color 0x3c0 */ + ia->ia_iosize = 0x30; /* XXX 0x20 */ + ia->ia_maddr = 0xa0000; + ia->ia_msize = 0x20000; + return (2); /* more than generic pcdisplay */ } void @@ -107,71 +92,19 @@ vga_isa_attach(parent, self, aux) void *aux; { struct isa_attach_args *ia = aux; +#if 0 struct vga_isa_softc *sc = (struct vga_isa_softc *)self; - struct vga_config *vc; - int console; - - console = vga_isa_console_tag; - if (console) - vc = sc->sc_vc = &vga_isa_console_vc; - else { - vc = sc->sc_vc = (struct vga_config *) - malloc(sizeof(struct vga_config), M_DEVBUF, M_WAITOK); - - /* set up bus-independent VGA configuration */ - vga_common_setup(ia->ia_iot, ia->ia_memt, vc); - } - vc->vc_mmap = vgaisammap; - vc->vc_ioctl = vgaisaioctl; +#endif printf("\n"); - vga_wscons_attach(self, vc, console); + vga_common_attach(self, ia->ia_iot, ia->ia_memt, + WSDISPLAY_TYPE_ISAVGA); } int -vga_isa_console_match(iot, memt) +vga_isa_cnattach(iot, memt) bus_space_tag_t iot, memt; { - - return (vga_common_probe(iot, memt)); -} - -void -vga_isa_console_attach(iot, memt) - bus_space_tag_t iot, memt; -{ - struct vga_config *vc = &vga_isa_console_vc; - - /* for later recognition */ - vga_isa_console_tag = 1; - - /* set up bus-independent VGA configuration */ - vga_common_setup(iot, memt, vc); - - vga_wscons_console(vc); -} - -int -vgaisaioctl(v, cmd, data, flag, p) - void *v; - u_long cmd; - caddr_t data; - int flag; - struct proc *p; -{ - struct vga_isa_softc *sc = v; - - return (vgaioctl(sc->sc_vc, cmd, data, flag, p)); -} - -int -vgaisammap(v, offset, prot) - void *v; - off_t offset; - int prot; -{ - struct vga_isa_softc *sc = v; - - return (vgammap(sc->sc_vc, offset, prot)); + return (vga_cnattach(iot, memt, WSDISPLAY_TYPE_ISAVGA, 1)); } diff --git a/sys/dev/isa/vga_isavar.h b/sys/dev/isa/vga_isavar.h index 0b752a0566a..5eabb16ad61 100644 --- a/sys/dev/isa/vga_isavar.h +++ b/sys/dev/isa/vga_isavar.h @@ -1,5 +1,5 @@ -/* $OpenBSD: vga_isavar.h,v 1.2 1997/11/06 12:26:55 niklas Exp $ */ -/* $NetBSD: vga_isavar.h,v 1.2 1996/11/23 06:06:45 cgd Exp $ */ +/* $OpenBSD: vga_isavar.h,v 1.3 2000/11/15 20:17:38 aaron Exp $ */ +/* $NetBSD: vga_isavar.h,v 1.1 1998/03/22 15:14:36 drochner Exp $ */ /* * Copyright (c) 1996 Carnegie-Mellon University. @@ -28,5 +28,4 @@ * rights to redistribute these changes. */ -int vga_isa_console_match __P((bus_space_tag_t, bus_space_tag_t)); -void vga_isa_console_attach __P((bus_space_tag_t, bus_space_tag_t)); +int vga_isa_cnattach __P((bus_space_tag_t, bus_space_tag_t)); diff --git a/sys/dev/pci/vga_pci.c b/sys/dev/pci/vga_pci.c index 33f88528697..9b68e49d45f 100644 --- a/sys/dev/pci/vga_pci.c +++ b/sys/dev/pci/vga_pci.c @@ -1,5 +1,5 @@ -/* $OpenBSD: vga_pci.c,v 1.7 1998/01/05 13:35:27 deraadt Exp $ */ -/* $NetBSD: vga_pci.c,v 1.4 1996/12/05 01:39:38 cgd Exp $ */ +/* $OpenBSD: vga_pci.c,v 1.8 2000/11/15 20:17:38 aaron Exp $ */ +/* $NetBSD: vga_pci.c,v 1.3 1998/06/08 06:55:58 thorpej Exp $ */ /* * Copyright (c) 1995, 1996 Carnegie-Mellon University. @@ -34,50 +34,39 @@ #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/ic/mc6845reg.h> +#include <dev/ic/pcdisplayvar.h> +#include <dev/ic/vgareg.h> #include <dev/ic/vgavar.h> #include <dev/pci/vga_pcivar.h> +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wsdisplayvar.h> + struct vga_pci_softc { struct device sc_dev; pcitag_t sc_pcitag; /* PCI tag, in case we need it. */ - struct vga_config *sc_vc; /* VGA configuration */ +#if 0 + struct vga_config *sc_vc; /* VGA configuration */ +#endif }; -#ifdef __BROKEN_INDIRECT_CONFIG int vga_pci_match __P((struct device *, void *, void *)); -#else -int vga_pci_match __P((struct device *, struct cfdata *, void *)); -#endif void vga_pci_attach __P((struct device *, struct device *, void *)); -int vgapcimmap __P((void *, off_t, int)); -int vgapciioctl __P((void *, u_long, caddr_t, int, struct proc *)); - struct cfattach vga_pci_ca = { - sizeof(struct vga_pci_softc), (cfmatch_t)vga_pci_match, vga_pci_attach, + sizeof(struct vga_pci_softc), vga_pci_match, vga_pci_attach, }; -pcitag_t vga_pci_console_tag; -struct vga_config vga_pci_console_vc; - int vga_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; @@ -99,8 +88,14 @@ vga_pci_match(parent, match, aux) if (!potential) return (0); + /* check whether it is disabled by firmware */ + if ((pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) + & (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) + != (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) + return (0); + /* If it's the console, we have a winner! */ - if (!bcmp(&pa->pa_tag, &vga_pci_console_tag, sizeof(pa->pa_tag))) + if (vga_is_console(pa->pa_iot, WSDISPLAY_TYPE_PCIVGA)) return (1); /* @@ -119,66 +114,23 @@ vga_pci_attach(parent, self, aux) { struct pci_attach_args *pa = aux; struct vga_pci_softc *sc = (struct vga_pci_softc *)self; - struct vga_config *vc; - int console; - - console = (!bcmp(&pa->pa_tag, &vga_pci_console_tag, sizeof(pa->pa_tag))); - if (console) - vc = sc->sc_vc = &vga_pci_console_vc; - else { - vc = sc->sc_vc = (struct vga_config *) - malloc(sizeof(struct vga_config), M_DEVBUF, M_WAITOK); - - /* set up bus-independent VGA configuration */ - vga_common_setup(pa->pa_iot, pa->pa_memt, vc); - } - vc->vc_mmap = vgapcimmap; - vc->vc_ioctl = vgapciioctl; + char devinfo[256]; sc->sc_pcitag = pa->pa_tag; - printf("\n"); + pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo); + printf(": %s (rev. 0x%02x)\n", devinfo, + PCI_REVISION(pa->pa_class)); - vga_wscons_attach(self, vc, console); + vga_common_attach(self, pa->pa_iot, pa->pa_memt, + WSDISPLAY_TYPE_PCIVGA); } -void -vga_pci_console(iot, memt, pc, bus, device, function) +int +vga_pci_cnattach(iot, memt, pc, bus, device, function) bus_space_tag_t iot, memt; pci_chipset_tag_t pc; int bus, device, function; { - struct vga_config *vc = &vga_pci_console_vc; - - /* for later recognition */ - vga_pci_console_tag = pci_make_tag(pc, bus, device, function); - - /* set up bus-independent VGA configuration */ - vga_common_setup(iot, memt, vc); - - vga_wscons_console(vc); -} - -int -vgapciioctl(v, cmd, data, flag, p) - void *v; - u_long cmd; - caddr_t data; - int flag; - struct proc *p; -{ - struct vga_pci_softc *sc = v; - - return (vgaioctl(sc->sc_vc, cmd, data, flag, p)); -} - -int -vgapcimmap(v, offset, prot) - void *v; - off_t offset; - int prot; -{ - struct vga_pci_softc *sc = v; - - return (vgammap(sc->sc_vc, offset, prot)); + return (vga_cnattach(iot, memt, WSDISPLAY_TYPE_PCIVGA, 0)); } diff --git a/sys/dev/pci/vga_pcivar.h b/sys/dev/pci/vga_pcivar.h index cc9d50295a8..6e968d5f1c9 100644 --- a/sys/dev/pci/vga_pcivar.h +++ b/sys/dev/pci/vga_pcivar.h @@ -1,5 +1,5 @@ -/* $OpenBSD: vga_pcivar.h,v 1.2 1997/11/06 12:26:56 niklas Exp $ */ -/* $NetBSD: vga_pcivar.h,v 1.1 1996/11/19 04:38:36 cgd Exp $ */ +/* $OpenBSD: vga_pcivar.h,v 1.3 2000/11/15 20:17:38 aaron Exp $ */ +/* $NetBSD: vga_pcivar.h,v 1.1 1998/03/22 15:16:19 drochner Exp $ */ /* * Copyright (c) 1995, 1996 Carnegie-Mellon University. @@ -34,5 +34,5 @@ (PCI_CLASS(class) == PCI_CLASS_PREHISTORIC && \ PCI_SUBCLASS(class) == PCI_SUBCLASS_PREHISTORIC_VGA)) ? 1 : 0) -void vga_pci_console __P((bus_space_tag_t, bus_space_tag_t, - pci_chipset_tag_t, int, int, int)); +int vga_pci_cnattach __P((bus_space_tag_t, bus_space_tag_t, + pci_chipset_tag_t, int, int, int)); |