[SeaBIOS] [PATCH 2/3] vga: add pci hardware detection

Gerd Hoffmann kraxel at redhat.com
Wed Feb 8 17:38:58 CET 2012


Add support for pci hardware detection (using pci id lookup), so we can
create a unified rom with support for different pieces of hardware.

Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
---
 vgasrc/Kconfig   |   12 ++----
 vgasrc/vgabios.c |    2 +-
 vgasrc/vgahw.c   |  114 +++++++++++++++++++++++++++++++++++++++---------------
 vgasrc/vgahw.h   |   17 ++++++++
 4 files changed, 105 insertions(+), 40 deletions(-)

diff --git a/vgasrc/Kconfig b/vgasrc/Kconfig
index 881e9ec..e011238 100644
--- a/vgasrc/Kconfig
+++ b/vgasrc/Kconfig
@@ -15,15 +15,11 @@ menu "VGA ROM"
             help
                 Build basic VGA BIOS support.
 
-        config VGA_CIRRUS
-            bool "QEMU Cirrus CLGD 54xx VGA BIOS"
+        config VGA_QEMU
+            bool "QEMU VGA BIOS"
             help
-                Build support for Cirrus VGA emulation.
-
-        config VGA_BOCHS
-            bool "Bochs DISPI interface VGA BIOS"
-            help
-                Build support for Bochs DISPI interface.
+                Build VGA BIOS for QEMU.  This builds a unified BIOS,
+                supporting both bochs vga interface and cirrus vga emulation.
 
         config VGA_GEODEGX2
             bool "GeodeGX2 interface VGA BIOS"
diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c
index 7b6c50a..a1cf11a 100644
--- a/vgasrc/vgabios.c
+++ b/vgasrc/vgabios.c
@@ -1001,7 +1001,7 @@ handle_1012XX(struct bregs *regs)
 static void
 handle_1012(struct bregs *regs)
 {
-    if (CONFIG_VGA_CIRRUS && regs->bl >= 0x80) {
+    if (HAVE_VGA_CIRRUS && regs->bl >= 0x80) {
         clext_1012(regs);
         return;
     }
diff --git a/vgasrc/vgahw.c b/vgasrc/vgahw.c
index 65afeb1..03d8757 100644
--- a/vgasrc/vgahw.c
+++ b/vgasrc/vgahw.c
@@ -1,28 +1,57 @@
 #include "vgahw.h"
+#include "config.h" // CONFIG_*
+#include "util.h" // dprintf
+#include "biosvar.h" // GET_GLOBAL
+#include "pci.h" // pci_config_readw
+#include "pci_regs.h" // PCI_VENDOR_ID
+#include "vgabios.h" // VgaBDF
+
+enum qemu_vga_type qemu_vga_type VAR16;
+
+struct qemu_pci_table {
+    u16 vid;
+    u16 did;
+    char *name;
+    enum qemu_vga_type type;
+};
+
+static struct qemu_pci_table hwtab[] VAR16 = {
+    {
+        .vid  = 0x1013,
+        .did  = 0x00b8,
+        .name = "cirrus",
+        .type = VGA_TYPE_CIRRUS,
+    },{
+        .vid  = 0x1234,
+        .did  = 0x1111,
+        .name = "std",
+        .type = VGA_TYPE_BOCHS,
+    }
+};
 
 struct vgamode_s *vgahw_find_mode(int mode)
 {
-    if (CONFIG_VGA_CIRRUS)
+    if (HAVE_VGA_CIRRUS)
         return clext_find_mode(mode);
-    if (CONFIG_VGA_BOCHS)
+    if (HAVE_VGA_BOCHS)
         return bochsvga_find_mode(mode);
     return stdvga_find_mode(mode);
 }
 
 int vgahw_set_mode(struct vgamode_s *vmode_g, int flags)
 {
-    if (CONFIG_VGA_CIRRUS)
+    if (HAVE_VGA_CIRRUS)
         return clext_set_mode(vmode_g, flags);
-    if (CONFIG_VGA_BOCHS)
+    if (HAVE_VGA_BOCHS)
         return bochsvga_set_mode(vmode_g, flags);
     return stdvga_set_mode(vmode_g, flags);
 }
 
 void vgahw_list_modes(u16 seg, u16 *dest, u16 *last)
 {
-    if (CONFIG_VGA_CIRRUS)
+    if (HAVE_VGA_CIRRUS)
         clext_list_modes(seg, dest, last);
-    else if (CONFIG_VGA_BOCHS)
+    else if (HAVE_VGA_BOCHS)
         bochsvga_list_modes(seg, dest, last);
     else
         stdvga_list_modes(seg, dest, last);
@@ -30,10 +59,34 @@ void vgahw_list_modes(u16 seg, u16 *dest, u16 *last)
 
 int vgahw_init(void)
 {
-    if (CONFIG_VGA_CIRRUS)
-        return clext_init();
-    if (CONFIG_VGA_BOCHS)
-        return bochsvga_init();
+    if (CONFIG_VGA_QEMU) {
+        if (CONFIG_VGA_PCI) {
+            u16 bdf = GET_GLOBAL(VgaBDF);
+            u16 vid = pci_config_readw(bdf, PCI_VENDOR_ID);
+            u16 did = pci_config_readw(bdf, PCI_DEVICE_ID);
+            int i;
+
+            for (i = 0; i < ARRAY_SIZE(hwtab); i++) {
+                if (GET_GLOBAL(hwtab[i].vid) == vid &&
+                    GET_GLOBAL(hwtab[i].did) == did) {
+                    dprintf(1, "vgahw: detected qemu %s vga [pci %04x:%04x]\n",
+                            GET_GLOBAL(hwtab[i].name), vid, did);
+                    SET_VGA(qemu_vga_type, GET_GLOBAL(hwtab[i].type));
+                    break;
+                }
+            }
+        }
+
+        if (GET_GLOBAL(qemu_vga_type) == VGA_TYPE_UNDEFINED) {
+            SET_VGA(qemu_vga_type, VGA_TYPE_STDVGA);
+            dprintf(1, "vgahw: no known hardware found, using stdvga\n");
+        }
+        if (HAVE_VGA_CIRRUS)
+            return clext_init();
+        if (HAVE_VGA_BOCHS)
+            return bochsvga_init();
+    }
+
     if (CONFIG_VGA_GEODEGX2 || CONFIG_VGA_GEODELX)
         return geodevga_init();
     return stdvga_init();
@@ -41,96 +94,95 @@ int vgahw_init(void)
 
 int vgahw_get_window(struct vgamode_s *vmode_g, int window)
 {
-    if (CONFIG_VGA_CIRRUS)
+    if (HAVE_VGA_CIRRUS)
         return clext_get_window(vmode_g, window);
-    if (CONFIG_VGA_BOCHS)
+    if (HAVE_VGA_BOCHS)
         return bochsvga_get_window(vmode_g, window);
     return stdvga_get_window(vmode_g, window);
 }
 
 int vgahw_set_window(struct vgamode_s *vmode_g, int window, int val)
 {
-    if (CONFIG_VGA_CIRRUS)
+    if (HAVE_VGA_CIRRUS)
         return clext_set_window(vmode_g, window, val);
-    if (CONFIG_VGA_BOCHS)
+    if (HAVE_VGA_BOCHS)
         return bochsvga_set_window(vmode_g, window, val);
     return stdvga_set_window(vmode_g, window, val);
 }
 
 int vgahw_get_linelength(struct vgamode_s *vmode_g)
 {
-    if (CONFIG_VGA_CIRRUS)
+    if (HAVE_VGA_CIRRUS)
         return clext_get_linelength(vmode_g);
-    if (CONFIG_VGA_BOCHS)
+    if (HAVE_VGA_BOCHS)
         return bochsvga_get_linelength(vmode_g);
     return stdvga_get_linelength(vmode_g);
 }
 
 int vgahw_set_linelength(struct vgamode_s *vmode_g, int val)
 {
-    if (CONFIG_VGA_CIRRUS)
+    if (HAVE_VGA_CIRRUS)
         return clext_set_linelength(vmode_g, val);
-    if (CONFIG_VGA_BOCHS)
+    if (HAVE_VGA_BOCHS)
         return bochsvga_set_linelength(vmode_g, val);
     return stdvga_set_linelength(vmode_g, val);
 }
 
 int vgahw_get_displaystart(struct vgamode_s *vmode_g)
 {
-    if (CONFIG_VGA_CIRRUS)
+    if (HAVE_VGA_CIRRUS)
         return clext_get_displaystart(vmode_g);
-    if (CONFIG_VGA_BOCHS)
+    if (HAVE_VGA_BOCHS)
         return bochsvga_get_displaystart(vmode_g);
     return stdvga_get_displaystart(vmode_g);
 }
 
 int vgahw_set_displaystart(struct vgamode_s *vmode_g, int val)
 {
-    if (CONFIG_VGA_CIRRUS)
+    if (HAVE_VGA_CIRRUS)
         return clext_set_displaystart(vmode_g, val);
-    if (CONFIG_VGA_BOCHS)
+    if (HAVE_VGA_BOCHS)
         return bochsvga_set_displaystart(vmode_g, val);
     return stdvga_set_displaystart(vmode_g, val);
 }
 
 int vgahw_get_dacformat(struct vgamode_s *vmode_g)
 {
-    if (CONFIG_VGA_BOCHS)
+    if (HAVE_VGA_BOCHS)
         return bochsvga_get_dacformat(vmode_g);
     return stdvga_get_dacformat(vmode_g);
 }
 
 int vgahw_set_dacformat(struct vgamode_s *vmode_g, int val)
 {
-    if (CONFIG_VGA_BOCHS)
+    if (HAVE_VGA_BOCHS)
         return bochsvga_set_dacformat(vmode_g, val);
     return stdvga_set_dacformat(vmode_g, val);
 }
 
 int vgahw_size_state(int states)
 {
-    if (CONFIG_VGA_CIRRUS)
+    if (HAVE_VGA_CIRRUS)
         return clext_size_state(states);
-    if (CONFIG_VGA_BOCHS)
+    if (HAVE_VGA_BOCHS)
         return bochsvga_size_state(states);
     return stdvga_size_state(states);
 }
 
 int vgahw_save_state(u16 seg, void *data, int states)
 {
-    if (CONFIG_VGA_CIRRUS)
+    if (HAVE_VGA_CIRRUS)
         return clext_save_state(seg, data, states);
-    if (CONFIG_VGA_BOCHS)
+    if (HAVE_VGA_BOCHS)
         return bochsvga_save_state(seg, data, states);
     return stdvga_save_state(seg, data, states);
 }
 
 int vgahw_restore_state(u16 seg, void *data, int states)
 {
-    if (CONFIG_VGA_CIRRUS)
+    if (HAVE_VGA_CIRRUS)
         return clext_restore_state(seg, data, states);
-    if (CONFIG_VGA_BOCHS)
+    if (HAVE_VGA_BOCHS)
         return bochsvga_restore_state(seg, data, states);
     return stdvga_restore_state(seg, data, states);
 }
-
diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h
index 4643d38..186f7b5 100644
--- a/vgasrc/vgahw.h
+++ b/vgasrc/vgahw.h
@@ -9,6 +9,23 @@
 #include "stdvga.h" // stdvga_set_mode
 #include "geodevga.h" // geodevga_init
 
+enum qemu_vga_type {
+    VGA_TYPE_UNDEFINED = 0,
+    VGA_TYPE_STDVGA,
+    VGA_TYPE_CIRRUS,
+    VGA_TYPE_BOCHS,
+};
+
+extern enum qemu_vga_type qemu_vga_type;
+
+#if CONFIG_VGA_QEMU
+# define HAVE_VGA_CIRRUS (GET_GLOBAL(qemu_vga_type) == VGA_TYPE_CIRRUS)
+# define HAVE_VGA_BOCHS  (GET_GLOBAL(qemu_vga_type) == VGA_TYPE_BOCHS)
+#else
+# define HAVE_VGA_CIRRUS (0)
+# define HAVE_VGA_BOCHS  (0)
+#endif
+
 struct vgamode_s *vgahw_find_mode(int mode);
 int vgahw_set_mode(struct vgamode_s *vmode_g, int flags);
 void vgahw_list_modes(u16 seg, u16 *dest, u16 *last);
-- 
1.7.1




More information about the SeaBIOS mailing list