aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/syscons
diff options
context:
space:
mode:
authorXin LI <delphij@FreeBSD.org>2010-03-02 01:56:55 +0000
committerXin LI <delphij@FreeBSD.org>2010-03-02 01:56:55 +0000
commitaa3d547d095ff07fdc39ffc5ae4c371844b504ab (patch)
tree7ed974e780fcc4cd6ef6cb1dd534de1780381fb5 /sys/dev/syscons
parent4dcf8bb3e27cb46f60afb73c7d1fb61ca6a322ab (diff)
Notes
Diffstat (limited to 'sys/dev/syscons')
-rw-r--r--sys/dev/syscons/scvesactl.c2
-rw-r--r--sys/dev/syscons/scvgarndr.c20
-rw-r--r--sys/dev/syscons/scvidctl.c77
-rw-r--r--sys/dev/syscons/syscons.c138
-rw-r--r--sys/dev/syscons/syscons.h8
5 files changed, 194 insertions, 51 deletions
diff --git a/sys/dev/syscons/scvesactl.c b/sys/dev/syscons/scvesactl.c
index 9a2c253869c8..b896484bb76e 100644
--- a/sys/dev/syscons/scvesactl.c
+++ b/sys/dev/syscons/scvesactl.c
@@ -43,7 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/fbio.h>
#include <sys/consio.h>
-#include <machine/pc/vesa.h>
+#include <dev/fb/vesa.h>
#include <dev/fb/fbreg.h>
#include <dev/syscons/syscons.h>
diff --git a/sys/dev/syscons/scvgarndr.c b/sys/dev/syscons/scvgarndr.c
index 1ab41d2e5e4d..fd823ce434ba 100644
--- a/sys/dev/syscons/scvgarndr.c
+++ b/sys/dev/syscons/scvgarndr.c
@@ -193,6 +193,8 @@ static u_short mouse_or_mask[16] = {
case 15: \
writew(pos, vga_palette15[color]); \
break; \
+ case 8: \
+ writeb(pos, (uint8_t)color); \
}
static uint32_t vga_palette32[16] = {
@@ -215,6 +217,7 @@ static uint16_t vga_palette15[16] = {
#ifndef SC_NO_CUTPASTE
static uint32_t mouse_buf32[256];
static uint16_t mouse_buf16[256];
+static uint8_t mouse_buf8[256];
#endif
#endif
@@ -498,7 +501,9 @@ vga_rndrinit(scr_stat *scp)
scp->rndr->draw_cursor = vga_pxlcursor_planar;
scp->rndr->blink_cursor = vga_pxlblink_planar;
scp->rndr->draw_mouse = vga_pxlmouse_planar;
- } else if (scp->sc->adp->va_info.vi_mem_model == V_INFO_MM_DIRECT) {
+ } else
+ if (scp->sc->adp->va_info.vi_mem_model == V_INFO_MM_DIRECT ||
+ scp->sc->adp->va_info.vi_mem_model == V_INFO_MM_PACKED) {
scp->rndr->clear = vga_pxlclear_direct;
scp->rndr->draw_border = vga_pxlborder_direct;
scp->rndr->draw = vga_vgadraw_direct;
@@ -1148,6 +1153,7 @@ vga_pxlmouse_direct(scr_stat *scp, int x, int y, int on)
int i, j;
uint32_t *u32;
uint16_t *u16;
+ uint8_t *u8;
int bpp;
if (!on)
@@ -1179,6 +1185,10 @@ vga_pxlmouse_direct(scr_stat *scp, int x, int y, int on)
u16 = (uint16_t*)(p + j * pixel_size);
writew(u16, mouse_buf16[i * 16 + j]);
break;
+ case 8:
+ u8 = (uint8_t*)(p + j * pixel_size);
+ writeb(u8, mouse_buf8[i * 16 + j]);
+ break;
}
}
@@ -1214,6 +1224,14 @@ vga_pxlmouse_direct(scr_stat *scp, int x, int y, int on)
else if (mouse_and_mask[i] & (1 << (15 - j)))
writew(u16, 0);
break;
+ case 8:
+ u8 = (uint8_t*)(p + j * pixel_size);
+ mouse_buf8[i * 16 + j] = *u8;
+ if (mouse_or_mask[i] & (1 << (15 - j)))
+ writeb(u8, 15);
+ else if (mouse_and_mask[i] & (1 << (15 - j)))
+ writeb(u8, 0);
+ break;
}
}
diff --git a/sys/dev/syscons/scvidctl.c b/sys/dev/syscons/scvidctl.c
index d69e0a8fc36f..0f55499bac74 100644
--- a/sys/dev/syscons/scvidctl.c
+++ b/sys/dev/syscons/scvidctl.c
@@ -369,30 +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 (!sc_support_pixel_mode(&info))
return ENODEV;
/* stop screen saver, etc */
@@ -468,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)))
@@ -721,6 +740,11 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
#endif
#ifndef SC_NO_PALETTE_LOADING
+#ifdef SC_PIXEL_MODE
+ if ((adp->va_flags & V_ADP_DAC8) != 0)
+ vidd_load_palette(adp, scp->sc->palette2);
+ else
+#endif
vidd_load_palette(adp, scp->sc->palette);
#endif
@@ -778,7 +802,10 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
if (scp == scp->sc->cur_scp) {
set_mode(scp);
#ifndef SC_NO_PALETTE_LOADING
- vidd_load_palette(adp, scp->sc->palette);
+ if ((adp->va_flags & V_ADP_DAC8) != 0)
+ vidd_load_palette(adp, scp->sc->palette2);
+ else
+ vidd_load_palette(adp, scp->sc->palette);
#endif
}
sc_clear_screen(scp);
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index 653ff08274a9..8dffe5cd5380 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/cons.h>
#include <sys/consio.h>
@@ -342,16 +343,105 @@ sc_alloc_tty(int index, int devnum)
return (tp);
}
+#ifdef SC_PIXEL_MODE
+static void
+sc_set_vesa_mode(scr_stat *scp, sc_softc_t *sc, int unit)
+{
+ video_info_t info;
+ 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 ||
+ vidd_get_info(sc->adp, vmode, &info) != 0 ||
+ !sc_support_pixel_mode(&info))
+ vmode = 0;
+
+ /*
+ * If the mode is unset or unsupported, search for an available
+ * 800x600 graphics mode with the highest color 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);
+ }
+
+#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
+
int
sc_attach_unit(int unit, int flags)
{
sc_softc_t *sc;
scr_stat *scp;
-#ifdef SC_PIXEL_MODE
- video_info_t info;
-#endif
- int vc;
struct cdev *dev;
+ int vc;
flags &= ~SC_KERNEL_CONSOLE;
@@ -373,21 +463,8 @@ sc_attach_unit(int unit, int flags)
sc_console = scp;
#ifdef SC_PIXEL_MODE
- if ((sc->config & SC_VESA800X600)
- && (vidd_get_info(sc->adp, M_VESA_800x600, &info) == 0)) {
-#ifdef DEV_SPLASH
- if (sc->flags & SC_SPLASH_SCRN)
- splash_term(sc->adp);
-#endif
- sc_set_graphics_mode(scp, NULL, M_VESA_800x600);
- sc_set_pixel_mode(scp, NULL, COL, ROW, 16, 8);
- sc->initial_mode = M_VESA_800x600;
-#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 */
@@ -517,7 +594,7 @@ sctty_open(struct tty *tp)
if (scp == NULL) {
scp = SC_STAT(tp) = alloc_scp(sc, SC_VTY(tp));
if (ISGRAPHSC(scp))
- sc_set_pixel_mode(scp, NULL, COL, ROW, 16, 8);
+ sc_set_pixel_mode(scp, NULL, 0, 0, 16, 8);
}
if (!tp->t_winsize.ws_col && !tp->t_winsize.ws_row) {
tp->t_winsize.ws_col = scp->xsize;
@@ -2049,6 +2126,11 @@ restore_scrn_saver_mode(scr_stat *scp, int changemode)
}
if (set_mode(scp) == 0) {
#ifndef SC_NO_PALETTE_LOADING
+#ifdef SC_PIXEL_MODE
+ if ((scp->sc->adp->va_flags & V_ADP_DAC8) != 0)
+ vidd_load_palette(scp->sc->adp, scp->sc->palette2);
+ else
+#endif
vidd_load_palette(scp->sc->adp, scp->sc->palette);
#endif
--scrn_blanked;
@@ -2452,8 +2534,14 @@ exchange_scr(sc_softc_t *sc)
if (!ISGRAPHSC(scp))
sc_set_cursor_image(scp);
#ifndef SC_NO_PALETTE_LOADING
- if (ISGRAPHSC(sc->old_scp))
+ if (ISGRAPHSC(sc->old_scp)) {
+#ifdef SC_PIXEL_MODE
+ if ((sc->adp->va_flags & V_ADP_DAC8) != 0)
+ vidd_load_palette(sc->adp, sc->palette2);
+ else
+#endif
vidd_load_palette(sc->adp, sc->palette);
+ }
#endif
sc_set_border(scp, scp->border);
@@ -2802,6 +2890,10 @@ scinit(int unit, int flags)
#ifndef SC_NO_PALETTE_LOADING
vidd_save_palette(sc->adp, sc->palette);
+#ifdef SC_PIXEL_MODE
+ for (i = 0; i < sizeof(sc->palette2); i++)
+ sc->palette2[i] = i / 3;
+#endif
#endif
#ifdef DEV_SPLASH
@@ -2995,6 +3087,8 @@ init_scp(sc_softc_t *sc, int vty, scr_stat *scp)
scp->ysize = info.vi_height;
scp->xpixel = scp->xsize*info.vi_cwidth;
scp->ypixel = scp->ysize*info.vi_cheight;
+ }
+
scp->font_size = info.vi_cheight;
scp->font_width = info.vi_cwidth;
if (info.vi_cheight < 14) {
@@ -3016,7 +3110,7 @@ init_scp(sc_softc_t *sc, int vty, scr_stat *scp)
scp->font = NULL;
#endif
}
- }
+
sc_vtb_init(&scp->vtb, VTB_MEMORY, 0, 0, NULL, FALSE);
#ifndef __sparc64__
sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, 0, 0, NULL, FALSE);
diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h
index c0ed6c1fd642..aab6b5c82f1c 100644
--- a/sys/dev/syscons/syscons.h
+++ b/sys/dev/syscons/syscons.h
@@ -191,7 +191,7 @@ struct tty;
typedef struct sc_softc {
int unit; /* unit # */
int config; /* configuration flags */
-#define SC_VESA800X600 (1 << 7)
+#define SC_VESAMODE (1 << 7)
#define SC_AUTODETECT_KBD (1 << 8)
#define SC_KERNEL_CONSOLE (1 << 9)
@@ -245,7 +245,10 @@ typedef struct sc_softc {
#endif
#ifndef SC_NO_PALETTE_LOADING
- u_char palette[256*3];
+ u_char palette[256 * 3];
+#ifdef SC_PIXEL_MODE
+ u_char palette2[256 * 3];
+#endif
#endif
#ifndef SC_NO_FONT_LOADING
@@ -616,6 +619,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);