summaryrefslogtreecommitdiff
path: root/sys/arch/alpha/dev
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1997-07-09 02:58:41 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1997-07-09 02:58:41 +0000
commit8feb5b83a9e4e8b3292bd50bdecba817e0c2508b (patch)
tree555b026f78dcde0a8a4b17650f1d0f7d8a6b9fda /sys/arch/alpha/dev
parente54d53bf5d398310e88964f238acf908453a137a (diff)
alpha/common/ insults my filec
Diffstat (limited to 'sys/arch/alpha/dev')
-rw-r--r--sys/arch/alpha/dev/shared_intr.c241
-rw-r--r--sys/arch/alpha/dev/vga.c356
-rw-r--r--sys/arch/alpha/dev/vgavar.h52
3 files changed, 649 insertions, 0 deletions
diff --git a/sys/arch/alpha/dev/shared_intr.c b/sys/arch/alpha/dev/shared_intr.c
new file mode 100644
index 00000000000..9acd3d52599
--- /dev/null
+++ b/sys/arch/alpha/dev/shared_intr.c
@@ -0,0 +1,241 @@
+/* $NetBSD: shared_intr.c,v 1.1 1996/11/17 02:03:08 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Authors: 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.
+ */
+
+/*
+ * Common shared-interrupt-line functionality.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/syslog.h>
+#include <sys/queue.h>
+
+#include <machine/intr.h>
+
+extern int cold;
+
+static const char *intr_typename __P((int));
+
+static const char *
+intr_typename(type)
+ int type;
+{
+
+ switch (type) {
+ case IST_UNUSABLE:
+ return ("disabled");
+ case IST_NONE:
+ return ("none");
+ case IST_PULSE:
+ return ("pulsed");
+ case IST_EDGE:
+ return ("edge-triggered");
+ case IST_LEVEL:
+ return ("level-triggered");
+ }
+ panic("intr_typename: unknown type %d", type);
+}
+
+struct alpha_shared_intr *
+alpha_shared_intr_alloc(n)
+ unsigned int n;
+{
+ struct alpha_shared_intr *intr;
+ unsigned int i;
+
+ intr = malloc(n * sizeof (struct alpha_shared_intr), M_DEVBUF,
+ cold ? M_NOWAIT : M_WAITOK);
+ if (intr == NULL)
+ panic("alpha_shared_intr_alloc: couldn't malloc intr");
+
+ for (i = 0; i < n; i++) {
+ TAILQ_INIT(&intr[i].intr_q);
+ intr[i].intr_sharetype = IST_NONE;
+ intr[i].intr_dfltsharetype = IST_NONE;
+ intr[i].intr_nstrays = 0;
+ intr[i].intr_maxstrays = 5;
+ }
+
+ return (intr);
+}
+
+int
+alpha_shared_intr_dispatch(intr, num)
+ struct alpha_shared_intr *intr;
+ unsigned int num;
+{
+ struct alpha_shared_intrhand *ih;
+ int rv, handled;
+
+ ih = intr[num].intr_q.tqh_first;
+ handled = 0;
+ while (ih != NULL) {
+
+ /*
+ * The handler returns one of three values:
+ * 0: This interrupt wasn't for me.
+ * 1: This interrupt was for me.
+ * -1: This interrupt might have been for me, but I can't say
+ * for sure.
+ */
+ rv = (*ih->ih_fn)(ih->ih_arg);
+
+ handled = handled || (rv != 0);
+ ih = ih->ih_q.tqe_next;
+ }
+
+ return (handled);
+}
+
+void *
+alpha_shared_intr_establish(intr, num, type, level, fn, arg, basename)
+ struct alpha_shared_intr *intr;
+ unsigned int num;
+ int type, level;
+ int (*fn) __P((void *));
+ void *arg;
+ const char *basename;
+{
+ struct alpha_shared_intrhand *ih;
+
+ if (intr[num].intr_sharetype == IST_UNUSABLE) {
+ printf("alpha_shared_intr_establish: %s %d: unusable\n",
+ basename, num);
+ return NULL;
+ }
+
+ /* no point in sleeping unless someone can free memory. */
+ ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
+ if (ih == NULL)
+ panic("alpha_shared_intr_establish: can't malloc intrhand");
+
+#ifdef DIAGNOSTIC
+ if (type == IST_NONE)
+ panic("alpha_shared_intr_establish: bogus type");
+#endif
+
+ switch (intr[num].intr_sharetype) {
+ case IST_EDGE:
+ case IST_LEVEL:
+ if (type == intr[num].intr_sharetype)
+ break;
+ case IST_PULSE:
+ if (type != IST_NONE) {
+ if (intr[num].intr_q.tqh_first == NULL) {
+ printf("alpha_shared_intr_establish: %s %d: warning: using %s on %s\n",
+ basename, num, intr_typename(type),
+ intr_typename(intr[num].intr_sharetype));
+ type = intr[num].intr_sharetype;
+ } else {
+ panic("alpha_shared_intr_establish: %s %d: can't share %s with %s",
+ basename, num, intr_typename(type),
+ intr_typename(intr[num].intr_sharetype));
+ }
+ }
+ break;
+
+ case IST_NONE:
+ /* not currently used; safe */
+ break;
+ }
+
+ ih->ih_fn = fn;
+ ih->ih_arg = arg;
+ ih->ih_level = level;
+
+ intr[num].intr_sharetype = type;
+ TAILQ_INSERT_TAIL(&intr[num].intr_q, ih, ih_q);
+
+ return (ih);
+}
+
+int
+alpha_shared_intr_get_sharetype(intr, num)
+ struct alpha_shared_intr *intr;
+ unsigned int num;
+{
+
+ return (intr[num].intr_sharetype);
+}
+
+int
+alpha_shared_intr_isactive(intr, num)
+ struct alpha_shared_intr *intr;
+ unsigned int num;
+{
+
+ return (intr[num].intr_q.tqh_first != NULL);
+}
+
+void
+alpha_shared_intr_set_dfltsharetype(intr, num, newdfltsharetype)
+ struct alpha_shared_intr *intr;
+ unsigned int num;
+ int newdfltsharetype;
+{
+
+#ifdef DIAGNOSTIC
+ if (alpha_shared_intr_isactive(intr, num))
+ panic("alpha_shared_intr_set_dfltsharetype on active intr");
+#endif
+
+ intr[num].intr_dfltsharetype = newdfltsharetype;
+ intr[num].intr_sharetype = intr[num].intr_dfltsharetype;
+}
+
+void
+alpha_shared_intr_set_maxstrays(intr, num, newmaxstrays)
+ struct alpha_shared_intr *intr;
+ unsigned int num;
+ int newmaxstrays;
+{
+
+#ifdef DIAGNOSTIC
+ if (alpha_shared_intr_isactive(intr, num))
+ panic("alpha_shared_intr_set_maxstrays on active intr");
+#endif
+
+ intr[num].intr_maxstrays = newmaxstrays;
+ intr[num].intr_nstrays = 0;
+}
+
+void
+alpha_shared_intr_stray(intr, num, basename)
+ struct alpha_shared_intr *intr;
+ unsigned int num;
+ const char *basename;
+{
+
+ intr[num].intr_nstrays++;
+ if (intr[num].intr_nstrays <= intr[num].intr_maxstrays)
+ log(LOG_ERR, "stray %s %d%s\n", basename, num,
+ intr[num].intr_nstrays >= intr[num].intr_maxstrays ?
+ "; stopped logging" : "");
+}
diff --git a/sys/arch/alpha/dev/vga.c b/sys/arch/alpha/dev/vga.c
new file mode 100644
index 00000000000..14c096f2e72
--- /dev/null
+++ b/sys/arch/alpha/dev/vga.c
@@ -0,0 +1,356 @@
+/* $OpenBSD: vga.c,v 1.1 1997/07/09 02:58:35 deraadt 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 <alpha/wscons/wsconsvar.h>
+#include <alpha/common/vgavar.h>
+
+#define VGA_IO_D_6845_ADDR 0x4
+#define VGA_IO_D_6845_DATA 0x5
+
+struct cfdriver vga_cd = {
+ NULL, "vga", DV_DULL,
+};
+
+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));
+void vga_copyrows __P((void *, int, int, int));
+void vga_eraserows __P((void *, int, int));
+
+struct wscons_emulfuncs vga_emulfuncs = {
+ vga_cursor,
+ vga_putstr,
+ vga_copycols,
+ vga_erasecols,
+ vga_copyrows,
+ vga_eraserows,
+};
+
+int vgaprint __P((void *, const char *));
+int vgaioctl __P((void *, u_long, caddr_t, int, struct proc *));
+int vgammap __P((void *, off_t, int));
+
+/*
+ * The following functions implement back-end configuration grabbing
+ * and attachment.
+ */
+int
+vga_common_probe(iot, memt)
+ bus_space_tag_t iot, memt;
+{
+ bus_space_handle_t ioh_b, ioh_c, ioh_d, memh;
+ u_int16_t vgadata;
+ int gotio_b, gotio_c, gotio_d, gotmem, rv;
+
+ gotio_b = gotio_c = gotio_d = 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))
+ goto bad;
+ gotio_c = 1;
+ if (bus_space_map(iot, 0x3d0, 0x10, 0, &ioh_d))
+ goto bad;
+ gotio_d = 1;
+ if (bus_space_map(memt, 0xb8000, 0x8000, 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);
+
+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 (gotmem)
+ bus_space_unmap(memt, memh, 0x8000);
+
+ return (rv);
+}
+
+void
+vga_common_setup(iot, memt, vc)
+ bus_space_tag_t iot, memt;
+ struct vga_config *vc;
+{
+ int cpos;
+
+ 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 */
+
+ /* 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!
+ */
+ vc->vc_at = 0x40 | 0x0f; /* blue bg|white fg */
+ vc->vc_so_at = 0x40 | 0x0f | 0x80; /* blue bg|white fg|blink */
+}
+
+void
+vga_wscons_attach(parent, vc, console)
+ struct device *parent;
+ struct vga_config *vc;
+ int console;
+{
+ struct wscons_attach_args waa;
+ struct wscons_odev_spec *wo;
+
+ waa.waa_isconsole = console;
+ wo = &waa.waa_odev_spec;
+
+ wo->wo_emulfuncs = &vga_emulfuncs;
+ wo->wo_emulfuncs_cookie = vc;
+
+ wo->wo_ioctl = vgaioctl;
+ wo->wo_mmap = vgammap;
+ wo->wo_miscfuncs_cookie = vc;
+
+ 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);
+}
+
+void
+vga_wscons_console(vc)
+ struct vga_config *vc;
+{
+ struct wscons_odev_spec wo;
+
+ wo.wo_emulfuncs = &vga_emulfuncs;
+ wo.wo_emulfuncs_cookie = vc;
+
+ /* ioctl and mmap are unused until real attachment. */
+
+ 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);
+}
+
+int
+vgaprint(aux, pnp)
+ void *aux;
+ const char *pnp;
+{
+
+ if (pnp)
+ printf("wscons at %s", pnp);
+ return (UNCONF);
+}
+
+int
+vgaioctl(v, cmd, data, flag, p)
+ void *v;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+
+ /* XXX */
+ return -1;
+}
+
+int
+vgammap(v, offset, prot)
+ void *v;
+ off_t offset;
+ int prot;
+{
+
+ /* XXX */
+ 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;
+{
+ 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;
+
+#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;
+ } else {
+ vc->vc_crow = row;
+ vc->vc_ccol = col;
+ }
+
+ pos = row * vc->vc_ncol + col;
+
+ 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);
+}
+
+void
+vga_putstr(id, row, col, cp, len)
+ void *id;
+ int row, col;
+ char *cp;
+ int len;
+{
+ 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);
+ }
+}
+
+void
+vga_copycols(id, row, srccol, dstcol, ncols)
+ void *id;
+ int row, srccol, dstcol, ncols;
+{
+ struct vga_config *vc = id;
+ bus_size_t srcoff, dstoff;
+
+ srcoff = (row * vc->vc_ncol + srccol) * 2;
+ dstoff = (row * vc->vc_ncol + dstcol) * 2;
+
+ /* XXX SHOULDN'T USE THIS IF REGIONS OVERLAP... */
+ bus_space_copy_2(vc->vc_memt, vc->vc_memh, srcoff, vc->vc_memh, dstoff,
+ ncols);
+}
+
+void
+vga_erasecols(id, row, startcol, ncols)
+ void *id;
+ int row, startcol, ncols;
+{
+ struct vga_config *vc = id;
+ bus_size_t off;
+ u_int16_t val;
+
+ off = (row * vc->vc_ncol + startcol) * 2;
+
+ val = (vc->vc_at << 8) | ' ';
+
+ bus_space_set_region_2(vc->vc_memt, vc->vc_memh, off, val, ncols);
+}
+
+void
+vga_copyrows(id, srcrow, dstrow, nrows)
+ void *id;
+ int srcrow, dstrow, nrows;
+{
+ struct vga_config *vc = id;
+ bus_size_t srcoff, dstoff;
+
+ srcoff = (srcrow * vc->vc_ncol + 0) * 2;
+ dstoff = (dstrow * vc->vc_ncol + 0) * 2;
+
+ /* XXX SHOULDN'T USE THIS IF REGIONS OVERLAP... */
+ bus_space_copy_2(vc->vc_memt, vc->vc_memh, srcoff, vc->vc_memh, dstoff,
+ nrows * vc->vc_ncol);
+}
+
+void
+vga_eraserows(id, startrow, nrows)
+ void *id;
+ int startrow, nrows;
+{
+ struct vga_config *vc = id;
+ bus_size_t off, count;
+ u_int16_t val;
+
+ off = (startrow * vc->vc_ncol + 0) * 2;
+ count = nrows * vc->vc_ncol;
+
+ val = (vc->vc_at << 8) | ' ';
+
+ bus_space_set_region_2(vc->vc_memt, vc->vc_memh, off, val, count);
+}
diff --git a/sys/arch/alpha/dev/vgavar.h b/sys/arch/alpha/dev/vgavar.h
new file mode 100644
index 00000000000..3c5353a83b0
--- /dev/null
+++ b/sys/arch/alpha/dev/vgavar.h
@@ -0,0 +1,52 @@
+/* $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 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 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 *));