diff options
| author | Xin LI <delphij@FreeBSD.org> | 2010-03-02 01:56:55 +0000 |
|---|---|---|
| committer | Xin LI <delphij@FreeBSD.org> | 2010-03-02 01:56:55 +0000 |
| commit | aa3d547d095ff07fdc39ffc5ae4c371844b504ab (patch) | |
| tree | 7ed974e780fcc4cd6ef6cb1dd534de1780381fb5 /sys/dev/syscons | |
| parent | 4dcf8bb3e27cb46f60afb73c7d1fb61ca6a322ab (diff) | |
Notes
Diffstat (limited to 'sys/dev/syscons')
| -rw-r--r-- | sys/dev/syscons/scvesactl.c | 2 | ||||
| -rw-r--r-- | sys/dev/syscons/scvgarndr.c | 20 | ||||
| -rw-r--r-- | sys/dev/syscons/scvidctl.c | 77 | ||||
| -rw-r--r-- | sys/dev/syscons/syscons.c | 138 | ||||
| -rw-r--r-- | sys/dev/syscons/syscons.h | 8 |
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); |
