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:
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user