summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2010-02-23 21:51:14 +0000
committerjkim <jkim@FreeBSD.org>2010-02-23 21:51:14 +0000
commit1f5a49bf177e6b9bf4e342108408c9a02dbe0b62 (patch)
tree74511fa17ee4c97f2b6b9f1addc7cdb3567f0034
parentde16302b4022f077896ab72e017bb3194f077726 (diff)
downloadFreeBSD-src-1f5a49bf177e6b9bf4e342108408c9a02dbe0b62.zip
FreeBSD-src-1f5a49bf177e6b9bf4e342108408c9a02dbe0b62.tar.gz
Yet another attempt to make palette loading more safer:
- Add a separate palette data for 8-bit DAC mode when SC_PIXEL_MODE is set and fill it up with default gray-scale palette data for text. Now we don't have to set `hint.sc.0.vesa_mode' to get the default palette data. - Add a new adapter flag, V_ADP_DAC8 to track whether the controller is using 8-bit palette format and load correct palette when switching modes. - Set 8-bit DAC mode only for non-VGA compatible graphics mode.
-rw-r--r--sys/dev/fb/vesa.c57
-rw-r--r--sys/dev/syscons/scvidctl.c10
-rw-r--r--sys/dev/syscons/syscons.c20
-rw-r--r--sys/dev/syscons/syscons.h5
-rw-r--r--sys/sys/fbio.h1
5 files changed, 63 insertions, 30 deletions
diff --git a/sys/dev/fb/vesa.c b/sys/dev/fb/vesa.c
index baebe85..2602440 100644
--- a/sys/dev/fb/vesa.c
+++ b/sys/dev/fb/vesa.c
@@ -165,7 +165,9 @@ static int int10_set_mode(int mode);
static int vesa_bios_post(void);
static int vesa_bios_get_mode(int mode, struct vesa_mode *vmode);
static int vesa_bios_set_mode(int mode);
+#if 0
static int vesa_bios_get_dac(void);
+#endif
static int vesa_bios_set_dac(int bits);
static int vesa_bios_save_palette(int start, int colors, u_char *palette,
int bits);
@@ -318,6 +320,7 @@ vesa_bios_set_mode(int mode)
return (regs.R_AX != 0x004f);
}
+#if 0
static int
vesa_bios_get_dac(void)
{
@@ -334,6 +337,7 @@ vesa_bios_get_dac(void)
return (regs.R_BH);
}
+#endif
static int
vesa_bios_set_dac(int bits)
@@ -1198,6 +1202,10 @@ vesa_set_mode(video_adapter_t *adp, int mode)
if (VESA_MODE(adp->va_mode)) {
if (!VESA_MODE(mode) &&
(*prevvidsw->get_info)(adp, mode, &info) == 0) {
+ if ((adp->va_flags & V_ADP_DAC8) != 0) {
+ vesa_bios_set_dac(6);
+ adp->va_flags &= ~V_ADP_DAC8;
+ }
int10_set_mode(adp->va_initial_bios_mode);
if (adp->va_info.vi_flags & V_INFO_LINEAR)
pmap_unmapdev(adp->va_buffer,
@@ -1228,8 +1236,14 @@ vesa_set_mode(video_adapter_t *adp, int mode)
if (vesa_bios_set_mode(mode | ((info.vi_flags & V_INFO_LINEAR) ? 0x4000 : 0)))
return (1);
- if ((vesa_adp_info->v_flags & V_DAC8) != 0)
- vesa_bios_set_dac(8);
+ /* Palette format is reset by the above VBE function call. */
+ adp->va_flags &= ~V_ADP_DAC8;
+
+ if ((vesa_adp_info->v_flags & V_DAC8) != 0 &&
+ (info.vi_flags & V_INFO_GRAPHICS) != 0 &&
+ (info.vi_flags & V_INFO_NONVGA) != 0 &&
+ vesa_bios_set_dac(8) > 6)
+ adp->va_flags |= V_ADP_DAC8;
if (adp->va_info.vi_flags & V_INFO_LINEAR)
pmap_unmapdev(adp->va_buffer, adp->va_buffer_size);
@@ -1308,10 +1322,10 @@ vesa_save_palette(video_adapter_t *adp, u_char *palette)
{
int bits;
- if (adp == vesa_adp && VESA_MODE(adp->va_mode)) {
- bits = vesa_bios_get_dac();
- if ((adp->va_info.vi_flags & V_INFO_NONVGA) != 0 || bits > 6)
- return (vesa_bios_save_palette(0, 256, palette, bits));
+ if (adp == vesa_adp && VESA_MODE(adp->va_mode) &&
+ (adp->va_info.vi_flags & V_INFO_NONVGA) != 0) {
+ bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 8 : 6;
+ return (vesa_bios_save_palette(0, 256, palette, bits));
}
return ((*prevvidsw->save_palette)(adp, palette));
@@ -1322,10 +1336,10 @@ vesa_load_palette(video_adapter_t *adp, u_char *palette)
{
int bits;
- if (adp == vesa_adp && VESA_MODE(adp->va_mode)) {
- bits = vesa_bios_get_dac();
- if ((adp->va_info.vi_flags & V_INFO_NONVGA) != 0 || bits > 6)
- return (vesa_bios_load_palette(0, 256, palette, bits));
+ if (adp == vesa_adp && VESA_MODE(adp->va_mode) &&
+ (adp->va_info.vi_flags & V_INFO_NONVGA) != 0) {
+ bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 8 : 6;
+ return (vesa_bios_load_palette(0, 256, palette, bits));
}
return ((*prevvidsw->load_palette)(adp, palette));
@@ -1530,10 +1544,10 @@ get_palette(video_adapter_t *adp, int base, int count,
return (1);
if (!VESA_MODE(adp->va_mode))
return (1);
- bits = vesa_bios_get_dac();
- if ((adp->va_info.vi_flags & V_INFO_NONVGA) == 0 && bits <= 6)
+ if ((adp->va_info.vi_flags & V_INFO_NONVGA) == 0)
return (1);
+ bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 8 : 6;
r = malloc(count * 3, M_DEVBUF, M_WAITOK);
g = r + count;
b = g + count;
@@ -1568,10 +1582,10 @@ set_palette(video_adapter_t *adp, int base, int count,
return (1);
if (!VESA_MODE(adp->va_mode))
return (1);
- bits = vesa_bios_get_dac();
- if ((adp->va_info.vi_flags & V_INFO_NONVGA) == 0 && bits <= 6)
+ if ((adp->va_info.vi_flags & V_INFO_NONVGA) == 0)
return (1);
+ bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 8 : 6;
r = malloc(count * 3, M_DEVBUF, M_WAITOK);
g = r + count;
b = g + count;
@@ -1789,7 +1803,6 @@ vesa_unload(void)
{
u_char palette[256*3];
int error;
- int bits;
int s;
/* if the adapter is currently in a VESA mode, don't unload */
@@ -1803,15 +1816,11 @@ vesa_unload(void)
s = spltty();
if ((error = vesa_unload_ioctl()) == 0) {
if (vesa_adp != NULL) {
- if (vesa_adp_info->v_flags & V_DAC8) {
- bits = vesa_bios_get_dac();
- if (bits > 6) {
- vesa_bios_save_palette(0, 256,
- palette, bits);
- vesa_bios_set_dac(6);
- vesa_bios_load_palette(0, 256,
- palette, 6);
- }
+ if ((vesa_adp->va_flags & V_ADP_DAC8) != 0) {
+ vesa_bios_save_palette(0, 256, palette, 8);
+ vesa_bios_set_dac(6);
+ vesa_adp->va_flags &= ~V_ADP_DAC8;
+ vesa_bios_load_palette(0, 256, palette, 6);
}
vesa_adp->va_flags &= ~V_ADP_VESA;
vidsw[vesa_adp->va_index] = prevvidsw;
diff --git a/sys/dev/syscons/scvidctl.c b/sys/dev/syscons/scvidctl.c
index f973169..d4f1725 100644
--- a/sys/dev/syscons/scvidctl.c
+++ b/sys/dev/syscons/scvidctl.c
@@ -725,6 +725,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
@@ -782,7 +787,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 f50d686..88bf019 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -414,9 +414,6 @@ sc_attach_unit(int unit, int flags)
#endif
sc_set_graphics_mode(scp, NULL, vmode);
sc_set_pixel_mode(scp, NULL, 0, 0, 16, 8);
-#ifndef SC_NO_PALETTE_LOADING
- vidd_save_palette(sc->adp, sc->palette);
-#endif
sc->initial_mode = vmode;
#ifdef DEV_SPLASH
/* put up the splash again! */
@@ -2090,6 +2087,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;
@@ -2493,8 +2495,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);
@@ -2843,6 +2851,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
diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h
index 2f05755..ee38089 100644
--- a/sys/dev/syscons/syscons.h
+++ b/sys/dev/syscons/syscons.h
@@ -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
diff --git a/sys/sys/fbio.h b/sys/sys/fbio.h
index 415ad96..5745182 100644
--- a/sys/sys/fbio.h
+++ b/sys/sys/fbio.h
@@ -332,6 +332,7 @@ struct video_adapter {
#define V_ADP_INITIALIZED (1 << 17)
#define V_ADP_REGISTERED (1 << 18)
#define V_ADP_ATTACHED (1 << 19)
+#define V_ADP_DAC8 (1 << 20)
vm_offset_t va_io_base;
int va_io_size;
vm_offset_t va_crtc_addr;
OpenPOWER on IntegriCloud