vgabios: Move BDA setting from driver code to common code.
authorKevin O'Connor <kevin@koconnor.net>
Sat, 21 Jan 2012 16:26:37 +0000 (11:26 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Thu, 2 Feb 2012 01:35:48 +0000 (20:35 -0500)
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@koconnor.net>
vgasrc/bochsvga.c
vgasrc/bochsvga.h
vgasrc/clext.c
vgasrc/clext.h
vgasrc/stdvga.c
vgasrc/stdvga.h
vgasrc/stdvgamodes.c
vgasrc/vbe.c
vgasrc/vgabios.c
vgasrc/vgabios.h
vgasrc/vgahw.h

index 213dbcd2f932b2c2e66d1801d3d58e2c6417a2f6..6cbbf9c8fddff1ec4a2016fffaa56bb356928800 100644 (file)
@@ -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();
     }
 
index 81fb8f7286e672fece16a6e2380fa3b17b65a636..1eaa91acc7601b9a2dc2ebe115d544a06941bc6d 100644 (file)
@@ -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
index ea2b42891fcdf1403a10d44aca0e6d3490f90074..363ef5df51bf1ada2f6856b62ae456e21f13e9ca 100644 (file)
@@ -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
index a14cf1389540d784b9e5dc389ef841947cdcff59..718b7561d75745c41ec3964a3c38f398eef2415d 100644 (file)
@@ -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;
index 0fab905ec5506bf50e5ccbca013687824202e011..b7def3290be23ee93b2a4eee8391f362afe1a35a 100644 (file)
@@ -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;
 }
 
index ee143581ed0b4997c41687d177b98330a802f00d..cc93f0d91a28d20198339996d25367dfdb580380 100644 (file)
@@ -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);
index 08c3a58ece93bef816426952cc18210eaa38f930..1b47e98d103fe326be5e66bae6501620b5081ee4 100644 (file)
@@ -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)
 {
index caf856d7f4c7503d43f94dd7b67006a9ac74d972..b6ffb979ad58072a00a737865e7d4cae84539554 100644 (file)
@@ -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;
 }
 
index 62b09b45caad464c3e9d8014a75d4f0f4b1d9e72..d35cb0272293eb4dcfdc8743bd88b05d1a96c84e 100644 (file)
@@ -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
 
@@ -316,7 +317,9 @@ save_bda_state(u16 seg, struct saveBDAstate *info)
 static void
 restore_bda_state(u16 seg, struct saveBDAstate *info)
 {
-    SET_BDA(video_mode, GET_FARVAR(seg, info->video_mode));
+    u16 mode = GET_FARVAR(seg, info->video_mode);
+    SET_BDA(video_mode, mode);
+    SET_BDA(vbe_mode, mode);
     SET_BDA(video_cols, GET_FARVAR(seg, info->video_cols));
     SET_BDA(video_pagesize, GET_FARVAR(seg, info->video_pagesize));
     SET_BDA(crtc_address, GET_FARVAR(seg, info->crtc_address));
@@ -344,19 +347,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 +418,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 +444,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
index 6a3a379738777a18a1e93d3c204177c1a2af19a4..23d234ac1637e6a838f655ab54151334cdba21c4 100644 (file)
@@ -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
index 1101e510737a1f9510be364f9fc8334d47fd7009..bb5112a691d23def31ea523f17eeb3ac9834dada 100644 (file)
@@ -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) {