diff options
-rw-r--r-- | sys/arch/sparc64/conf/GENERIC | 4 | ||||
-rw-r--r-- | sys/arch/sparc64/conf/RAMDISK | 4 | ||||
-rw-r--r-- | sys/arch/sparc64/conf/files.sparc64 | 10 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/cons.h | 19 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/pcons.c | 223 | ||||
-rw-r--r-- | sys/dev/wscons/wsdisplay.c | 17 | ||||
-rw-r--r-- | sys/dev/wscons/wsemul_dumb.c | 26 |
7 files changed, 270 insertions, 33 deletions
diff --git a/sys/arch/sparc64/conf/GENERIC b/sys/arch/sparc64/conf/GENERIC index 222873d74f3..2e671cb52ba 100644 --- a/sys/arch/sparc64/conf/GENERIC +++ b/sys/arch/sparc64/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.169 2007/02/28 23:02:24 deraadt Exp $ +# $OpenBSD: GENERIC,v 1.170 2007/03/07 06:23:02 miod Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -20,6 +20,7 @@ option USBVERBOSE option WSEMUL_SUN # provide sun terminal emulation; required option WSEMUL_NO_VT100 # do not provide vt100 terminal emulation +option WSEMUL_DUMB config bsd swap generic @@ -239,6 +240,7 @@ uperf* at sbus? ## PROM console driver -- if all else fails pcons0 at mainbus0 # PROM console +wsdisplay* at pcons? ## Mostek/DS1287 clocks clock* at sbus? diff --git a/sys/arch/sparc64/conf/RAMDISK b/sys/arch/sparc64/conf/RAMDISK index 80fb223cf4f..da204a1f9cb 100644 --- a/sys/arch/sparc64/conf/RAMDISK +++ b/sys/arch/sparc64/conf/RAMDISK @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISK,v 1.59 2007/02/25 22:29:41 kettenis Exp $ +# $OpenBSD: RAMDISK,v 1.60 2007/03/07 06:23:02 miod Exp $ # Machine architecture; required by config(8) machine sparc64 @@ -30,6 +30,7 @@ option BOOT_CONFIG # add support for boot -c option WSEMUL_SUN # provide sun terminal emulation; required option WSEMUL_NO_VT100 # do not provide vt100 terminal emulation +option WSEMUL_DUMB # Generic swap; second partition of root disk or network. config bsd root on rd0a @@ -228,6 +229,7 @@ sbus* at xbox? ## PROM console driver -- if all else fails pcons0 at mainbus0 # PROM console +wsdisplay* at pcons? pseudo-device rd 2 # ramdisk pseudo-device loop 1 # network loopback diff --git a/sys/arch/sparc64/conf/files.sparc64 b/sys/arch/sparc64/conf/files.sparc64 index a3d02070407..6c355acb226 100644 --- a/sys/arch/sparc64/conf/files.sparc64 +++ b/sys/arch/sparc64/conf/files.sparc64 @@ -1,4 +1,4 @@ -# $OpenBSD: files.sparc64,v 1.76 2007/02/03 20:08:50 miod Exp $ +# $OpenBSD: files.sparc64,v 1.77 2007/03/07 06:23:02 miod Exp $ # $NetBSD: files.sparc64,v 1.50 2001/08/10 20:53:50 eeh Exp $ # maxpartitions must be first item in files.${ARCH} @@ -34,10 +34,6 @@ device clkbrd attach clkbrd at fhc file arch/sparc64/dev/clkbrd.c clkbrd -device pcons -attach pcons at mainbus -file arch/sparc64/dev/pcons.c pcons needs-flag - # Sun HME Ethernet controllers device hme: ether, ifnet, mii, ifmedia file dev/ic/hme.c hme @@ -52,6 +48,10 @@ include "dev/wscons/files.wscons" include "dev/rasops/files.rasops" include "dev/wsfont/files.wsfont" +device pcons: wsemuldisplaydev +attach pcons at mainbus +file arch/sparc64/dev/pcons.c pcons needs-flag + include "dev/sbus/files.sbus" include "dev/i2o/files.i2o" include "dev/mii/files.mii" diff --git a/sys/arch/sparc64/dev/cons.h b/sys/arch/sparc64/dev/cons.h index 0234189e786..0419815fbe7 100644 --- a/sys/arch/sparc64/dev/cons.h +++ b/sys/arch/sparc64/dev/cons.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cons.h,v 1.2 2002/03/14 01:26:44 millert Exp $ */ +/* $OpenBSD: cons.h,v 1.3 2007/03/07 06:23:04 miod Exp $ */ /* $NetBSD: cons.h,v 1.3 2000/05/19 05:26:17 eeh Exp $ */ /*- @@ -29,23 +29,6 @@ * 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 timeout sc_poll_to; - 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(dev_t dev, int on); diff --git a/sys/arch/sparc64/dev/pcons.c b/sys/arch/sparc64/dev/pcons.c index 7029724e3b2..f34aa17065c 100644 --- a/sys/arch/sparc64/dev/pcons.c +++ b/sys/arch/sparc64/dev/pcons.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pcons.c,v 1.9 2005/04/26 18:54:36 miod Exp $ */ +/* $OpenBSD: pcons.c,v 1.10 2007/03/07 06:23:04 miod Exp $ */ /* $NetBSD: pcons.c,v 1.7 2001/05/02 10:32:20 scw Exp $ */ /*- @@ -56,6 +56,30 @@ #include <dev/cons.h> +#include "wsdisplay.h" + +#if NWSDISPLAY > 0 +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wsdisplayvar.h> +#endif + +struct pconssoftc { + struct device of_dev; + +#if NWSDISPLAY > 0 + int sc_wsdisplay; + u_int sc_nscreens; +#endif + + struct tty *of_tty; + struct timeout sc_poll_to; + int of_flags; +}; +/* flags: */ +#define OFPOLL 1 + +#define OFBURSTLEN 128 /* max number of bytes to write in one chunk */ + /* XXXXXXXX - this is in MI code in NetBSD */ /* * Stuff to handle debugger magic key sequences. @@ -121,8 +145,11 @@ extern struct cfdriver pcons_cd; static struct cnm_state pcons_cnm_state; static int pconsprobe(void); +static void pcons_wsdisplay_init(struct pconssoftc *); extern struct consdev *cn_tab; +cons_decl(prom_); + static int pconsmatch(parent, match, aux) struct device *parent; @@ -130,12 +157,10 @@ pconsmatch(parent, match, aux) void *aux; { struct mainbus_attach_args *ma = aux; - extern int prom_cngetc(dev_t); /* Only attach if no other console has attached. */ return (strcmp("pcons", ma->ma_name) == 0 && cn_tab->cn_getc == prom_cngetc); - } static void pcons_poll(void *); @@ -146,11 +171,35 @@ pconsattach(parent, self, aux) void *aux; { struct pconssoftc *sc = (struct pconssoftc *) self; +#if NWSDISPLAY > 0 + char buffer[128]; + extern struct consdev wsdisplay_cons; + extern int wsdisplay_getc_dummy(dev_t); +#endif printf("\n"); if (!pconsprobe()) return; +#if NWSDISPLAY > 0 + /* + * Attach a dumb wsdisplay device if a wscons input driver has + * registered as the console, or is about to do so (usb keyboards). + */ + if (wsdisplay_cons.cn_getc != wsdisplay_getc_dummy) + sc->sc_wsdisplay = 1; + else { + if (OF_getprop(OF_instance_to_package(stdin), "compatible", + buffer, sizeof(buffer)) != -1 && + strncmp("usb", buffer, 3) == 0) + sc->sc_wsdisplay = 1; + } + + if (sc->sc_wsdisplay != 0) { + pcons_wsdisplay_init(sc); + return; + } +#endif cn_init_magic(&pcons_cnm_state); cn_set_magic("+++++"); timeout_set(&sc->sc_poll_to, pcons_poll, sc); @@ -174,6 +223,10 @@ pconsopen(dev, flag, mode, p) sc = pcons_cd.cd_devs[unit]; if (!sc) return ENXIO; +#if NWSDISPLAY > 0 + if (sc->sc_wsdisplay != 0) + return ENXIO; +#endif if (!(tp = sc->of_tty)) { sc->of_tty = tp = ttymalloc(); } @@ -499,3 +552,167 @@ cn_get_magic(char *magic, int maglen) { return (EINVAL); } +#if NWSDISPLAY > 0 + +int pcons_alloc_screen(void *, const struct wsscreen_descr *, void **, + int *, int *, long *); +void pcons_cursor(void *, int, int, int); +void pcons_free_screen(void *, void *); +int pcons_ioctl(void *, u_long, caddr_t, int, struct proc *); +int pcons_mapchar(void *, int, unsigned int *); +paddr_t pcons_mmap(void *, off_t, int); +void pcons_putchar(void *, int, int, u_int, long); +int pcons_show_screen(void *, void *, int, void (*)(void *, int, int), + void *); + +struct wsdisplay_emulops pcons_emulops = { + NULL, + pcons_mapchar, + pcons_putchar +}; + +struct wsscreen_descr pcons_stdscreen = { + "dumb", 80, 34, &pcons_emulops, 12, 22, 0 +}; + +const struct wsscreen_descr *pcons_scrlist[] = { + &pcons_stdscreen +}; + +struct wsscreen_list pcons_screenlist = { + 1, pcons_scrlist +}; + +struct wsdisplay_accessops pcons_accessops = { + pcons_ioctl, + pcons_mmap, + pcons_alloc_screen, + pcons_free_screen, + pcons_show_screen +}; + +int +pcons_alloc_screen(void *v, const struct wsscreen_descr *typ, void **cookiep, + int *curxp, int *curyp, long *attrp) +{ + struct pconssoftc *sc = v; + int *rowp, *colp; + int row, col; + + if (sc->sc_nscreens > 0) + return (ENOMEM); + + row = col = 0; + if (romgetcursoraddr(&rowp, &colp) == 0) { + if (rowp != NULL) + row = *rowp; + if (colp != NULL) + col = *colp; + } + + *cookiep = v; + *attrp = 0; + *curxp = col; + *curyp = row; + + sc->sc_nscreens++; + return (0); +} + +void +pcons_free_screen(void *v, void *cookie) +{ + struct pconssoftc *sc = v; + + sc->sc_nscreens--; +} + +int +pcons_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p) +{ + switch (cmd) { + case WSDISPLAYIO_GTYPE: + *(u_int *)data = WSDISPLAY_TYPE_UNKNOWN; + break; + default: + return (-1); + } + + return (0); +} + +paddr_t +pcons_mmap(void *v, off_t off, int prot) +{ + return ((paddr_t)-1); +} + +int +pcons_show_screen(void *v, void *cookie, int waitok, + void (*cb)(void *, int, int), void *arg) +{ + return (0); +} + +int +pcons_mapchar(void *v, int uc, unsigned int *idx) +{ + if ((uc & 0xff) == uc) { + *idx = uc; + return (1); + } else { + *idx = ' '; + return (0); + } +} + +void +pcons_putchar(void *v, int row, int col, u_int uc, long attr) +{ + u_char buf[1]; + int s; + + buf[0] = (u_char)uc; + s = splhigh(); + OF_write(stdout, &buf, 1); + splx(s); +} + +void +pcons_wsdisplay_init(struct pconssoftc *sc) +{ + struct wsemuldisplaydev_attach_args waa; + int *rowp, *colp; + int options, row, col; + + row = col = 0; + if (romgetcursoraddr(&rowp, &colp) == 0) { + if (rowp != NULL) + row = *rowp; + if (colp != NULL) + col = *colp; + } + + options = OF_finddevice("/options"); + pcons_stdscreen.nrows = getpropint(options, "screen-#rows", 34); + pcons_stdscreen.ncols = getpropint(options, "screen-#columns", 80); + + /* + * We claim console here, because we can only get there if stdin + * is a keyboard. However, the PROM could have been configured with + * stdin being a keyboard and stdout being a serial sink. + * But since this combination is not supported under OpenBSD at the + * moment, it is reasonably safe to attach a dumb display as console + * here. + */ + wsdisplay_cnattach(&pcons_stdscreen, sc, col, row, 0); + + waa.console = 1; + waa.scrdata = &pcons_screenlist; + waa.accessops = &pcons_accessops; + waa.accesscookie = sc; + waa.defaultscreens = 1; + + config_found((struct device *)sc, &waa, wsemuldisplaydevprint); +} +#endif diff --git a/sys/dev/wscons/wsdisplay.c b/sys/dev/wscons/wsdisplay.c index 89b2ff521fb..8b78a22f0a0 100644 --- a/sys/dev/wscons/wsdisplay.c +++ b/sys/dev/wscons/wsdisplay.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wsdisplay.c,v 1.76 2007/02/14 00:53:48 jsg Exp $ */ +/* $OpenBSD: wsdisplay.c,v 1.77 2007/03/07 06:23:04 miod Exp $ */ /* $NetBSD: wsdisplay.c,v 1.82 2005/02/27 00:27:52 perry Exp $ */ /* @@ -777,6 +777,7 @@ wsdisplay_cnattach(const struct wsscreen_descr *type, void *cookie, int ccol, int crow, long defattr) { const struct wsemul_ops *wsemul; + const struct wsdisplay_emulops *emulops; KASSERT(!wsdisplay_console_initted); KASSERT(type->nrows > 0); @@ -784,11 +785,21 @@ wsdisplay_cnattach(const struct wsscreen_descr *type, void *cookie, int ccol, KASSERT(crow < type->nrows); KASSERT(ccol < type->ncols); - wsdisplay_console_conf.emulops = type->textops; + wsdisplay_console_conf.emulops = emulops = type->textops; wsdisplay_console_conf.emulcookie = cookie; wsdisplay_console_conf.scrdata = type; - wsemul = wsemul_pick(""); /* default */ +#ifdef WSEMUL_DUMB + /* + * If the emulops structure is crippled, force a dumb emulation. + */ + if (emulops->cursor == NULL || + emulops->copycols == NULL || emulops->copyrows == NULL || + emulops->erasecols == NULL || emulops->eraserows == NULL) + wsemul = wsemul_pick("dumb"); + else +#endif + wsemul = wsemul_pick(""); wsdisplay_console_conf.wsemul = wsemul; wsdisplay_console_conf.wsemulcookie = (*wsemul->cnattach)(type, cookie, ccol, crow, defattr); diff --git a/sys/dev/wscons/wsemul_dumb.c b/sys/dev/wscons/wsemul_dumb.c index fc8d55ea557..a347703988f 100644 --- a/sys/dev/wscons/wsemul_dumb.c +++ b/sys/dev/wscons/wsemul_dumb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wsemul_dumb.c,v 1.3 2007/02/14 01:12:16 jsg Exp $ */ +/* $OpenBSD: wsemul_dumb.c,v 1.4 2007/03/07 06:23:04 miod Exp $ */ /* $NetBSD: wsemul_dumb.c,v 1.7 2000/01/05 11:19:36 drochner Exp $ */ /* @@ -68,6 +68,7 @@ struct wsemul_dumb_emuldata { const struct wsdisplay_emulops *emulops; void *emulcookie; void *cbcookie; + int crippled; u_int nrows, ncols, crow, ccol; long defattr; }; @@ -82,10 +83,11 @@ wsemul_dumb_cnattach(type, cookie, ccol, crow, defattr) long defattr; { struct wsemul_dumb_emuldata *edp; + const struct wsdisplay_emulops *emulops; edp = &wsemul_dumb_console_emuldata; - edp->emulops = type->textops; + edp->emulops = emulops = type->textops; edp->emulcookie = cookie; edp->nrows = type->nrows; edp->ncols = type->ncols; @@ -93,6 +95,9 @@ wsemul_dumb_cnattach(type, cookie, ccol, crow, defattr) edp->ccol = ccol; edp->defattr = defattr; edp->cbcookie = NULL; + edp->crippled = emulops->cursor == NULL || + emulops->copycols == NULL || emulops->copyrows == NULL || + emulops->erasecols == NULL || emulops->eraserows == NULL; return (edp); } @@ -138,10 +143,24 @@ wsemul_dumb_output(cookie, data, count, kernel) u_char c; int n; + if (edp->crippled) { + while (count-- > 0) { + c = *data++; + + if (c == ASCII_BEL) + wsdisplay_emulbell(edp->cbcookie); + else + (*edp->emulops->putchar)(edp->emulcookie, 0, + 0, c, 0); + } + return; + } + /* XXX */ (*edp->emulops->cursor)(edp->emulcookie, 0, edp->crow, edp->ccol); while (count-- > 0) { c = *data++; + switch (c) { case ASCII_BEL: wsdisplay_emulbell(edp->cbcookie); @@ -238,6 +257,9 @@ wsemul_dumb_resetop(cookie, op) { struct wsemul_dumb_emuldata *edp = cookie; + if (edp->crippled) + return; + switch (op) { case WSEMUL_CLEARSCREEN: (*edp->emulops->eraserows)(edp->emulcookie, 0, edp->nrows, |