Fix the sparc64 console.

Unlike the other Sun machines, UltraSPARCs can have consoles run on different
chips than zs, so we need to support them.  So, here we go:

	Add a new PROM console driver with a major number and everything.
	This is the default driver if nothing else attaches.  It does not
	use the keyboard driver since the PROM translates keystrokes itself.
	(Unfortunately it also swallows L1-A).

	Have the keyboard driver take over the console when it attaches on a
	serial port.  When a serial port detects a keyboard and attaches the
	keyboard driver, it needs to provide a set of consdev vectors.  They
	keyboard driver will use those to send I/O to the keyboard and mouse.
This commit is contained in:
eeh 2000-05-19 05:26:16 +00:00
parent 9a063e5f4d
commit 424619ca1a
14 changed files with 334 additions and 329 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kd.c,v 1.10 2000/03/24 11:46:46 hannken Exp $ */
/* $NetBSD: kd.c,v 1.11 2000/05/19 05:26:16 eeh Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -450,8 +450,9 @@ kd_cons_input(c)
}
void
cons_attach_input(cc)
cons_attach_input(cc, cn)
struct cons_channel *cc;
struct consdev *cn;
{
struct kd_softc *kd = &kd_softc;

View File

@ -1,4 +1,4 @@
# $NetBSD: files.sparc64,v 1.28 2000/04/22 17:05:59 mrg Exp $
# $NetBSD: files.sparc64,v 1.29 2000/05/19 05:26:17 eeh Exp $
# @(#)files.sparc64 8.1 (Berkeley) 7/19/93
# sparc64-specific configuration info
@ -12,6 +12,10 @@ define mainbus {}
device mainbus: pcibus, mainbus
attach mainbus at root
device pcons
attach pcons at mainbus
file arch/sparc64/dev/pcons.c pcons needs-flag
include "dev/sbus/files.sbus"
attach sbus at mainbus
file arch/sparc64/dev/sbus.c sbus

View File

@ -1,4 +1,53 @@
/* $NetBSD: cons.h,v 1.2 1999/02/15 04:54:34 hubertf Exp $ */
/* $NetBSD: cons.h,v 1.3 2000/05/19 05:26:17 eeh Exp $ */
/*-
* Copyright (c) 2000 Eduardo E. Horvath
* 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. 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.
*/
/*
* PROM console driver.
*
* This is the default fallback console driver if nothing else attaches.
*/
struct pconssoftc {
struct device of_dev;
struct tty *of_tty;
struct callout sc_poll_ch;
int of_flags;
};
/* flags: */
#define OFPOLL 1
#define OFBURSTLEN 128 /* max number of bytes to write in one chunk */
/* These are shared with the consinit OBP console */
extern int stdin, stdout;
void pcons_cnpollc __P((dev_t dev, int on));
struct consdev;
struct zs_chanstate;

View File

@ -1,4 +1,4 @@
/* $NetBSD: consinit.c,v 1.4 2000/04/19 08:15:06 pk Exp $ */
/* $NetBSD: consinit.c,v 1.5 2000/05/19 05:26:17 eeh Exp $ */
/*-
* Copyright (c) 1999 Eduardo E. Horvath
@ -28,12 +28,8 @@
* SUCH DAMAGE.
*/
/*
* Default console driver. Uses the PROM or whatever
* driver(s) are appropriate.
*/
#include "opt_ddb.h"
#include "pcons.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -61,10 +57,11 @@
#include <sparc64/sparc64/vaddrs.h>
#include <sparc64/dev/cons.h>
static void prom_cnprobe __P((struct consdev *));
static void prom_cninit __P((struct consdev *));
static int prom_cngetc __P((dev_t));
int prom_cngetc __P((dev_t));
static void prom_cnputc __P((dev_t, int));
static void prom_cnpollc __P((dev_t, int));
static void prom_cnputc __P((dev_t, int));
int stdin = NULL, stdout = NULL;
@ -75,11 +72,11 @@ int stdin = NULL, stdout = NULL;
* is called to select a real console.
*/
struct consdev consdev_prom = {
nullcnprobe,
prom_cnprobe,
prom_cninit,
prom_cngetc,
prom_cnputc,
nullcnpollc,
prom_cnpollc,
NULL,
};
@ -91,45 +88,40 @@ struct consdev consdev_prom = {
struct consdev *cn_tab = &consdev_prom;
void
nullcnprobe(cn)
struct consdev *cn;
prom_cnprobe(cd)
struct consdev *cd;
{
#if NPCONS > 0
int maj;
for (maj = 0; maj < nchrdev; maj++)
if (cdevsw[maj].d_open == pconsopen)
break;
cd->cn_dev = makedev(maj, 0);
cd->cn_pri = CN_INTERNAL;
#endif
}
int
prom_cngetc(dev)
dev_t dev;
{
unsigned char ch = '\0';
int l;
while ((l = OF_read(stdin, &ch, 1)) != 1)
/* void */;
if (ch == '\r')
ch = '\n';
return ch;
}
static void
prom_cninit(cn)
struct consdev *cn;
{
if (!stdin) {
int node = OF_finddevice("/chosen");
OF_getprop(node, "stdin", &stdin, sizeof(stdin));
}
if (!stdout) {
int node = OF_finddevice("/chosen");
OF_getprop(node, "stdout", &stdout, sizeof(stdout));
}
}
/*
* PROM console input putchar.
* (dummy - this is output only)
*/
static int
prom_cngetc(dev)
dev_t dev;
{
char c;
if (!stdin) {
int node = OF_finddevice("/chosen");
OF_getprop(node, "stdin", &stdin, sizeof(stdin));
}
while (OF_read(stdin, &c, 1) != 1)
/*void*/;
if (c == '\r')
c = '\n';
return (c);
if (!stdin) stdin = OF_stdin();
if (!stdout) stdout = OF_stdout();
}
/*
@ -143,16 +135,32 @@ prom_cnputc(dev, c)
int s;
char c0 = (c & 0x7f);
if (!stdout) {
int node = OF_finddevice("/chosen");
OF_getprop(node, "stdout", &stdout, sizeof(stdout));
}
#if 0
if (!stdout) stdout = OF_stdout();
#endif
s = splhigh();
OF_write(stdout, &c0, 1);
splx(s);
}
void
prom_cnpollc(dev, on)
dev_t dev;
int on;
{
if (on) {
/* Entering debugger. */
#if NFB > 0
fb_unblank();
#endif
} else {
/* Resuming kernel. */
}
#if NPCONS > 0
pcons_cnpollc(dev, on);
#endif
}
/*****************************************************************/
#ifdef DEBUG
@ -207,6 +215,8 @@ consinit()
}
printf("console is %s\n", consname);
/* Defer the rest to the device attach */
/* Initialize PROM console */
(*cn_tab->cn_probe)(cn_tab);
(*cn_tab->cn_init)(cn_tab);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: kd.c,v 1.11 2000/03/23 06:45:37 thorpej Exp $ */
/* $NetBSD: kd.c,v 1.12 2000/05/19 05:26:17 eeh Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -99,6 +99,7 @@ static int kdparam(struct tty *, struct termios *);
static void kdstart(struct tty *);
static void kd_init __P((struct kd_softc *));
static void kd_cons_input __P((int));
static int kdcngetc __P((dev_t));
int cons_ocount; /* output byte count */
@ -426,16 +427,6 @@ kd_putfb(tp)
}
}
void
cons_attach_input(cc)
struct cons_channel *cc;
{
struct kd_softc *kd = &kd_softc;
kd->kd_in = cc;
cc->cc_upstream = kd_cons_input;
}
/*
* Default PROM-based console input stream
*/
@ -485,17 +476,15 @@ kd_cons_input(c)
****************************************************************/
/* The debugger gets its own key translation state. */
static struct kbd_state kdcn_state;
static struct kbd_state *kdcn_state;
static void kdcnprobe __P((struct consdev *));
static void kdcninit __P((struct consdev *));
static int kdcngetc __P((dev_t));
static void kdcnputc __P((dev_t, int));
static void kdcnpollc __P((dev_t, int));
/* The keyboard driver uses cn_hw to access the real console driver */
extern struct consdev consdev_prom;
struct consdev *cn_hw = &consdev_prom;
struct consdev consdev_kd = {
kdcnprobe,
kdcninit,
@ -504,6 +493,43 @@ struct consdev consdev_kd = {
kdcnpollc,
NULL,
};
struct consdev *cn_hw = &consdev_kd;
void
cons_attach_input(cc, cn)
struct cons_channel *cc;
struct consdev *cn;
{
struct kd_softc *kd = &kd_softc;
struct kbd_softc *kds = cc->cc_dev;
struct kbd_state *ks;
/* Share the keyboard state */
kdcn_state = ks = &kds->k_state;
kd->kd_in = cc;
cc->cc_upstream = kd_cons_input;
/* Attach lower level. */
cn_hw->cn_pollc = cn->cn_pollc;
cn_hw->cn_getc = cn->cn_getc;
/* Attach us as console. */
cn_tab->cn_dev = makedev(KDMAJOR, 0);
cn_tab->cn_probe = kdcnprobe;
cn_tab->cn_init = kdcninit;
cn_tab->cn_getc = kdcngetc;
cn_tab->cn_pollc = kdcnpollc;
cn_tab->cn_pri = CN_INTERNAL;
/* Set up initial PROM input channel for /dev/console */
prom_cons_channel.cc_dev = NULL;
prom_cons_channel.cc_iopen = kd_rom_iopen;
prom_cons_channel.cc_iclose = kd_rom_iclose;
/* Indicate that it is OK to use the PROM fbwrite */
kd_is_console = 1;
}
/* We never call this. */
static void
@ -516,7 +542,8 @@ static void
kdcninit(cn)
struct consdev *cn;
{
struct kbd_state *ks = &kdcn_state;
#if 0
struct kbd_state *ks = kdcn_state;
cn->cn_dev = makedev(KDMAJOR, 0);
cn->cn_pri = CN_INTERNAL;
@ -533,15 +560,19 @@ kdcninit(cn)
/* Indicate that it is OK to use the PROM fbwrite */
kd_is_console = 1;
#endif
}
static int
kdcngetc(dev)
dev_t dev;
{
struct kbd_state *ks = &kdcn_state;
struct kbd_state *ks = kdcn_state;
int code, class, data, keysym;
extern int prom_cngetc __P((dev_t));
if (cn_hw->cn_getc == prom_cngetc) return (*cn_hw->cn_getc)(dev);
for (;;) {
code = (*cn_hw->cn_getc)(dev);
keysym = kbd_code_to_keysym(ks, code);
@ -595,7 +626,7 @@ kdcnpollc(dev, on)
dev_t dev;
int on;
{
struct kbd_state *ks = &kdcn_state;
struct kbd_state *ks = kdcn_state;
if (on) {
/* Entering debugger. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: zs.c,v 1.19 2000/05/17 09:28:22 mrg Exp $ */
/* $NetBSD: zs.c,v 1.20 2000/05/19 05:26:17 eeh Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -111,22 +111,12 @@ struct zsdevice {
struct zschan zs_chan_a;
};
/* ZS channel used as the console device (if any) */
void *zs_conschan_get, *zs_conschan_put;
/* Saved PROM mappings */
static struct zsdevice *zsaddr[NZS];
/* Flags from cninit() */
static int zs_hwflags[NZS][2];
/* Default speed for each channel */
static int zs_defspeed[NZS][2] = {
{ 9600, /* ttya */
9600 }, /* ttyb */
{ 1200, /* keyboard */
1200 }, /* mouse */
{ 9600, /* ttyc */
9600 }, /* ttyd */
};
static u_char zs_init_reg[16] = {
0, /* 0: CMD (reset, etc.) */
0, /* 1: No interrupts yet. */
@ -146,31 +136,19 @@ static u_char zs_init_reg[16] = {
ZSWR15_BREAK_IE,
};
struct zschan *
zs_get_chan_addr(zs_unit, channel)
int zs_unit, channel;
{
struct zsdevice *addr;
struct zschan *zc;
/* Console ops */
static int zscngetc __P((dev_t));
static void zscnputc __P((dev_t, int));
static void zscnpollc __P((dev_t, int));
if (zs_unit >= NZS)
return (NULL);
addr = zsaddr[zs_unit];
#if defined(DEBUG) && defined(DDB)
if (addr == NULL) {
db_printf("zs_get_chan_addr(): unit %d channel %d not found\n", zs_unit, channel);
Debugger();
}
#endif
if (addr == NULL)
return (NULL);
if (channel == 0) {
zc = &addr->zs_chan_a;
} else {
zc = &addr->zs_chan_b;
}
return (zc);
}
struct consdev zs_consdev = {
NULL,
NULL,
zscngetc,
zscnputc,
zscnpollc,
NULL,
};
/****************************************************************
@ -178,32 +156,22 @@ zs_get_chan_addr(zs_unit, channel)
****************************************************************/
/* Definition of the driver for autoconfig. */
static int zs_match_sbus __P((struct device *, struct cfdata *, void *));
static int zs_match_mainbus __P((struct device *, struct cfdata *, void *));
static int zs_match_obio __P((struct device *, struct cfdata *, void *));
static void zs_attach_sbus __P((struct device *, struct device *, void *));
static void zs_attach_mainbus __P((struct device *, struct device *, void *));
static void zs_attach_obio __P((struct device *, struct device *, void *));
static void zs_attach __P((struct zsc_softc *, int));
static void zs_attach __P((struct zsc_softc *, struct zsdevice *, int));
static int zs_print __P((void *, const char *name));
/* Do we really need this ? */
struct cfattach zs_ca = {
sizeof(struct zsc_softc), zs_match_sbus, zs_attach_sbus
sizeof(struct zsc_softc), zs_match_mainbus, zs_attach_mainbus
};
struct cfattach zs_mainbus_ca = {
sizeof(struct zsc_softc), zs_match_mainbus, zs_attach_mainbus
};
struct cfattach zs_obio_ca = {
sizeof(struct zsc_softc), zs_match_obio, zs_attach_obio
};
extern struct cfdriver zs_cd;
extern struct consdev consdev_kd;
extern struct consdev consdev_zs;
extern struct consdev *cn_hw;
extern int stdinnode;
extern int fbnode;
@ -214,6 +182,12 @@ static struct intrhand levelsoft = { zssoft, 0, IPL_SOFTSERIAL };
static int zs_get_speed __P((struct zs_chanstate *));
/* Console device support */
static int zs_console_flags __P((int, int, int));
/* Power management hooks */
int zs_enable __P((struct zs_chanstate *));
void zs_disable __P((struct zs_chanstate *));
/*
* Is the zs chip present?
@ -223,54 +197,13 @@ zs_match_mainbus(parent, cf, aux)
struct device *parent;
struct cfdata *cf;
void *aux;
{
struct mainbus_attach_args *ma = aux;
if (strcmp(cf->cf_driver->cd_name, ma->ma_name) != 0)
return (0);
return (getpropint(ma->ma_node, "slave", -2) == cf->cf_unit);
}
static int
zs_match_sbus(parent, cf, aux)
struct device *parent;
struct cfdata *cf;
void *aux;
{
struct sbus_attach_args *sa = aux;
if (strcmp(cf->cf_driver->cd_name, sa->sa_name) != 0)
return (0);
return 1;
}
static int
zs_match_obio(parent, cf, aux)
struct device *parent;
struct cfdata *cf;
void *aux;
{
#ifdef SUN4U
return 0;
#else
union obio_attach_args *uoba = aux;
struct obio4_attach_args *oba;
if (uoba->uoba_isobio4 == 0) {
struct sbus_attach_args *sa = &uoba->uoba_sbus;
if (strcmp(cf->cf_driver->cd_name, sa->sa_name) != 0)
return (0);
return (getpropint(sa->sa_node, "slave", -2) == cf->cf_unit);
}
oba = &uoba->uoba_oba4;
return (bus_space_probe(oba->oba_bustag, 0, oba->oba_paddr,
1, 0, 0, NULL, NULL));
#endif
return (1);
}
static void
@ -278,43 +211,19 @@ zs_attach_mainbus(parent, self, aux)
struct device *parent;
struct device *self;
void *aux;
{
#ifdef SUN4U
return;
#else
struct zsc_softc *zsc = (void *) self;
struct mainbus_attach_args *ma = aux;
int zs_unit = zsc->zsc_dev.dv_unit;
zsc->zsc_bustag = ma->ma_bustag;
zsc->zsc_dmatag = ma->ma_dmatag;
/* Use the mapping setup by the Sun PROM. */
if (zsaddr[zs_unit] == NULL)
zsaddr[zs_unit] = findzs(zs_unit);
if ((void*)zsaddr[zs_unit] != (void*)(u_long)ma->ma_address[0])
panic("zsattach_mainbus");
zs_attach(zsc, ma->ma_pri);
#endif
}
static void
zs_attach_sbus(parent, self, aux)
struct device *parent;
struct device *self;
void *aux;
{
struct zsc_softc *zsc = (void *) self;
struct sbus_attach_args *sa = aux;
int zs_unit = zsc->zsc_dev.dv_unit;
struct consdev *cn = NULL;
zsc->zsc_bustag = sa->sa_bustag;
zsc->zsc_dmatag = sa->sa_dmatag;
if (sa->sa_nintr == 0) {
printf(" no interrupt lines\n");
return;
}
/* Use the mapping setup by the Sun PROM. */
if (zsaddr[zs_unit] == NULL) {
/* Only map registers once. */
if (sa->sa_npromvaddrs) {
/*
* We're converting from a 32-bit pointer to a 64-bit
@ -328,7 +237,7 @@ zs_attach_sbus(parent, self, aux)
*/
zsaddr[zs_unit] =
(struct zsdevice *)
(unsigned long)sa->sa_promvaddrs[0];
(uintptr_t)sa->sa_promvaddrs[0];
} else {
bus_space_handle_t kvaddr;
@ -342,73 +251,16 @@ zs_attach_sbus(parent, self, aux)
return;
}
zsaddr[zs_unit] = (struct zsdevice *)
(long)kvaddr;
(uintptr_t)kvaddr;
}
}
/*
* Check to see if we're the console. We presume the input comes from
* the same location as the output, although that may not be true.
* To support input from the serial line but output to a display we
* would need to generate some really weird consdev vectors.
*/
if (sa->sa_node == stdinnode) {
char buf[256];
int chan = 0;
int len;
if ((len = OF_instance_to_path(sa->sa_node, buf, sizeof(buf))) > 0) {
/* With zs nodes, the last :a or :b selects the channel */
if (buf[len] == 0) len--;
if (buf[len] == 'b') chan = 1;
/* But keyboards don't have a :a or :b */
}
zs_hwflags[zs_unit][chan] = ZS_HWFLAG_CONSOLE;
zs_conschan = zs_get_chan_addr(zs_unit, chan);
if (OF_getproplen(sa->sa_node, "keyboard") >= 0) {
cn_hw = &consdev_zs;
cn = &consdev_kd;
} else {
cn = &consdev_zs;
}
}
if (cn) {
cn_tab = cn;
(*cn->cn_init)(cn);
#ifdef KGDB
zs_kgdb_init();
#endif
}
zs_attach(zsc, sa->sa_pri);
zsc->zsc_bustag = sa->sa_bustag;
zsc->zsc_dmatag = sa->sa_dmatag;
zsc->zsc_promunit = getpropint(sa->sa_node, "slave", -2);
zsc->zsc_node = sa->sa_node;
zs_attach(zsc, zsaddr[zs_unit], sa->sa_pri);
}
static void
zs_attach_obio(parent, self, aux)
struct device *parent;
struct device *self;
void *aux;
{
#ifndef SUN4U
struct zsc_softc *zsc = (void *) self;
union obio_attach_args *uoba = aux;
int zs_unit = zsc->zsc_dev.dv_unit;
/* Use the mapping setup by the Sun PROM. */
if (zsaddr[zs_unit] == NULL)
zsaddr[zs_unit] = findzs(zs_unit);
if (uoba->uoba_isobio4 == 0) {
struct sbus_attach_args *sa = &uoba->uoba_sbus;
zsc->zsc_bustag = sa->sa_bustag;
zsc->zsc_dmatag = sa->sa_dmatag;
zs_attach(zsc, sa->sa_pri);
} else {
struct obio4_attach_args *oba = &uoba->uoba_oba4;
zsc->zsc_bustag = oba->oba_bustag;
zsc->zsc_dmatag = oba->oba_dmatag;
zs_attach(zsc, oba->oba_pri);
}
#endif
}
/*
* Attach a found zs.
*
@ -416,25 +268,30 @@ zs_attach_obio(parent, self, aux)
* SOFT CARRIER, AND keyboard PROPERTY FOR KEYBOARD/MOUSE?
*/
static void
zs_attach(zsc, pri)
zs_attach(zsc, zsd, pri)
struct zsc_softc *zsc;
struct zsdevice *zsd;
int pri;
{
struct zsc_attach_args zsc_args;
volatile struct zschan *zc;
struct zs_chanstate *cs;
int s, zs_unit, channel;
static int didintr, prevpri; /* XXX: multiple sbus's with mutilple zs's? */
int s, channel;
static int didintr, prevpri;
if (zsd == NULL) {
printf("configuration incomplete\n");
return;
}
printf(" softpri %d\n", PIL_TTY);
/*
* Initialize software state for each channel.
*/
zs_unit = zsc->zsc_dev.dv_unit;
for (channel = 0; channel < 2; channel++) {
struct zschan *zc;
zsc_args.channel = channel;
zsc_args.hwflags = zs_hwflags[zs_unit][channel];
cs = &zsc->zsc_cs_store[channel];
zsc->zsc_cs[channel] = cs;
@ -443,22 +300,33 @@ zs_attach(zsc, pri)
cs->cs_ops = &zsops_null;
cs->cs_brg_clk = PCLK / 16;
zc = zs_get_chan_addr(zs_unit, channel);
if (zs_hwflags[zs_unit][channel] == ZS_HWFLAG_CONSOLE) {
zs_conschan = (struct zschan *)zc;
zc = (channel == 0) ? &zsd->zs_chan_a : &zsd->zs_chan_b;
zsc_args.hwflags = zs_console_flags(zsc->zsc_promunit,
zsc->zsc_node,
channel);
if (zsc_args.hwflags & ZS_HWFLAG_CONSOLE) {
zsc_args.hwflags |= ZS_HWFLAG_USE_CONSDEV;
zsc_args.consdev = &zs_consdev;
}
if ((zsc_args.hwflags & ZS_HWFLAG_CONSOLE_INPUT) != 0) {
zs_conschan_get = zc;
}
if ((zsc_args.hwflags & ZS_HWFLAG_CONSOLE_OUTPUT) != 0) {
zs_conschan_put = zc;
}
/* Childs need to set cn_dev, etc */
cs->cs_reg_csr = &zc->zc_csr;
cs->cs_reg_data = &zc->zc_data;
bcopy(zs_init_reg, cs->cs_creg, 16);
bcopy(zs_init_reg, cs->cs_preg, 16);
/* XXX: Get these from the PROM properties! */
/* XXX: See the mvme167 code. Better. */
if (zsc_args.hwflags & ZS_HWFLAG_CONSOLE)
cs->cs_defspeed = zs_get_speed(cs);
else
cs->cs_defspeed = zs_defspeed[zs_unit][channel];
/* XXX: Consult PROM properties for this?! */
cs->cs_defspeed = zs_get_speed(cs);
cs->cs_defcflag = zs_def_cflag;
/* Make these correspond to cs_defcflag (-crtscts) */
@ -524,7 +392,7 @@ zs_attach(zsc, pri)
* lower interrupts just enough to let zs interrupts in.
* This is done after both zs devices are attached.
*/
if (zs_unit == 1) {
if (zsc->zsc_promunit == 1) {
printf("zs1: enabling zs interrupts\n");
(void)splfd(); /* XXX: splzs - 1 */
}
@ -557,11 +425,13 @@ static int
zshard(arg)
void *arg;
{
register struct zsc_softc *zsc;
register int unit, rr3, rval, softreq;
struct zsc_softc *zsc;
int unit, rr3, rval, softreq;
rval = softreq = 0;
for (unit = 0; unit < zs_cd.cd_ndevs; unit++) {
struct zs_chanstate *cs;
zsc = zs_cd.cd_devs[unit];
if (zsc == NULL)
continue;
@ -571,8 +441,10 @@ zshard(arg)
rval |= rr3;
zsc->zsc_intrcnt.ev_count++;
}
softreq |= zsc->zsc_cs[0]->cs_softreq;
softreq |= zsc->zsc_cs[1]->cs_softreq;
if ((cs = zsc->zsc_cs[0]) != NULL)
softreq |= zsc->zsc_cs[0]->cs_softreq;
if ((cs = zsc->zsc_cs[1]) != NULL)
softreq |= zsc->zsc_cs[1]->cs_softreq;
}
/* We are at splzs here, so no need to lock. */
@ -590,8 +462,8 @@ static int
zssoft(arg)
void *arg;
{
register struct zsc_softc *zsc;
register int s, unit;
struct zsc_softc *zsc;
int s, unit;
/* This is not the only ISR on this IPL. */
if (zssoftpending == 0)
@ -752,7 +624,7 @@ u_char
zs_read_csr(cs)
struct zs_chanstate *cs;
{
register u_char val;
u_char val;
val = *cs->cs_reg_csr;
ZS_DELAY();
@ -770,7 +642,7 @@ void zs_write_csr(cs, val)
u_char zs_read_data(cs)
struct zs_chanstate *cs;
{
register u_char val;
u_char val;
val = *cs->cs_reg_data;
ZS_DELAY();
@ -793,7 +665,6 @@ void zs_write_data(cs, val)
****************************************************************/
extern void Debugger __P((void));
void *zs_conschan;
/*
* Handle user request to enter kernel debugger.
@ -802,7 +673,7 @@ void
zs_abort(cs)
struct zs_chanstate *cs;
{
register volatile struct zschan *zc = zs_conschan;
volatile struct zschan *zc = zs_conschan_get;
int rr0;
/* Wait for end of break to avoid PROM abort. */
@ -830,6 +701,7 @@ zs_abort(cs)
#endif
}
/*
* Polled input char.
*/
@ -837,8 +709,8 @@ int
zs_getc(arg)
void *arg;
{
register volatile struct zschan *zc = arg;
register int s, c, rr0;
volatile struct zschan *zc = arg;
int s, c, rr0;
s = splhigh();
/* Wait for a character to arrive. */
@ -866,8 +738,8 @@ zs_putc(arg, c)
void *arg;
int c;
{
register volatile struct zschan *zc = arg;
register int s, rr0;
volatile struct zschan *zc = arg;
int s, rr0;
s = splhigh();
@ -894,27 +766,8 @@ zs_putc(arg, c)
/*****************************************************************/
static void zscninit __P((struct consdev *));
static int zscngetc __P((dev_t));
static void zscnputc __P((dev_t, int));
static void zscnpollc __P((dev_t, int));
/*
* Console table shared by ttya, ttyb
*/
struct consdev consdev_zs = {
nullcnprobe,
zscninit,
zscngetc,
zscnputc,
zscnpollc,
NULL,
};
static void
zscninit(cn)
struct consdev *cn;
{
}
/*
* Polled console input putchar.
@ -923,7 +776,7 @@ static int
zscngetc(dev)
dev_t dev;
{
return (zs_getc(zs_conschan));
return (zs_getc(zs_conschan_get));
}
/*
@ -934,7 +787,7 @@ zscnputc(dev, c)
dev_t dev;
int c;
{
zs_putc(zs_conschan, c);
zs_putc(zs_conschan_put, c);
}
int swallow_zsintrs;
@ -954,3 +807,47 @@ zscnpollc(dev, on)
if (on) swallow_zsintrs++;
else swallow_zsintrs--;
}
int
zs_console_flags(promunit, node, channel)
int promunit;
int node;
int channel;
{
int cookie, flags = 0;
u_int chosen;
char buf[255];
/*
* We'll just to the OBP grovelling down here since that's
* the only type of firmware we support.
*/
chosen = OF_finddevice("/chosen");
/* Default to channel 0 if there are no explicit prom args */
cookie = 0;
if (node == OF_instance_to_package(OF_stdin())) {
if (OF_getprop(chosen, "input-device", buf, sizeof(buf)) != -1) {
if (!strcmp("ttyb", buf))
cookie = 1;
}
if (channel == cookie)
flags |= ZS_HWFLAG_CONSOLE_INPUT;
}
if (node == OF_instance_to_package(OF_stdout())) {
if (OF_getprop(chosen, "output-device", buf, sizeof(buf)) != -1) {
if (!strcmp("ttyb", buf))
cookie = 1;
}
if (channel == cookie)
flags |= ZS_HWFLAG_CONSOLE_OUTPUT;
}
return (flags);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: conf.h,v 1.6 2000/04/14 08:36:39 mrg Exp $ */
/* $NetBSD: conf.h,v 1.7 2000/05/19 05:26:18 eeh Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -101,3 +101,5 @@ cdev_decl(scsibus);
bdev_decl(wd);
cdev_decl(wd);
cdev_decl(pcons);

View File

@ -1,4 +1,4 @@
/* $NetBSD: z8530var.h,v 1.1.1.1 1998/06/20 04:58:52 eeh Exp $ */
/* $NetBSD: z8530var.h,v 1.2 2000/05/19 05:26:18 eeh Exp $ */
/*
* Copyright (c) 1992, 1993
@ -54,6 +54,8 @@ struct zsc_softc {
struct zs_chanstate *zsc_cs[2]; /* channel A and B soft state */
/* Machine-dependent part follows... */
int zsc_promunit; /* PROM's view of zs devices */
int zsc_node; /* PROM node, if any */
struct evcnt zsc_intrcnt; /* count interrupts */
struct zs_chanstate zsc_cs_store[2];
};

View File

@ -1,4 +1,4 @@
/* $NetBSD: autoconf.c,v 1.29 2000/04/12 11:40:12 pk Exp $ */
/* $NetBSD: autoconf.c,v 1.30 2000/05/19 05:26:18 eeh Exp $ */
/*
* Copyright (c) 1996
@ -215,6 +215,8 @@ bootstrap(nctx)
/* Moved zs_kgdb_init() to dev/zs.c:consinit(). */
zs_kgdb_init(); /* XXX */
#endif
/* Initialize the PROM console so printf will not panic */
(*cn_tab->cn_init)(cn_tab);
#ifdef DDB
db_machine_init();
#ifdef DB_ELF_SYMBOLS
@ -730,6 +732,10 @@ extern struct sparc_bus_space_tag mainbus_space_tag;
free(ma.ma_interrupts, M_DEVBUF);
free(ma.ma_address, M_DEVBUF);
}
/* Try to attach PROM console */
bzero(&ma, sizeof ma);
ma.ma_name = "pcons";
(void) config_found(dev, (void *)&ma, mbprint);
}
struct cfattach mainbus_ca = {

View File

@ -1,4 +1,4 @@
/* $NetBSD: conf.c,v 1.6 2000/04/14 13:29:58 tsutsui Exp $ */
/* $NetBSD: conf.c,v 1.7 2000/05/19 05:26:18 eeh Exp $ */
/*
* Copyright (c) 1992, 1993
@ -244,6 +244,7 @@ struct cdevsw cdevsw[] =
cdev_rnd_init(NRND,rnd), /* 119: random source pseudo-device */
cdev_scsibus_init(NSCSIBUS,scsibus), /* 120: SCSI bus */
cdev_disk_init(NRAID,raid), /* 121: RAIDframe disk driver */
cdev_tty_init(1,pcons), /* 122: PROM console */
};
int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]);
@ -405,6 +406,7 @@ static int chrtoblktbl[] = {
/*119 */ NODEV,
/*120 */ NODEV,
/*121 */ 25,
/*122 */ NODEV,
};
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: ofw_machdep.c,v 1.8 1999/05/22 20:30:54 eeh Exp $ */
/* $NetBSD: ofw_machdep.c,v 1.9 2000/05/19 05:26:18 eeh Exp $ */
/*
* Copyright (C) 1996 Wolfgang Solfrank.
@ -550,26 +550,26 @@ static u_int stdout = NULL;
int
OF_stdin()
{
u_int chosen;
if (stdin == NULL) {
u_int chosen;
if (stdin != NULL)
return stdin;
chosen = OF_finddevice("/chosen");
OF_getprop(chosen, "stdin", &stdin, sizeof(stdin));
}
chosen = OF_finddevice("/chosen");
OF_getprop(chosen, "stdin", &stdin, sizeof(stdin));
return stdin;
}
int
OF_stdout()
{
u_int chosen;
if (stdout == NULL) {
u_int chosen;
if (stdout != NULL)
return stdout;
chosen = OF_finddevice("/chosen");
OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
}
chosen = OF_finddevice("/chosen");
OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
return stdout;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: kd.c,v 1.31 2000/03/31 14:24:03 tsutsui Exp $ */
/* $NetBSD: kd.c,v 1.32 2000/05/19 05:26:17 eeh Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -382,8 +382,9 @@ kd_putfb(tp)
}
void
cons_attach_input(cc)
cons_attach_input(cc, cn)
struct cons_channel *cc;
struct consdev *cn;
{
struct kd_softc *kd = &kd_softc;

View File

@ -1,4 +1,4 @@
/* $NetBSD: kbd_zs.c,v 1.5 2000/03/30 12:45:42 augustss Exp $ */
/* $NetBSD: kbd_zs.c,v 1.6 2000/05/19 05:26:18 eeh Exp $ */
/*
* Copyright (c) 1992, 1993
@ -156,7 +156,7 @@ kbd_zs_attach(parent, self, aux)
cc->cc_iopen = kbd_cc_open;
cc->cc_iclose = kbd_cc_close;
cc->cc_upstream = NULL;
cons_attach_input(cc);
cons_attach_input(cc, args->consdev);
k->k_cc = cc;
k->k_isconsole = 1;
printf(" (console input)");

View File

@ -1,4 +1,4 @@
/* $NetBSD: kbdvar.h,v 1.5 2000/03/24 11:46:48 hannken Exp $ */
/* $NetBSD: kbdvar.h,v 1.6 2000/05/19 05:26:18 eeh Exp $ */
/*
* Copyright (c) 1992, 1993
@ -171,4 +171,4 @@ struct cons_channel {
};
/* Special hook to attach the keyboard driver to the console */
void cons_attach_input __P((struct cons_channel *));
void cons_attach_input __P((struct cons_channel *, struct consdev *));