From 7b0be7b999199903470157428c3fe5453e6c093f Mon Sep 17 00:00:00 2001 From: Miod Vallat Date: Wed, 7 Mar 2007 06:23:05 +0000 Subject: For unsupported (yet) Expert3D style frame buffers, attach pcons and attach a really dumb wsdisplay to pcons, so that wskbd/wsmouse input drivers can be used for input, and prom for output. This is a band-aid for the release, so that people with such frame buffers do not need to unplug them or switch to serial console to install OpenBSD. Probably not the best way to do this, but this one has a minimal footprint and no tentacles in wscons. ok deraadt@ --- sys/arch/sparc64/conf/GENERIC | 4 +- sys/arch/sparc64/conf/RAMDISK | 4 +- sys/arch/sparc64/conf/files.sparc64 | 10 +- sys/arch/sparc64/dev/cons.h | 19 +-- sys/arch/sparc64/dev/pcons.c | 223 +++++++++++++++++++++++++++++++++++- sys/dev/wscons/wsdisplay.c | 17 ++- sys/dev/wscons/wsemul_dumb.c | 26 ++++- 7 files changed, 270 insertions(+), 33 deletions(-) (limited to 'sys') 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 +#include "wsdisplay.h" + +#if NWSDISPLAY > 0 +#include +#include +#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, -- cgit v1.2.3