summaryrefslogtreecommitdiff
path: root/sys/arch/alpha/pci/pcivga.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/alpha/pci/pcivga.c')
-rw-r--r--sys/arch/alpha/pci/pcivga.c354
1 files changed, 206 insertions, 148 deletions
diff --git a/sys/arch/alpha/pci/pcivga.c b/sys/arch/alpha/pci/pcivga.c
index 5f62ab3fa73..96c3cfdadf9 100644
--- a/sys/arch/alpha/pci/pcivga.c
+++ b/sys/arch/alpha/pci/pcivga.c
@@ -1,7 +1,7 @@
-/* $NetBSD: pcivga.c,v 1.4 1995/12/24 02:29:47 mycroft Exp $ */
+/* $NetBSD: pcivga.c,v 1.8 1996/04/17 21:49:58 cgd Exp $ */
/*
- * Copyright (c) 1995 Carnegie-Mellon University.
+ * Copyright (c) 1995, 1996 Carnegie-Mellon University.
* All rights reserved.
*
* Author: Chris G. Demetriou
@@ -36,39 +36,41 @@
#include <machine/autoconf.h>
#include <machine/pte.h>
-#include <dev/pseudo/ansicons.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
#include <alpha/pci/pcivgavar.h>
-#include <alpha/pci/wsconsvar.h>
+#include <alpha/wscons/wsconsvar.h>
+
+#define PCIVGA_6845_ADDR 0x24
+#define PCIVGA_6845_DATA 0x25
int pcivgamatch __P((struct device *, void *, void *));
void pcivgaattach __P((struct device *, struct device *, void *));
+int pcivgaprint __P((void *, char *));
+
+struct cfattach pcivga_ca = {
+ sizeof(struct pcivga_softc), pcivgamatch, pcivgaattach,
+};
-struct cfdriver pcivgacd = {
- NULL, "pcivga", pcivgamatch, pcivgaattach, DV_DULL,
- sizeof(struct pcivga_softc)
+struct cfdriver pcivga_cd = {
+ NULL, "pcivga", DV_DULL,
};
-void pcivga_getdevconfig __P((__const struct pci_conf_fns *, void *,
- __const struct pci_mem_fns *, void *,
- __const struct pci_pio_fns *, void *,
- pci_conftag_t tag, struct pcivga_devconfig *dc));
+void pcivga_getdevconfig __P((bus_chipset_tag_t, pci_chipset_tag_t,
+ pcitag_t, struct pcivga_devconfig *dc));
struct pcivga_devconfig pcivga_console_dc;
-void pcivga_cursor __P((void *, int, int));
+void pcivga_cursor __P((void *, int, int, int));
void pcivga_putstr __P((void *, int, int, char *, int));
void pcivga_copycols __P((void *, int, int, int,int));
void pcivga_erasecols __P((void *, int, int, int));
void pcivga_copyrows __P((void *, int, int, int));
void pcivga_eraserows __P((void *, int, int));
-void pcivga_bell __P((void *)); /* XXX */
-struct ansicons_functions pcivga_acf = {
- pcivga_bell,
+struct wscons_emulfuncs pcivga_emulfuncs = {
pcivga_cursor,
pcivga_putstr,
pcivga_copycols,
@@ -77,7 +79,9 @@ struct ansicons_functions pcivga_acf = {
pcivga_eraserows,
};
-#define PCIVGAUNIT(dev) minor(dev)
+int pcivgaioctl __P((struct device *, u_long, caddr_t, int,
+ struct proc *));
+int pcivgammap __P((struct device *, off_t, int));
int
pcivgamatch(parent, match, aux)
@@ -85,55 +89,71 @@ pcivgamatch(parent, match, aux)
void *match, *aux;
{
struct cfdata *cf = match;
- struct pcidev_attach_args *pda = aux;
+ struct pci_attach_args *pa = aux;
/*
* If it's prehistoric/vga or display/vga, we match.
*/
- if (PCI_CLASS(pda->pda_class) == PCI_CLASS_PREHISTORIC &&
- PCI_SUBCLASS(pda->pda_class) == PCI_SUBCLASS_PREHISTORIC_VGA)
+ if (PCI_CLASS(pa->pa_class) == PCI_CLASS_PREHISTORIC &&
+ PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_PREHISTORIC_VGA)
return (1);
- if (PCI_CLASS(pda->pda_class) == PCI_CLASS_DISPLAY &&
- PCI_SUBCLASS(pda->pda_class) == PCI_SUBCLASS_DISPLAY_VGA)
+ if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY &&
+ PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA)
return (1);
return (0);
}
void
-pcivga_getdevconfig(pcf, pcfa, pmf, pmfa, ppf, ppfa, tag, dc)
- __const struct pci_conf_fns *pcf;
- __const struct pci_mem_fns *pmf;
- __const struct pci_pio_fns *ppf;
- void *pcfa, *pmfa, *ppfa;
- pci_conftag_t tag;
+pcivga_getdevconfig(bc, pc, tag, dc)
+ bus_chipset_tag_t bc;
+ pci_chipset_tag_t pc;
+ pcitag_t tag;
struct pcivga_devconfig *dc;
{
+ bus_io_handle_t ioh;
+ int cpos;
- dc->dc_pcf = pcf;
- dc->dc_pcfa = pcfa;
- dc->dc_pmf = pmf;
- dc->dc_pmfa = pmfa;
- dc->dc_ppf = ppf;
- dc->dc_ppfa = ppfa;
+ dc->dc_bc = bc;
+ dc->dc_pc = pc;
dc->dc_pcitag = tag;
/* XXX deal with mapping foo */
- /* XXX */
- dc->dc_crtat = (u_short *)PCI_MEM_MAP(pmf, pmfa, 0xb8000, 0x8000, 1);
- dc->dc_iobase = 0x3d4; /* XXX */
+ if (bus_mem_map(bc, 0xb8000, 0x8000, 0, &dc->dc_memh))
+ panic("pcivga_getdevconfig: couldn't map memory");
+ if (bus_io_map(bc, 0x3b0, 0x30, &ioh))
+ panic("pcivga_getdevconfig: couldn't map io");
+ dc->dc_ioh = ioh;
dc->dc_nrow = 25;
dc->dc_ncol = 80;
+
dc->dc_ccol = dc->dc_crow = 0;
+ bus_io_write_1(bc, ioh, PCIVGA_6845_ADDR, 14);
+ cpos = bus_io_read_1(bc, ioh, PCIVGA_6845_DATA) << 8;
+ bus_io_write_1(bc, ioh, PCIVGA_6845_ADDR, 15);
+ cpos |= bus_io_read_1(bc, ioh, PCIVGA_6845_DATA);
+
+ dc->dc_crow = cpos / dc->dc_ncol;
+ dc->dc_ccol = cpos % dc->dc_ncol;
+
dc->dc_so = 0;
+#if 0
dc->dc_at = 0x00 | 0xf; /* black bg | white fg */
dc->dc_so_at = 0x00 | 0xf | 0x80; /* black bg | white fg | blink */
/* clear screen, frob cursor, etc.? */
pcivga_eraserows(dc, 0, dc->dc_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!
+ */
+ dc->dc_at = 0x40 | 0x0f; /* blue bg | white fg */
+ dc->dc_so_at = 0x40 | 0x0f | 0x80; /* blue bg | white fg | blink */
}
void
@@ -141,29 +161,26 @@ pcivgaattach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
- struct pcidev_attach_args *pda = aux;
+ struct pci_attach_args *pa = aux;
struct pcivga_softc *sc = (struct pcivga_softc *)self;
+ struct wscons_attach_args waa;
+ struct wscons_odev_spec *wo;
char devinfo[256];
int console;
- console = (pda->pda_tag == pcivga_console_dc.dc_pcitag);
+ console = (pa->pa_tag == pcivga_console_dc.dc_pcitag);
if (console)
sc->sc_dc = &pcivga_console_dc;
else {
sc->sc_dc = (struct pcivga_devconfig *)
malloc(sizeof(struct pcivga_devconfig), M_DEVBUF, M_WAITOK);
- pcivga_getdevconfig(pda->pda_conffns, pda->pda_confarg,
- pda->pda_memfns, pda->pda_memarg, pda->pda_piofns,
- pda->pda_memarg, pda->pda_tag, sc->sc_dc);
- }
- if (sc->sc_dc->dc_crtat == NULL) {
- printf(": couldn't map memory space; punt!\n");
- return;
+ pcivga_getdevconfig(pa->pa_bc, pa->pa_pc, pa->pa_tag,
+ sc->sc_dc);
}
- pci_devinfo(pda->pda_id, pda->pda_class, 0, devinfo);
+ pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo);
printf(": %s (rev. 0x%02x)\n", devinfo,
- PCI_REVISION(pda->pda_class));
+ PCI_REVISION(pa->pa_class));
#if 0
if (sc->sc_dc->dc_tgaconf == NULL) {
@@ -180,94 +197,120 @@ pcivgaattach(parent, self, aux)
#if 0
pci_intrdata = pci_conf_read(sc->sc_pcitag, PCI_INTERRUPT_REG);
if (PCI_INTERRUPT_PIN(pci_intrdata) != PCI_INTERRUPT_PIN_NONE) {
- sc->sc_intr = pci_map_int(sc->sc_pcitag, IPL_TTY, tgaintr, sc,
- sc->sc_dev.dv_xname);
+ sc->sc_intr = pci_map_int(sc->sc_pcitag, IPL_TTY, tgaintr, sc);
if (sc->sc_intr == NULL)
printf("%s: WARNING: couldn't map interrupt\n",
sc->sc_dev.dv_xname);
}
#endif
- if (!wscattach_output(self, console, &sc->sc_dc->dc_ansicons,
- &pcivga_acf, sc->sc_dc, sc->sc_dc->dc_nrow, sc->sc_dc->dc_ncol,
- 0, 0)) {
- panic("pcivgaattach: wscattach failed");
- /* NOTREACHED */
- }
+ waa.waa_isconsole = console;
+ wo = &waa.waa_odev_spec;
+ wo->wo_ef = &pcivga_emulfuncs;
+ wo->wo_efa = sc->sc_dc;
+ wo->wo_nrows = sc->sc_dc->dc_nrow;
+ wo->wo_ncols = sc->sc_dc->dc_ncol;
+ wo->wo_crow = sc->sc_dc->dc_crow;
+ wo->wo_ccol = sc->sc_dc->dc_ccol;
+ wo->wo_ioctl = pcivgaioctl;
+ wo->wo_mmap = pcivgammap;
+
+ config_found(self, &waa, pcivgaprint);
}
-#if 0
int
-tgammap(dev, offset, nprot)
- dev_t dev;
- int offset;
- int nprot;
+pcivgaprint(aux, pnp)
+ void *aux;
+ char *pnp;
{
- struct pcivga_softc *sc = pcivgacd.cd_devs[TGAUNIT(dev)];
- if (offset > sc->sc_dc->dc_pcivgaconf->pcivgac_cspace_size)
- return -1;
- return alpha_btop(sc->sc_dc->dc_paddr + offset);
+ if (pnp)
+ printf("wscons at %s", pnp);
+ return (UNCONF);
}
+
+int
+pcivgaioctl(dev, cmd, data, flag, p)
+ struct device *dev;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+
+ return -1; /* XXX */
+}
+
+int
+pcivgammap(dev, offset, prot)
+ struct device *dev;
+ off_t offset;
+ int prot;
+{
+ struct pcivga_softc *sc = (struct pcivga_softc *)dev;
+ int rv;
+
+ rv = -1;
+#if 0 /* XXX */
+ if (offset >= 0 && offset < 0x100000) { /* 1MB */
+ /* Deal with mapping the VGA memory */
+ if (offset >= 0xb8000 && offset < 0xc0000) {
+ offset -= 0xb8000;
+ rv = alpha_btop(k0segtophys(sc->sc_dc->dc_crtat) +
+ offset);
+ }
+ } else {
+ /* XXX should do something with PCI memory */
+ rv = -1;
+ }
#endif
+ return rv;
+}
void
-pcivga_console(pcf, pcfa, pmf, pmfa, ppf, ppfa, bus, device, function)
- __const struct pci_conf_fns *pcf;
- __const struct pci_mem_fns *pmf;
- __const struct pci_pio_fns *ppf;
- void *pcfa, *pmfa, *ppfa;
- pci_bus_t bus;
- pci_device_t device;
- pci_function_t function;
+pcivga_console(bc, pc, bus, device, function)
+ bus_chipset_tag_t bc;
+ pci_chipset_tag_t pc;
+ int bus, device, function;
{
struct pcivga_devconfig *dcp = &pcivga_console_dc;
+ struct wscons_odev_spec wo;
- pcivga_getdevconfig(pcf, pcfa, pmf, pmfa, ppf, ppfa,
- PCI_MAKE_TAG(bus, device, function), dcp);
+ pcivga_getdevconfig(bc, pc,
+ pci_make_tag(pc, bus, device, function), dcp);
- /* sanity checks */
- if (dcp->dc_crtat == NULL)
- panic("pcivga_console(%d, %d): couldn't map memory space",
- device, function);
-#if 0
- if (dcp->dc_pcivgaconf == NULL)
- panic("pcivga_console(%d, %d): unknown board configuration",
- device, function);
-#endif
+ wo.wo_ef = &pcivga_emulfuncs;
+ wo.wo_efa = dcp;
+ wo.wo_nrows = dcp->dc_nrow;
+ wo.wo_ncols = dcp->dc_ncol;
+ wo.wo_crow = dcp->dc_crow;
+ wo.wo_ccol = dcp->dc_ccol;
+ /* ioctl and mmap are unused until real attachment. */
- wsc_console(&dcp->dc_ansicons, &pcivga_acf, dcp,
- dcp->dc_nrow, dcp->dc_ncol, 0, 0);
+ wscons_attach_console(&wo);
}
/*
* The following functions implement the MI ANSI terminal emulation on
* a VGA display.
*/
-void /* XXX */
-pcivga_bell(id) /* XXX */
- void *id; /* XXX */
-{ /* XXX */
- /* XXX */
- printf("pcivga_bell: unimplemented\n"); /* XXX */
-} /* XXX */
-
void
-pcivga_cursor(id, row, col)
+pcivga_cursor(id, on, row, col)
void *id;
- int row, col;
+ int on, row, col;
{
struct pcivga_devconfig *dc = id;
+ bus_chipset_tag_t bc = dc->dc_bc;
+ bus_io_handle_t ioh = dc->dc_ioh;
int pos;
#if 0
printf("pcivga_cursor: %d %d\n", row, col);
#endif
/* turn the cursor off */
- if (row == -1 || col == -1) {
- dc->dc_crow = dc->dc_ccol = PCIVGA_CURSOR_OFF;
-
- /* XXX disable cursor??? */
+ if (!on) {
+ /* XXX disable cursor how??? */
+ dc->dc_crow = dc->dc_ccol = -1;
} else {
dc->dc_crow = row;
dc->dc_ccol = col;
@@ -275,10 +318,10 @@ pcivga_cursor(id, row, col)
pos = row * dc->dc_ncol + col;
- OUTB(dc->dc_ppf, dc->dc_ppfa, dc->dc_iobase, 14);
- OUTB(dc->dc_ppf, dc->dc_ppfa, dc->dc_iobase+1, pos >> 8);
- OUTB(dc->dc_ppf, dc->dc_ppfa, dc->dc_iobase, 15);
- OUTB(dc->dc_ppf, dc->dc_ppfa, dc->dc_iobase+1, pos);
+ bus_io_write_1(bc, ioh, PCIVGA_6845_ADDR, 14);
+ bus_io_write_1(bc, ioh, PCIVGA_6845_DATA, pos >> 8);
+ bus_io_write_1(bc, ioh, PCIVGA_6845_ADDR, 15);
+ bus_io_write_1(bc, ioh, PCIVGA_6845_DATA, pos);
}
void
@@ -289,20 +332,16 @@ pcivga_putstr(id, row, col, cp, len)
int len;
{
struct pcivga_devconfig *dc = id;
+ bus_chipset_tag_t bc = dc->dc_bc;
+ bus_mem_handle_t memh = dc->dc_memh;
char *dcp;
- int i;
+ int i, off;
- for (i = 0; i < len; i++, cp++) {
- dcp = (char *)&dc->dc_crtat[row * dc->dc_ncol + col];
-#if 0
-printf("*cp = %c, attr = 0x%x\n", *cp, dc->dc_so ? dc->dc_so_at : dc->dc_at);
-printf("was: %c/", *dcp);
-#endif
- *dcp++ = *cp;
-#if 0
-printf("0x%x\n", *dcp);
-#endif
- *dcp++ = dc->dc_so ? dc->dc_so_at : dc->dc_at;
+ off = (row * dc->dc_ncol + col) * 2;
+ for (i = 0; i < len; i++, cp++, off += 2) {
+ bus_mem_write_1(bc, memh, off, *cp);
+ bus_mem_write_1(bc, memh, off + 1,
+ dc->dc_so ? dc->dc_so_at : dc->dc_at);
}
}
@@ -312,16 +351,20 @@ pcivga_copycols(id, row, srccol, dstcol, ncols)
int row, srccol, dstcol, ncols;
{
struct pcivga_devconfig *dc = id;
- u_short *ssp, *dsp;
- int nclr;
+ bus_chipset_tag_t bc = dc->dc_bc;
+ bus_mem_handle_t memh = dc->dc_memh;
+ bus_mem_size_t srcoff, srcend, dstoff;
-#if 0
- printf("pcivga_copycols: row %d: %d, %d -> %d\n", row, srccol, ncols,
- dstcol);
-#endif
- ssp = &dc->dc_crtat[row * dc->dc_ncol + srccol];
- dsp = &dc->dc_crtat[row * dc->dc_ncol + dstcol];
- bcopy(ssp, dsp, ncols * sizeof(u_short));
+ /*
+ * YUCK. Need bus copy functions.
+ */
+ srcoff = (row * dc->dc_ncol + srccol) * 2;
+ srcend = srcoff + ncols * 2;
+ dstoff = (row * dc->dc_ncol + dstcol) * 2;
+
+ for (; srcoff < srcend; srcoff += 2, dstoff += 2)
+ bus_mem_write_2(bc, memh, dstoff,
+ bus_mem_read_2(bc, memh, srcoff));
}
void
@@ -330,15 +373,20 @@ pcivga_erasecols(id, row, startcol, ncols)
int row, startcol, ncols;
{
struct pcivga_devconfig *dc = id;
- u_short *ssp;
- int i;
+ bus_chipset_tag_t bc = dc->dc_bc;
+ bus_mem_handle_t memh = dc->dc_memh;
+ bus_mem_size_t off, endoff;
+ u_int16_t val;
-#if 0
- printf("pcivga_erasecols: row %d: %d, %d\n", row, startcol, ncols);
-#endif
- ssp = &dc->dc_crtat[row * dc->dc_ncol + startcol];
- for (i = 0; i < ncols; i++)
- *ssp++ = (dc->dc_at << 8) | ' ';
+ /*
+ * YUCK. Need bus 'set' functions.
+ */
+ off = (row * dc->dc_ncol + startcol) * 2;
+ endoff = off + ncols * 2;
+ val = (dc->dc_at << 8) | ' ';
+
+ for (; off < endoff; off += 2)
+ bus_mem_write_2(bc, memh, off, val);
}
void
@@ -347,15 +395,20 @@ pcivga_copyrows(id, srcrow, dstrow, nrows)
int srcrow, dstrow, nrows;
{
struct pcivga_devconfig *dc = id;
- u_short *ssp, *dsp;
- int nclr;
+ bus_chipset_tag_t bc = dc->dc_bc;
+ bus_mem_handle_t memh = dc->dc_memh;
+ bus_mem_size_t srcoff, srcend, dstoff;
-#if 0
- printf("pcivga_copyrows: %d, %d -> %d\n", srcrow, nrows, dstrow);
-#endif
- ssp = &dc->dc_crtat[srcrow * dc->dc_ncol + 0];
- dsp = &dc->dc_crtat[dstrow * dc->dc_ncol + 0];
- bcopy(ssp, dsp, nrows * dc->dc_ncol * sizeof(u_short));
+ /*
+ * YUCK. Need bus copy functions.
+ */
+ srcoff = (srcrow * dc->dc_ncol + 0) * 2;
+ srcend = srcoff + (nrows * dc->dc_ncol * 2);
+ dstoff = (dstrow * dc->dc_ncol + 0) * 2;
+
+ for (; srcoff < srcend; srcoff += 2, dstoff += 2)
+ bus_mem_write_2(bc, memh, dstoff,
+ bus_mem_read_2(bc, memh, srcoff));
}
void
@@ -364,13 +417,18 @@ pcivga_eraserows(id, startrow, nrows)
int startrow, nrows;
{
struct pcivga_devconfig *dc = id;
- u_short *ssp;
- int i;
+ bus_chipset_tag_t bc = dc->dc_bc;
+ bus_mem_handle_t memh = dc->dc_memh;
+ bus_mem_size_t off, endoff;
+ u_int16_t val;
-#if 0
- printf("pcivga_eraserows: %d, %d\n", startrow, nrows);
-#endif
- ssp = &dc->dc_crtat[startrow * dc->dc_ncol + 0];
- for (i = 0; i < nrows * dc->dc_ncol; i++)
- *ssp++ = (dc->dc_at << 8) | ' ';
+ /*
+ * YUCK. Need bus 'set' functions.
+ */
+ off = (startrow * dc->dc_ncol + 0) * 2;
+ endoff = off + (nrows * dc->dc_ncol) * 2;
+ val = (dc->dc_at << 8) | ' ';
+
+ for (; off < endoff; off += 2)
+ bus_mem_write_2(bc, memh, off, val);
}