--- xc/programs/Xserver/hw/xfree86/drivers/i810/i830_driver.c.orig	Wed Jan  9 05:59:29 2002
+++ xc/programs/Xserver/hw/xfree86/drivers/i810/i830_driver.c	Wed Sep  4 10:51:58 2002
@@ -87,6 +87,8 @@
  *          switched VT's
  */
 
+#include <unistd.h>
+
 #include "xf86.h"
 #include "xf86_ansic.h"
 #include "xf86_OSproc.h"
@@ -145,6 +147,7 @@
 static void I830DisplayPowerManagementSet(ScrnInfoPtr pScrn,
 					  int PowerManagementMode,
 					  int flags);
+static void I830StolenMemoryHack (ScrnInfoPtr pScrn);
 
 #ifdef I830DEBUG
 void DPRINTF_stub (const char *filename,int line,const char *function,const char *fmt, ...) {
@@ -476,33 +479,32 @@
 
 static int I830DetectMemory (ScrnInfoPtr pScrn)
 {
-   I810Ptr pI810;
-   VESAPtr pVesa;
-   PCITAG bridge;
-   CARD16 gmch_ctrl;
-   int memsize;
-
-   pI810 = I810PTR (pScrn);
-   pVesa = pI810->vesa;
-
-   bridge = pciTag (0,0,0);	/* This is always the host bridge */
-   gmch_ctrl = pciReadWord (bridge,I830_GMCH_CTRL);
-
-   switch (gmch_ctrl & I830_GMCH_GMS_MASK)
-	 {
-	  case I830_GMCH_GMS_STOLEN_512:
-		memsize = KB (512);
+	I810Ptr pI810;
+	VESAPtr pVesa;
+	PCITAG bridge;
+	CARD16 gmch_ctrl;
+	int memsize;
+
+	pI810 = I810PTR (pScrn);
+	pVesa = pI810->vesa;
+
+	bridge = pciTag (0,0,0);	/* This is always the host bridge */
+	gmch_ctrl = pciReadWord (bridge,I830_GMCH_CTRL);
+
+	switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
+	case I830_GMCH_GMS_STOLEN_512:
+	  memsize = KB (512) - KB (132);
 		xf86DrvMsg (pScrn->scrnIndex,X_INFO,"detected %dK stolen memory.\n",memsize / 1024);
 		break;
-	  case I830_GMCH_GMS_STOLEN_1024:
-		memsize = MB (1);
+	case I830_GMCH_GMS_STOLEN_1024:
+		memsize = MB (1) - KB (132);
 		xf86DrvMsg (pScrn->scrnIndex,X_INFO,"detected %dK stolen memory.\n",memsize / 1024);
 		break;
-	  case I830_GMCH_GMS_STOLEN_8192:
-		memsize = MB (8);
+	case I830_GMCH_GMS_STOLEN_8192:
+	  memsize = MB (8) - KB (132);
 		xf86DrvMsg (pScrn->scrnIndex,X_INFO,"detected %dK stolen memory.\n",memsize / 1024);
 		break;
-	  case I830_GMCH_GMS_LOCAL:
+	case I830_GMCH_GMS_LOCAL:
 		/* I'd like to use the VGA controller registers here, but MMIOBase isn't
 		 * yet, so for now, we'll just use the BIOS instead... */
 		pVesa->pInt->num = 0x10;
@@ -511,13 +513,13 @@
 		memsize = pVesa->pInt->cx * KB (1);
 		xf86DrvMsg (pScrn->scrnIndex,X_INFO,"detected %dK local memory.\n",memsize / 1024);
 		break;
-	  default:
+	default:
 		/* not that this is possible, but anyway (: */
 		memsize = 0;
 		xf86DrvMsg (pScrn->scrnIndex,X_INFO,"no video memory detected.\n");
-	 }
+	}
 
-   return (memsize);
+	return (memsize);
 }
 
 Bool I830BIOSPreInit (ScrnInfoPtr pScrn,int flags)
@@ -743,6 +745,8 @@
 
    xf86DrvMsg (pScrn->scrnIndex,from,"Will alloc AGP framebuffer: %d kByte\n",pScrn->videoRam);
 
+   I830StolenMemoryHack (pScrn);
+
    /*
 	* If the driver can do gamma correction, it should call xf86SetGamma() here.
     */
@@ -1474,13 +1478,12 @@
 
 /* At the moment some of the BIOS vesa mode sets doesn't seem to work, so
  * we set those modes using the legacy BIOS calls */
-Bool I830VESASetVBEMode (ScrnInfoPtr pScrn,int mode,CRTCInfoBlock *block)
-{
-   I810Ptr pI810;
-   VESAPtr pVesa;
+Bool I830VESASetVBEMode (ScrnInfoPtr pScrn,int mode,CRTCInfoBlock *block) {
+	I810Ptr pI810;
+	VESAPtr pVesa;
 
-   pI810 = I810PTR (pScrn);
-   pVesa = pI810->vesa;
+	pI810 = I810PTR (pScrn);
+	pVesa = pI810->vesa;
 
    DPRINTF(PFX,"Setting mode 0x%.8x\n",mode);
 
@@ -1503,7 +1506,6 @@
 	  default:
 		pVesa->pInt->ax = 0x4f02;
 		pVesa->pInt->bx = mode & ~(1 << 11);
-/* This doesn't work. The BIOS is f**cked */
 #if 0
 		if (block != NULL)
 		  {
@@ -2517,3 +2519,51 @@
    return (*pScreen->CloseScreen)(scrnIndex, pScreen);
 }
 
+/* Magic bit swiveling to enable high resolution with 16bpp in BIOSes that
+ * preallocate only 1MB of video memory.
+ */
+static void
+I830StolenMemoryHack (ScrnInfoPtr pScrn)
+{
+  I810Ptr        pI810;
+  unsigned long  swf1;
+  int		 devmem;
+  char		*MMIOBase;
+
+  pI810 = I810PTR (pScrn);
+
+  if (pI810->StolenSize < MB (8) - KB (132)) {
+
+    if ((devmem = open ("/dev/mem", O_RDWR)) < 0) {
+      xf86DrvMsg (pScrn->scrnIndex, X_WARNING, 
+		  "Cannot open /dev/mem: " 
+		  "resolution limited by 1MB video RAM\n");
+      return;
+    }
+
+    MMIOBase = (char *) mmap (NULL, I810_REG_SIZE, 
+			      PROT_READ | PROT_WRITE, MAP_SHARED, 
+			      devmem, (off_t) pI810->MMIOAddr);
+
+    if (MMIOBase == (char *) -1) {
+      close (devmem);
+      xf86DrvMsg (pScrn->scrnIndex, X_WARNING, 
+		  "Cannot mmap IO registers: " 
+		  "resolution limited by 1MB video RAM\n");
+      return;
+    }
+
+    swf1 = *((unsigned long *) (MMIOBase + 0x71414));
+    DPRINTF (PFX, "SWF1[before] == 0x%.8x\n", swf1);
+    swf1 &= ~0xf;
+    swf1 |= 8;
+    *((unsigned long *) (MMIOBase + 0x71414)) = swf1;
+    DPRINTF (PFX, "SWF1[after ] == 0x%.8x\n", swf1);
+
+    munmap (MMIOBase, I810_REG_SIZE);
+    close (devmem);
+
+    xf86DrvMsg (pScrn->scrnIndex, X_INFO, "1MB stolen memory hack enabled\n");
+
+  }
+}
