Expand int155f "vgahook" detection.
authorKevin O'Connor <kevin@koconnor.net>
Sun, 19 Jul 2009 22:52:46 +0000 (18:52 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Sun, 19 Jul 2009 22:52:46 +0000 (18:52 -0400)
Verify VGA card vendor is via before supporting via 155f calls.
Add support for future code depending on coreboot board id.
Add code for via VX855 memory size and speed detection.

Makefile
src/coreboot.c
src/optionroms.c
src/util.h
src/vgahooks.c

index 2978105b6d5e156d4c0b18b1f2b8a9d08cfbf708..41e6514d175aa1f12b02eeaf85d95f6e57038b38 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -10,8 +10,8 @@ OUT=out/
 # Source files
 SRCBOTH=output.c util.c floppy.c ata.c misc.c mouse.c kbd.c pci.c \
         serial.c clock.c pic.c cdrom.c ps2port.c smp.c resume.c \
-        pnpbios.c pirtable.c
-SRC16=$(SRCBOTH) system.c disk.c apm.c pcibios.c vgahooks.c font.c
+        pnpbios.c pirtable.c vgahooks.c
+SRC16=$(SRCBOTH) system.c disk.c apm.c pcibios.c font.c
 SRC32=$(SRCBOTH) post.c shadow.c memmap.c coreboot.c boot.c \
       acpi.c smm.c mptable.c smbios.c pciinit.c optionroms.c mtrr.c \
       lzmadecode.c
index b8479c5bacac0987de5394c0b6f113873055c30e..a7604141e217d6d895a746af1adf936b6e65b732 100644 (file)
@@ -143,6 +143,16 @@ struct cb_memory {
 #define MEM_RANGE_COUNT(_rec) \
         (((_rec)->size - sizeof(*(_rec))) / sizeof((_rec)->map[0]))
 
+struct cb_mainboard {
+    u32 tag;
+    u32 size;
+    u8  vendor_idx;
+    u8  part_idx;
+    char  strings[0];
+};
+
+#define CB_TAG_MAINBOARD 0x0003
+
 struct cb_forward {
     u32 tag;
     u32 size;
@@ -260,6 +270,15 @@ coreboot_fill_map()
     // smbios/dmi table is found from coreboot and use that instead.
     smbios_init();
 
+    struct cb_mainboard *cbmb = find_cb_subtable(cbh, CB_TAG_MAINBOARD);
+    if (cbmb) {
+        const char *vendor = &cbmb->strings[cbmb->vendor_idx];
+        const char *part = &cbmb->strings[cbmb->part_idx];
+        dprintf(1, "Found mainboard %s %s\n", vendor, part);
+
+        vgahook_setup(vendor, part);
+    }
+
     return;
 
 fail:
index 24fc4c3c248b69c85cecd75646445160fb6af12b..1d47c1e56c49b3c1322f9e239a46b60f65a70c4d 100644 (file)
@@ -408,6 +408,7 @@ vga_setup()
         return;
 
     dprintf(1, "Scan for VGA option rom\n");
+    VGAbdf = -1;
     next_rom = OPTION_ROM_START;
 
     if (CONFIG_OPTIONROMS_DEPLOYED) {
@@ -415,7 +416,7 @@ vga_setup()
         init_optionrom((void*)OPTION_ROM_START, 0, 1);
     } else {
         // Find and deploy PCI VGA rom.
-        int bdf = pci_find_class(PCI_CLASS_DISPLAY_VGA);
+        int bdf = VGAbdf = pci_find_class(PCI_CLASS_DISPLAY_VGA);
         if (bdf >= 0)
             init_pcirom(bdf, 1);
 
index b32a517463c33e5b3b50e106ed266354072c7dab..b566f561f5981b72ea209549c01ede52b8bbca1e 100644 (file)
@@ -211,7 +211,9 @@ struct cbfs_file *cbfs_copyfile_prefix(void *dst, u32 maxlen, const char *prefix
 void coreboot_setup();
 
 // vgahooks.c
+extern int VGAbdf;
 void handle_155f();
+void vgahook_setup(const char *vendor, const char *part);
 
 // optionroms.c
 void call_bcv(u16 seg, u16 ip);
index fcb779344a471bddf4030af6947f45ba9aff0eba..ddeb1d31d7bf210a23a6d348c19fd12cae0771be 100644 (file)
@@ -7,12 +7,29 @@
 #include "bregs.h" // set_code_fail
 #include "biosvar.h" // GET_GLOBAL
 #include "pci.h" // pci_find_device
+#include "pci_regs.h" // PCI_VENDOR_ID
 #include "pci_ids.h" // PCI_VENDOR_ID_VIA
 #include "util.h" // handle_155f
 #include "config.h" // CONFIG_*
 
+// The Bus/Dev/Fn of the primary VGA device.
+int VGAbdf VAR16_32;
+// Coreboot board detected.
+int CBmainboard VAR16_32;
+
 static void
-handle_155f01(struct bregs *regs)
+handle_155fXX(struct bregs *regs)
+{
+    set_code_fail(regs, RET_EUNSUPPORTED);
+}
+
+
+/****************************************************************
+ * Via hooks
+ ****************************************************************/
+
+static void
+via_155f01(struct bregs *regs)
 {
     regs->eax = 0x5f;
     regs->cl = 2; // panel type =  2 = 1024 * 768
@@ -21,7 +38,7 @@ handle_155f01(struct bregs *regs)
 }
 
 static void
-handle_155f02(struct bregs *regs)
+via_155f02(struct bregs *regs)
 {
     regs->eax = 0x5f;
     regs->bx = 2;
@@ -32,40 +49,34 @@ handle_155f02(struct bregs *regs)
 }
 
 static int
-getFBSize()
+getFBSize(u16 bdf)
 {
-    /* Find K8M890 */
-    int bdf = pci_find_device(PCI_VENDOR_ID_VIA, 0x3336);
-    if (bdf < 0)
-        goto err;
-
     /* FB config */
     u8 reg = pci_config_readb(bdf, 0xa1);
 
     /* GFX disabled ? */
     if (!(reg & 0x80))
-        goto err;
+        return -1;
 
     static u8 mem_power[] VAR16 = {0, 3, 4, 5, 6, 7, 8, 9};
     return GET_GLOBAL(mem_power[(reg >> 4) & 0x7]);
-err:
-    dprintf(1, "Warning: VGA memory size is hardcoded\n");
-    return 5; // 32M frame buffer
 }
 
 static int
-getRamSpeed()
+getViaRamSpeed(u16 bdf)
+{
+    return (pci_config_readb(bdf, 0x90) & 0x07) + 3;
+}
+
+static int
+getAMDRamSpeed()
 {
     int bdf = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MEMCTL);
     if (bdf < 0)
-        goto err;
+        return -1;
 
     /* mem clk 0 = DDR2 400 */
-    u8 reg = pci_config_readb(bdf, 0x94) & 0x7;
-    return reg + 6;
-err:
-    dprintf(1, "Warning: VGA memory clock speed is hardcoded\n");
-    return 4; // MCLK = DDR266
+    return (pci_config_readb(bdf, 0x94) & 0x7) + 6;
 }
 
 /* int 0x15 - 5f18
@@ -87,46 +98,96 @@ err:
        B: and above: Unknown
    EBX[?..8] Total memory size?
    EAX = 0x5f for success
-
-    K8M890 BIOS wants only this call (Desktop NoTv)
 */
 
+#define PCI_DEVICE_ID_VIA_K8M890CE_3    0x3336
+#define PCI_DEVICE_ID_VIA_VX855_MEMCTRL 0x3409
+
 static void
-handle_155f18(struct bregs *regs)
+via_155f18(struct bregs *regs)
 {
+    u32 ramspeed, fbsize;
+
+    int bdf = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_K8M890CE_3);
+    if (bdf >= 0) {
+        fbsize = getFBSize(bdf);
+        ramspeed = getAMDRamSpeed();
+        goto done;
+    }
+    bdf = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855_MEMCTRL);
+    if (bdf >= 0) {
+        fbsize = getFBSize(bdf);
+        ramspeed = getViaRamSpeed(bdf);
+        goto done;
+    }
+
+    dprintf(1, "Warning: VGA memory size and speed is hardcoded\n");
+    fbsize = 5; // 32M frame buffer
+    ramspeed = 4; // MCLK = DDR266
+
+done:
+    if (fbsize < 0 || ramspeed < 0) {
+        set_code_fail(regs, RET_EUNSUPPORTED);
+        return;
+    }
     regs->eax = 0x5f;
-    u32 ramspeed = getRamSpeed();
-    u32 fbsize = getFBSize();
     regs->ebx = 0x500 | (ramspeed << 4) | fbsize;
     regs->ecx = 0x060;
     set_success(regs);
 }
 
 static void
-handle_155f19(struct bregs *regs)
+via_155f19(struct bregs *regs)
 {
     set_fail_silent(regs);
 }
 
 static void
-handle_155fXX(struct bregs *regs)
+via_155f(struct bregs *regs)
 {
-    set_code_fail(regs, RET_EUNSUPPORTED);
+    switch (regs->al) {
+    case 0x01: via_155f01(regs); break;
+    case 0x02: via_155f02(regs); break;
+    case 0x18: via_155f18(regs); break;
+    case 0x19: via_155f19(regs); break;
+    default:   handle_155fXX(regs); break;
+    }
 }
 
+
+/****************************************************************
+ * Entry and setup
+ ****************************************************************/
+
+// Main 16bit entry point
 void
 handle_155f(struct bregs *regs)
 {
-    if (! CONFIG_VGAHOOKS) {
-        handle_155fXX(regs);
+    if (! CONFIG_VGAHOOKS)
+        goto fail;
+
+    // XXX - Use this value later.
+    //int cbmb = GET_GLOBAL(CBmainboard);
+
+    int bdf = GET_GLOBAL(VGAbdf);
+    if (bdf < 0)
+        goto fail;
+    u16 vendor = pci_config_readw(bdf, PCI_VENDOR_ID);
+    if (vendor == PCI_VENDOR_ID_VIA) {
+        via_155f(regs);
         return;
     }
 
-    switch (regs->al) {
-    case 0x01: handle_155f01(regs); break;
-    case 0x02: handle_155f02(regs); break;
-    case 0x18: handle_155f18(regs); break;
-    case 0x19: handle_155f19(regs); break;
-    default:   handle_155fXX(regs); break;
-    }
+fail:
+    handle_155fXX(regs);
+}
+
+// Setup
+void
+vgahook_setup(const char *vendor, const char *part)
+{
+    if (! CONFIG_VGAHOOKS)
+        return;
+    // XXX - add support later.
+    CBmainboard = 0;
 }