diff options
author | Francisco Jerez <currojerez@riseup.net> | 2009-05-05 00:44:17 +0200 |
---|---|---|
committer | Francisco Jerez <currojerez@riseup.net> | 2009-05-05 00:48:12 +0200 |
commit | 32628d9884d577d7a672c172c12b7097be276700 (patch) | |
tree | 93680f2995c5da9043799e50116b9bc30200b79c /src | |
parent | 00921b014fa0b5358c22a769cf2450cbd4bdc8a5 (diff) |
Probe the amount of installed memory by trial and error on SM712.
In some cases the BIOS hasn't filled in the "scratchpad registers"
(SR71) with the right amount of memory installed (e.g. MIPS
platform). There seems to be no other way to do it than to test it.
This should fix bug 21528.
Diffstat (limited to 'src')
-rw-r--r-- | src/smi_driver.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/smi_driver.c b/src/smi_driver.c index 7219612..c0e72e4 100644 --- a/src/smi_driver.c +++ b/src/smi_driver.c @@ -1423,6 +1423,55 @@ SMI_MapMmio(ScrnInfoPtr pScrn) return (TRUE); } +/* HACK - In some cases the BIOS hasn't filled in the "scratchpad + registers" (SR71) with the right amount of memory installed (e.g. MIPS + platform). Probe it manually. */ +static unsigned long +SMI_ProbeMem(ScrnInfoPtr pScrn, unsigned long mem_skip, unsigned long mem_max) +{ + SMIPtr pSmi = SMIPTR(pScrn); + unsigned long mem_probe = 1024*1024; + unsigned long aperture_base; + void* mem; + + ENTER(); + + aperture_base = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM) + mem_skip; + mem_max = min(mem_max , PCI_REGION_SIZE(pSmi->PciInfo, 0) - mem_skip); + +#ifndef XSERVER_LIBPCIACCESS + mem = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pSmi->PciTag, + aperture_base, mem_max); + + if(!mem) + LEAVE(0); +#else + if(pci_device_map_range(pSmi->PciInfo, aperture_base, mem_max, + PCI_DEV_MAP_FLAG_WRITABLE, &mem)) + LEAVE(0); +#endif + + while(mem_probe <= mem_max){ + MMIO_OUT32(mem, mem_probe-4, 0x55555555); + if(MMIO_IN32(mem, mem_probe-4) != 0x55555555) + break; + + MMIO_OUT32(mem, mem_probe-4, 0xAAAAAAAA); + if(MMIO_IN32(mem, mem_probe-4) != 0xAAAAAAAA) + break; + + mem_probe <<= 1; + } + +#ifndef XSERVER_LIBPCIACCESS + xf86UnMapVidMem(pScrn->scrnIndex, mem, mem_max); +#else + pci_device_unmap_range(pSmi->PciInfo, mem, mem_max); +#endif + + LEAVE(mem_probe >> 1); +} + static Bool SMI_DetectMem(ScrnInfoPtr pScrn) { @@ -1452,6 +1501,9 @@ SMI_DetectMem(ScrnInfoPtr pScrn) pSmi->videoRAMKBytes = lynx3d_table[config >> 6] * 1024 + 512; break; + case SMI_LYNXEMplus: + pSmi->videoRAMKBytes = SMI_ProbeMem(pScrn, 0, 0x400000) / 1024; + break; case SMI_LYNX3DM: pSmi->videoRAMKBytes = lynx3dm_table[config >> 6] * 1024; break; |