From e66867e4cf9f0bc8a1971664ccc3d5c56b08b2fb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 16 Jun 2009 10:28:00 +1000 Subject: bios: use image from PRAMIN in preference to PROM on NV50 There's at least one known case (rh#492658) where the DCB table present in the VBIOS image from PROM is not suitable for use. It contained all 16 entries filled, each entry valid in itself, but contradicting other entries. The VBIOS image in PRAMIN however, still has all 16 entries filled, but the first few entries now match what is present on the hardware, and the rest are set as type 0xf, which we ignore. --- src/nv_bios.c | 66 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 23 deletions(-) diff --git a/src/nv_bios.c b/src/nv_bios.c index 865b22d..b307fc6 100644 --- a/src/nv_bios.c +++ b/src/nv_bios.c @@ -187,42 +187,62 @@ static void load_vbios_pci(NVPtr pNv, uint8_t *data) #endif } +struct methods { + const char desc[8]; + void (*loadbios)(NVPtr, uint8_t *); + const bool rw; + int score; +}; + +static struct methods nv04_methods[] = { + { "PROM", load_vbios_prom, false }, + { "PRAMIN", load_vbios_pramin, true }, + { "PCI ROM", load_vbios_pci, true } +}; + +static struct methods nv50_methods[] = { + { "PRAMIN", load_vbios_pramin, true }, + { "PROM", load_vbios_prom, false }, + { "PCI ROM", load_vbios_pci, true } +}; + static bool NVShadowVBIOS(ScrnInfoPtr pScrn, uint8_t *data) { NVPtr pNv = NVPTR(pScrn); - struct methods { - const char desc[8]; - void (*loadbios)(NVPtr, uint8_t *); - const bool rw; - int score; - } method[] = { - { "PROM", load_vbios_prom, false }, - { "PRAMIN", load_vbios_pramin, true }, - { "PCI ROM", load_vbios_pci, true } - }; - int i, testscore = 3; - - for (i = 0; i < sizeof(method) / sizeof(struct methods); i++) { + struct methods *methods, *method; + int testscore = 3; + + if (pNv->Architecture < NV_ARCH_50) + methods = nv04_methods; + else + methods = nv50_methods; + + method = methods; + while (method->loadbios) { NV_TRACE(pScrn, "Attempting to load BIOS image from %s\n", - method[i].desc); + method->desc); data[0] = data[1] = 0; /* avoid reuse of previous image */ - method[i].loadbios(pNv, data); - method[i].score = score_vbios(pScrn, data, method[i].rw); - if (method[i].score == testscore) + method->loadbios(pNv, data); + method->score = score_vbios(pScrn, data, method->rw); + if (method->score == testscore) return true; + method++; } - while (--testscore > 0) - for (i = 0; i < sizeof(method) / sizeof(struct methods); i++) - if (method[i].score == testscore) { + while (--testscore > 0) { + method = methods; + while (method->loadbios) { + if (method->score == testscore) { NV_TRACE(pScrn, "Using BIOS image from %s\n", - method[i].desc); - method[i].loadbios(pNv, data); + method->desc); + method->loadbios(pNv, data); return true; } + method++; + } + } NV_ERROR(pScrn, "No valid BIOS image found\n"); - return false; } -- cgit v1.2.3