xf86-video-intel: src/i830.h src/i830_memory.c

Eric Anholt anholt at kemper.freedesktop.org
Mon Jul 9 13:09:56 PDT 2007


 src/i830.h        |    4 +--
 src/i830_memory.c |   57 +++++++++++++++++++++++++++++-------------------------
 2 files changed, 33 insertions(+), 28 deletions(-)

New commits:
diff-tree 88f8b688e2316ae4a1f7485f0010ce90de54783a (from bf831117b4659cc4f2774098dee938505f780a9b)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jul 9 12:56:13 2007 -0700

    Fix some physical address handling for >4GB addresses.
    
    The upper bits would have been inappropriately dropped on G33-class hardware,
    and on G965-class hardware in a 32-bit environment.  The only use of physical
    addresses on these should be for FBC, though, and FBC requires addresses
    below 4GB.  This is unresolved.

diff --git a/src/i830.h b/src/i830.h
index 8b6c5e6..409057c 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -134,7 +134,7 @@ struct _i830_memory {
      * Physical (or more properly, bus) address of the allocation.
      * Only set if requested during allocation.
      */
-    unsigned long bus_addr;
+    uint64_t bus_addr;
     /** AGP memory handle */
     int key;
     /**
@@ -235,7 +235,7 @@ typedef struct _I830CrtcPrivateRec {
     /* Physical or virtual addresses of the cursor for setting in the cursor
      * registers.
      */
-    unsigned long cursor_addr;
+    uint64_t cursor_addr;
     unsigned long cursor_argb_addr;
     Bool	cursor_is_argb;
 } I830CrtcPrivateRec, *I830CrtcPrivatePtr;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index a589738..b38a5df 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -319,9 +319,9 @@ i830_allocator_init(ScrnInfoPtr pScrn, u
  * physical address.
  *
  * \return physical address if successful.
- * \return (unsigned long)-1 if unsuccessful.
+ * \return (uint64_t)-1 if unsuccessful.
  */
-static unsigned long
+static uint64_t
 i830_get_gtt_physical(ScrnInfoPtr pScrn, unsigned long offset)
 {
     I830Ptr pI830 = I830PTR(pScrn);
@@ -334,8 +334,11 @@ i830_get_gtt_physical(ScrnInfoPtr pScrn,
     gttentry = INGTT(offset / 1024);
 
     /* Mask out these reserved bits on this hardware. */
-    if (!IS_I965G(pI830))
+    if (!IS_I9XX(pI830) || IS_I915G(pI830) || IS_I915GM(pI830) ||
+	IS_I945G(pI830) || IS_I945GM(pI830))
+    {
 	gttentry &= ~PTE_ADDRESS_MASK_HIGH;
+    }
 
     /* If it's not a mapping type we know, then bail. */
     if ((gttentry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_UNCACHED &&
@@ -346,19 +349,10 @@ i830_get_gtt_physical(ScrnInfoPtr pScrn,
 		   (unsigned int)(gttentry & PTE_MAPPING_TYPE_MASK));
 	return -1;
     }
-    /* If we can't represent the address with an unsigned long, bail. */
-    if (sizeof(unsigned long) == 4 &&
-	(gttentry & PTE_ADDRESS_MASK_HIGH) != 0)
-    {
-	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		   "High memory PTE (0x%08x) on 32-bit system\n",
-		   (unsigned int)gttentry);
-	return -1;
-    }
     assert((gttentry & PTE_VALID) != 0);
 
     return (gttentry & PTE_ADDRESS_MASK) |
-	(gttentry & PTE_ADDRESS_MASK_HIGH << (32 - 4));
+	((uint64_t)(gttentry & PTE_ADDRESS_MASK_HIGH) << (32 - 4));
 }
 
 /**
@@ -366,14 +360,15 @@ i830_get_gtt_physical(ScrnInfoPtr pScrn,
  * physical address.
  *
  * \return physical address if successful.
- * \return (unsigned long)-1 if unsuccessful.
+ * \return (uint64_t)-1 if unsuccessful.
  */
-static unsigned long
+static uint64_t
 i830_get_stolen_physical(ScrnInfoPtr pScrn, unsigned long offset,
 			 unsigned long size)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    unsigned long physical, scan;
+    uint64_t physical;
+    unsigned long scan;
 
     /* Check that the requested region is within stolen memory. */
     if (offset + size >= pI830->stolen_size)
@@ -387,11 +382,12 @@ i830_get_stolen_physical(ScrnInfoPtr pSc
      * contiguously.
      */
     for (scan = offset + 4096; scan < offset + size; scan += 4096) {
-	unsigned long scan_physical = i830_get_gtt_physical(pScrn, scan);
+	uint64_t scan_physical = i830_get_gtt_physical(pScrn, scan);
 
 	if ((scan - offset) != (scan_physical - physical)) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		       "Non-contiguous GTT entries: (%ld,%ld) vs (%ld,%ld)\n",
+		       "Non-contiguous GTT entries: (%ld,0x16%llx) vs "
+		       "(%ld,0x%16llx)\n",
 		       scan, scan_physical, offset, physical);
 	    return -1;
 	}
@@ -444,7 +440,7 @@ i830_allocate_aperture(ScrnInfoPtr pScrn
 	    mem->bus_addr = i830_get_stolen_physical(pScrn, mem->offset,
 						     mem->size);
 
-	    if (mem->bus_addr == ((unsigned long)-1)) {
+	    if (mem->bus_addr == ((uint64_t)-1)) {
 		/* Move the start of the allocation to just past the end of
 		 * stolen memory.
 		 */
@@ -498,11 +494,15 @@ i830_allocate_agp_memory(ScrnInfoPtr pSc
 
     size = mem->size - (mem->agp_offset - mem->offset);
 
-    if (flags & NEED_PHYSICAL_ADDR)
+    if (flags & NEED_PHYSICAL_ADDR) {
+	unsigned long agp_bus_addr;
+
 	mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2,
-					  &mem->bus_addr);
-    else
+					  &agp_bus_addr);
+	mem->bus_addr = agp_bus_addr;
+    } else {
 	mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
+    }
     if (mem->key == -1 || ((flags & NEED_PHYSICAL_ADDR) && mem->bus_addr == 0))
     {
 	return FALSE;
@@ -688,7 +688,8 @@ i830_describe_allocations(ScrnInfoPtr pS
 			   mem->size / 1024);
 	} else {
 	    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
-			   "%s0x%08lx-0x%08lx: %s (%ld kB, 0x%08lx physical)\n",
+			   "%s0x%08lx-0x%08lx: %s "
+			   "(%ld kB, 0x%16llx physical)\n",
 			   prefix,
 			   mem->offset, mem->end - 1, mem->name,
 			   mem->size / 1024, mem->bus_addr);
@@ -956,9 +957,13 @@ i830_allocate_cursor_buffers(ScrnInfoPtr
 	unsigned long cursor_offset_base = pI830->cursor_mem->offset;
 	unsigned long cursor_addr_base, offset = 0;
 
-	if (pI830->CursorNeedsPhysical)
-	    cursor_addr_base = pI830->cursor_mem->bus_addr;
-	else
+	if (pI830->CursorNeedsPhysical) {
+	    /* On any hardware that requires physical addresses for cursors,
+	     * the PTEs don't support memory above 4GB, so we can safely
+	     * ignore the top 32 bits of cursor_mem->bus_addr.
+	     */
+	    cursor_addr_base = (unsigned long)pI830->cursor_mem->bus_addr;
+	} else
 	    cursor_addr_base = pI830->cursor_mem->offset;
 
 	/* Set up the offsets for our cursors in each CRTC. */


More information about the xorg-commit mailing list