diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2017-08-27 12:42:23 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2017-08-27 12:42:23 +0000 |
commit | 52004fdc7f039354116cfffa13fd53937398d606 (patch) | |
tree | a0b717b59e3315796bc8d39f8ebd0e02dd20243a /sys/dev | |
parent | b6c82a4368d687d945dda9021d20427474b78503 (diff) |
Add glass console support for arm64. This uses the "stdout-path" property
of the /chosen node in the device tree to decide whether the framebuffer
should be used as the console device. Most, if not all, machines will
have that set to use a serial console and there is no easy way yet to
change that.
ok jsg@
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/fdt/simplefb.c | 160 |
1 files changed, 127 insertions, 33 deletions
diff --git a/sys/dev/fdt/simplefb.c b/sys/dev/fdt/simplefb.c index 2a3e1c7d715..893dafea658 100644 --- a/sys/dev/fdt/simplefb.c +++ b/sys/dev/fdt/simplefb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: simplefb.c,v 1.1 2017/01/03 19:57:01 kettenis Exp $ */ +/* $OpenBSD: simplefb.c,v 1.2 2017/08/27 12:42:22 kettenis Exp $ */ /* * Copyright (c) 2016 Mark Kettenis * @@ -29,6 +29,9 @@ #include <dev/wscons/wsdisplayvar.h> #include <dev/rasops/rasops.h> +#define SIMPLEFB_WIDTH 160 +#define SIMPLEFB_HEIGHT 50 + struct simplefb_format { const char *format; int depth; @@ -46,9 +49,10 @@ struct simplefb_format simplefb_formats[] = { { "x1r5g5b5", 15 }, { "a1r5g5b5", 15 }, { "r8g8b8", 24 }, - { "x8r8g8b8", 32 }, - { "a8r8g8b8", 32 }, - { "a8b8g8r8", 32, 0, 8, 8, 8, 16, 8 } + { "x8r8g8b8", 32, 16, 8, 8, 8, 0, 8 }, + { "a8r8g8b8", 32, 16, 8, 8, 8, 0, 8 }, + { "x8b8g8r8", 32 }, + { "a8b8g8r8", 32 } }; struct simplefb_softc { @@ -66,6 +70,10 @@ struct simplefb_softc { psize_t sc_psize; }; +struct rasops_info simplefb_ri; +struct wsscreen_descr simplefb_wsd = { "std" }; +struct wsdisplay_charcell simplefb_bs[SIMPLEFB_WIDTH * SIMPLEFB_HEIGHT]; + int simplefb_match(struct device *, void *, void *); void simplefb_attach(struct device *, struct device *, void *); @@ -77,6 +85,8 @@ struct cfdriver simplefb_cd = { NULL, "simplefb", DV_DULL }; +const char *simplefb_init(int, struct rasops_info *); + int simplefb_wsioctl(void *, u_long, caddr_t, int, struct proc *); paddr_t simplefb_wsmmap(void *, off_t, int); int simplefb_alloc_screen(void *, const struct wsscreen_descr *, @@ -108,52 +118,44 @@ simplefb_attach(struct device *parent, struct device *self, void *aux) struct fdt_attach_args *faa = aux; struct rasops_info *ri = &sc->sc_ri; struct wsemuldisplaydev_attach_args waa; - char format[16]; - int i; + const char *format; + int console = 0; + long defattr; if (faa->fa_nreg < 1) return; - format[0] = 0; - OF_getprop(faa->fa_node, "format", format, sizeof(format)); - format[sizeof(format) - 1] = 0; - - for (i = 0; i < nitems(simplefb_formats); i++) { - if (strcmp(format, simplefb_formats[i].format) == 0) { - sc->sc_format = &simplefb_formats[i]; - break; - } - } - if (sc->sc_format == NULL) { + format = simplefb_init(faa->fa_node, ri); + if (format) { printf(": unsupported format \"%s\"\n", format); return; } + if (faa->fa_node == stdout_node) + console = 1; + sc->sc_iot = faa->fa_iot; sc->sc_paddr = faa->fa_reg[0].addr; sc->sc_psize = faa->fa_reg[0].size; if (bus_space_map(sc->sc_iot, sc->sc_paddr, sc->sc_psize, - BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE, &sc->sc_ioh)) - panic("%s: bus_space_map failed!", __func__); - - ri->ri_width = OF_getpropint(faa->fa_node, "width", 0); - ri->ri_height = OF_getpropint(faa->fa_node, "height", 0); - ri->ri_stride = OF_getpropint(faa->fa_node, "stride", 0); - ri->ri_depth = sc->sc_format->depth; - ri->ri_rpos = sc->sc_format->rpos; - ri->ri_rnum = sc->sc_format->rnum; - ri->ri_gpos = sc->sc_format->gpos; - ri->ri_gnum = sc->sc_format->gnum; - ri->ri_bpos = sc->sc_format->bpos; - ri->ri_bnum = sc->sc_format->bnum; - ri->ri_flg = RI_CENTER | RI_CLEAR | RI_FULLCLEAR; - ri->ri_flg |= RI_VCONS | RI_WRONLY; + BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE, &sc->sc_ioh)) { + printf(": can't map framebuffer\n"); + return; + } + ri->ri_bits = bus_space_vaddr(sc->sc_iot, sc->sc_ioh); ri->ri_hw = sc; + if (console) { + /* Preserve contents. */ + ri->ri_bs = simplefb_bs; + ri->ri_flg &= ~RI_CLEAR; + } + printf(": %dx%d\n", ri->ri_width, ri->ri_height); - rasops_init(ri, 160, 160); + ri->ri_flg |= RI_VCONS; + rasops_init(ri, SIMPLEFB_HEIGHT, SIMPLEFB_WIDTH); strlcpy(sc->sc_wsd.name, "std", sizeof(sc->sc_wsd.name)); sc->sc_wsd.capabilities = ri->ri_caps; @@ -167,15 +169,57 @@ simplefb_attach(struct device *parent, struct device *self, void *aux) sc->sc_wsl.nscreens = 1; sc->sc_wsl.screens = (const struct wsscreen_descr **)sc->sc_scrlist; + if (console) { + ri->ri_ops.alloc_attr(ri->ri_active, 0, 0, 0, &defattr); + wsdisplay_cnattach(&sc->sc_wsd, ri->ri_active, + simplefb_ri.ri_ccol, simplefb_ri.ri_crow, defattr); + } + memset(&waa, 0, sizeof(waa)); waa.scrdata = &sc->sc_wsl; waa.accessops = &simplefb_accessops; waa.accesscookie = ri; + waa.console = console; config_found_sm(self, &waa, wsemuldisplaydevprint, wsemuldisplaydevsubmatch); } +const char * +simplefb_init(int node, struct rasops_info *ri) +{ + struct simplefb_format *fmt = NULL; + static char format[16]; + int i; + + format[0] = 0; + OF_getprop(node, "format", format, sizeof(format)); + format[sizeof(format) - 1] = 0; + + for (i = 0; i < nitems(simplefb_formats); i++) { + if (strcmp(format, simplefb_formats[i].format) == 0) { + fmt = &simplefb_formats[i]; + break; + } + } + if (fmt == NULL) + return format; + + ri->ri_width = OF_getpropint(node, "width", 0); + ri->ri_height = OF_getpropint(node, "height", 0); + ri->ri_stride = OF_getpropint(node, "stride", 0); + ri->ri_depth = fmt->depth; + ri->ri_rpos = fmt->rpos; + ri->ri_rnum = fmt->rnum; + ri->ri_gpos = fmt->gpos; + ri->ri_gnum = fmt->gnum; + ri->ri_bpos = fmt->bpos; + ri->ri_bnum = fmt->bnum; + ri->ri_flg = RI_CENTER | RI_CLEAR | RI_FULLCLEAR | RI_WRONLY; + + return NULL; +} + int simplefb_wsioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) { @@ -241,3 +285,53 @@ simplefb_alloc_screen(void *v, const struct wsscreen_descr *type, { return rasops_alloc_screen(v, cookiep, curxp, curyp, attrp); } + +#include "ukbd.h" + +#if NUKBD > 0 +#include <dev/usb/ukbdvar.h> +#endif + +void +simplefb_init_cons(bus_space_tag_t iot) +{ + struct rasops_info *ri = &simplefb_ri; + bus_space_handle_t ioh; + struct fdt_reg reg; + void *node; + long defattr = 0; + + node = fdt_find_cons("simple-framebuffer"); + if (node == NULL) + return; + + if (fdt_get_reg(node, 0, ®)) + return; + + if (bus_space_map(iot, reg.addr, reg.size, + BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE, &ioh)) + return; + + ri->ri_bits = bus_space_vaddr(iot, ioh); + + if (simplefb_init(stdout_node, ri)) + return; + + ri->ri_bs = simplefb_bs; + rasops_init(ri, SIMPLEFB_HEIGHT, SIMPLEFB_WIDTH); + + simplefb_wsd.capabilities = ri->ri_caps; + simplefb_wsd.ncols = ri->ri_cols; + simplefb_wsd.nrows = ri->ri_rows; + simplefb_wsd.textops = &ri->ri_ops; + simplefb_wsd.fontwidth = ri->ri_font->fontwidth; + simplefb_wsd.fontheight = ri->ri_font->fontheight; + + ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr); + wsdisplay_cnattach(&simplefb_wsd, ri, 0, 0, defattr); + +#if NUKBD > 0 + /* Allow USB keyboards to become the console input device. */ + ukbd_cnattach(); +#endif +} |