Tracking down bug #12503, looking for comment on my theory

Alex Villací­s Lasso a_villacis at palosanto.com
Wed Jan 16 11:24:20 PST 2008


I post this so that the experts on the mailing list can tell me whether 
my understanding of the problem is sane (or insane). All comments apply 
to my home machine, which reserves 16M for video memory reports the 
following on lspci -v:

01:00.0 VGA compatible controller: S3 Inc. VT8375 [ProSavage8 KM266/KL266]
(prog-if 00 [VGA])
        Subsystem: S3 Inc. VT8375 [ProSavage8 KM266/KL266]
        Flags: bus master, 66MHz, medium devsel, latency 32, IRQ 11
        Memory at dfe80000 (32-bit, non-prefetchable) [size=512K]
        Memory at d0000000 (32-bit, prefetchable) [size=128M]
        Expansion ROM at dfe70000 [disabled] [size=64K]
        Capabilities: [dc] Power Management version 2
        Capabilities: [80] AGP version 2.0


First, there is a serious regression in the current git of 
xf86-video-savage, in which HEAD 
(9c959f53ca8376aa136a9d434c3383cdb20487c2) will reliably lock up the 
machine on X server startup whenever XSERVER_LIBPCIACCESS is *not* set 
(as is the case in Fedora 8), so that a hard reset is needed to fix it. 
I filed bug 12503 for it at bugs.freedesktop.org. After some tests, I 
found that 1eec792391d9ce9127817107100a53382f167749 still works in my 
case, but 514dc647d108e179965adb1377b1d4c011afa367 does not. I have 
enabled tracing in the driver, and I have seen the following:

As I understand it, the driver needs three main memory areas:
- Framebuffer memory
- Memory-mapped I/O (MMIO)
- AGP aperture
It seems that some savages report three separate memory areas for all 
three roles. Others, like my chipset, report only two, and use different 
areas inside the bigger one (128M at 0xd0000000 in my case) for both the 
framebuffer and the aperture.

Before the commit at 514dc647d108e179965adb1377b1d4c011afa367, the 
driver does one memory mapping for every PCI area, and then hands out 
the addresses for the memory roles. In my setup, the driver did one big 
128M mapping for the framebuffer, then calculated an offset for the 
aperture within the mapping:

 (**) SAVAGE(0): Option: Enable use of the BCI for Xv
 SavageMapMem()
-PHYS: MmioBase.........at 0xdfe80000, 524288 bytes
-PHYS: FrameBufferBase..at 0xd0000000, 134217728 bytes
-PHYS: ApertureBase.....at 0xd2000000, 134217728 bytes
-(==) SAVAGE(0): Write-combining range (0xd0000000,0x8000000)
 SavageEnableMMIO
-MAP: MapBase (MMIO)..at 0xb7c17000
-MAP: FBBase..........at 0xafc17000
-MAP: ApertureMap.....at 0xb1c17000
 (==) SAVAGE(0): Using gamma correction (1.0, 1.0, 1.0)
-(--) SAVAGE(0): probed videoram:  16384k
...
-(--) SAVAGE(0): Detected current MCLK value of 14.318 MHz
...
 SavageMapMem()
-PHYS: MmioBase.........at 0xdfe80000, 524288 bytes
-PHYS: FrameBufferBase..at 0xd0000000, 134217728 bytes
-PHYS: ApertureBase.....at 0xd2000000, 134217728 bytes
-(==) SAVAGE(0): Write-combining range (0xd0000000,0x8000000)
-SavageEnableMMIO
-MAP: MapBase (MMIO)..at 0xafb06000
-MAP: FBBase..........at 0xa7b06000
-MAP: ApertureMap.....at 0xa9b06000
 SavageSave()
-(II) SAVAGE(0): 4740 kB of Videoram needed for 3D; 16384 kB of Videoram 
available
-(II) SAVAGE(0): Sufficient Videoram available for 3D
-(II) SAVAGE(0): [drm] bpp: 16 depth: 16
-(II) SAVAGE(0): [drm] Sarea 2200+284: 2484

SavageMapMem is called twice on startup. More on this later.

Please note that the videoram is correctly detected as 16M and the MCLK 
value appears to be correct.

After the commit, the driver does not make one mapping per memory area, 
but one mapping per memory role, with different sizes and offsets. In my 
setup, instead of two mappings (one for shared framebuffer/aperture, one 
for MMIO), it ends up doing three:

 (**) SAVAGE(0): Option: Enable use of the BCI for Xv
 SavageMapMem()
+PHYS: MmioRegion.base...at 0xdfe80000, 524288 bytes
+PHYS: FbRegion.base..at 0xd0000000, 0 bytes
+PHYS: ApertureRegion.base.....at 0xd2000000, 83886080 bytes
+(II) SAVAGE(0): Splitting WC range: base: 0xd2000000, size: 0x5000000
+(II) SAVAGE(0): Splitting WC range: base: 0xd4000000, size: 0x3000000
+(==) SAVAGE(0): Write-combining range (0xd6000000,0x1000000)
+(==) SAVAGE(0): Write-combining range (0xd4000000,0x3000000)
+(==) SAVAGE(0): Write-combining range (0xd2000000,0x5000000)
+MAP: ApertureMap.....at 0xb3cec000
+(==) SAVAGE(0): Write-combining range (0xdfe80000,0x80000)
+MAP: MapBase.........at 0xb2c6c000
 SavageEnableMMIO
+MAP: (ends here)
 (==) SAVAGE(0): Using gamma correction (1.0, 1.0, 1.0)
+(--) SAVAGE(0): probed videoram:  4096k
 (II) Loading sub module "ddc"
...
+(--) SAVAGE(0): Detected current MCLK value of 3.580 MHz
...
 SavageMapMem()
+PHYS: MmioRegion.base...at 0xdfe80000, 524288 bytes
+PHYS: FbRegion.base..at 0xd0000000, 4194304 bytes
+PHYS: ApertureRegion.base.....at 0xd2000000, 83886080 bytes
+(==) SAVAGE(0): Write-combining range (0xd0000000,0x400000)
+MAP: FBBase..........at 0xb27db000
+MAP: (ends here)
 SavageSave()
+(WW) SAVAGE(0): Cannot read colourmap from VGA.  Will restore with default
+(II) SAVAGE(0): 4740 kB of Videoram needed for 3D; 4096 kB of Videoram 
available
+(EE) SAVAGE(0): Insufficient Videoram available for 3D -- Try a lower 
color depth or smaller desktop.  For integrated savages try increasing 
the videoram in the BIOS.
+(EE) SAVAGE(0): DRI isn't enabled
 SavageModeInit(1024x768, 65000Hz)

For starters, both MCLK and videoram size are now incorrectly detected. 
Then the colormap cannot be retrieved. Finally the hang happens.

Looking at the code, there are several things that might be wrong with this:
1) Previously, all the areas got mapped with xf86MapPciMem() and the 
VIDMEM_MMIO flag, and the function sorted out the write-combining later. 
The proof is that the message (==) SAVAGE(0): Write-combining range 
(0xd0000000,0x8000000) eventually appeared. Now, all the areas 
(including MMIO) are being mapped as VIDMEM_FRAMEBUFFER. This can't be 
right... or is it?

src/savage_driver.c line 3163
-------------------
    if (psav->MmioRegion.memory == NULL) {
#ifdef XSERVER_LIBPCIACCESS
        err = pci_device_map_range(psav->PciInfo, psav->MmioRegion.base,
                                   psav->MmioRegion.size,
                                   (PCI_DEV_MAP_FLAG_WRITABLE),
                                   & psav->MmioRegion.memory);
#else
        psav->MmioRegion.memory =
            xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, /* <--- 
Should this be VIDMEM_MMIO instead? */
                          psav->PciTag, psav->MmioRegion.base,
                          psav->MmioRegion.size);
        err = (psav->MmioRegion.memory == NULL) ? errno : 0;
#endif
-------------------
In my opinion, this is the most likely cause of the hang, since videoram 
detection, MCLK detection, and colormap all require register (MMIO) 
access, and all of these are affected prior to the hang.

2) Previously, there were just two big mmaps, starting at the beginning 
of the PCI areas. Now there are three, and none of them cover all of the 
area, and one of them starts at an offset from the beginning of the PCI 
area. In addition, all mmaps were previously powers of two, and now they 
are not (at least the aperture one).

Personally I am leaning towards 1, but I would like to know your opinion 
on this. Feel free to ask questions.

Alex Villacís Lasso

-- 
perl -e '$x=2.4;print sprintf("%.0f + %.0f = %.0f\n",$x,$x,$x+$x);'




More information about the xorg mailing list