summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2007-07-09 12:56:13 -0700
committerEric Anholt <eric@anholt.net>2007-07-09 13:01:12 -0700
commit88f8b688e2316ae4a1f7485f0010ce90de54783a (patch)
tree1dcc20d09e0244c15bb670329794213751960b9e
parentbf831117b4659cc4f2774098dee938505f780a9b (diff)
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.
-rw-r--r--src/i830.h4
-rw-r--r--src/i830_memory.c57
2 files changed, 33 insertions, 28 deletions
diff --git a/src/i830.h b/src/i830.h
index 8b6c5e65..409057cc 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 a589738d..b38a5dfe 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -319,9 +319,9 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset,
* 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, unsigned long offset)
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 long offset)
(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, unsigned long offset)
* 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 pScrn, unsigned long offset,
* 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, const char *name,
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 pScrn, i830_memory *mem, int flags)
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 pScrn, int verbosity, const char *prefix)
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 pScrn)
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. */