aboutsummaryrefslogtreecommitdiff
path: root/src/vgahooks.c
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2009-07-19 18:52:46 -0400
committerKevin O'Connor <kevin@koconnor.net>2009-07-19 18:52:46 -0400
commit22e1b91ea88b2d7ebdf9f0fc90ca1d90fbe25225 (patch)
treed79993697b829e288a52b469dae484b4f15fa8ac /src/vgahooks.c
parent0775070d50fde278fe8e40e6fcbcfea3286791f1 (diff)
downloadseabios-hppa-22e1b91ea88b2d7ebdf9f0fc90ca1d90fbe25225.zip
seabios-hppa-22e1b91ea88b2d7ebdf9f0fc90ca1d90fbe25225.tar.gz
seabios-hppa-22e1b91ea88b2d7ebdf9f0fc90ca1d90fbe25225.tar.bz2
Expand int155f "vgahook" detection.
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.
Diffstat (limited to 'src/vgahooks.c')
-rw-r--r--src/vgahooks.c133
1 files changed, 97 insertions, 36 deletions
diff --git a/src/vgahooks.c b/src/vgahooks.c
index fcb7793..ddeb1d3 100644
--- a/src/vgahooks.c
+++ b/src/vgahooks.c
@@ -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;
}