On Thu, Oct 08, 2015 at 12:08:20PM +0300, ville.syrjala@xxxxxxxxxxxxxxx wrote: > From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > > There isn't an explicit stolen memory base register on gen2. > Some old comment in the i915 code suggests we should get it via > max_low_pfn_mapped, but that's clearly a bad idea on my MGM. > > The e820 map in said machine looks like this: > [ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009f7ff] usable > [ 0.000000] BIOS-e820: [mem 0x000000000009f800-0x000000000009ffff] reserved > [ 0.000000] BIOS-e820: [mem 0x00000000000ce000-0x00000000000cffff] reserved > [ 0.000000] BIOS-e820: [mem 0x00000000000dc000-0x00000000000fffff] reserved > [ 0.000000] BIOS-e820: [mem 0x0000000000100000-0x000000001f6effff] usable > [ 0.000000] BIOS-e820: [mem 0x000000001f6f0000-0x000000001f6f7fff] ACPI data > [ 0.000000] BIOS-e820: [mem 0x000000001f6f8000-0x000000001f6fffff] ACPI NVS > [ 0.000000] BIOS-e820: [mem 0x000000001f700000-0x000000001fffffff] reserved > [ 0.000000] BIOS-e820: [mem 0x00000000fec10000-0x00000000fec1ffff] reserved > [ 0.000000] BIOS-e820: [mem 0x00000000ffb00000-0x00000000ffbfffff] reserved > [ 0.000000] BIOS-e820: [mem 0x00000000fff00000-0x00000000ffffffff] reserved > > That makes max_low_pfn_mapped = 1f6f0000, so assuming our stolen memory > would start there would place it on top of some ACPI memory regions. > So not a good idea as already stated. > > The 9MB region after the ACPI regions at 0x1f700000 however looks > promising given that the macine reports the stolen memory size to be > 8MB. Looking at the PGTBL_CTL register, the GTT entries are at offset > 0x1fee00000, and given that the GTT entries occupy 128KB, it looks like > the stolen memory could start at 0x1f700000 and the GTT entries would > occupy the last 128KB of the stolen memory. > > After some more digging through chipset documentation, I've determined > the BIOS first allocates space for something called TSEG (something to > do with SMM) from the top of memory, and then it allocates the graphics > stolen memory below that. Accordind to the chipset documentation TSEG > has a fixed size of 1MB on 855. So that explains the top 1MB in the > e820 region. And it also confirms that the GTT entries are in fact at > the end of the the stolen memory region. > > Derive the stolen memory base address on gen2 the same as the BIOS does > (TOM-TSEG_SIZE-stolen_size). There are a few differences between the > registers on various gen2 chipsets, so a few different codepaths are > required. > > 865G is again bit more special since it seems to support enough memory > to hit 4GB address space issues. This means the PCI allocations will > also affect the location of the stolen memory. Fortunately there > appears to be the TOUD register which may give us the correct answer > directly. But the chipset docs are a bit unclear, so I'm not 100% > sure that the graphics stolen memory is always the last thing the > BIOS steals. Someone would need to verify it on a real system. > > I tested this on the my 830 and 855 machines, and so far everything > looks peachy. > > v2: Rewrite to use the TOM-TSEG_SIZE-stolen_size and TOUD methods > v3: Fix TSEG size for 830 > v4: Add missing 'else' (Chris) > > Tested-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> > Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> Queued for -next, thanks for the patch. -Daniel > --- > drivers/gpu/drm/i915/i915_gem_stolen.c | 92 ++++++++++++++++++++++++++++++---- > 1 file changed, 81 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c > index 69eebc6..cdacf3f 100644 > --- a/drivers/gpu/drm/i915/i915_gem_stolen.c > +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c > @@ -30,6 +30,9 @@ > #include <drm/i915_drm.h> > #include "i915_drv.h" > > +#define KB(x) ((x) * 1024) > +#define MB(x) (KB(x) * 1024) > + > /* > * The BIOS typically reserves some of the system's memory for the exclusive > * use of the integrated graphics. This memory is no longer available for > @@ -91,24 +94,91 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) > /* Almost universally we can find the Graphics Base of Stolen Memory > * at offset 0x5c in the igfx configuration space. On a few (desktop) > * machines this is also mirrored in the bridge device at different > - * locations, or in the MCHBAR. On gen2, the layout is again slightly > - * different with the Graphics Segment immediately following Top of > - * Memory (or Top of Usable DRAM). Note it appears that TOUD is only > - * reported by 865g, so we just use the top of memory as determined > - * by the e820 probe. > + * locations, or in the MCHBAR. > + * > + * On 865 we just check the TOUD register. > + * > + * On 830/845/85x the stolen memory base isn't available in any > + * register. We need to calculate it as TOM-TSEG_SIZE-stolen_size. > * > - * XXX However gen2 requires an unavailable symbol. > */ > base = 0; > if (INTEL_INFO(dev)->gen >= 3) { > /* Read Graphics Base of Stolen Memory directly */ > pci_read_config_dword(dev->pdev, 0x5c, &base); > base &= ~((1<<20) - 1); > - } else { /* GEN2 */ > -#if 0 > - /* Stolen is immediately above Top of Memory */ > - base = max_low_pfn_mapped << PAGE_SHIFT; > -#endif > + } else if (IS_I865G(dev)) { > + u16 toud = 0; > + > + /* > + * FIXME is the graphics stolen memory region > + * always at TOUD? Ie. is it always the last > + * one to be allocated by the BIOS? > + */ > + pci_bus_read_config_word(dev->pdev->bus, PCI_DEVFN(0, 0), > + I865_TOUD, &toud); > + > + base = toud << 16; > + } else if (IS_I85X(dev)) { > + u32 tseg_size = 0; > + u32 tom; > + u8 tmp; > + > + pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0), > + I85X_ESMRAMC, &tmp); > + > + if (tmp & TSEG_ENABLE) > + tseg_size = MB(1); > + > + pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 1), > + I85X_DRB3, &tmp); > + tom = tmp * MB(32); > + > + base = tom - tseg_size - dev_priv->gtt.stolen_size; > + } else if (IS_845G(dev)) { > + u32 tseg_size = 0; > + u32 tom; > + u8 tmp; > + > + pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0), > + I845_ESMRAMC, &tmp); > + > + if (tmp & TSEG_ENABLE) { > + switch (tmp & I845_TSEG_SIZE_MASK) { > + case I845_TSEG_SIZE_512K: > + tseg_size = KB(512); > + break; > + case I845_TSEG_SIZE_1M: > + tseg_size = MB(1); > + break; > + } > + } > + > + pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0), > + I830_DRB3, &tmp); > + tom = tmp * MB(32); > + > + base = tom - tseg_size - dev_priv->gtt.stolen_size; > + } else if (IS_I830(dev)) { > + u32 tseg_size = 0; > + u32 tom; > + u8 tmp; > + > + pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0), > + I830_ESMRAMC, &tmp); > + > + if (tmp & TSEG_ENABLE) { > + if (tmp & I830_TSEG_SIZE_1M) > + tseg_size = MB(1); > + else > + tseg_size = KB(512); > + } > + > + pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0), > + I830_DRB3, &tmp); > + tom = tmp * MB(32); > + > + base = tom - tseg_size - dev_priv->gtt.stolen_size; > } > > if (base == 0) > -- > 2.4.9 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx