summaryrefslogtreecommitdiffstats
path: root/sys/dev/syscons
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2010-02-24 20:13:34 +0000
committerjkim <jkim@FreeBSD.org>2010-02-24 20:13:34 +0000
commitf819ca27dd898d05382ce0a7d4fe3278d5f8d10d (patch)
tree9c3020317aae0b772b9abd7f49ad103b92df42fa /sys/dev/syscons
parent83c4cf226c4e74a147f8e2d45e8845e1b35c37b8 (diff)
downloadFreeBSD-src-f819ca27dd898d05382ce0a7d4fe3278d5f8d10d.zip
FreeBSD-src-f819ca27dd898d05382ce0a7d4fe3278d5f8d10d.tar.gz
Improve VESA mode switching via loader tunable `hint.sc.0.vesa_mode'.
The most notable change is history buffer is fully saved/restored now.
Diffstat (limited to 'sys/dev/syscons')
-rw-r--r--sys/dev/syscons/scvidctl.c71
-rw-r--r--sys/dev/syscons/syscons.c115
-rw-r--r--sys/dev/syscons/syscons.h1
3 files changed, 123 insertions, 64 deletions
diff --git a/sys/dev/syscons/scvidctl.c b/sys/dev/syscons/scvidctl.c
index d4f1725..0f55499 100644
--- a/sys/dev/syscons/scvidctl.c
+++ b/sys/dev/syscons/scvidctl.c
@@ -369,34 +369,7 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize))
return EINVAL;
- /*
- * We currently support the following graphic modes:
- *
- * - 4 bpp planar modes whose memory size does not exceed 64K
- * - 15, 16, 24 and 32 bpp linear modes
- */
-
- if (info.vi_mem_model == V_INFO_MM_PLANAR) {
- if (info.vi_planes != 4)
- return ENODEV;
-
- /*
- * A memory size >64K requires bank switching to access the entire
- * screen. XXX
- */
-
- if (info.vi_width * info.vi_height / 8 > info.vi_window_size)
- return ENODEV;
- } else if (info.vi_mem_model == V_INFO_MM_DIRECT) {
- if (!(info.vi_flags & V_INFO_LINEAR) &&
- (info.vi_depth != 15) && (info.vi_depth != 16) &&
- (info.vi_depth != 24) && (info.vi_depth != 32))
- return ENODEV;
- } else if (info.vi_mem_model == V_INFO_MM_PACKED) {
- if (!(info.vi_flags & V_INFO_LINEAR) &&
- (info.vi_depth != 8))
- return ENODEV;
- } else
+ if (!sc_support_pixel_mode(&info))
return ENODEV;
/* stop screen saver, etc */
@@ -472,6 +445,48 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
#endif /* SC_PIXEL_MODE */
}
+int
+sc_support_pixel_mode(void *arg)
+{
+#ifdef SC_PIXEL_MODE
+ video_info_t *info = arg;
+
+ if ((info->vi_flags & V_INFO_GRAPHICS) == 0)
+ return (0);
+
+ /*
+ * We currently support the following graphic modes:
+ *
+ * - 4 bpp planar modes whose memory size does not exceed 64K
+ * - 15, 16, 24 and 32 bpp linear modes
+ */
+ switch (info->vi_mem_model) {
+ case V_INFO_MM_PLANAR:
+ if (info->vi_planes != 4)
+ break;
+ /*
+ * A memory size >64K requires bank switching to access
+ * the entire screen. XXX
+ */
+ if (info->vi_width * info->vi_height / 8 > info->vi_window_size)
+ break;
+ return (1);
+ case V_INFO_MM_DIRECT:
+ if ((info->vi_flags & V_INFO_LINEAR) == 0 &&
+ info->vi_depth != 15 && info->vi_depth != 16 &&
+ info->vi_depth != 24 && info->vi_depth != 32)
+ break;
+ return (1);
+ case V_INFO_MM_PACKED:
+ if ((info->vi_flags & V_INFO_LINEAR) == 0 &&
+ info->vi_depth != 8)
+ break;
+ return (1);
+ }
+#endif
+ return (0);
+}
+
#define fb_ioctl(a, c, d) \
(((a) == NULL) ? ENODEV : \
vidd_ioctl((a), (c), (caddr_t)(d)))
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index 88bf019..719935d 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -344,35 +344,94 @@ sc_alloc_tty(int index, int devnum)
}
#ifdef SC_PIXEL_MODE
-static int
-sc_initial_mode(video_adapter_t *adp, int unit)
+static void
+sc_set_vesa_mode(scr_stat *scp, sc_softc_t *sc, int unit)
{
video_info_t info;
- int depth, vmode;
+ int depth;
int i;
+ int vmode;
vmode = 0;
(void)resource_int_value("sc", unit, "vesa_mode", &vmode);
- if (vmode < M_VESA_BASE || vmode > M_VESA_MODE_MAX)
- vmode = 0;
+ if (vmode < M_VESA_BASE || vmode > M_VESA_MODE_MAX ||
+ vidd_get_info(sc->adp, vmode, &info) != 0 ||
+ !sc_support_pixel_mode(&info))
+ vmode = 0;
/*
- * If the default mode is not supported, search for an available
+ * If the mode is unset or unsupported, search for an available
* 800x600 graphics mode with the highest color depth.
*/
- if (vmode == 0 || vidd_get_info(adp, vmode, &info) != 0) {
- depth = vmode = 0;
- for (i = M_VESA_BASE; i <= M_VESA_MODE_MAX; i++)
- if (vidd_get_info(adp, i, &info) == 0 &&
- (info.vi_flags & V_INFO_GRAPHICS) != 0 &&
- info.vi_width == 800 && info.vi_height == 600 &&
- info.vi_depth > depth) {
- vmode = i;
- depth = info.vi_depth;
- }
+ if (vmode == 0) {
+ for (depth = 0, i = M_VESA_BASE; i <= M_VESA_MODE_MAX; i++)
+ if (vidd_get_info(sc->adp, i, &info) == 0 &&
+ info.vi_width == 800 && info.vi_height == 600 &&
+ sc_support_pixel_mode(&info) &&
+ info.vi_depth > depth) {
+ vmode = i;
+ depth = info.vi_depth;
+ }
+ if (vmode == 0)
+ return;
+ vidd_get_info(sc->adp, vmode, &info);
}
- return (vmode);
+#ifndef SC_NO_FONT_LOADING
+ if ((sc->fonts_loaded & FONT_16) == 0)
+ return;
+#endif
+#ifdef DEV_SPLASH
+ if ((sc->flags & SC_SPLASH_SCRN) != 0)
+ splash_term(sc->adp);
+#endif
+#ifndef SC_NO_HISTORY
+ if (scp->history != NULL) {
+ sc_vtb_append(&scp->vtb, 0, scp->history,
+ scp->ypos * scp->xsize + scp->xpos);
+ scp->history_pos = sc_vtb_tail(scp->history);
+ }
+#endif
+ vidd_set_mode(sc->adp, vmode);
+ scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN);
+ scp->status &= ~(GRAPHICS_MODE | MOUSE_VISIBLE);
+ scp->xpixel = info.vi_width;
+ scp->ypixel = info.vi_height;
+ scp->xsize = scp->xpixel / 8;
+ scp->ysize = scp->ypixel / 16;
+ scp->xpos = 0;
+ scp->ypos = scp->ysize - 1;
+ scp->xoff = scp->yoff = 0;
+#ifndef SC_NO_FONT_LOADING
+ scp->font = sc->font_16;
+#else
+ scp->font = NULL;
+#endif
+ scp->font_size = 16;
+ scp->font_width = 8;
+ scp->start = scp->xsize * scp->ysize - 1;
+ scp->end = 0;
+ scp->cursor_pos = scp->cursor_oldpos = scp->xsize * scp->xsize;
+ scp->mode = sc->initial_mode = vmode;
+#ifndef __sparc64__
+ sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize,
+ (void *)sc->adp->va_window, FALSE);
+#endif
+ sc_alloc_scr_buffer(scp, FALSE, FALSE);
+ sc_init_emulator(scp, NULL);
+#ifndef SC_NO_CUTPASTE
+ sc_alloc_cut_buffer(scp, FALSE);
+#endif
+#ifndef SC_NO_HISTORY
+ sc_alloc_history_buffer(scp, 0, 0, FALSE);
+#endif
+ sc_set_border(scp, scp->border);
+ sc_set_cursor_image(scp);
+ scp->status &= ~UNKNOWN_MODE;
+#ifdef DEV_SPLASH
+ if ((sc->flags & SC_SPLASH_SCRN) != 0)
+ splash_init(sc->adp, scsplash_callback, sc);
+#endif
}
#endif
@@ -381,8 +440,8 @@ sc_attach_unit(int unit, int flags)
{
sc_softc_t *sc;
scr_stat *scp;
- int vc;
struct cdev *dev;
+ int vc;
flags &= ~SC_KERNEL_CONSOLE;
@@ -404,24 +463,8 @@ sc_attach_unit(int unit, int flags)
sc_console = scp;
#ifdef SC_PIXEL_MODE
- if ((sc->config & SC_VESAMODE) != 0) {
- int vmode;
- vmode = sc_initial_mode(sc->adp, unit);
- if (vmode >= M_VESA_BASE) {
-#ifdef DEV_SPLASH
- if (sc->flags & SC_SPLASH_SCRN)
- splash_term(sc->adp);
-#endif
- sc_set_graphics_mode(scp, NULL, vmode);
- sc_set_pixel_mode(scp, NULL, 0, 0, 16, 8);
- sc->initial_mode = vmode;
-#ifdef DEV_SPLASH
- /* put up the splash again! */
- if (sc->flags & SC_SPLASH_SCRN)
- splash_init(sc->adp, scsplash_callback, sc);
-#endif
- }
- }
+ if ((sc->config & SC_VESAMODE) != 0)
+ sc_set_vesa_mode(scp, sc, unit);
#endif /* SC_PIXEL_MODE */
/* initialize cursor */
diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h
index ee38089..a23f884 100644
--- a/sys/dev/syscons/syscons.h
+++ b/sys/dev/syscons/syscons.h
@@ -623,6 +623,7 @@ int sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode,
int sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode);
int sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize,
int ysize, int fontsize, int font_width);
+int sc_support_pixel_mode(void *arg);
int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data,
struct thread *td);
OpenPOWER on IntegriCloud