summaryrefslogtreecommitdiff
path: root/sys/arch/sparc/dev/cons.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1996-08-11 05:35:37 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1996-08-11 05:35:37 +0000
commite511a52691ddb2290f5d3c9ca6e9f0fc3b320289 (patch)
treef68510b774a71e2a0879cb013e3abd7a15665abc /sys/arch/sparc/dev/cons.c
parentfc98d7c9a0046f274410f903f952ef6224f68e10 (diff)
netbsd port, now we merge our changes back in
Diffstat (limited to 'sys/arch/sparc/dev/cons.c')
-rw-r--r--sys/arch/sparc/dev/cons.c226
1 files changed, 191 insertions, 35 deletions
diff --git a/sys/arch/sparc/dev/cons.c b/sys/arch/sparc/dev/cons.c
index d4e096bf88d..08df311233b 100644
--- a/sys/arch/sparc/dev/cons.c
+++ b/sys/arch/sparc/dev/cons.c
@@ -1,4 +1,4 @@
-/* $NetBSD: cons.c,v 1.15 1995/07/13 12:02:19 pk Exp $ */
+/* $NetBSD: cons.c,v 1.23.4.1 1996/06/02 09:07:53 mrg Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -49,7 +49,6 @@
*/
#include <sys/param.h>
-#include <sys/types.h>
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/ioctl.h>
@@ -57,11 +56,18 @@
#include <sys/file.h>
#include <sys/conf.h>
+#include <dev/cons.h>
+
#include <machine/bsd_openprom.h>
+#include <machine/eeprom.h>
#include <machine/psl.h>
-#ifdef SUN4
+#include <machine/cpu.h>
+#include <machine/kbd.h>
+#if defined(SUN4)
#include <machine/oldmon.h>
#endif
+#include <machine/autoconf.h>
+#include <machine/conf.h>
#include "zs.h"
@@ -71,25 +77,25 @@ int rom_console_input; /* when set, hardclock calls cnrom() */
int cons_ocount; /* output byte count */
-extern struct promvec *promvec;
-
/*
* The output driver may munge the minor number in cons.t_dev.
*/
struct tty cons; /* rom console tty device */
-static void (*fcnstop) __P((struct tty *, int));
+static int (*fcnstop) __P((struct tty *, int));
static void cnstart __P((struct tty *));
-void cnstop __P((struct tty *, int));
+int cnstop __P((struct tty *, int));
static void cnfbstart __P((struct tty *));
-static void cnfbstop __P((struct tty *, int));
+static int cnfbstop __P((struct tty *, int));
static void cnfbdma __P((void *));
+static struct tty *xxcntty __P((dev_t));
extern char char_type[];
-/*XXX*/static struct tty *
-cntty()
+/*XXX*/
+static struct tty *
+xxcntty(dev_t dev)
{
return &cons;
}
@@ -99,16 +105,121 @@ consinit()
{
register struct tty *tp = &cons;
register int in, out;
- void zsconsole();
-/*XXX*/ cdevsw[0].d_tty = cntty;
+/*XXX*/ cdevsw[0].d_tty = xxcntty;
tp->t_dev = makedev(0, 0); /* /dev/console */
tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
tp->t_param = (int (*)(struct tty *, struct termios *))nullop;
- in = *promvec->pv_stdin;
- out = *promvec->pv_stdout;
- switch (in) {
+ if (promvec->pv_romvec_vers > 2) {
+ /* We need to probe the PROM device tree */
+ register int node,fd;
+ char buffer[128];
+ register struct nodeops *no;
+ register struct v2devops *op;
+ register char *cp;
+ extern int fbnode;
+
+ in = out = -1;
+ no = promvec->pv_nodeops;
+ op = &promvec->pv_v2devops;
+
+ node = findroot();
+ if (no->no_proplen(node, "stdin-path") >= sizeof(buffer)) {
+ printf("consinit: increase buffer size and recompile\n");
+ goto setup_output;
+ }
+ /* XXX: fix above */
+
+ no->no_getprop(node, "stdin-path",buffer);
+
+ /*
+ * Open an "instance" of this device.
+ * You'd think it would be appropriate to call v2_close()
+ * on the handle when we're done with it. But that seems
+ * to cause the device to shut down somehow; for the moment,
+ * we simply leave it open...
+ */
+ if ((fd = op->v2_open(buffer)) == 0 ||
+ (node = op->v2_fd_phandle(fd)) == 0) {
+ printf("consinit: bogus stdin path %s.\n",buffer);
+ goto setup_output;
+ }
+ if (no->no_proplen(node,"keyboard") >= 0) {
+ in = PROMDEV_KBD;
+ goto setup_output;
+ }
+ if (strcmp(getpropstring(node,"device_type"),"serial") != 0) {
+ /* not a serial, not keyboard. what is it?!? */
+ in = -1;
+ goto setup_output;
+ }
+ /*
+ * At this point we assume the device path is in the form
+ * ....device@x,y:a for ttya and ...device@x,y:b for ttyb.
+ * If it isn't, we defer to the ROM
+ */
+ cp = buffer;
+ while (*cp)
+ cp++;
+ cp -= 2;
+#ifdef DEBUG
+ if (cp < buffer)
+ panic("consinit: bad stdin path %s",buffer);
+#endif
+ /* XXX: only allows tty's a->z, assumes PROMDEV_TTYx contig */
+ if (cp[0]==':' && cp[1] >= 'a' && cp[1] <= 'z')
+ in = PROMDEV_TTYA + (cp[1] - 'a');
+ /* else use rom */
+setup_output:
+ node = findroot();
+ if (no->no_proplen(node, "stdout-path") >= sizeof(buffer)) {
+ printf("consinit: increase buffer size and recompile\n");
+ goto setup_console;
+ }
+ /* XXX: fix above */
+
+ no->no_getprop(node, "stdout-path", buffer);
+
+ if ((fd = op->v2_open(buffer)) == 0 ||
+ (node = op->v2_fd_phandle(fd)) == 0) {
+ printf("consinit: bogus stdout path %s.\n",buffer);
+ goto setup_output;
+ }
+ if (strcmp(getpropstring(node,"device_type"),"display") == 0) {
+ /* frame buffer output */
+ out = PROMDEV_SCREEN;
+ fbnode = node;
+ } else if (strcmp(getpropstring(node,"device_type"), "serial")
+ != 0) {
+ /* not screen, not serial. Whatzit? */
+ out = -1;
+ } else { /* serial console. which? */
+ /*
+ * At this point we assume the device path is in the
+ * form:
+ * ....device@x,y:a for ttya, etc.
+ * If it isn't, we defer to the ROM
+ */
+ cp = buffer;
+ while (*cp)
+ cp++;
+ cp -= 2;
+#ifdef DEBUG
+ if (cp < buffer)
+ panic("consinit: bad stdout path %s",buffer);
+#endif
+ /* XXX: only allows tty's a->z, assumes PROMDEV_TTYx contig */
+ if (cp[0]==':' && cp[1] >= 'a' && cp[1] <= 'z')
+ out = PROMDEV_TTYA + (cp[1] - 'a');
+ else out = -1;
+ }
+ } else {
+ in = *promvec->pv_stdin;
+ out = *promvec->pv_stdout;
+ }
+setup_console:
+ switch (in) {
#if NZS > 0
case PROMDEV_TTYA:
zsconsole(tp, 0, 0, NULL);
@@ -152,12 +263,13 @@ consinit()
default:
printf("unknown console output sink %d; using rom\n", out);
tp->t_oproc = cnstart;
- fcnstop = (void (*)(struct tty *, int))nullop;
+ fcnstop = (int (*)(struct tty *, int))nullop;
break;
}
}
/* ARGSUSED */
+int
cnopen(dev, flag, mode, p)
dev_t dev;
int flag, mode;
@@ -165,12 +277,42 @@ cnopen(dev, flag, mode, p)
{
register struct tty *tp = &cons;
static int firstopen = 1;
+ static int rows = 0, cols = 0;
- if(firstopen) {
+ if (firstopen) {
clalloc(&tp->t_rawq, 1024, 1);
clalloc(&tp->t_canq, 1024, 1);
/* output queue doesn't need quoting */
clalloc(&tp->t_outq, 1024, 0);
+ tty_attach(tp);
+ /*
+ * get the console struct winsize.
+ */
+ if (CPU_ISSUN4COR4M) {
+ int i;
+ char *prop;
+
+ if ((prop = getpropstring(optionsnode, "screen-#rows"))) {
+ i = 0;
+ while (*prop != '\0')
+ i = i * 10 + *prop++ - '0';
+ rows = (unsigned short)i;
+ }
+ if ((prop = getpropstring(optionsnode, "screen-#columns"))) {
+ i = 0;
+ while (*prop != '\0')
+ i = i * 10 + *prop++ - '0';
+ cols = (unsigned short)i;
+ }
+ }
+ if (CPU_ISSUN4) {
+ struct eeprom *ep = (struct eeprom *)eeprom_va;
+
+ if (ep) {
+ rows = (u_short)ep->eeTtyRows;
+ cols = (u_short)ep->eeTtyCols;
+ }
+ }
firstopen = 0;
}
@@ -186,12 +328,15 @@ cnopen(dev, flag, mode, p)
tp->t_state = TS_ISOPEN | TS_CARR_ON;
(void)(*tp->t_param)(tp, &tp->t_termios);
ttsetwater(tp);
+ tp->t_winsize.ws_row = rows;
+ tp->t_winsize.ws_col = cols;
} else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0)
return (EBUSY);
return ((*linesw[tp->t_line].l_open)(dev, tp));
}
/* ARGSUSED */
+int
cnclose(dev, flag, mode, p)
dev_t dev;
int flag, mode;
@@ -205,6 +350,7 @@ cnclose(dev, flag, mode, p)
}
/* ARGSUSED */
+int
cnread(dev, uio, flag)
dev_t dev;
struct uio *uio;
@@ -216,19 +362,21 @@ cnread(dev, uio, flag)
}
/* ARGSUSED */
+int
cnwrite(dev, uio, flag)
dev_t dev;
struct uio *uio;
int flag;
{
register struct tty *tp;
-
+
if ((tp = constty) == NULL ||
(tp->t_state & (TS_CARR_ON|TS_ISOPEN)) != (TS_CARR_ON|TS_ISOPEN))
tp = &cons;
return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
}
+int
cnioctl(dev, cmd, data, flag, p)
dev_t dev;
u_long cmd;
@@ -258,6 +406,7 @@ cnioctl(dev, cmd, data, flag, p)
return (ENOTTY);
}
+int
cnselect(dev, which, p)
dev_t dev;
int which;
@@ -281,9 +430,9 @@ cnstart(tp)
register int c, s;
register union {
void (*v1)__P((int));
- void (*v3)__P((int, u_char *, int));
+ int (*v3)__P((int, void *, int));
} putc;
- register int fd, v;
+ register int fd = 0, v;
s = spltty();
if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
@@ -291,7 +440,7 @@ cnstart(tp)
return;
}
if ((v = promvec->pv_romvec_vers) > 2) {
- putc.v3 = (void (*))promvec->pv_v2devops.v2_write;
+ putc.v3 = promvec->pv_v2devops.v2_write;
fd = *promvec->pv_v2bootargs.v2_fd1;
} else
putc.v1 = promvec->pv_putchar;
@@ -304,7 +453,7 @@ cnstart(tp)
*/
(void) splhigh();
if (v > 2) {
- u_char c0 = c & 0177;
+ unsigned char c0 = c & 0177;
(*putc.v3)(fd, &c0, 1);
} else
(*putc.v1)(c & 0177);
@@ -318,12 +467,13 @@ cnstart(tp)
splx(s);
}
-void
+int
cnstop(tp, flag)
register struct tty *tp;
int flag;
{
- (*fcnstop)(tp, flag);
+ (void)(*fcnstop)(tp, flag);
+ return 0;
}
/*
@@ -367,7 +517,7 @@ cnfbstart(tp)
/*
* Stop frame buffer output: just assert TS_FLUSH if necessary.
*/
-static void
+static int
cnfbstop(tp, flag)
register struct tty *tp;
int flag;
@@ -377,6 +527,7 @@ cnfbstop(tp, flag)
if ((tp->t_state & (TS_BUSY | TS_TTSTOP)) == TS_BUSY)
tp->t_state |= TS_FLUSH;
splx(s);
+ return 0;
}
/*
@@ -387,7 +538,7 @@ cnfbdma(tpaddr)
void *tpaddr;
{
register struct tty *tp = tpaddr;
- register char *p, *q;
+ register unsigned char *p, *q;
register int n, c, s;
s = spltty(); /* paranoid */
@@ -406,7 +557,7 @@ cnfbdma(tpaddr)
(*promvec->pv_v2devops.v2_write)
(*promvec->pv_v2bootargs.v2_fd1, p, n);
} else
- (*promvec->pv_putstr)(p, n);
+ (*promvec->pv_putstr)((char *)p, n);
ndflush(&tp->t_outq, n);
}
if (tp->t_line)
@@ -423,6 +574,7 @@ cnfbdma(tpaddr)
volatile int cn_rxc = -1; /* XXX receive `silo' */
/* called from hardclock, which is above spltty, so no tty calls! */
+int
cnrom()
{
register int c;
@@ -442,6 +594,7 @@ cnrom()
}
/* pseudo console software interrupt scheduled when cnrom() returns 1 */
+void
cnrint()
{
register struct tty *tp;
@@ -466,6 +619,7 @@ cnrint()
(*linesw[tp->t_line].l_rint)(c, tp);
}
+int
cngetc()
{
register int s, c;
@@ -473,30 +627,30 @@ cngetc()
if (promvec->pv_romvec_vers > 2) {
register int n = 0;
unsigned char c0;
+ s = splhigh();
while (n <= 0) {
- s = splhigh();
n = (*promvec->pv_v2devops.v2_read)
(*promvec->pv_v2bootargs.v2_fd0, &c0, 1);
- splx(s);
}
+ splx(s);
c = c0;
} else {
-#ifdef SUN4
+#if defined(SUN4)
/* SUN4 PROM: must turn off echo to avoid double char echo */
extern struct om_vector *oldpvec;
- int saveecho;
+ int saveecho = 0;
#endif
s = splhigh();
-#ifdef SUN4
- if (cputyp == CPU_SUN4) {
+#if defined(SUN4)
+ if (CPU_ISSUN4) {
saveecho = *(oldpvec->echo);
*(oldpvec->echo) = 0;
}
#endif
c = (*promvec->pv_getchar)();
-#ifdef SUN4
- if (cputyp == CPU_SUN4)
+#if defined(SUN4)
+ if (CPU_ISSUN4)
*(oldpvec->echo) = saveecho;
#endif
splx(s);
@@ -506,6 +660,7 @@ cngetc()
return (c);
}
+void
cnputc(c)
register int c;
{
@@ -523,6 +678,7 @@ cnputc(c)
splx(s);
}
+void
cnpollc(on)
int on;
{