diff options
author | Ben Skeggs <skeggsb@gmail.com> | 2007-06-25 12:44:12 +1000 |
---|---|---|
committer | Ben Skeggs <skeggsb@gmail.com> | 2007-06-25 12:44:12 +1000 |
commit | 8f1c9af02651404f8b4800b150a86bb47062fd68 (patch) | |
tree | 07cf3e380893cb2dcef6d375f1bbff7ee2481a18 | |
parent | 824331e3fce36098e8dec31746204f7c13038abb (diff) | |
download | xorg-driver-xf86-video-nouveau-8f1c9af02651404f8b4800b150a86bb47062fd68.tar.gz |
Check PRAMIN for BIOS image if not found in PROM.
-rw-r--r-- | src/nv_bios.c | 95 |
1 files changed, 70 insertions, 25 deletions
diff --git a/src/nv_bios.c b/src/nv_bios.c index 286e85f..d093100 100644 --- a/src/nv_bios.c +++ b/src/nv_bios.c @@ -47,6 +47,70 @@ typedef struct { CARD16 io_flag_condition_offset; } bios_t; +static Bool NVValidBios(ScrnInfoPtr pScrn, const unsigned char *data) +{ + /* check for BIOS signature */ + if (!(data[0] == 0x55 && data[1] == 0xAA)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "...BIOS signature not found\n"); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "...appears to be valid\n"); + return TRUE; +} + +static void NVDownloadBiosPROM(ScrnInfoPtr pScrn, unsigned char *data) +{ + NVPtr pNv = NVPTR(pScrn); + int i; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Attempting to locate BIOS image in PROM\n"); + + /* enable ROM access */ + nvWriteMC(pNv, 0x1850, 0x0); + for (i=0; i<NV_PROM_SIZE; i++) { + /* according to nvclock, we need that to work around a 6600GT/6800LE bug */ + data[i] = pNv->PROM[i]; + data[i] = pNv->PROM[i]; + data[i] = pNv->PROM[i]; + data[i] = pNv->PROM[i]; + data[i] = pNv->PROM[i]; + } + /* disable ROM access */ + nvWriteMC(pNv, 0x1850, 0x1); +} + +static void NVDownloadBiosPRAMIN(ScrnInfoPtr pScrn, unsigned char *data) +{ + NVPtr pNv = NVPTR(pScrn); + const unsigned char *pramin = (void*)&pNv->REGS[0x00700000/4]; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Attempting to locate BIOS image in PRAMIN\n"); + memcpy(data, pramin, 65536); +} + +static Bool NVDownloadBios(ScrnInfoPtr pScrn, bios_t *bios) +{ + NVPtr pNv = NVPTR(pScrn); + + bios->data = xcalloc(1, 65536); + + NVDownloadBiosPROM(pScrn, bios->data); + if (NVValidBios(pScrn, bios->data)) + return TRUE; + + NVDownloadBiosPRAMIN(pScrn, bios->data); + if (NVValidBios(pScrn, bios->data)) + return TRUE; + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to locate BIOS image\n"); + xfree(bios->data); + return FALSE; +} typedef struct { char* name; @@ -1507,39 +1571,20 @@ unsigned int NVParseBios(ScrnInfoPtr pScrn) unsigned char nv_signature[]={0xff,0x7f,'N','V',0x0}; unsigned char bit_signature[]={'B','I','T'}; NVPtr pNv; - int i; + int i, ret; pNv = NVPTR(pScrn); - bios.data=xalloc(NV_PROM_SIZE); - - /* enable ROM access */ - nvWriteMC(pNv, 0x1850, 0x0); - for(i=0;i<NV_PROM_SIZE;i++) - { - /* according to nvclock, we need that to work around a 6600GT/6800LE bug */ - bios.data[i]=pNv->PROM[i]; - bios.data[i]=pNv->PROM[i]; - bios.data[i]=pNv->PROM[i]; - bios.data[i]=pNv->PROM[i]; - bios.data[i]=pNv->PROM[i]; - } - /* disable ROM access */ - nvWriteMC(pNv, 0x1850, 0x1); - - /* check for BIOS signature */ - if (!(bios.data[0] == 0x55 && bios.data[1] == 0xAA)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIOS signature not found!\n"); - xfree(bios.data); + if (!NVDownloadBios(pScrn, &bios)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "No valid BIOS image found.\n"); return 0; } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIOS signature found.\n"); - /* check for known signatures */ - if (bit_offset = findstr(&bios, bit_signature, sizeof(bit_signature))) { + if ((bit_offset = findstr(&bios, bit_signature, sizeof(bit_signature)))) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIT signature found.\n"); parse_bit_structure(pScrn, &bios, bit_offset + 4); - } else if (bit_offset = findstr(&bios, nv_signature, sizeof(nv_signature))) { + } else if ((bit_offset = findstr(&bios, nv_signature, sizeof(nv_signature)))) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV signature found.\n"); parse_pins_structure(pScrn, &bios, bit_offset); } else { |