[coreboot] [PATCH] SeaBIOS - vgahooks improvements

Kevin O'Connor kevin at koconnor.net
Fri Dec 26 17:16:10 CET 2008


On Wed, Dec 24, 2008 at 12:16:14AM +0100, Rudolf Marek wrote:
>> The K8M890 BIOS needs int 0x15 0x5f18 to write to scratch register for 
>> a driver the memory size of framebuffer and also the memory speed. The  
>> X.org openchrome driver as well Unichrome driver needs that.
[...]
> diff --git a/src/vgahooks.c b/src/vgahooks.c
> index 7c229ba..86050fd 100644
> --- a/src/vgahooks.c
> +++ b/src/vgahooks.c
[...]
> +    bdf = pci_find_device(PCI_VENDOR_ID_VIA, 0x3336); /* K8M890 supported so far */
[...]
> +    bdf = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MEMCTL); /* get the memory speed */
[...]

I think I understand your patch a little bit better now.  The first
pci device is used to obtain the framebuffer size, and the second
device is used to find the ram speed.

Perhaps we should break this into two separate functions - that way
it's clear that each device provides independent information.
(Something like the attached?)

Also, does unichrome/openchrome drivers need the framebuffer size?
It seems odd to me that they'd read a scratch register for that, when
they could just as easily read the real register.

-Kevin
-------------- next part --------------
diff --git a/src/vgahooks.c b/src/vgahooks.c
index 7c229ba..33e017b 100644
--- a/src/vgahooks.c
+++ b/src/vgahooks.c
@@ -5,6 +5,9 @@
 // This file may be distributed under the terms of the GNU GPLv3 license.
 
 #include "bregs.h" // set_fail
+#include "biosvar.h" // GET_GLOBAL
+#include "pci.h" // pci_find_device
+#include "pci_ids.h" // PCI_VENDOR_ID_VIA
 #include "util.h" // handle_155f
 #include "config.h" // CONFIG_*
 
@@ -26,11 +29,72 @@ handle_155f02(struct bregs *regs)
     set_success(regs);
 }
 
+static int
+getFBSize()
+{
+    /* 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;
+
+    static u8 mem_power[] = {0, 3, 4, 5, 6, 7, 8, 9};
+    return GET_GLOBAL(mem_power[(reg >> 4) & 0x7]);
+err:
+    return 5; // 32M frame buffer
+}
+
+static int
+getRamSpeed()
+{
+    int bdf = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MEMCTL);
+    if (bdf < 0)
+        goto err;
+
+    /* mem clk 0 = DDR2 400 */
+    u8 reg = pci_config_readb(bdf, 0x94) & 0x7;
+    return reg + 7;
+err:
+    dprintf(1, "Warning: Memory clock speed is hardcoded\n");
+    return 4; // MCLK = DDR266
+}
+
+/* ECX = unknown/dont care
+   EBX[3..0] FB size 1 = 8MB 2=16MB ...
+   EBX[7..4] Memory speed:
+       0: SDR  66Mhz
+       1: SDR 100Mhz
+       2: SDR 133Mhz
+       3: DDR 100Mhz (PC1600 or DDR200)
+       4: DDR 133Mhz (PC2100 or DDR266)
+       5: DDR 166Mhz (PC2700 or DDR333)
+       6: DDR 200Mhz (PC3200 or DDR400)
+       Guesses (confirmed)
+       7: DDR2 100Mhz (DDR2 400)
+       8: DDR2 133Mhz (DDR2 533)
+       9: DDR2 166Mhz (DDR2 667)
+       A: DDR2 200Mhz (DDR2 800)
+       B: DDR2 233Mhz (DDR2 1066)
+       C: and above: Unknown
+   EBX[?..8] Total memory size?
+   EAX = 0x5f for success
+
+    K8M890 BIOS wants only this call (Desktop NoTv)
+*/
+
 static void
 handle_155f18(struct bregs *regs)
 {
     regs->eax = 0x5f;
-    regs->ebx = 0x545; // MCLK = 133, 32M frame buffer, 256 M main memory
+    u32 ramspeed = getRamSpeed();
+    u32 fbsize = getFBSize();
+    regs->ebx = 0x500 | (ramspeed << 4) | fbsize;
     regs->ecx = 0x060;
     set_success(regs);
 }


More information about the coreboot mailing list