Merge pull request #1899 from lioncash/state
vm_manager/svc: Modify MemoryState enum, and correct error handling for svcQueryMemory
This commit is contained in:
commit
1a23970d17
|
@ -150,7 +150,7 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
|
||||||
vm_manager
|
vm_manager
|
||||||
.MapMemoryBlock(vm_manager.GetTLSIORegionEndAddress() - stack_size,
|
.MapMemoryBlock(vm_manager.GetTLSIORegionEndAddress() - stack_size,
|
||||||
std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size,
|
std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size,
|
||||||
MemoryState::Mapped)
|
MemoryState::Stack)
|
||||||
.Unwrap();
|
.Unwrap();
|
||||||
|
|
||||||
vm_manager.LogLayout();
|
vm_manager.LogLayout();
|
||||||
|
|
|
@ -262,8 +262,7 @@ public:
|
||||||
ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms);
|
ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms);
|
||||||
ResultCode HeapFree(VAddr target, u32 size);
|
ResultCode HeapFree(VAddr target, u32 size);
|
||||||
|
|
||||||
ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size,
|
ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, MemoryState state);
|
||||||
MemoryState state = MemoryState::Mapped);
|
|
||||||
|
|
||||||
ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size);
|
ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size);
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "core/hle/lock.h"
|
#include "core/hle/lock.h"
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
#include "core/memory.h"
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -273,7 +274,7 @@ static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return current_process->MirrorMemory(dst_addr, src_addr, size);
|
return current_process->MirrorMemory(dst_addr, src_addr, size, MemoryState::Stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unmaps a region that was previously mapped with svcMapMemory
|
/// Unmaps a region that was previously mapped with svcMapMemory
|
||||||
|
@ -1066,10 +1067,9 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64
|
||||||
return shared_memory->Unmap(*current_process, addr);
|
return shared_memory->Unmap(*current_process, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Query process memory
|
static ResultCode QueryProcessMemory(VAddr memory_info_address, VAddr page_info_address,
|
||||||
static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_info*/,
|
Handle process_handle, VAddr address) {
|
||||||
Handle process_handle, u64 addr) {
|
LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address);
|
||||||
LOG_TRACE(Kernel_SVC, "called process=0x{:08X} addr={:X}", process_handle, addr);
|
|
||||||
const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
|
const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
|
||||||
SharedPtr<Process> process = handle_table.Get<Process>(process_handle);
|
SharedPtr<Process> process = handle_table.Get<Process>(process_handle);
|
||||||
if (!process) {
|
if (!process) {
|
||||||
|
@ -1079,28 +1079,32 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& vm_manager = process->VMManager();
|
const auto& vm_manager = process->VMManager();
|
||||||
const auto vma = vm_manager.FindVMA(addr);
|
const MemoryInfo memory_info = vm_manager.QueryMemory(address);
|
||||||
|
|
||||||
memory_info->attributes = 0;
|
Memory::Write64(memory_info_address, memory_info.base_address);
|
||||||
if (vm_manager.IsValidHandle(vma)) {
|
Memory::Write64(memory_info_address + 8, memory_info.size);
|
||||||
memory_info->base_address = vma->second.base;
|
Memory::Write32(memory_info_address + 16, memory_info.state);
|
||||||
memory_info->permission = static_cast<u32>(vma->second.permissions);
|
Memory::Write32(memory_info_address + 20, memory_info.attributes);
|
||||||
memory_info->size = vma->second.size;
|
Memory::Write32(memory_info_address + 24, memory_info.permission);
|
||||||
memory_info->type = static_cast<u32>(vma->second.meminfo_state);
|
Memory::Write32(memory_info_address + 32, memory_info.ipc_ref_count);
|
||||||
} else {
|
Memory::Write32(memory_info_address + 28, memory_info.device_ref_count);
|
||||||
memory_info->base_address = 0;
|
Memory::Write32(memory_info_address + 36, 0);
|
||||||
memory_info->permission = static_cast<u32>(VMAPermission::None);
|
|
||||||
memory_info->size = 0;
|
// Page info appears to be currently unused by the kernel and is always set to zero.
|
||||||
memory_info->type = static_cast<u32>(MemoryState::Unmapped);
|
Memory::Write32(page_info_address, 0);
|
||||||
}
|
|
||||||
|
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Query memory
|
static ResultCode QueryMemory(VAddr memory_info_address, VAddr page_info_address,
|
||||||
static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAddr addr) {
|
VAddr query_address) {
|
||||||
LOG_TRACE(Kernel_SVC, "called, addr={:X}", addr);
|
LOG_TRACE(Kernel_SVC,
|
||||||
return QueryProcessMemory(memory_info, page_info, CurrentProcess, addr);
|
"called, memory_info_address=0x{:016X}, page_info_address=0x{:016X}, "
|
||||||
|
"query_address=0x{:016X}",
|
||||||
|
memory_info_address, page_info_address, query_address);
|
||||||
|
|
||||||
|
return QueryProcessMemory(memory_info_address, page_info_address, CurrentProcess,
|
||||||
|
query_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exits the current process
|
/// Exits the current process
|
||||||
|
@ -1907,7 +1911,7 @@ static const FunctionDef SVC_Table[] = {
|
||||||
{0x73, nullptr, "SetProcessMemoryPermission"},
|
{0x73, nullptr, "SetProcessMemoryPermission"},
|
||||||
{0x74, nullptr, "MapProcessMemory"},
|
{0x74, nullptr, "MapProcessMemory"},
|
||||||
{0x75, nullptr, "UnmapProcessMemory"},
|
{0x75, nullptr, "UnmapProcessMemory"},
|
||||||
{0x76, nullptr, "QueryProcessMemory"},
|
{0x76, SvcWrap<QueryProcessMemory>, "QueryProcessMemory"},
|
||||||
{0x77, nullptr, "MapProcessCodeMemory"},
|
{0x77, nullptr, "MapProcessCodeMemory"},
|
||||||
{0x78, nullptr, "UnmapProcessCodeMemory"},
|
{0x78, nullptr, "UnmapProcessCodeMemory"},
|
||||||
{0x79, nullptr, "CreateProcess"},
|
{0x79, nullptr, "CreateProcess"},
|
||||||
|
|
|
@ -8,22 +8,6 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
struct MemoryInfo {
|
|
||||||
u64 base_address;
|
|
||||||
u64 size;
|
|
||||||
u32 type;
|
|
||||||
u32 attributes;
|
|
||||||
u32 permission;
|
|
||||||
u32 device_refcount;
|
|
||||||
u32 ipc_refcount;
|
|
||||||
INSERT_PADDING_WORDS(1);
|
|
||||||
};
|
|
||||||
static_assert(sizeof(MemoryInfo) == 0x28, "MemoryInfo has incorrect size.");
|
|
||||||
|
|
||||||
struct PageInfo {
|
|
||||||
u64 flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
void CallSVC(u32 immediate);
|
void CallSVC(u32 immediate);
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -7,9 +7,7 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/arm/arm_interface.h"
|
#include "core/arm/arm_interface.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/kernel/svc.h"
|
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
#include "core/memory.h"
|
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
@ -132,6 +130,11 @@ void SvcWrap() {
|
||||||
func(Param(0), Param(1), static_cast<u32>(Param(2)), static_cast<u32>(Param(3))).raw);
|
func(Param(0), Param(1), static_cast<u32>(Param(2)), static_cast<u32>(Param(3))).raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <ResultCode func(u64, u64, u32, u64)>
|
||||||
|
void SvcWrap() {
|
||||||
|
FuncReturn(func(Param(0), Param(1), static_cast<u32>(Param(2)), Param(3)).raw);
|
||||||
|
}
|
||||||
|
|
||||||
template <ResultCode func(u32, u64, u32)>
|
template <ResultCode func(u32, u64, u32)>
|
||||||
void SvcWrap() {
|
void SvcWrap() {
|
||||||
FuncReturn(func(static_cast<u32>(Param(0)), Param(1), static_cast<u32>(Param(2))).raw);
|
FuncReturn(func(static_cast<u32>(Param(0)), Param(1), static_cast<u32>(Param(2))).raw);
|
||||||
|
@ -191,21 +194,6 @@ void SvcWrap() {
|
||||||
FuncReturn(retval);
|
FuncReturn(retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <ResultCode func(MemoryInfo*, PageInfo*, u64)>
|
|
||||||
void SvcWrap() {
|
|
||||||
MemoryInfo memory_info = {};
|
|
||||||
PageInfo page_info = {};
|
|
||||||
u32 retval = func(&memory_info, &page_info, Param(2)).raw;
|
|
||||||
|
|
||||||
Memory::Write64(Param(0), memory_info.base_address);
|
|
||||||
Memory::Write64(Param(0) + 8, memory_info.size);
|
|
||||||
Memory::Write32(Param(0) + 16, memory_info.type);
|
|
||||||
Memory::Write32(Param(0) + 20, memory_info.attributes);
|
|
||||||
Memory::Write32(Param(0) + 24, memory_info.permission);
|
|
||||||
|
|
||||||
FuncReturn(retval);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <ResultCode func(u32*, u64, u64, u32)>
|
template <ResultCode func(u32*, u64, u64, u32)>
|
||||||
void SvcWrap() {
|
void SvcWrap() {
|
||||||
u32 param_1 = 0;
|
u32 param_1 = 0;
|
||||||
|
|
|
@ -25,14 +25,14 @@ static const char* GetMemoryStateName(MemoryState state) {
|
||||||
"CodeMutable", "Heap",
|
"CodeMutable", "Heap",
|
||||||
"Shared", "Unknown1",
|
"Shared", "Unknown1",
|
||||||
"ModuleCodeStatic", "ModuleCodeMutable",
|
"ModuleCodeStatic", "ModuleCodeMutable",
|
||||||
"IpcBuffer0", "Mapped",
|
"IpcBuffer0", "Stack",
|
||||||
"ThreadLocal", "TransferMemoryIsolated",
|
"ThreadLocal", "TransferMemoryIsolated",
|
||||||
"TransferMemory", "ProcessMemory",
|
"TransferMemory", "ProcessMemory",
|
||||||
"Unknown2", "IpcBuffer1",
|
"Inaccessible", "IpcBuffer1",
|
||||||
"IpcBuffer3", "KernelStack",
|
"IpcBuffer3", "KernelStack",
|
||||||
};
|
};
|
||||||
|
|
||||||
return names[static_cast<int>(state)];
|
return names[ToSvcMemoryState(state)];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const {
|
bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const {
|
||||||
|
@ -302,6 +302,25 @@ ResultCode VMManager::HeapFree(VAddr target, u64 size) {
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MemoryInfo VMManager::QueryMemory(VAddr address) const {
|
||||||
|
const auto vma = FindVMA(address);
|
||||||
|
MemoryInfo memory_info{};
|
||||||
|
|
||||||
|
if (IsValidHandle(vma)) {
|
||||||
|
memory_info.base_address = vma->second.base;
|
||||||
|
memory_info.permission = static_cast<u32>(vma->second.permissions);
|
||||||
|
memory_info.size = vma->second.size;
|
||||||
|
memory_info.state = ToSvcMemoryState(vma->second.meminfo_state);
|
||||||
|
} else {
|
||||||
|
memory_info.base_address = address_space_end;
|
||||||
|
memory_info.permission = static_cast<u32>(VMAPermission::None);
|
||||||
|
memory_info.size = 0 - address_space_end;
|
||||||
|
memory_info.state = static_cast<u32>(MemoryState::Inaccessible);
|
||||||
|
}
|
||||||
|
|
||||||
|
return memory_info;
|
||||||
|
}
|
||||||
|
|
||||||
ResultCode VMManager::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, MemoryState state) {
|
ResultCode VMManager::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, MemoryState state) {
|
||||||
const auto vma = FindVMA(src_addr);
|
const auto vma = FindVMA(src_addr);
|
||||||
|
|
||||||
|
|
|
@ -43,26 +43,129 @@ enum class VMAPermission : u8 {
|
||||||
ReadWriteExecute = Read | Write | Execute,
|
ReadWriteExecute = Read | Write | Execute,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Set of values returned in MemoryInfo.state by svcQueryMemory.
|
// clang-format off
|
||||||
|
/// Represents memory states and any relevant flags, as used by the kernel.
|
||||||
|
/// svcQueryMemory interprets these by masking away all but the first eight
|
||||||
|
/// bits when storing memory state into a MemoryInfo instance.
|
||||||
enum class MemoryState : u32 {
|
enum class MemoryState : u32 {
|
||||||
Unmapped = 0x0,
|
Mask = 0xFF,
|
||||||
Io = 0x1,
|
FlagProtect = 1U << 8,
|
||||||
Normal = 0x2,
|
FlagDebug = 1U << 9,
|
||||||
CodeStatic = 0x3,
|
FlagIPC0 = 1U << 10,
|
||||||
CodeMutable = 0x4,
|
FlagIPC3 = 1U << 11,
|
||||||
Heap = 0x5,
|
FlagIPC1 = 1U << 12,
|
||||||
Shared = 0x6,
|
FlagMapped = 1U << 13,
|
||||||
ModuleCodeStatic = 0x8,
|
FlagCode = 1U << 14,
|
||||||
ModuleCodeMutable = 0x9,
|
FlagAlias = 1U << 15,
|
||||||
IpcBuffer0 = 0xA,
|
FlagModule = 1U << 16,
|
||||||
Mapped = 0xB,
|
FlagTransfer = 1U << 17,
|
||||||
ThreadLocal = 0xC,
|
FlagQueryPhysicalAddressAllowed = 1U << 18,
|
||||||
TransferMemoryIsolated = 0xD,
|
FlagSharedDevice = 1U << 19,
|
||||||
TransferMemory = 0xE,
|
FlagSharedDeviceAligned = 1U << 20,
|
||||||
ProcessMemory = 0xF,
|
FlagIPCBuffer = 1U << 21,
|
||||||
IpcBuffer1 = 0x11,
|
FlagMemoryPoolAllocated = 1U << 22,
|
||||||
IpcBuffer3 = 0x12,
|
FlagMapProcess = 1U << 23,
|
||||||
KernelStack = 0x13,
|
FlagUncached = 1U << 24,
|
||||||
|
FlagCodeMemory = 1U << 25,
|
||||||
|
|
||||||
|
// Convenience flag sets to reduce repetition
|
||||||
|
IPCFlags = FlagIPC0 | FlagIPC3 | FlagIPC1,
|
||||||
|
|
||||||
|
CodeFlags = FlagDebug | IPCFlags | FlagMapped | FlagCode | FlagQueryPhysicalAddressAllowed |
|
||||||
|
FlagSharedDevice | FlagSharedDeviceAligned | FlagMemoryPoolAllocated,
|
||||||
|
|
||||||
|
DataFlags = FlagProtect | IPCFlags | FlagMapped | FlagAlias | FlagTransfer |
|
||||||
|
FlagQueryPhysicalAddressAllowed | FlagSharedDevice | FlagSharedDeviceAligned |
|
||||||
|
FlagMemoryPoolAllocated | FlagIPCBuffer | FlagUncached,
|
||||||
|
|
||||||
|
Unmapped = 0x00,
|
||||||
|
Io = 0x01 | FlagMapped,
|
||||||
|
Normal = 0x02 | FlagMapped | FlagQueryPhysicalAddressAllowed,
|
||||||
|
CodeStatic = 0x03 | CodeFlags | FlagMapProcess,
|
||||||
|
CodeMutable = 0x04 | CodeFlags | FlagMapProcess | FlagCodeMemory,
|
||||||
|
Heap = 0x05 | DataFlags | FlagCodeMemory,
|
||||||
|
Shared = 0x06 | FlagMapped | FlagMemoryPoolAllocated,
|
||||||
|
ModuleCodeStatic = 0x08 | CodeFlags | FlagModule | FlagMapProcess,
|
||||||
|
ModuleCodeMutable = 0x09 | DataFlags | FlagModule | FlagMapProcess | FlagCodeMemory,
|
||||||
|
|
||||||
|
IpcBuffer0 = 0x0A | FlagMapped | FlagQueryPhysicalAddressAllowed | FlagMemoryPoolAllocated |
|
||||||
|
IPCFlags | FlagSharedDevice | FlagSharedDeviceAligned,
|
||||||
|
|
||||||
|
Stack = 0x0B | FlagMapped | IPCFlags | FlagQueryPhysicalAddressAllowed |
|
||||||
|
FlagSharedDevice | FlagSharedDeviceAligned | FlagMemoryPoolAllocated,
|
||||||
|
|
||||||
|
ThreadLocal = 0x0C | FlagMapped | FlagMemoryPoolAllocated,
|
||||||
|
|
||||||
|
TransferMemoryIsolated = 0x0D | IPCFlags | FlagMapped | FlagQueryPhysicalAddressAllowed |
|
||||||
|
FlagSharedDevice | FlagSharedDeviceAligned | FlagMemoryPoolAllocated |
|
||||||
|
FlagUncached,
|
||||||
|
|
||||||
|
TransferMemory = 0x0E | FlagIPC3 | FlagIPC1 | FlagMapped | FlagQueryPhysicalAddressAllowed |
|
||||||
|
FlagSharedDevice | FlagSharedDeviceAligned | FlagMemoryPoolAllocated,
|
||||||
|
|
||||||
|
ProcessMemory = 0x0F | FlagIPC3 | FlagIPC1 | FlagMapped | FlagMemoryPoolAllocated,
|
||||||
|
|
||||||
|
// Used to signify an inaccessible or invalid memory region with memory queries
|
||||||
|
Inaccessible = 0x10,
|
||||||
|
|
||||||
|
IpcBuffer1 = 0x11 | FlagIPC3 | FlagIPC1 | FlagMapped | FlagQueryPhysicalAddressAllowed |
|
||||||
|
FlagSharedDevice | FlagSharedDeviceAligned | FlagMemoryPoolAllocated,
|
||||||
|
|
||||||
|
IpcBuffer3 = 0x12 | FlagIPC3 | FlagMapped | FlagQueryPhysicalAddressAllowed |
|
||||||
|
FlagSharedDeviceAligned | FlagMemoryPoolAllocated,
|
||||||
|
|
||||||
|
KernelStack = 0x13 | FlagMapped,
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
constexpr MemoryState operator|(MemoryState lhs, MemoryState rhs) {
|
||||||
|
return static_cast<MemoryState>(u32(lhs) | u32(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr MemoryState operator&(MemoryState lhs, MemoryState rhs) {
|
||||||
|
return static_cast<MemoryState>(u32(lhs) & u32(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr MemoryState operator^(MemoryState lhs, MemoryState rhs) {
|
||||||
|
return static_cast<MemoryState>(u32(lhs) ^ u32(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr MemoryState operator~(MemoryState lhs) {
|
||||||
|
return static_cast<MemoryState>(~u32(lhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr MemoryState& operator|=(MemoryState& lhs, MemoryState rhs) {
|
||||||
|
lhs = lhs | rhs;
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr MemoryState& operator&=(MemoryState& lhs, MemoryState rhs) {
|
||||||
|
lhs = lhs & rhs;
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr MemoryState& operator^=(MemoryState& lhs, MemoryState rhs) {
|
||||||
|
lhs = lhs ^ rhs;
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr u32 ToSvcMemoryState(MemoryState state) {
|
||||||
|
return static_cast<u32>(state & MemoryState::Mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MemoryInfo {
|
||||||
|
u64 base_address;
|
||||||
|
u64 size;
|
||||||
|
u32 state;
|
||||||
|
u32 attributes;
|
||||||
|
u32 permission;
|
||||||
|
u32 ipc_ref_count;
|
||||||
|
u32 device_ref_count;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(MemoryInfo) == 0x28, "MemoryInfo has incorrect size.");
|
||||||
|
|
||||||
|
struct PageInfo {
|
||||||
|
u32 flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -186,8 +289,15 @@ public:
|
||||||
ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms);
|
ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms);
|
||||||
ResultCode HeapFree(VAddr target, u64 size);
|
ResultCode HeapFree(VAddr target, u64 size);
|
||||||
|
|
||||||
ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size,
|
ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, MemoryState state);
|
||||||
MemoryState state = MemoryState::Mapped);
|
|
||||||
|
/// Queries the memory manager for information about the given address.
|
||||||
|
///
|
||||||
|
/// @param address The address to query the memory manager about for information.
|
||||||
|
///
|
||||||
|
/// @return A MemoryInfo instance containing information about the given address.
|
||||||
|
///
|
||||||
|
MemoryInfo QueryMemory(VAddr address) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans all VMAs and updates the page table range of any that use the given vector as backing
|
* Scans all VMAs and updates the page table range of any that use the given vector as backing
|
||||||
|
|
Reference in New Issue