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

Gerd Hoffmann kraxel at redhat.com
Tue Jan 24 15:46:06 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/vgahw.c |   85 +++++++++++++++++++++++++++++++++++++++++++++++++------
 vgasrc/vgahw.h |   20 +++++++++++++
 2 files changed, 95 insertions(+), 10 deletions(-)

diff --git a/vgasrc/vgahw.c b/vgasrc/vgahw.c
index 0ef3af5..7620d59 100644
--- a/vgasrc/vgahw.c
+++ b/vgasrc/vgahw.c
@@ -1,37 +1,102 @@
 #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
+
+struct vga_pci_table {
+    u16 vid;
+    u16 did;
+    char *name;
+    enum vga_type type;
+    int supported;
+};
+
+static struct vga_pci_table hwtab[] VAR16 = {
+    {
+        .vid  = 0x1013,
+        .did  = 0x00b8,
+        .name = "QEMU Cirrus VGA (CLGD 54xx)",
+        .type = VGA_TYPE_CIRRUS,
+        .supported = CONFIG_VGA_CIRRUS,
+    },{
+        .vid  = 0x1234,
+        .did  = 0x1111,
+        .name = "QEMU Standard VGA",
+        .type = VGA_TYPE_BOCHS,
+        .supported = CONFIG_VGA_BOCHS,
+    },{
+        .vid  = 0x100b,
+        .did  = 0x0030,
+        .name = "Geode GX2",
+        .type = VGA_TYPE_GEODEGX2,
+        .supported = CONFIG_VGA_GEODEGX2,
+    },{
+        .vid  = 0x1022,
+        .did  = 0x2081,
+        .name = "Geode LX",
+        .type = VGA_TYPE_GEODELX,
+        .supported = CONFIG_VGA_GEODELX,
+    }
+};
+
+enum vga_type vga_type VAR16;
 
 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(int mode, int flags) {
-    if (CONFIG_VGA_CIRRUS)
+    if (HAVE_VGA_CIRRUS)
         return clext_set_mode(mode, flags);
-    if (CONFIG_VGA_BOCHS)
+    if (HAVE_VGA_BOCHS)
         return bochsvga_set_mode(mode, flags);
     return stdvga_set_mode(mode, 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);
 }
 
 int vgahw_init(void) {
-    if (CONFIG_VGA_CIRRUS)
+    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 %s [pci %04x:%04x]\n",
+                        GET_GLOBAL(hwtab[i].name), vid, did);
+                if (GET_GLOBAL(hwtab[i].supported)) {
+                    SET_VGA(vga_type, GET_GLOBAL(hwtab[i].type));
+                } else {
+                    SET_VGA(vga_type, VGA_TYPE_STDVGA);
+                    dprintf(1, "vgahw: support not compiled, using stdvga\n");
+                }
+                break;
+            }
+        }
+    } else {
+    }
+
+    if (HAVE_VGA_CIRRUS)
         return clext_init();
-    if (CONFIG_VGA_BOCHS)
+    if (HAVE_VGA_BOCHS)
         return bochsvga_init();
-    if (CONFIG_VGA_GEODEGX2 || CONFIG_VGA_GEODELX)
+    if (HAVE_VGA_GEODEGX2 || HAVE_VGA_GEODELX)
         return geodevga_init();
     return stdvga_init();
 }
-
diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h
index 34de00d..82caaea 100644
--- a/vgasrc/vgahw.h
+++ b/vgasrc/vgahw.h
@@ -9,6 +9,26 @@
 #include "stdvga.h" // stdvga_set_mode
 #include "geodevga.h" // geodevga_init
 
+enum vga_type {
+    VGA_TYPE_UNDEFINED = 0,
+    VGA_TYPE_STDVGA,
+    VGA_TYPE_CIRRUS,
+    VGA_TYPE_BOCHS,
+    VGA_TYPE_GEODEGX2,
+    VGA_TYPE_GEODELX,
+};
+
+extern enum vga_type vga_type;
+
+#define HAVE_VGA_CIRRUS   (CONFIG_VGA_CIRRUS &&                         \
+                           (GET_GLOBAL(vga_type) == VGA_TYPE_CIRRUS))
+#define HAVE_VGA_BOCHS    (CONFIG_VGA_BOCHS &&                          \
+                           (GET_GLOBAL(vga_type) == VGA_TYPE_BOCHS))
+#define HAVE_VGA_GEODEGX2 (CONFIG_VGA_GEODEGX2 &&                       \
+                           (GET_GLOBAL(vga_type) == VGA_TYPE_GEODEGX2))
+#define HAVE_VGA_GEODELX  (CONFIG_VGA_GEODELX &&                        \
+                           (GET_GLOBAL(vga_type) == VGA_TYPE_GEODELX))
+
 struct vgamode_s *vgahw_find_mode(int mode);
 int vgahw_set_mode(int mode, int flags);
 void vgahw_list_modes(u16 seg, u16 *dest, u16 *last);
-- 
1.7.1




More information about the SeaBIOS mailing list