Module Name: src
Committed By: riastradh
Date: Sun Jul 17 13:10:54 UTC 2022
Modified Files:
src/sys/dev/wsfb: genfb.c genfbvar.h
Log Message:
genfb(4): Make internal parts of struct genfb_softc private.
This way the ABI has no ifdefs, so it has a chance to be usable in
modules. This also makes genfb much easier to maintain without
worrying about ABI breakage.
To generate a diff of this commit:
cvs rdiff -u -r1.88 -r1.89 src/sys/dev/wsfb/genfb.c
cvs rdiff -u -r1.27 -r1.28 src/sys/dev/wsfb/genfbvar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/wsfb/genfb.c
diff -u src/sys/dev/wsfb/genfb.c:1.88 src/sys/dev/wsfb/genfb.c:1.89
--- src/sys/dev/wsfb/genfb.c:1.88 Sun Jul 17 13:10:04 2022
+++ src/sys/dev/wsfb/genfb.c Sun Jul 17 13:10:54 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: genfb.c,v 1.88 2022/07/17 13:10:04 riastradh Exp $ */
+/* $NetBSD: genfb.c,v 1.89 2022/07/17 13:10:54 riastradh Exp $ */
/*-
* Copyright (c) 2007 Michael Lorenz
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: genfb.c,v 1.88 2022/07/17 13:10:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: genfb.c,v 1.89 2022/07/17 13:10:54 riastradh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -75,6 +75,64 @@ __KERNEL_RCSID(0, "$NetBSD: genfb.c,v 1.
#define GENFB_BRIGHTNESS_STEP 15
#define GENFB_CHAR_WIDTH_MM 3
+struct genfb_private {
+ struct genfb_ops sc_ops;
+ struct vcons_screen sc_console_screen;
+ struct wsscreen_descr sc_defaultscreen_descr;
+ const struct wsscreen_descr *sc_screens[1];
+ struct wsscreen_list sc_screenlist;
+ struct genfb_colormap_callback *sc_cmcb;
+ struct genfb_parameter_callback *sc_backlight;
+ struct genfb_parameter_callback *sc_brightness;
+ struct genfb_mode_callback *sc_modecb;
+ int sc_backlight_level, sc_backlight_on;
+ void *sc_shadowfb;
+ bool sc_enable_shadowfb;
+ int sc_mode;
+ u_char sc_cmap_red[256];
+ u_char sc_cmap_green[256];
+ u_char sc_cmap_blue[256];
+ bool sc_want_clear;
+#ifdef SPLASHSCREEN
+ struct splash_info sc_splash;
+#endif
+ struct wsdisplay_accessops sc_accessops;
+#if GENFB_GLYPHCACHE > 0
+ /*
+ * The generic glyphcache code makes a bunch of assumptions that are
+ * true for most graphics hardware with a directly supported blitter.
+ * For example it assume that
+ * - VRAM access from the host is expensive
+ * - copying data around in VRAM is cheap and can happen in parallel
+ * to the host CPU
+ * -> therefore we draw glyphs normally if we have to, so the ( assumed
+ * to be hardware assisted ) driver supplied putchar() method doesn't
+ * need to be glyphcache aware, then copy them away for later use
+ * for genfb things are a bit different. On most hardware:
+ * - VRAM access from the host is still expensive
+ * - copying data around in VRAM is also expensive since we don't have
+ * a blitter and VRAM is mapped uncached
+ * - VRAM reads are usually slower than writes ( write combining and
+ * such help writes but not reads, and VRAM might be behind an
+ * asymmetric bus like AGP ) and must be avoided, both are much
+ * slower than main memory
+ * -> therefore we cache glyphs in main memory, no reason to map it
+ * uncached, we draw into the cache first and then copy the glyph
+ * into video memory to avoid framebuffer reads and to allow more
+ * efficient write accesses than putchar() would offer
+ * Because of this we can't use the generic code but we can recycle a
+ * few data structures.
+ */
+ uint8_t *sc_cache;
+ struct rasops_info sc_cache_ri;
+ void (*sc_putchar)(void *, int, int, u_int, long);
+ int sc_cache_cells;
+ int sc_nbuckets; /* buckets allocated */
+ gc_bucket *sc_buckets; /* we allocate as many as we can get into ram */
+ int sc_attrmap[256]; /* mapping a colour attribute to a bucket */
+#endif
+};
+
static int genfb_ioctl(void *, void *, u_long, void *, int, struct lwp *);
static paddr_t genfb_mmap(void *, void *, off_t, int);
static void genfb_pollc(void *, int);
@@ -107,11 +165,14 @@ static struct genfb_softc *genfb_softc =
void
genfb_init(struct genfb_softc *sc)
{
+ struct genfb_private *scp;
prop_dictionary_t dict;
uint64_t cmap_cb, pmf_cb, mode_cb, bl_cb, br_cb, fbaddr;
uint64_t fboffset;
bool console;
+ scp = sc->sc_private = kmem_zalloc(sizeof(*sc->sc_private), KM_SLEEP);
+
dict = device_properties(sc->sc_dev);
#ifdef GENFB_DEBUG
printf("%s", prop_dictionary_externalize(dict));
@@ -120,20 +181,20 @@ genfb_init(struct genfb_softc *sc)
if (!prop_dictionary_get_uint32(dict, "width", &sc->sc_width)) {
GPRINTF("no width property\n");
- return;
+ goto bad;
}
if (!prop_dictionary_get_uint32(dict, "height", &sc->sc_height)) {
GPRINTF("no height property\n");
- return;
+ goto bad;
}
if (!prop_dictionary_get_uint32(dict, "depth", &sc->sc_depth)) {
GPRINTF("no depth property\n");
- return;
+ goto bad;
}
if (!prop_dictionary_get_uint64(dict, "address", &fboffset)) {
GPRINTF("no address property\n");
- return;
+ goto bad;
}
sc->sc_fboffset = (bus_addr_t)fboffset;
@@ -143,13 +204,13 @@ genfb_init(struct genfb_softc *sc)
sc->sc_fbaddr = (void *)(uintptr_t)fbaddr;
}
- sc->sc_shadowfb = NULL;
+ scp->sc_shadowfb = NULL;
if (!prop_dictionary_get_bool(dict, "enable_shadowfb",
- &sc->sc_enable_shadowfb))
+ &scp->sc_enable_shadowfb))
#ifdef GENFB_SHADOWFB
- sc->sc_enable_shadowfb = true;
+ scp->sc_enable_shadowfb = true;
#else
- sc->sc_enable_shadowfb = false;
+ scp->sc_enable_shadowfb = false;
#endif
if (!prop_dictionary_get_uint32(dict, "linebytes", &sc->sc_stride))
@@ -165,10 +226,10 @@ genfb_init(struct genfb_softc *sc)
sc->sc_fbsize = sc->sc_height * sc->sc_stride;
/* optional colour map callback */
- sc->sc_cmcb = NULL;
+ scp->sc_cmcb = NULL;
if (prop_dictionary_get_uint64(dict, "cmap_callback", &cmap_cb)) {
if (cmap_cb != 0)
- sc->sc_cmcb = (void *)(vaddr_t)cmap_cb;
+ scp->sc_cmcb = (void *)(vaddr_t)cmap_cb;
}
/* optional pmf callback */
@@ -179,31 +240,31 @@ genfb_init(struct genfb_softc *sc)
}
/* optional mode callback */
- sc->sc_modecb = NULL;
+ scp->sc_modecb = NULL;
if (prop_dictionary_get_uint64(dict, "mode_callback", &mode_cb)) {
if (mode_cb != 0)
- sc->sc_modecb = (void *)(vaddr_t)mode_cb;
+ scp->sc_modecb = (void *)(vaddr_t)mode_cb;
}
/* optional backlight control callback */
- sc->sc_backlight = NULL;
+ scp->sc_backlight = NULL;
if (prop_dictionary_get_uint64(dict, "backlight_callback", &bl_cb)) {
if (bl_cb != 0) {
- sc->sc_backlight = (void *)(vaddr_t)bl_cb;
+ scp->sc_backlight = (void *)(vaddr_t)bl_cb;
aprint_naive_dev(sc->sc_dev,
"enabling backlight control\n");
}
}
/* optional brightness control callback */
- sc->sc_brightness = NULL;
+ scp->sc_brightness = NULL;
if (prop_dictionary_get_uint64(dict, "brightness_callback", &br_cb)) {
if (br_cb != 0) {
- sc->sc_brightness = (void *)(vaddr_t)br_cb;
+ scp->sc_brightness = (void *)(vaddr_t)br_cb;
aprint_naive_dev(sc->sc_dev,
"enabling brightness control\n");
if (console &&
- sc->sc_brightness->gpc_upd_parameter != NULL) {
+ scp->sc_brightness->gpc_upd_parameter != NULL) {
pmf_event_register(sc->sc_dev,
PMFE_DISPLAY_BRIGHTNESS_UP,
genfb_brightness_up, TRUE);
@@ -213,11 +274,17 @@ genfb_init(struct genfb_softc *sc)
}
}
}
+
+ return;
+
+bad: kmem_free(sc->sc_private, sizeof(*sc->sc_private));
+ sc->sc_private = NULL;
}
int
genfb_attach(struct genfb_softc *sc, struct genfb_ops *ops)
{
+ struct genfb_private *scp = sc->sc_private;
struct wsemuldisplaydev_attach_args aa;
prop_dictionary_t dict;
struct rasops_info *ri;
@@ -230,14 +297,16 @@ genfb_attach(struct genfb_softc *sc, str
int error = ENXIO;
#endif
+ KASSERTMSG(scp != NULL, "missing genfb_init");
+
dict = device_properties(sc->sc_dev);
prop_dictionary_get_bool(dict, "is_console", &console);
if (prop_dictionary_get_uint16(dict, "cursor-row", &crow) == false)
crow = 0;
- if (prop_dictionary_get_bool(dict, "clear-screen", &sc->sc_want_clear)
+ if (prop_dictionary_get_bool(dict, "clear-screen", &scp->sc_want_clear)
== false)
- sc->sc_want_clear = true;
+ scp->sc_want_clear = true;
fb_phys = (paddr_t)sc->sc_fboffset;
if (fb_phys == 0) {
@@ -251,7 +320,7 @@ genfb_attach(struct genfb_softc *sc, str
fb_phys ? (void *)(intptr_t)fb_phys : sc->sc_fbaddr,
sc->sc_width, sc->sc_height, sc->sc_depth, sc->sc_stride);
- sc->sc_defaultscreen_descr = (struct wsscreen_descr){
+ scp->sc_defaultscreen_descr = (struct wsscreen_descr){
"default",
0, 0,
NULL,
@@ -260,38 +329,39 @@ genfb_attach(struct genfb_softc *sc, str
WSSCREEN_RESIZE,
NULL
};
- sc->sc_screens[0] = &sc->sc_defaultscreen_descr;
- sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens};
- memcpy(&sc->sc_ops, ops, sizeof(struct genfb_ops));
- sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
- if (sc->sc_modecb != NULL)
- sc->sc_modecb->gmc_setmode(sc, sc->sc_mode);
-
- sc->sc_accessops.ioctl = genfb_ioctl;
- sc->sc_accessops.mmap = genfb_mmap;
- sc->sc_accessops.pollc = genfb_pollc;
-
- if (sc->sc_enable_shadowfb) {
- sc->sc_shadowfb = kmem_alloc(sc->sc_fbsize, KM_SLEEP);
- if (sc->sc_want_clear == false)
- memcpy(sc->sc_shadowfb, sc->sc_fbaddr, sc->sc_fbsize);
+ scp->sc_screens[0] = &scp->sc_defaultscreen_descr;
+ scp->sc_screenlist = (struct wsscreen_list){1, scp->sc_screens};
+ memcpy(&scp->sc_ops, ops, sizeof(struct genfb_ops));
+ scp->sc_mode = WSDISPLAYIO_MODE_EMUL;
+ if (scp->sc_modecb != NULL)
+ scp->sc_modecb->gmc_setmode(sc, scp->sc_mode);
+
+ scp->sc_accessops.ioctl = genfb_ioctl;
+ scp->sc_accessops.mmap = genfb_mmap;
+ scp->sc_accessops.pollc = genfb_pollc;
+
+ if (scp->sc_enable_shadowfb) {
+ scp->sc_shadowfb = kmem_alloc(sc->sc_fbsize, KM_SLEEP);
+ if (scp->sc_want_clear == false) {
+ memcpy(scp->sc_shadowfb, sc->sc_fbaddr, sc->sc_fbsize);
+ }
aprint_verbose_dev(sc->sc_dev,
"shadow framebuffer enabled, size %zu KB\n",
sc->sc_fbsize >> 10);
}
- vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr,
- &sc->sc_accessops);
+ vcons_init(&sc->vd, sc, &scp->sc_defaultscreen_descr,
+ &scp->sc_accessops);
sc->vd.init_screen = genfb_init_screen;
/* Do not print anything between this point and the screen
* clear operation below. Otherwise it will be lost. */
- ri = &sc->sc_console_screen.scr_ri;
+ ri = &scp->sc_console_screen.scr_ri;
- vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
+ vcons_init_screen(&sc->vd, &scp->sc_console_screen, 1,
&defattr);
- sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
+ scp->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
#if GENFB_GLYPHCACHE > 0
genfb_setup_glyphcache(sc, defattr);
@@ -304,24 +374,24 @@ genfb_attach(struct genfb_softc *sc, str
*/
if (DISABLESPLASH)
#endif
- vcons_redraw_screen(&sc->sc_console_screen);
+ vcons_redraw_screen(&scp->sc_console_screen);
- sc->sc_defaultscreen_descr.textops = &ri->ri_ops;
- sc->sc_defaultscreen_descr.capabilities = ri->ri_caps;
- sc->sc_defaultscreen_descr.nrows = ri->ri_rows;
- sc->sc_defaultscreen_descr.ncols = ri->ri_cols;
+ scp->sc_defaultscreen_descr.textops = &ri->ri_ops;
+ scp->sc_defaultscreen_descr.capabilities = ri->ri_caps;
+ scp->sc_defaultscreen_descr.nrows = ri->ri_rows;
+ scp->sc_defaultscreen_descr.ncols = ri->ri_cols;
if (crow >= ri->ri_rows) {
crow = 0;
- sc->sc_want_clear = 1;
+ scp->sc_want_clear = 1;
}
if (console)
- wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, crow,
+ wsdisplay_cnattach(&scp->sc_defaultscreen_descr, ri, 0, crow,
defattr);
/* Clear the whole screen to bring it to a known state. */
- if (sc->sc_want_clear)
+ if (scp->sc_want_clear)
(*ri->ri_ops.eraserows)(ri, 0, ri->ri_rows, defattr);
#ifdef SPLASHSCREEN
@@ -330,51 +400,51 @@ genfb_attach(struct genfb_softc *sc, str
if (i >= SPLASH_CMAP_OFFSET &&
i < SPLASH_CMAP_OFFSET + SPLASH_CMAP_SIZE) {
splash_get_cmap(i,
- &sc->sc_cmap_red[i],
- &sc->sc_cmap_green[i],
- &sc->sc_cmap_blue[i]);
+ &scp->sc_cmap_red[i],
+ &scp->sc_cmap_green[i],
+ &scp->sc_cmap_blue[i]);
} else {
- sc->sc_cmap_red[i] = rasops_cmap[j];
- sc->sc_cmap_green[i] = rasops_cmap[j + 1];
- sc->sc_cmap_blue[i] = rasops_cmap[j + 2];
+ scp->sc_cmap_red[i] = rasops_cmap[j];
+ scp->sc_cmap_green[i] = rasops_cmap[j + 1];
+ scp->sc_cmap_blue[i] = rasops_cmap[j + 2];
}
j += 3;
}
genfb_restore_palette(sc);
- sc->sc_splash.si_depth = sc->sc_depth;
- sc->sc_splash.si_bits = sc->sc_console_screen.scr_ri.ri_origbits;
- sc->sc_splash.si_hwbits = sc->sc_fbaddr;
- sc->sc_splash.si_width = sc->sc_width;
- sc->sc_splash.si_height = sc->sc_height;
- sc->sc_splash.si_stride = sc->sc_stride;
- sc->sc_splash.si_fillrect = NULL;
+ scp->sc_splash.si_depth = sc->sc_depth;
+ scp->sc_splash.si_bits = scp->sc_console_screen.scr_ri.ri_origbits;
+ scp->sc_splash.si_hwbits = sc->sc_fbaddr;
+ scp->sc_splash.si_width = sc->sc_width;
+ scp->sc_splash.si_height = sc->sc_height;
+ scp->sc_splash.si_stride = sc->sc_stride;
+ scp->sc_splash.si_fillrect = NULL;
if (!DISABLESPLASH) {
- error = splash_render(&sc->sc_splash,
+ error = splash_render(&scp->sc_splash,
SPLASH_F_CENTER|SPLASH_F_FILL);
if (error) {
- SCREEN_ENABLE_DRAWING(&sc->sc_console_screen);
+ SCREEN_ENABLE_DRAWING(&scp->sc_console_screen);
genfb_init_palette(sc);
- vcons_replay_msgbuf(&sc->sc_console_screen);
+ vcons_replay_msgbuf(&scp->sc_console_screen);
}
}
#else
genfb_init_palette(sc);
if (console && (boothowto & (AB_SILENT|AB_QUIET)) == 0)
- vcons_replay_msgbuf(&sc->sc_console_screen);
+ vcons_replay_msgbuf(&scp->sc_console_screen);
#endif
if (genfb_softc == NULL)
genfb_softc = sc;
aa.console = console;
- aa.scrdata = &sc->sc_screenlist;
- aa.accessops = &sc->sc_accessops;
+ aa.scrdata = &scp->sc_screenlist;
+ aa.accessops = &scp->sc_accessops;
aa.accesscookie = &sc->vd;
#ifdef GENFB_DISABLE_TEXT
if (!DISABLESPLASH && error == 0)
- SCREEN_DISABLE_DRAWING(&sc->sc_console_screen);
+ SCREEN_DISABLE_DRAWING(&scp->sc_console_screen);
#endif
config_found(sc->sc_dev, &aa, wsemuldisplaydevprint,
@@ -389,6 +459,7 @@ genfb_ioctl(void *v, void *vs, u_long cm
{
struct vcons_data *vd = v;
struct genfb_softc *sc = vd->cookie;
+ struct genfb_private *scp = sc->sc_private;
struct wsdisplay_fbinfo *wdf;
struct vcons_screen *ms = vd->active;
struct wsdisplay_param *param;
@@ -422,32 +493,34 @@ genfb_ioctl(void *v, void *vs, u_long cm
/* notify the bus backend */
error = 0;
- if (sc->sc_ops.genfb_ioctl)
- error = sc->sc_ops.genfb_ioctl(sc, vs,
- cmd, data, flag, l);
+ if (scp->sc_ops.genfb_ioctl) {
+ error = scp->sc_ops.genfb_ioctl(sc, vs,
+ cmd, data, flag, l);
+ }
if (error && error != EPASSTHROUGH)
return error;
- if (new_mode != sc->sc_mode) {
- sc->sc_mode = new_mode;
- if (sc->sc_modecb != NULL)
- sc->sc_modecb->gmc_setmode(sc,
- sc->sc_mode);
+ if (new_mode != scp->sc_mode) {
+ scp->sc_mode = new_mode;
+ if (scp->sc_modecb != NULL) {
+ scp->sc_modecb->gmc_setmode(sc,
+ scp->sc_mode);
+ }
if (new_mode == WSDISPLAYIO_MODE_EMUL) {
genfb_restore_palette(sc);
vcons_redraw_screen(ms);
}
}
return 0;
-
+
case WSDISPLAYIO_SSPLASH:
#if defined(SPLASHSCREEN)
if(*(int *)data == 1) {
- SCREEN_DISABLE_DRAWING(&sc->sc_console_screen);
- splash_render(&sc->sc_splash,
- SPLASH_F_CENTER|SPLASH_F_FILL);
+ SCREEN_DISABLE_DRAWING(&scp->sc_console_screen);
+ splash_render(&scp->sc_splash,
+ SPLASH_F_CENTER|SPLASH_F_FILL);
} else {
- SCREEN_ENABLE_DRAWING(&sc->sc_console_screen);
+ SCREEN_ENABLE_DRAWING(&scp->sc_console_screen);
genfb_init_palette(sc);
}
vcons_redraw_screen(ms);
@@ -459,20 +532,20 @@ genfb_ioctl(void *v, void *vs, u_long cm
param = (struct wsdisplay_param *)data;
switch (param->param) {
case WSDISPLAYIO_PARAM_BRIGHTNESS:
- if (sc->sc_brightness == NULL)
+ if (scp->sc_brightness == NULL)
return EPASSTHROUGH;
param->min = 0;
param->max = 255;
- return sc->sc_brightness->gpc_get_parameter(
- sc->sc_brightness->gpc_cookie,
+ return scp->sc_brightness->gpc_get_parameter(
+ scp->sc_brightness->gpc_cookie,
¶m->curval);
case WSDISPLAYIO_PARAM_BACKLIGHT:
- if (sc->sc_backlight == NULL)
+ if (scp->sc_backlight == NULL)
return EPASSTHROUGH;
param->min = 0;
param->max = 1;
- return sc->sc_backlight->gpc_get_parameter(
- sc->sc_backlight->gpc_cookie,
+ return scp->sc_backlight->gpc_get_parameter(
+ scp->sc_backlight->gpc_cookie,
¶m->curval);
}
return EPASSTHROUGH;
@@ -481,27 +554,27 @@ genfb_ioctl(void *v, void *vs, u_long cm
param = (struct wsdisplay_param *)data;
switch (param->param) {
case WSDISPLAYIO_PARAM_BRIGHTNESS:
- if (sc->sc_brightness == NULL)
+ if (scp->sc_brightness == NULL)
return EPASSTHROUGH;
val = param->curval;
if (val < 0) val = 0;
if (val > 255) val = 255;
- return sc->sc_brightness->gpc_set_parameter(
- sc->sc_brightness->gpc_cookie, val);
+ return scp->sc_brightness->gpc_set_parameter(
+ scp->sc_brightness->gpc_cookie, val);
case WSDISPLAYIO_PARAM_BACKLIGHT:
- if (sc->sc_backlight == NULL)
+ if (scp->sc_backlight == NULL)
return EPASSTHROUGH;
val = param->curval;
if (val < 0) val = 0;
if (val > 1) val = 1;
- return sc->sc_backlight->gpc_set_parameter(
- sc->sc_backlight->gpc_cookie, val);
+ return scp->sc_backlight->gpc_set_parameter(
+ scp->sc_backlight->gpc_cookie, val);
}
- return EPASSTHROUGH;
+ return EPASSTHROUGH;
}
ret = EPASSTHROUGH;
- if (sc->sc_ops.genfb_ioctl)
- ret = sc->sc_ops.genfb_ioctl(sc, vs, cmd, data, flag, l);
+ if (scp->sc_ops.genfb_ioctl)
+ ret = scp->sc_ops.genfb_ioctl(sc, vs, cmd, data, flag, l);
if (ret != EPASSTHROUGH)
return ret;
/*
@@ -515,7 +588,6 @@ genfb_ioctl(void *v, void *vs, u_long cm
struct wsdisplayio_edid_info *d = data;
return wsdisplayio_get_edid(sc->sc_dev, d);
}
-
case WSDISPLAYIO_GET_FBINFO: {
struct wsdisplayio_fbinfo *fbi = data;
return wsdisplayio_get_fbinfo(&ms->scr_ri, fbi);
@@ -529,9 +601,10 @@ genfb_mmap(void *v, void *vs, off_t offs
{
struct vcons_data *vd = v;
struct genfb_softc *sc = vd->cookie;
+ struct genfb_private *scp = sc->sc_private;
- if (sc->sc_ops.genfb_mmap)
- return sc->sc_ops.genfb_mmap(sc, vs, offset, prot);
+ if (scp->sc_ops.genfb_mmap)
+ return scp->sc_ops.genfb_mmap(sc, vs, offset, prot);
return -1;
}
@@ -556,6 +629,7 @@ genfb_init_screen(void *cookie, struct v
int existing, long *defattr)
{
struct genfb_softc *sc = cookie;
+ struct genfb_private *scp = sc->sc_private;
struct rasops_info *ri = &scr->scr_ri;
int wantcols;
bool is_bgr, is_swapped, is_10bit;
@@ -565,20 +639,20 @@ genfb_init_screen(void *cookie, struct v
ri->ri_height = sc->sc_height;
ri->ri_stride = sc->sc_stride;
ri->ri_flg = RI_CENTER;
- if (sc->sc_want_clear)
+ if (scp->sc_want_clear)
ri->ri_flg |= RI_FULLCLEAR;
scr->scr_flags |= VCONS_LOADFONT;
- if (sc->sc_shadowfb != NULL) {
+ if (scp->sc_shadowfb != NULL) {
ri->ri_hwbits = (char *)sc->sc_fbaddr;
- ri->ri_bits = (char *)sc->sc_shadowfb;
+ ri->ri_bits = (char *)scp->sc_shadowfb;
} else {
ri->ri_bits = (char *)sc->sc_fbaddr;
scr->scr_flags |= VCONS_DONT_READ;
}
- if (existing && sc->sc_want_clear)
+ if (existing && scp->sc_want_clear)
ri->ri_flg |= RI_CLEAR;
switch (ri->ri_depth) {
@@ -627,7 +701,7 @@ genfb_init_screen(void *cookie, struct v
break;
case 8:
- if (sc->sc_cmcb != NULL)
+ if (scp->sc_cmcb != NULL)
ri->ri_flg |= RI_ENABLE_ALPHA | RI_8BIT_IS_RGB;
break;
@@ -643,18 +717,18 @@ genfb_init_screen(void *cookie, struct v
rasops_init(ri, 0, wantcols);
ri->ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_UNDERLINE |
- WSSCREEN_RESIZE;
+ WSSCREEN_RESIZE;
rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
- sc->sc_width / ri->ri_font->fontwidth);
+ sc->sc_width / ri->ri_font->fontwidth);
ri->ri_hw = scr;
#if GENFB_GLYPHCACHE > 0
- sc->sc_putchar = ri->ri_ops.putchar;
+ scp->sc_putchar = ri->ri_ops.putchar;
ri->ri_ops.putchar = genfb_putchar;
#endif
#ifdef GENFB_DISABLE_TEXT
- if (scr == &sc->sc_console_screen && !DISABLESPLASH)
- SCREEN_DISABLE_DRAWING(&sc->sc_console_screen);
+ if (scr == &scp->sc_console_screen && !DISABLESPLASH)
+ SCREEN_DISABLE_DRAWING(&scp->sc_console_screen);
#endif
}
@@ -702,6 +776,7 @@ genfb_calc_cols(struct genfb_softc *sc,
static int
genfb_putcmap(struct genfb_softc *sc, struct wsdisplay_cmap *cm)
{
+ struct genfb_private *scp = sc->sc_private;
u_char *r, *g, *b;
u_int index = cm->index;
u_int count = cm->count;
@@ -724,13 +799,13 @@ genfb_putcmap(struct genfb_softc *sc, st
if (error)
return error;
- memcpy(&sc->sc_cmap_red[index], &rbuf[index], count);
- memcpy(&sc->sc_cmap_green[index], &gbuf[index], count);
- memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count);
-
- r = &sc->sc_cmap_red[index];
- g = &sc->sc_cmap_green[index];
- b = &sc->sc_cmap_blue[index];
+ memcpy(&scp->sc_cmap_red[index], &rbuf[index], count);
+ memcpy(&scp->sc_cmap_green[index], &gbuf[index], count);
+ memcpy(&scp->sc_cmap_blue[index], &bbuf[index], count);
+
+ r = &scp->sc_cmap_red[index];
+ g = &scp->sc_cmap_green[index];
+ b = &scp->sc_cmap_blue[index];
for (i = 0; i < count; i++) {
genfb_putpalreg(sc, index, *r, *g, *b);
@@ -743,6 +818,7 @@ genfb_putcmap(struct genfb_softc *sc, st
static int
genfb_getcmap(struct genfb_softc *sc, struct wsdisplay_cmap *cm)
{
+ struct genfb_private *scp = sc->sc_private;
u_int index = cm->index;
u_int count = cm->count;
int error;
@@ -750,13 +826,13 @@ genfb_getcmap(struct genfb_softc *sc, st
if (index >= 256 || count > 256 || index + count > 256)
return EINVAL;
- error = copyout(&sc->sc_cmap_red[index], cm->red, count);
+ error = copyout(&scp->sc_cmap_red[index], cm->red, count);
if (error)
return error;
- error = copyout(&sc->sc_cmap_green[index], cm->green, count);
+ error = copyout(&scp->sc_cmap_green[index], cm->green, count);
if (error)
return error;
- error = copyout(&sc->sc_cmap_blue[index], cm->blue, count);
+ error = copyout(&scp->sc_cmap_blue[index], cm->blue, count);
if (error)
return error;
@@ -766,12 +842,13 @@ genfb_getcmap(struct genfb_softc *sc, st
void
genfb_restore_palette(struct genfb_softc *sc)
{
+ struct genfb_private *scp = sc->sc_private;
int i;
if (sc->sc_depth <= 8) {
for (i = 0; i < (1 << sc->sc_depth); i++) {
- genfb_putpalreg(sc, i, sc->sc_cmap_red[i],
- sc->sc_cmap_green[i], sc->sc_cmap_blue[i]);
+ genfb_putpalreg(sc, i, scp->sc_cmap_red[i],
+ scp->sc_cmap_green[i], scp->sc_cmap_blue[i]);
}
}
}
@@ -779,6 +856,7 @@ genfb_restore_palette(struct genfb_softc
static void
genfb_init_palette(struct genfb_softc *sc)
{
+ struct genfb_private *scp = sc->sc_private;
int i, j, tmp;
if (sc->sc_depth == 8) {
@@ -790,28 +868,28 @@ genfb_init_palette(struct genfb_softc *s
* in order to make white look actually white
*/
tmp |= (tmp >> 3) | (tmp >> 6);
- sc->sc_cmap_red[i] = tmp;
+ scp->sc_cmap_red[i] = tmp;
tmp = (i & 0x1c) << 3;
tmp |= (tmp >> 3) | (tmp >> 6);
- sc->sc_cmap_green[i] = tmp;
+ scp->sc_cmap_green[i] = tmp;
tmp = (i & 0x03) << 6;
tmp |= tmp >> 2;
tmp |= tmp >> 4;
- sc->sc_cmap_blue[i] = tmp;
+ scp->sc_cmap_blue[i] = tmp;
- genfb_putpalreg(sc, i, sc->sc_cmap_red[i],
- sc->sc_cmap_green[i],
- sc->sc_cmap_blue[i]);
+ genfb_putpalreg(sc, i, scp->sc_cmap_red[i],
+ scp->sc_cmap_green[i],
+ scp->sc_cmap_blue[i]);
}
} else {
/* steal rasops' ANSI cmap */
j = 0;
for (i = 0; i < 256; i++) {
- sc->sc_cmap_red[i] = rasops_cmap[j];
- sc->sc_cmap_green[i] = rasops_cmap[j + 1];
- sc->sc_cmap_blue[i] = rasops_cmap[j + 2];
+ scp->sc_cmap_red[i] = rasops_cmap[j];
+ scp->sc_cmap_green[i] = rasops_cmap[j + 1];
+ scp->sc_cmap_blue[i] = rasops_cmap[j + 2];
j += 3;
}
}
@@ -821,10 +899,10 @@ static int
genfb_putpalreg(struct genfb_softc *sc, uint8_t idx, uint8_t r, uint8_t g,
uint8_t b)
{
+ struct genfb_private *scp = sc->sc_private;
- if (sc->sc_cmcb) {
-
- sc->sc_cmcb->gcc_set_mapreg(sc->sc_cmcb->gcc_cookie,
+ if (scp->sc_cmcb) {
+ scp->sc_cmcb->gcc_set_mapreg(scp->sc_cmcb->gcc_cookie,
idx, r, g, b);
}
return 0;
@@ -870,8 +948,8 @@ genfb_borrow(bus_addr_t addr, bus_space_
{
struct genfb_softc *sc = genfb_softc;
- if (sc && sc->sc_ops.genfb_borrow)
- return sc->sc_ops.genfb_borrow(sc, addr, hdlp);
+ if (sc && sc->sc_private && sc->sc_private->sc_ops.genfb_borrow)
+ return sc->sc_private->sc_ops.genfb_borrow(sc, addr, hdlp);
return 0;
}
@@ -879,37 +957,40 @@ static void
genfb_brightness_up(device_t dev)
{
struct genfb_softc *sc = device_private(dev);
+ struct genfb_private *scp = sc->sc_private;
- KASSERT(sc->sc_brightness != NULL);
- KASSERT(sc->sc_brightness->gpc_upd_parameter != NULL);
+ KASSERT(scp->sc_brightness != NULL);
+ KASSERT(scp->sc_brightness->gpc_upd_parameter != NULL);
- (void)sc->sc_brightness->gpc_upd_parameter(
- sc->sc_brightness->gpc_cookie, GENFB_BRIGHTNESS_STEP);
+ (void)scp->sc_brightness->gpc_upd_parameter(
+ scp->sc_brightness->gpc_cookie, GENFB_BRIGHTNESS_STEP);
}
static void
genfb_brightness_down(device_t dev)
{
struct genfb_softc *sc = device_private(dev);
+ struct genfb_private *scp = sc->sc_private;
- KASSERT(sc->sc_brightness != NULL);
- KASSERT(sc->sc_brightness->gpc_upd_parameter != NULL);
+ KASSERT(scp->sc_brightness != NULL);
+ KASSERT(scp->sc_brightness->gpc_upd_parameter != NULL);
- (void)sc->sc_brightness->gpc_upd_parameter(
- sc->sc_brightness->gpc_cookie, - GENFB_BRIGHTNESS_STEP);
+ (void)scp->sc_brightness->gpc_upd_parameter(
+ scp->sc_brightness->gpc_cookie, -GENFB_BRIGHTNESS_STEP);
}
void
genfb_enable_polling(device_t dev)
{
struct genfb_softc *sc = device_private(dev);
+ struct genfb_private *scp = sc->sc_private;
- if (sc->sc_console_screen.scr_vd) {
- SCREEN_ENABLE_DRAWING(&sc->sc_console_screen);
- vcons_hard_switch(&sc->sc_console_screen);
+ if (scp->sc_console_screen.scr_vd) {
+ SCREEN_ENABLE_DRAWING(&scp->sc_console_screen);
+ vcons_hard_switch(&scp->sc_console_screen);
vcons_enable_polling(&sc->vd);
- if (sc->sc_ops.genfb_enable_polling)
- (*sc->sc_ops.genfb_enable_polling)(sc);
+ if (scp->sc_ops.genfb_enable_polling)
+ (*scp->sc_ops.genfb_enable_polling)(sc);
}
}
@@ -917,10 +998,11 @@ void
genfb_disable_polling(device_t dev)
{
struct genfb_softc *sc = device_private(dev);
+ struct genfb_private *scp = sc->sc_private;
- if (sc->sc_console_screen.scr_vd) {
- if (sc->sc_ops.genfb_disable_polling)
- (*sc->sc_ops.genfb_disable_polling)(sc);
+ if (scp->sc_console_screen.scr_vd) {
+ if (scp->sc_ops.genfb_disable_polling)
+ (*scp->sc_ops.genfb_disable_polling)(sc);
vcons_disable_polling(&sc->vd);
}
}
@@ -933,32 +1015,33 @@ attr2idx(long attr)
{
if ((attr & 0xf0f00ff8) != 0)
return -1;
-
+
return (((attr >> 16) & 0x0f) | ((attr >> 20) & 0xf0));
}
static int
genfb_setup_glyphcache(struct genfb_softc *sc, long defattr)
{
- struct rasops_info *ri = &sc->sc_console_screen.scr_ri,
- *cri = &sc->sc_cache_ri;
+ struct genfb_private *scp = sc->sc_private;
+ struct rasops_info *ri = &scp->sc_console_screen.scr_ri,
+ *cri = &scp->sc_cache_ri;
gc_bucket *b;
int i, usedcells = 0, idx, j;
- sc->sc_cache = kmem_alloc(GLYPHCACHESIZE, KM_SLEEP);
+ scp->sc_cache = kmem_alloc(GLYPHCACHESIZE, KM_SLEEP);
/*
* now we build a mutant rasops_info for the cache - same pixel type
- * and such as the real fb, but only one character per line for
+ * and such as the real fb, but only one character per line for
* simplicity and locality
*/
memcpy(cri, ri, sizeof(struct rasops_info));
- cri->ri_ops.putchar = sc->sc_putchar;
+ cri->ri_ops.putchar = scp->sc_putchar;
cri->ri_width = ri->ri_font->fontwidth;
cri->ri_stride = ri->ri_xscale;
- cri->ri_bits = sc->sc_cache;
+ cri->ri_bits = scp->sc_cache;
cri->ri_hwbits = NULL;
- cri->ri_origbits = sc->sc_cache;
+ cri->ri_origbits = scp->sc_cache;
cri->ri_cols = 1;
cri->ri_rows = GLYPHCACHESIZE /
(cri->ri_stride * cri->ri_font->fontheight);
@@ -966,14 +1049,15 @@ genfb_setup_glyphcache(struct genfb_soft
cri->ri_yorigin = 0;
cri->ri_xscale = ri->ri_xscale;
cri->ri_yscale = ri->ri_font->fontheight * ri->ri_xscale;
-
+
printf("size %d %d %d\n", GLYPHCACHESIZE, ri->ri_width, ri->ri_stride);
printf("cells: %d\n", cri->ri_rows);
- sc->sc_nbuckets = uimin(256, cri->ri_rows / 223);
- sc->sc_buckets = kmem_alloc(sizeof(gc_bucket) * sc->sc_nbuckets, KM_SLEEP);
- printf("buckets: %d\n", sc->sc_nbuckets);
- for (i = 0; i < sc->sc_nbuckets; i++) {
- b = &sc->sc_buckets[i];
+ scp->sc_nbuckets = uimin(256, cri->ri_rows / 223);
+ scp->sc_buckets = kmem_alloc(sizeof(gc_bucket) * scp->sc_nbuckets,
+ KM_SLEEP);
+ printf("buckets: %d\n", scp->sc_nbuckets);
+ for (i = 0; i < scp->sc_nbuckets; i++) {
+ b = &scp->sc_buckets[i];
b->gb_firstcell = usedcells;
b->gb_numcells = uimin(223, cri->ri_rows - usedcells);
usedcells += 223;
@@ -984,18 +1068,18 @@ genfb_setup_glyphcache(struct genfb_soft
/* initialize the attribute map... */
for (i = 0; i < 256; i++) {
- sc->sc_attrmap[i] = -1;
+ scp->sc_attrmap[i] = -1;
}
/* first bucket goes to default attr */
idx = attr2idx(defattr);
printf("defattr %08lx idx %x\n", defattr, idx);
-
+
if (idx >= 0) {
- sc->sc_attrmap[idx] = 0;
- sc->sc_buckets[0].gb_index = idx;
+ scp->sc_attrmap[idx] = 0;
+ scp->sc_buckets[0].gb_index = idx;
}
-
+
return 0;
}
@@ -1005,6 +1089,7 @@ genfb_putchar(void *cookie, int row, int
struct rasops_info *ri = cookie;
struct vcons_screen *scr = ri->ri_hw;
struct genfb_softc *sc = scr->scr_cookie;
+ struct genfb_private *scp = sc->sc_private;
uint8_t *src, *dst, *hwdst;
gc_bucket *b;
int i, idx, bi, cell;
@@ -1015,18 +1100,18 @@ genfb_putchar(void *cookie, int row, int
if (c < 33 || c > 255 || idx < 0) goto nope;
/* look for a bucket with the right attribute */
- bi = sc->sc_attrmap[idx];
+ bi = scp->sc_attrmap[idx];
if (bi == -1) {
/* nope, see if there's an empty one left */
bi = 1;
- while ((bi < sc->sc_nbuckets) &&
- (sc->sc_buckets[bi].gb_index != -1)) {
+ while ((bi < scp->sc_nbuckets) &&
+ (scp->sc_buckets[bi].gb_index != -1)) {
bi++;
}
- if (bi < sc->sc_nbuckets) {
+ if (bi < scp->sc_nbuckets) {
/* found one -> grab it */
- sc->sc_attrmap[idx] = bi;
- b = &sc->sc_buckets[bi];
+ scp->sc_attrmap[idx] = bi;
+ b = &scp->sc_buckets[bi];
b->gb_index = idx;
b->gb_usedcells = 0;
/* make sure this doesn't get evicted right away */
@@ -1039,19 +1124,19 @@ genfb_putchar(void *cookie, int row, int
time_t moo = time_uptime;
int oldest = 1;
- for (i = 1; i < sc->sc_nbuckets; i++) {
- if (sc->sc_buckets[i].gb_lastread < moo) {
+ for (i = 1; i < scp->sc_nbuckets; i++) {
+ if (scp->sc_buckets[i].gb_lastread < moo) {
oldest = i;
- moo = sc->sc_buckets[i].gb_lastread;
+ moo = scp->sc_buckets[i].gb_lastread;
}
}
/* if we end up here all buckets must be in use */
- b = &sc->sc_buckets[oldest];
- sc->sc_attrmap[b->gb_index] = -1;
+ b = &scp->sc_buckets[oldest];
+ scp->sc_attrmap[b->gb_index] = -1;
b->gb_index = idx;
b->gb_usedcells = 0;
- sc->sc_attrmap[idx] = oldest;
+ scp->sc_attrmap[idx] = oldest;
/* now scrub it */
for (i = 0; i < 223; i++)
b->gb_map[i] = -1;
@@ -1060,7 +1145,7 @@ genfb_putchar(void *cookie, int row, int
}
} else {
/* found one */
- b = &sc->sc_buckets[bi];
+ b = &scp->sc_buckets[bi];
}
/* see if there's room in the bucket */
@@ -1073,12 +1158,11 @@ genfb_putchar(void *cookie, int row, int
cell = atomic_add_int_nv(&b->gb_usedcells, 1) - 1;
b->gb_map[c - 33] = cell;
cell += b->gb_firstcell;
- sc->sc_putchar(&sc->sc_cache_ri, cell, 0, c, attr);
-
+ scp->sc_putchar(&scp->sc_cache_ri, cell, 0, c, attr);
} else
cell += b->gb_firstcell;
- src = sc->sc_cache + cell * sc->sc_cache_ri.ri_yscale;
+ src = scp->sc_cache + cell * scp->sc_cache_ri.ri_yscale;
dst = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
for (i = 0; i < ri->ri_font->fontheight; i++) {
memcpy(dst, src, ri->ri_xscale);
@@ -1086,7 +1170,7 @@ genfb_putchar(void *cookie, int row, int
dst += ri->ri_stride;
}
if (ri->ri_hwbits) {
- src = sc->sc_cache + cell * sc->sc_cache_ri.ri_yscale;
+ src = scp->sc_cache + cell * scp->sc_cache_ri.ri_yscale;
hwdst = ri->ri_hwbits
+ row * ri->ri_yscale + col * ri->ri_xscale;
for (i = 0; i < ri->ri_font->fontheight; i++) {
@@ -1098,7 +1182,7 @@ genfb_putchar(void *cookie, int row, int
b->gb_lastread = time_uptime;
return;
nope:
- sc->sc_putchar(cookie, row, col, c, attr);
+ scp->sc_putchar(cookie, row, col, c, attr);
}
#endif
Index: src/sys/dev/wsfb/genfbvar.h
diff -u src/sys/dev/wsfb/genfbvar.h:1.27 src/sys/dev/wsfb/genfbvar.h:1.28
--- src/sys/dev/wsfb/genfbvar.h:1.27 Mon Mar 28 11:21:40 2022
+++ src/sys/dev/wsfb/genfbvar.h Sun Jul 17 13:10:54 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: genfbvar.h,v 1.27 2022/03/28 11:21:40 mlelstv Exp $ */
+/* $NetBSD: genfbvar.h,v 1.28 2022/07/17 13:10:54 riastradh Exp $ */
/*-
* Copyright (c) 2007 Michael Lorenz
@@ -102,68 +102,13 @@ struct genfb_mode_callback {
struct genfb_softc {
device_t sc_dev;
+ struct genfb_private *sc_private;
struct vcons_data vd;
- struct genfb_ops sc_ops;
- struct vcons_screen sc_console_screen;
- struct wsscreen_descr sc_defaultscreen_descr;
- const struct wsscreen_descr *sc_screens[1];
- struct wsscreen_list sc_screenlist;
- struct genfb_colormap_callback *sc_cmcb;
struct genfb_pmf_callback *sc_pmfcb;
- struct genfb_parameter_callback *sc_backlight;
- struct genfb_parameter_callback *sc_brightness;
- struct genfb_mode_callback *sc_modecb;
- int sc_backlight_level, sc_backlight_on;
void *sc_fbaddr; /* kva */
- void *sc_shadowfb;
- bool sc_enable_shadowfb;
bus_addr_t sc_fboffset; /* bus address */
int sc_width, sc_height, sc_stride, sc_depth;
size_t sc_fbsize;
- int sc_mode;
- u_char sc_cmap_red[256];
- u_char sc_cmap_green[256];
- u_char sc_cmap_blue[256];
- bool sc_want_clear;
-#ifdef SPLASHSCREEN
- struct splash_info sc_splash;
-#endif
- struct wsdisplay_accessops sc_accessops;
-#if GENFB_GLYPHCACHE > 0
- /*
- * The generic glyphcache code makes a bunch of assumptions that are
- * true for most graphics hardware with a directly supported blitter.
- * For example it assume that
- * - VRAM access from the host is expensive
- * - copying data around in VRAM is cheap and can happen in parallel
- * to the host CPU
- * -> therefore we draw glyphs normally if we have to, so the ( assumed
- * to be hardware assisted ) driver supplied putchar() method doesn't
- * need to be glyphcache aware, then copy them away for later use
- * for genfb things are a bit different. On most hardware:
- * - VRAM access from the host is still expensive
- * - copying data around in VRAM is also expensive since we don't have
- * a blitter and VRAM is mapped uncached
- * - VRAM reads are usually slower than writes ( write combining and
- * such help writes but not reads, and VRAM might be behind an
- * asymmetric bus like AGP ) and must be avoided, both are much
- * slower than main memory
- * -> therefore we cache glyphs in main memory, no reason to map it
- * uncached, we draw into the cache first and then copy the glyph
- * into video memory to avoid framebuffer reads and to allow more
- * efficient write accesses than putchar() would offer
- * Because of this we can't use the generic code but we can recycle a
- * few data structures.
- */
- uint8_t *sc_cache;
- struct rasops_info sc_cache_ri;
- void (*sc_putchar)(void *, int, int, u_int, long);
- int sc_cache_cells;
- int sc_nbuckets; /* buckets allocated */
- gc_bucket *sc_buckets; /* we allocate as many as we can get into ram */
- int sc_attrmap[256]; /* mapping a colour attribute to a bucket */
-#endif
-
};
void genfb_cnattach(void);