[SeaBIOS] [PATCH 2/7] vga: add pci hardware detection
Gerd Hoffmann
kraxel at redhat.com
Mon Feb 6 15:51:38 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 | 109 ++++++++++++++++++++++++++++++++++++++++++++-----------
vgasrc/vgahw.h | 20 ++++++++++
2 files changed, 107 insertions(+), 22 deletions(-)
diff --git a/vgasrc/vgahw.c b/vgasrc/vgahw.c
index be5945e..77b8e77 100644
--- a/vgasrc/vgahw.c
+++ b/vgasrc/vgahw.c
@@ -1,28 +1,72 @@
#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
+
+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(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,66 +74,87 @@ void vgahw_list_modes(u16 seg, u16 *dest, u16 *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;
+ }
+ }
+ }
+
+ 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();
}
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);
}
-
diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h
index 751d4fd..2f51ee8 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(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