[Intel-gfx] G45 BIOS mis-initializes stolen GTT PTEs

Keith Packard keithp at keithp.com
Tue Oct 14 08:50:20 CEST 2008


Ok, so I've managed to get my G45 running without DRI.

What I discovered is that the very last PTE for stolen memory (pages
allocated by the BIOS for graphics use) was not initialized by the BIOS
correctly. When the graphics hardware tried to access that page, it
would get a segfault and lock up until it was reset.

Here's a patch which finds that PTE and fixes it if it is broken. If
your G45 is crashing randomly after startup, please give this patch a
try and see if it works.

As you can see, it's an ugly hack that doesn't check to make sure you're
running on a G45, so it's not exactly ready for upstream, but it should
detect and repair this specific bug.

From f4867dee03bfd3edb05f1fcccfe34eba209f6af7 Mon Sep 17 00:00:00 2001
From: Keith Packard <keithp at keithp.com>
Date: Mon, 13 Oct 2008 23:35:55 -0700
Subject: [PATCH] Check and repair the last stolen GTT entry for Intel G45 motherboards

At least one existing G45 motherboard BIOS mis-initializes the GTT entries
for stolen memory leaving the last PTE invalid. Detect this case and patch
it up to point at the page after the previous PTE.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 drivers/char/agp/intel-agp.c |   20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index a6a0c34..32ea05e 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -987,6 +987,26 @@ static int intel_i915_configure(void)
 	readl(intel_private.registers+I810_PGETBL_CTL);	/* PCI Posting. */
 
 	if (agp_bridge->driver->needs_scratch_page) {
+		u32 gtt;
+		for (i = 0; i < intel_private.gtt_entries; i++) {
+			gtt = readl(intel_private.gtt+i);
+			if ((gtt & I810_PTE_VALID) == 0)
+				dev_printk(KERN_ERR, &intel_private.pcidev->dev,
+					   "invalid stolen PTE %08x = %08x\n",
+					   i, gtt);
+		}
+		i = intel_private.gtt_entries - 1;
+		gtt = readl(intel_private.gtt + i);
+		if ((gtt & I810_PTE_VALID) == 0) {
+			gtt = readl(intel_private.gtt + (i-1));
+			if (gtt & I810_PTE_VALID) {
+				gtt += 0x1000;
+				dev_printk(KERN_ERR, &intel_private.pcidev->dev,
+					   "patching stolen PTE %08x to %08x\n",
+					   i, gtt);
+				writel(gtt, intel_private.gtt+i);
+			}
+		}
 		for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) {
 			writel(agp_bridge->scratch_page, intel_private.gtt+i);
 		}
-- 
1.5.6.5



-- 
keith.packard at intel.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20081013/0cb683bd/attachment.sig>


More information about the Intel-gfx mailing list