NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/42605: Replacing vesafb with genfb broke SPLASHSCREEN on i386



>Number:         42605
>Category:       kern
>Synopsis:       Replacing vesafb with genfb broke SPLASHSCREEN on i386
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jan 10 23:45:00 +0000 2010
>Originator:     Pierre Pronchery <khorben%defora.org@localhost>
>Release:        NetBSD 5.99.x
>Organization:
>Environment:
Architecture: i386
Machine: i386
>Description:

The vesafb driver was able to provide a framebuffer-based console during
the booting process, and then display a splash screen logo, with an
optional progress animation (SPLASHSCREEN_PROGRESS). Jared Mc Neill
introduced it in this message:
http://mail-index.netbsd.org/current-users/2006/02/18/0018.html

It had a number of limitations though, described by Jared again here:
http://blog.netbsd.org/tnf/entry/heads_up_x86_framebuffer_console
and here:
http://mail-index.netbsd.org/port-i386/2009/02/16/msg001242.html

This announced the replacement of vesafb by genfb, allowing to boot
NetBSD consoles on amd64 with higher resolutions (yay!).

Unfortunately, genfb doesn't support SPLASHSCREEN, which is therefore
not working on i386 anymore (where it did with vesafb). I have therefore
patched the genfb driver with what I think should provide it (found
below).

Unfortunately, I couldn't confirm that it works natively on my machine
(all black or all white screen, ThinkPad T60 amd64), and not better (but
not worse) than before when emulated (qemu amd64, weird colors).

Anyway, I guess this will also benefit any platform supported by genfb,
and maybe the NetBSD desktop project in particular :)

(besides, I have backported these changes to netbsd-5 if anyone is
interested)

Hope this helps,
-- khorben

>How-To-Repeat:

Enabling the splashscreen like this:

--- sys/arch/i386/conf/GENERIC  2010-01-08 01:02:02.000000000 -0300
+++ sys/arch/i386/conf/GENERIC.splash   2010-01-10 20:23:37.000000000 -0300
@@ -300,8 +300,8 @@
 # enable VGA raster mode capable of displaying multilingual text on console
 #options       VGA_RASTERCONSOLE
 # enable splash screen support; requires hw driver support
-#options       SPLASHSCREEN
-#options       SPLASHSCREEN_PROGRESS
+options        SPLASHSCREEN
+options        SPLASHSCREEN_PROGRESS
 
 # Keylock support
 #options       KEYLOCK

no longer provides it with genfb, where it did with vesafb.

>Fix:

Apply these two patches.

Index: dev/wsfb/genfb.c
===================================================================
RCS file: /cvsroot/src/sys/dev/wsfb/genfb.c,v
retrieving revision 1.28
diff -p -u -r1.28 genfb.c
--- dev/wsfb/genfb.c    24 Aug 2009 11:03:44 -0000      1.28
+++ dev/wsfb/genfb.c    10 Jan 2010 23:41:01 -0000
@@ -49,6 +49,12 @@ __KERNEL_RCSID(0, "$NetBSD: genfb.c,v 1.
 
 #include <dev/wsfb/genfbvar.h>
 
+#ifdef GENFB_DISABLE_TEXT
+#include <sys/reboot.h>
+#define DISABLESPLASH (boothowto & (RB_SINGLE | RB_USERCONF | RB_ASKNAME | \
+           AB_VERBOSE | AB_DEBUG) )
+#endif
+
 #include "opt_genfb.h"
 #include "opt_wsfb.h"
 
@@ -204,6 +210,15 @@ genfb_attach(struct genfb_softc *sc, str
            &defattr);
        sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
 
+#ifdef SPLASHSCREEN
+/*
+ * If system isn't going to go multiuser, or user has requested to see
+ * boot text, don't render splash screen immediately
+ */
+       if (DISABLESPLASH)
+#endif
+               vcons_redraw_screen(&sc->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;
@@ -218,15 +233,53 @@ genfb_attach(struct genfb_softc *sc, str
        j = 0;
        for (i = 0; i < min(1 << sc->sc_depth, 256); i++) {
 
+#ifndef SPLASHSCREEN
                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];
                genfb_putpalreg(sc, i, rasops_cmap[j], rasops_cmap[j + 1],
                    rasops_cmap[j + 2]);
                j += 3;
+#else
+               if(i >= SPLASH_CMAP_OFFSET &&
+                   i < SPLASH_CMAP_OFFSET + SPLASH_CMAP_SIZE) {
+                       sc->sc_cmap_red[i] = _splash_header_data_cmap[j][0];
+                       sc->sc_cmap_green[i] = _splash_header_data_cmap[j][1];
+                       sc->sc_cmap_blue[i] = _splash_header_data_cmap[j][2];
+               } 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];
+                       genfb_putpalreg(sc, i, rasops_cmap[j],
+                           rasops_cmap[j + 1],
+                           rasops_cmap[j + 2]);
+               }
+               j += 3;
+#endif
        }
 
+#ifdef SPLASHSCREEN
+       sc->sc_splash.si_depth = sc->sc_depth;
+       sc->sc_splash.si_bits = sc->sc_console_screen.scr_ri.ri_bits;
+       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;
+       if (!DISABLESPLASH)
+               splash_render(&sc->sc_splash, SPLASH_F_CENTER|SPLASH_F_FILL);
+#ifdef SPLASHSCREEN_PROGRESS
+       sc->sc_progress.sp_top = (sc->sc_height / 8) * 7;
+       sc->sc_progress.sp_width = (sc->sc_width / 4) * 3;
+       sc->sc_progress.sp_left = (sc->sc_width / 8) * 7;
+       sc->sc_progress.sp_height = 20;
+       sc->sc_progress.sp_state = -1;
+       sc->sc_progress.sp_si = &sc->sc_splash;
+       splash_progress_init(&sc->sc_progress);
+#endif
+#else
        vcons_replay_msgbuf(&sc->sc_console_screen);
+#endif
 
        if (genfb_softc == NULL)
                genfb_softc = sc;
@@ -236,6 +289,11 @@ genfb_attach(struct genfb_softc *sc, str
        aa.accessops = &genfb_accessops;
        aa.accesscookie = &sc->vd;
 
+#ifdef GENFB_DISABLE_TEXT
+       if (!DISABLESPLASH)
+               SCREEN_DISABLE_DRAWING(&sc->sc_console_screen);
+#endif
+
        config_found(&sc->sc_dev, &aa, wsemuldisplaydevprint);
 
        return 0;
@@ -293,6 +351,36 @@ genfb_ioctl(void *v, void *vs, u_long cm
                                }
                        }
                        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);
+#if defined(SPLASHSCREEN_PROGRESS)
+                               sc->sc_progress.sp_running = 1;
+#endif
+                       } else {
+                               SCREEN_ENABLE_DRAWING(&sc->sc_console_screen);
+#if defined(SPLASHSCREEN_PROGRESS)
+                               sc->sc_progress.sp_running = 0;
+#endif
+                       }
+                       vcons_redraw_screen(ms);
+                       return 0;
+#else
+                       return ENODEV;
+#endif
+               case WSDISPLAYIO_SPROGRESS:
+#if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS)
+                       sc->sc_progress.sp_force = 1;
+                       splash_progress_update(&sc->sc_progress);
+                       sc->sc_progress.sp_force = 0;
+                       vcons_redraw_screen(ms);
+                       return 0;
+#else
+                       return ENODEV;
+#endif
                default:
                        if (sc->sc_ops.genfb_ioctl)
                                return sc->sc_ops.genfb_ioctl(sc, vs, cmd,
@@ -347,6 +435,11 @@ genfb_init_screen(void *cookie, struct v
 
        /* TODO: actually center output */
        ri->ri_hw = scr;
+
+#ifdef GENFB_DISABLE_TEXT
+       if (scr == &sc->sc_console_screen && !DISABLESPLASH)
+               SCREEN_DISABLE_DRAWING(&sc->sc_console_screen);
+#endif
 }
 
 static int
Index: dev/wsfb/genfbvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/wsfb/genfbvar.h,v
retrieving revision 1.12
diff -p -u -r1.12 genfbvar.h
--- dev/wsfb/genfbvar.h 8 Jan 2010 19:51:11 -0000       1.12
+++ dev/wsfb/genfbvar.h 10 Jan 2010 23:41:01 -0000
@@ -32,6 +32,8 @@ __KERNEL_RCSID(0, "$NetBSD: genfbvar.h,v
 #ifndef GENFBVAR_H
 #define GENFBVAR_H
 
+#include "opt_splash.h"
+
 #include <sys/param.h>
 #include <sys/buf.h>
 #include <sys/conf.h>
@@ -45,6 +47,13 @@ __KERNEL_RCSID(0, "$NetBSD: genfbvar.h,v
 
 #include <dev/wscons/wsdisplay_vconsvar.h>
 
+#ifdef SPLASHSCREEN
+#define GENFB_DISABLE_TEXT
+#include <dev/splash/splash.h>
+/* XXX */
+extern const char _splash_header_data_cmap[64+32][3];
+#endif
+
 struct genfb_ops {
        int (*genfb_ioctl)(void *, void *, u_long, void *, int, struct lwp *);
        paddr_t (*genfb_mmap)(void *, void *, off_t, int);
@@ -62,7 +71,7 @@ struct genfb_pmf_callback {
 };
 
 struct genfb_softc {
-       struct  device sc_dev;
+       struct device sc_dev;
        struct vcons_data vd;
        struct genfb_ops sc_ops;
        struct vcons_screen sc_console_screen;
@@ -81,6 +90,12 @@ struct genfb_softc {
        u_char sc_cmap_green[256];
        u_char sc_cmap_blue[256];
        bool sc_want_clear;
+#ifdef SPLASHSCREEN
+       struct splash_info sc_splash;
+#ifdef SPLASHSCREEN_PROGRESS
+       struct splash_progress sc_progress;
+#endif
+#endif
 };
 
 void   genfb_cnattach(void);

And for the record, I spotted a typo:

Index: arch/i386/bios/vesafb.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/bios/Attic/vesafb.c,v
retrieving revision 1.31
diff -p -u -r1.31 vesafb.c
--- arch/i386/bios/vesafb.c     9 Jul 2008 20:41:02 -0000       1.31
+++ arch/i386/bios/vesafb.c     10 Jan 2010 22:54:56 -0000
@@ -645,7 +645,7 @@ vesafb_init_screen(void *c, struct vcons
                ri->ri_ops.copyrows  = vv_copyrows;
        }

-#ifdef VESA_DISABLE_TEXT
+#ifdef VESAFB_DISABLE_TEXT
        if (scr == &vesafb_console_screen && !DISABLESPLASH)
                SCREEN_DISABLE_DRAWING(&vesafb_console_screen);
 #endif



Home | Main Index | Thread Index | Old Index