Added function get_memory_map_etc() which works similar to
get_memory_map(), but has a saner semantics and allows specifying a team. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26600 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
0ae1957465
commit
6e60a6ac03
@ -151,6 +151,9 @@ extern status_t lock_memory(void *buffer, size_t numBytes, uint32 flags);
|
|||||||
extern status_t unlock_memory_etc(team_id team, void *address,
|
extern status_t unlock_memory_etc(team_id team, void *address,
|
||||||
size_t numBytes, uint32 flags);
|
size_t numBytes, uint32 flags);
|
||||||
extern status_t unlock_memory(void *buffer, size_t numBytes, uint32 flags);
|
extern status_t unlock_memory(void *buffer, size_t numBytes, uint32 flags);
|
||||||
|
extern status_t get_memory_map_etc(team_id team, const void *address,
|
||||||
|
size_t numBytes, physical_entry *table,
|
||||||
|
uint32* _numEntries);
|
||||||
extern long get_memory_map(const void *buffer, ulong size,
|
extern long get_memory_map(const void *buffer, ulong size,
|
||||||
physical_entry *table, long numEntries);
|
physical_entry *table, long numEntries);
|
||||||
extern area_id map_physical_memory(const char *areaName,
|
extern area_id map_physical_memory(const char *areaName,
|
||||||
|
@ -5100,13 +5100,21 @@ unlock_memory(void *address, size_t numBytes, uint32 flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! According to the BeBook, this function should always succeed.
|
/*! Similar to get_memory_map(), but also allows to specify the address space
|
||||||
This is no longer the case.
|
for the memory in question and has a saner semantics.
|
||||||
|
Returns \c B_OK when the complete range could be translated or
|
||||||
|
\c B_BUFFER_OVERFLOW, if the provided array wasn't big enough. In either
|
||||||
|
case the actual number of entries is written to \c *_numEntries. Any other
|
||||||
|
error case indicates complete failure; \c *_numEntries will be set to \c 0
|
||||||
|
in this case.
|
||||||
*/
|
*/
|
||||||
long
|
status_t
|
||||||
get_memory_map(const void *address, ulong numBytes, physical_entry *table,
|
get_memory_map_etc(team_id team, const void *address, size_t numBytes,
|
||||||
long numEntries)
|
physical_entry *table, uint32* _numEntries)
|
||||||
{
|
{
|
||||||
|
uint32 numEntries = *_numEntries;
|
||||||
|
*_numEntries = 0;
|
||||||
|
|
||||||
vm_address_space *addressSpace;
|
vm_address_space *addressSpace;
|
||||||
addr_t virtualAddress = (addr_t)address;
|
addr_t virtualAddress = (addr_t)address;
|
||||||
addr_t pageOffset = virtualAddress & (B_PAGE_SIZE - 1);
|
addr_t pageOffset = virtualAddress & (B_PAGE_SIZE - 1);
|
||||||
@ -5116,17 +5124,20 @@ get_memory_map(const void *address, ulong numBytes, physical_entry *table,
|
|||||||
addr_t offset = 0;
|
addr_t offset = 0;
|
||||||
bool interrupts = are_interrupts_enabled();
|
bool interrupts = are_interrupts_enabled();
|
||||||
|
|
||||||
TRACE(("get_memory_map(%p, %lu bytes, %ld entries)\n", address, numBytes,
|
TRACE(("get_memory_map_etc(%ld, %p, %lu bytes, %ld entries)\n", team,
|
||||||
numEntries));
|
address, numBytes, numEntries));
|
||||||
|
|
||||||
if (numEntries == 0 || numBytes == 0)
|
if (numEntries == 0 || numBytes == 0)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// in which address space is the address to be found?
|
// in which address space is the address to be found?
|
||||||
if (IS_USER_ADDRESS(virtualAddress))
|
if (IS_USER_ADDRESS(virtualAddress)) {
|
||||||
addressSpace = thread_get_current_thread()->team->address_space;
|
if (team == B_CURRENT_TEAM)
|
||||||
else
|
addressSpace = vm_get_current_user_address_space();
|
||||||
addressSpace = vm_kernel_address_space();
|
else
|
||||||
|
addressSpace = vm_get_address_space(team);
|
||||||
|
} else
|
||||||
|
addressSpace = vm_get_kernel_address_space();
|
||||||
|
|
||||||
if (addressSpace == NULL)
|
if (addressSpace == NULL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@ -5163,7 +5174,7 @@ get_memory_map(const void *address, ulong numBytes, physical_entry *table,
|
|||||||
// need to switch to the next physical_entry?
|
// need to switch to the next physical_entry?
|
||||||
if (index < 0 || (addr_t)table[index].address
|
if (index < 0 || (addr_t)table[index].address
|
||||||
!= physicalAddress - table[index].size) {
|
!= physicalAddress - table[index].size) {
|
||||||
if (++index + 1 > numEntries) {
|
if ((uint32)++index + 1 > numEntries) {
|
||||||
// table to small
|
// table to small
|
||||||
status = B_BUFFER_OVERFLOW;
|
status = B_BUFFER_OVERFLOW;
|
||||||
break;
|
break;
|
||||||
@ -5181,21 +5192,45 @@ get_memory_map(const void *address, ulong numBytes, physical_entry *table,
|
|||||||
if (interrupts)
|
if (interrupts)
|
||||||
map->ops->unlock(map);
|
map->ops->unlock(map);
|
||||||
|
|
||||||
// close the entry list
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
if (status == B_OK) {
|
if ((uint32)index + 1 > numEntries) {
|
||||||
// if it's only one entry, we will silently accept the missing ending
|
*_numEntries = index;
|
||||||
if (numEntries == 1)
|
return B_BUFFER_OVERFLOW;
|
||||||
return B_OK;
|
|
||||||
|
|
||||||
if (++index + 1 > numEntries)
|
|
||||||
return B_BUFFER_OVERFLOW;
|
|
||||||
|
|
||||||
table[index].address = NULL;
|
|
||||||
table[index].size = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
*_numEntries = index + 1;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! According to the BeBook, this function should always succeed.
|
||||||
|
This is no longer the case.
|
||||||
|
*/
|
||||||
|
long
|
||||||
|
get_memory_map(const void *address, ulong numBytes, physical_entry *table,
|
||||||
|
long numEntries)
|
||||||
|
{
|
||||||
|
uint32 entriesRead = numEntries;
|
||||||
|
status_t error = get_memory_map_etc(B_CURRENT_TEAM, address, numBytes,
|
||||||
|
table, &entriesRead);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
// close the entry list
|
||||||
|
|
||||||
|
// if it's only one entry, we will silently accept the missing ending
|
||||||
|
if (numEntries == 1)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
if (entriesRead + 1 > (uint32)numEntries)
|
||||||
|
return B_BUFFER_OVERFLOW;
|
||||||
|
|
||||||
|
table[entriesRead].address = NULL;
|
||||||
|
table[entriesRead].size = 0;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user