IORequest::_Copy*(): Resolved TODO: Don't cast the generic_addr_t to void*

anymore as that truncates physical addresses when PAE is enabled.
Now, if a 4 GB physical address limit is forced in DMAResource, the system
continues to work fine when the physical memory > 4 GB is used. Otherwise it
hangs or crashes.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37134 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2010-06-14 21:33:11 +00:00
parent 0559013789
commit 14a322f332
2 changed files with 25 additions and 26 deletions
+17 -20
View File
@@ -1168,7 +1168,7 @@ IORequest::_CopyData(void* _buffer, off_t offset, size_t size, bool copyIn)
// If we can, we directly copy from/to the virtual buffer. The memory is // If we can, we directly copy from/to the virtual buffer. The memory is
// locked in this case. // locked in this case.
status_t (*copyFunction)(void*, void*, size_t, team_id, bool); status_t (*copyFunction)(void*, generic_addr_t, size_t, team_id, bool);
if (fBuffer->IsPhysical()) { if (fBuffer->IsPhysical()) {
copyFunction = &IORequest::_CopyPhysical; copyFunction = &IORequest::_CopyPhysical;
} else { } else {
@@ -1193,8 +1193,8 @@ IORequest::_CopyData(void* _buffer, off_t offset, size_t size, bool copyIn)
// copy vector-wise // copy vector-wise
while (size > 0) { while (size > 0) {
generic_size_t toCopy = min_c(size, vecs[0].length - vecOffset); generic_size_t toCopy = min_c(size, vecs[0].length - vecOffset);
status_t error = copyFunction(buffer, status_t error = copyFunction(buffer, vecs[0].base + vecOffset, toCopy,
(uint8*)vecs[0].base + vecOffset, toCopy, fTeam, copyIn); fTeam, copyIn);
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -1209,39 +1209,36 @@ IORequest::_CopyData(void* _buffer, off_t offset, size_t size, bool copyIn)
/* static */ status_t /* static */ status_t
IORequest::_CopySimple(void* bounceBuffer, void* external, size_t size, IORequest::_CopySimple(void* bounceBuffer, generic_addr_t external, size_t size,
team_id team, bool copyIn) team_id team, bool copyIn)
{ {
TRACE(" IORequest::_CopySimple(%p, %p, %lu, %d)\n", bounceBuffer, external, TRACE(" IORequest::_CopySimple(%p, %#" B_PRIxGENADDR ", %lu, %d)\n",
size, copyIn); bounceBuffer, external, size, copyIn);
if (copyIn) if (copyIn)
memcpy(bounceBuffer, external, size); memcpy(bounceBuffer, (void*)(addr_t)external, size);
else else
memcpy(external, bounceBuffer, size); memcpy((void*)(addr_t)external, bounceBuffer, size);
return B_OK; return B_OK;
} }
/* static */ status_t /* static */ status_t
IORequest::_CopyPhysical(void* bounceBuffer, void* external, size_t size, IORequest::_CopyPhysical(void* bounceBuffer, generic_addr_t external,
team_id team, bool copyIn) size_t size, team_id team, bool copyIn)
{ {
// TODO: The physical address must be phys_addr_t! if (copyIn)
if (copyIn) { return vm_memcpy_from_physical(bounceBuffer, external, size, false);
return vm_memcpy_from_physical(bounceBuffer, (addr_t)external, size,
false);
}
return vm_memcpy_to_physical((addr_t)external, bounceBuffer, size, false); return vm_memcpy_to_physical(external, bounceBuffer, size, false);
} }
/* static */ status_t /* static */ status_t
IORequest::_CopyUser(void* _bounceBuffer, void* _external, size_t size, IORequest::_CopyUser(void* _bounceBuffer, generic_addr_t _external, size_t size,
team_id team, bool copyIn) team_id team, bool copyIn)
{ {
uint8* bounceBuffer = (uint8*)_bounceBuffer; uint8* bounceBuffer = (uint8*)_bounceBuffer;
uint8* external = (uint8*)_external; uint8* external = (uint8*)(addr_t)_external;
while (size > 0) { while (size > 0) {
static const int32 kEntryCount = 8; static const int32 kEntryCount = 8;
@@ -1258,8 +1255,8 @@ IORequest::_CopyUser(void* _bounceBuffer, void* _external, size_t size,
for (uint32 i = 0; i < count; i++) { for (uint32 i = 0; i < count; i++) {
const physical_entry& entry = entries[i]; const physical_entry& entry = entries[i];
error = _CopyPhysical(bounceBuffer, (void*)entry.address, error = _CopyPhysical(bounceBuffer, entry.address, entry.size, team,
entry.size, team, copyIn); copyIn);
if (error != B_OK) if (error != B_OK)
return error; return error;
+8 -6
View File
@@ -308,13 +308,15 @@ struct IORequest : IORequestChunk, DoublyLinkedListLinkImpl<IORequest> {
private: private:
status_t _CopyData(void* buffer, off_t offset, status_t _CopyData(void* buffer, off_t offset,
size_t size, bool copyIn); size_t size, bool copyIn);
static status_t _CopySimple(void* bounceBuffer, void* external, static status_t _CopySimple(void* bounceBuffer,
size_t size, team_id team, bool copyIn); generic_addr_t external, size_t size,
team_id team, bool copyIn);
static status_t _CopyPhysical(void* bounceBuffer, static status_t _CopyPhysical(void* bounceBuffer,
void* external, size_t size, team_id team, generic_addr_t external, size_t size,
bool copyIn); team_id team, bool copyIn);
static status_t _CopyUser(void* bounceBuffer, void* external, static status_t _CopyUser(void* bounceBuffer,
size_t size, team_id team, bool copyIn); generic_addr_t external, size_t size,
team_id team, bool copyIn);
mutex fLock; mutex fLock;
IORequestOwner* fOwner; IORequestOwner* fOwner;