[SeaBIOS] [PATCH 04/10] vgabios: Move BDA setting from driver code to common code.

Kevin O'Connor kevin at koconnor.net
Sat Jan 28 05:28:22 CET 2012


Always setup the BDA on a mode switch.  Call that BDA setup code
unconditionally.

Also, always set vbe_mode and use that for finding the current mode
and for reporting the mode to vbe callers.

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 vgasrc/bochsvga.c    |   30 +++++++++++++-----------------
 vgasrc/bochsvga.h    |    2 +-
 vgasrc/clext.c       |   37 ++++++++++++++++++++-----------------
 vgasrc/clext.h       |    2 +-
 vgasrc/stdvga.c      |   15 +++++----------
 vgasrc/stdvga.h      |    3 ++-
 vgasrc/stdvgamodes.c |    7 +++++++
 vgasrc/vbe.c         |   12 ++++--------
 vgasrc/vgabios.c     |   26 +++++++++++++++++++++-----
 vgasrc/vgabios.h     |    3 ++-
 vgasrc/vgahw.h       |    8 ++++----
 11 files changed, 80 insertions(+), 65 deletions(-)

diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c
index 213dbcd..6cbbf9c 100644
--- a/vgasrc/bochsvga.c
+++ b/vgasrc/bochsvga.c
@@ -1,9 +1,9 @@
 #include "vgabios.h" // struct vbe_modeinfo
-#include "vbe.h" // VBE_MODE_VESA_DEFINED
+#include "vbe.h" // VBE_CAPABILITY_8BIT_DAC
 #include "bochsvga.h" // bochsvga_set_mode
 #include "util.h" // dprintf
 #include "config.h" // CONFIG_*
-#include "biosvar.h" // SET_BDA
+#include "biosvar.h" // GET_GLOBAL
 #include "stdvga.h" // VGAREG_SEQU_ADDRESS
 #include "pci.h" // pci_config_readl
 #include "pci_regs.h" // PCI_BASE_ADDRESS_0
@@ -78,6 +78,12 @@ static struct bochsvga_mode
     { 0x18c, { MM_DIRECT, 2560, 1600, 32, 8, 16, SEG_GRAPH } },
 };
 
+static int is_bochsvga_mode(struct vgamode_s *vmode_g)
+{
+    return (vmode_g >= &bochsvga_modes[0].info
+            && vmode_g <= &bochsvga_modes[ARRAY_SIZE(bochsvga_modes)-1].info);
+}
+
 static u16 dispi_get_max_xres(void)
 {
     u16 en;
@@ -203,26 +209,18 @@ bochsvga_clear_scr(void)
 }
 
 int
-bochsvga_set_mode(int mode, int flags)
+bochsvga_set_mode(struct vgamode_s *vmode_g, int flags)
 {
-    if (!(mode & VBE_MODE_VESA_DEFINED)) {
-        dprintf(1, "set VGA mode %x\n", mode);
-
-        SET_BDA(vbe_mode, 0);
+    if (! is_bochsvga_mode(vmode_g)) {
         bochsvga_hires_enable(0);
-        return stdvga_set_mode(mode, flags);
+        return stdvga_set_mode(vmode_g, flags);
     }
 
-    struct vgamode_s *vmode_g = bochsvga_find_mode(mode);
-    if (!vmode_g) {
-        dprintf(1, "VBE mode %x not found\n", mode);
-        return VBE_RETURN_STATUS_FAILED;
-    }
     bochsvga_hires_enable(1);
 
     u8 depth = GET_GLOBAL(vmode_g->depth);
     if (depth == 4)
-        stdvga_set_mode(0x6a, 0);
+        stdvga_set_mode(stdvga_find_mode(0x6a), 0);
     if (depth == 8)
         // XXX load_dac_palette(3);
         ;
@@ -260,13 +258,11 @@ bochsvga_set_mode(int mode, int flags)
         stdvga_grdc_mask(0x05, 0x20, 0x40);
     }
 
-    SET_BDA(vbe_mode, mode | flags);
-
     if (flags & MF_LINEARFB) {
         /* Linear frame buffer */
         /* XXX: ??? */
     }
-    if (!(mode & MF_NOCLEARMEM)) {
+    if (!(flags & MF_NOCLEARMEM)) {
         bochsvga_clear_scr();
     }
 
diff --git a/vgasrc/bochsvga.h b/vgasrc/bochsvga.h
index 81fb8f7..1eaa91a 100644
--- a/vgasrc/bochsvga.h
+++ b/vgasrc/bochsvga.h
@@ -55,6 +55,6 @@ static inline void dispi_write(u16 reg, u16 val)
 int bochsvga_init(void);
 void bochsvga_list_modes(u16 seg, u16 *dest, u16 *last);
 struct vgamode_s *bochsvga_find_mode(int mode);
-int bochsvga_set_mode(int mode, int flags);
+int bochsvga_set_mode(struct vgamode_s *vmode_g, int flags);
 
 #endif // bochsvga.h
diff --git a/vgasrc/clext.c b/vgasrc/clext.c
index ea2b428..363ef5d 100644
--- a/vgasrc/clext.c
+++ b/vgasrc/clext.c
@@ -10,7 +10,6 @@
 #include "biosvar.h" // GET_GLOBAL
 #include "util.h" // dprintf
 #include "bregs.h" // struct bregs
-#include "vbe.h" // struct vbe_info
 #include "stdvga.h" // VGAREG_SEQU_ADDRESS
 #include "pci.h" // pci_config_readl
 #include "pci_regs.h" // PCI_BASE_ADDRESS_0
@@ -309,6 +308,13 @@ static struct {
  * helper functions
  ****************************************************************/
 
+int
+is_cirrus_mode(struct vgamode_s *vmode_g)
+{
+    return (vmode_g >= &cirrus_modes[0].info
+            && vmode_g <= &cirrus_modes[ARRAY_SIZE(cirrus_modes)-1].info);
+}
+
 static u16
 cirrus_vesamode_to_mode(u16 vesamode)
 {
@@ -414,24 +420,21 @@ cirrus_clear_vram(u16 param)
 }
 
 int
-clext_set_mode(int mode, int flags)
+clext_set_mode(struct vgamode_s *vmode_g, int flags)
 {
-    dprintf(1, "cirrus mode %x\n", mode);
-    SET_BDA(vbe_mode, 0);
-    struct cirrus_mode_s *table_g = cirrus_get_modeentry(mode);
-    if (table_g) {
-        cirrus_switch_mode(table_g);
-        if (!(flags & MF_LINEARFB))
-            cirrus_enable_16k_granularity();
-        if (!(flags & MF_NOCLEARMEM))
-            cirrus_clear_vram(0);
-        SET_BDA(video_mode, mode);
-        SET_BDA(vbe_mode, mode | flags);
-        return 0;
+    if (!is_cirrus_mode(vmode_g)) {
+        cirrus_switch_mode(&mode_switchback);
+        dprintf(1, "cirrus mode switch regular\n");
+        return stdvga_set_mode(vmode_g, flags);
     }
-    cirrus_switch_mode(&mode_switchback);
-    dprintf(1, "cirrus mode switch regular\n");
-    return stdvga_set_mode(mode, flags);
+    struct cirrus_mode_s *table_g = container_of(
+        vmode_g, struct cirrus_mode_s, info);
+    cirrus_switch_mode(table_g);
+    if (!(flags & MF_LINEARFB))
+        cirrus_enable_16k_granularity();
+    if (!(flags & MF_NOCLEARMEM))
+        cirrus_clear_vram(0);
+    return 0;
 }
 
 static int
diff --git a/vgasrc/clext.h b/vgasrc/clext.h
index a14cf13..718b756 100644
--- a/vgasrc/clext.h
+++ b/vgasrc/clext.h
@@ -4,7 +4,7 @@
 #include "types.h" // u16
 
 struct vgamode_s *clext_find_mode(int mode);
-int clext_set_mode(int mode, int flags);
+int clext_set_mode(struct vgamode_s *vmode_g, int flags);
 void clext_list_modes(u16 seg, u16 *dest, u16 *last);
 int clext_init(void);
 struct bregs;
diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c
index 0fab905..b7def32 100644
--- a/vgasrc/stdvga.c
+++ b/vgasrc/stdvga.c
@@ -10,7 +10,6 @@
 #include "farptr.h" // SET_FARVAR
 #include "biosvar.h" // GET_GLOBAL
 #include "util.h" // memcpy_far
-#include "vbe.h" // VBE_RETURN_STATUS_FAILED
 
 
 /****************************************************************
@@ -360,13 +359,12 @@ clear_screen(struct vgamode_s *vmode_g)
 }
 
 int
-stdvga_set_mode(int mode, int flags)
+stdvga_set_mode(struct vgamode_s *vmode_g, int flags)
 {
-    // find the entry in the video modes
-    struct vgamode_s *vmode_g = stdvga_find_mode(mode);
-    dprintf(1, "mode search %02x found %p\n", mode, vmode_g);
-    if (!vmode_g)
-        return VBE_RETURN_STATUS_FAILED;
+    if (! stdvga_is_mode(vmode_g)) {
+        warn_internalerror();
+        return -1;
+    }
     struct stdvga_mode_s *stdmode_g = container_of(
         vmode_g, struct stdvga_mode_s, info);
 
@@ -436,9 +434,6 @@ stdvga_set_mode(int mode, int flags)
     if (memmodel == MM_TEXT)
         stdvga_load_font(get_global_seg(), vgafont16, 0x100, 0, 0, 16);
 
-    // Setup BDA variables
-    modeswitch_set_bda(mode, flags, vmode_g);
-
     return 0;
 }
 
diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h
index ee14358..cc93f0d 100644
--- a/vgasrc/stdvga.h
+++ b/vgasrc/stdvga.h
@@ -84,6 +84,7 @@ struct saveDACcolors {
 
 // stdvgamodes.c
 struct vgamode_s *stdvga_find_mode(int mode);
+int stdvga_is_mode(struct vgamode_s *vmode_g);
 void stdvga_build_video_param(void);
 void stdvga_override_crtc(int mode, u8 *crtc);
 
@@ -135,7 +136,7 @@ void stdvga_set_scan_lines(u8 lines);
 u16 stdvga_get_vde(void);
 void stdvga_save_state(u16 seg, struct saveVideoHardware *info);
 void stdvga_restore_state(u16 seg, struct saveVideoHardware *info);
-int stdvga_set_mode(int mode, int flags);
+int stdvga_set_mode(struct vgamode_s *vmode_g, int flags);
 void stdvga_enable_video_addressing(u8 disable);
 void stdvga_list_modes(u16 seg, u16 *dest, u16 *last);
 int stdvga_init(void);
diff --git a/vgasrc/stdvgamodes.c b/vgasrc/stdvgamodes.c
index 08c3a58..1b47e98 100644
--- a/vgasrc/stdvgamodes.c
+++ b/vgasrc/stdvgamodes.c
@@ -298,6 +298,13 @@ static struct stdvga_mode_s vga_modes[] VAR16 = {
  * Mode functions
  ****************************************************************/
 
+int
+stdvga_is_mode(struct vgamode_s *vmode_g)
+{
+    return (vmode_g >= &vga_modes[0].info
+            && vmode_g <= &vga_modes[ARRAY_SIZE(vga_modes)-1].info);
+}
+
 struct vgamode_s *
 stdvga_find_mode(int mode)
 {
diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c
index caf856d..b6ffb97 100644
--- a/vgasrc/vbe.c
+++ b/vgasrc/vbe.c
@@ -184,9 +184,9 @@ vbe_104f02(struct bregs *regs)
 {
     dprintf(1, "VBE mode set: %x\n", regs->bx);
 
-    int mode = regs->bx & 0x1ff;
-    int flags = regs->bx & (MF_CUSTOMCRTC|MF_LINEARFB|MF_NOCLEARMEM);
-    int ret = vgahw_set_mode(mode, flags);
+    int mode = regs->bx & ~MF_VBEFLAGS;
+    int flags = regs->bx & MF_VBEFLAGS;
+    int ret = vga_set_mode(mode, flags);
 
     regs->ah = ret;
     regs->al = 0x4f;
@@ -195,12 +195,8 @@ vbe_104f02(struct bregs *regs)
 static void
 vbe_104f03(struct bregs *regs)
 {
-    u16 mode = GET_BDA(vbe_mode);
-    if (!mode)
-        regs->bx = GET_BDA(video_mode);
-
+    regs->bx = GET_BDA(vbe_mode);
     dprintf(1, "VBE current mode=%x\n", regs->bx);
-
     regs->ax = 0x004f;
 }
 
diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c
index 62b09b4..efc4a39 100644
--- a/vgasrc/vgabios.c
+++ b/vgasrc/vgabios.c
@@ -20,6 +20,7 @@
 #include "stdvga.h" // stdvga_set_cursor_shape
 #include "clext.h" // clext_1012
 #include "vgahw.h" // vgahw_set_mode
+#include "vbe.h" // VBE_RETURN_STATUS_FAILED
 #include "pci.h" // pci_config_readw
 #include "pci_regs.h" // PCI_VENDOR_ID
 
@@ -344,19 +345,32 @@ restore_bda_state(u16 seg, struct saveBDAstate *info)
 struct vgamode_s *
 get_current_mode(void)
 {
-    return vgahw_find_mode(GET_BDA(video_mode));
+    return vgahw_find_mode(GET_BDA(vbe_mode) & ~MF_VBEFLAGS);
 }
 
 // Setup BDA after a mode switch.
-void
-modeswitch_set_bda(int mode, int flags, struct vgamode_s *vmode_g)
+int
+vga_set_mode(int mode, int flags)
 {
+    dprintf(1, "set VGA mode %x\n", mode);
+    struct vgamode_s *vmode_g = vgahw_find_mode(mode);
+    if (!vmode_g)
+        return VBE_RETURN_STATUS_FAILED;
+
+    int ret = vgahw_set_mode(vmode_g, flags);
+    if (ret)
+        return ret;
+
     // Set the BIOS mem
     int width = GET_GLOBAL(vmode_g->width);
     int height = GET_GLOBAL(vmode_g->height);
     u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
     int cheight = GET_GLOBAL(vmode_g->cheight);
-    SET_BDA(video_mode, mode);
+    if (mode < 0x100)
+        SET_BDA(video_mode, mode);
+    else
+        SET_BDA(video_mode, 0xff);
+    SET_BDA(vbe_mode, mode | (flags & MF_VBEFLAGS));
     if (memmodel == MM_TEXT) {
         SET_BDA(video_cols, width);
         SET_BDA(video_rows, height-1);
@@ -402,6 +416,8 @@ modeswitch_set_bda(int mode, int flags, struct vgamode_s *vmode_g)
         SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont16));
         break;
     }
+
+    return 0;
 }
 
 
@@ -426,7 +442,7 @@ handle_1000(struct bregs *regs)
     if (regs->al & 0x80)
         flags |= MF_NOCLEARMEM;
 
-    vgahw_set_mode(mode, flags);
+    vga_set_mode(mode, flags);
 }
 
 static void
diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h
index 6a3a379..23d234a 100644
--- a/vgasrc/vgabios.h
+++ b/vgasrc/vgabios.h
@@ -44,6 +44,7 @@ struct saveBDAstate {
 #define MF_CUSTOMCRTC 0x0800
 #define MF_LINEARFB   0x4000
 #define MF_NOCLEARMEM 0x8000
+#define MF_VBEFLAGS   0xfe00
 
 // Memory model types
 #define MM_TEXT            0x00
@@ -83,7 +84,7 @@ struct cursorpos {
 };
 u16 calc_page_size(u8 memmodel, u16 width, u16 height);
 struct vgamode_s *get_current_mode(void);
-void modeswitch_set_bda(int mode, int flags, struct vgamode_s *vmode_g);
+int vga_set_mode(int mode, int flags);
 
 // vgafb.c
 void vgafb_scroll(int nblines, int attr
diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h
index 1101e51..bb5112a 100644
--- a/vgasrc/vgahw.h
+++ b/vgasrc/vgahw.h
@@ -17,12 +17,12 @@ static inline struct vgamode_s *vgahw_find_mode(int mode) {
     return stdvga_find_mode(mode);
 }
 
-static inline int vgahw_set_mode(int mode, int flags) {
+static inline int vgahw_set_mode(struct vgamode_s *vmode_g, int flags) {
     if (CONFIG_VGA_CIRRUS)
-        return clext_set_mode(mode, flags);
+        return clext_set_mode(vmode_g, flags);
     if (CONFIG_VGA_BOCHS)
-        return bochsvga_set_mode(mode, flags);
-    return stdvga_set_mode(mode, flags);
+        return bochsvga_set_mode(vmode_g, flags);
+    return stdvga_set_mode(vmode_g, flags);
 }
 
 static inline void vgahw_list_modes(u16 seg, u16 *dest, u16 *last) {
-- 
1.7.6.4




More information about the SeaBIOS mailing list