diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.h | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 52 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.h | 16 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc_wrap.h | 22 | ||||
| -rw-r--r-- | src/core/hle/kernel/vm_manager.cpp | 25 | ||||
| -rw-r--r-- | src/core/hle/kernel/vm_manager.h | 152 |
7 files changed, 188 insertions, 84 deletions
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index c817fb449..5356a4a3f 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -150,7 +150,7 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) { | |||
| 150 | vm_manager | 150 | vm_manager |
| 151 | .MapMemoryBlock(vm_manager.GetTLSIORegionEndAddress() - stack_size, | 151 | .MapMemoryBlock(vm_manager.GetTLSIORegionEndAddress() - stack_size, |
| 152 | std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size, | 152 | std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size, |
| 153 | MemoryState::Mapped) | 153 | MemoryState::Stack) |
| 154 | .Unwrap(); | 154 | .Unwrap(); |
| 155 | 155 | ||
| 156 | vm_manager.LogLayout(); | 156 | vm_manager.LogLayout(); |
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index bcb9ac4b8..459eedfa6 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h | |||
| @@ -262,8 +262,7 @@ public: | |||
| 262 | ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms); | 262 | ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms); |
| 263 | ResultCode HeapFree(VAddr target, u32 size); | 263 | ResultCode HeapFree(VAddr target, u32 size); |
| 264 | 264 | ||
| 265 | ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, | 265 | ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, MemoryState state); |
| 266 | MemoryState state = MemoryState::Mapped); | ||
| 267 | 266 | ||
| 268 | ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size); | 267 | ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size); |
| 269 | 268 | ||
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 8b0b3671a..5d36792ca 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include "core/hle/lock.h" | 35 | #include "core/hle/lock.h" |
| 36 | #include "core/hle/result.h" | 36 | #include "core/hle/result.h" |
| 37 | #include "core/hle/service/service.h" | 37 | #include "core/hle/service/service.h" |
| 38 | #include "core/memory.h" | ||
| 38 | 39 | ||
| 39 | namespace Kernel { | 40 | namespace Kernel { |
| 40 | namespace { | 41 | namespace { |
| @@ -273,7 +274,7 @@ static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { | |||
| 273 | return result; | 274 | return result; |
| 274 | } | 275 | } |
| 275 | 276 | ||
| 276 | return current_process->MirrorMemory(dst_addr, src_addr, size); | 277 | return current_process->MirrorMemory(dst_addr, src_addr, size, MemoryState::Stack); |
| 277 | } | 278 | } |
| 278 | 279 | ||
| 279 | /// Unmaps a region that was previously mapped with svcMapMemory | 280 | /// Unmaps a region that was previously mapped with svcMapMemory |
| @@ -1066,10 +1067,9 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 | |||
| 1066 | return shared_memory->Unmap(*current_process, addr); | 1067 | return shared_memory->Unmap(*current_process, addr); |
| 1067 | } | 1068 | } |
| 1068 | 1069 | ||
| 1069 | /// Query process memory | 1070 | static ResultCode QueryProcessMemory(VAddr memory_info_address, VAddr page_info_address, |
| 1070 | static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_info*/, | 1071 | Handle process_handle, VAddr address) { |
| 1071 | Handle process_handle, u64 addr) { | 1072 | LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); |
| 1072 | LOG_TRACE(Kernel_SVC, "called process=0x{:08X} addr={:X}", process_handle, addr); | ||
| 1073 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 1073 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 1074 | SharedPtr<Process> process = handle_table.Get<Process>(process_handle); | 1074 | SharedPtr<Process> process = handle_table.Get<Process>(process_handle); |
| 1075 | if (!process) { | 1075 | if (!process) { |
| @@ -1079,28 +1079,32 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i | |||
| 1079 | } | 1079 | } |
| 1080 | 1080 | ||
| 1081 | const auto& vm_manager = process->VMManager(); | 1081 | const auto& vm_manager = process->VMManager(); |
| 1082 | const auto vma = vm_manager.FindVMA(addr); | 1082 | const MemoryInfo memory_info = vm_manager.QueryMemory(address); |
| 1083 | 1083 | ||
| 1084 | memory_info->attributes = 0; | 1084 | Memory::Write64(memory_info_address, memory_info.base_address); |
| 1085 | if (vm_manager.IsValidHandle(vma)) { | 1085 | Memory::Write64(memory_info_address + 8, memory_info.size); |
| 1086 | memory_info->base_address = vma->second.base; | 1086 | Memory::Write32(memory_info_address + 16, memory_info.state); |
| 1087 | memory_info->permission = static_cast<u32>(vma->second.permissions); | 1087 | Memory::Write32(memory_info_address + 20, memory_info.attributes); |
| 1088 | memory_info->size = vma->second.size; | 1088 | Memory::Write32(memory_info_address + 24, memory_info.permission); |
| 1089 | memory_info->type = static_cast<u32>(vma->second.meminfo_state); | 1089 | Memory::Write32(memory_info_address + 32, memory_info.ipc_ref_count); |
| 1090 | } else { | 1090 | Memory::Write32(memory_info_address + 28, memory_info.device_ref_count); |
| 1091 | memory_info->base_address = 0; | 1091 | Memory::Write32(memory_info_address + 36, 0); |
| 1092 | memory_info->permission = static_cast<u32>(VMAPermission::None); | 1092 | |
| 1093 | memory_info->size = 0; | 1093 | // Page info appears to be currently unused by the kernel and is always set to zero. |
| 1094 | memory_info->type = static_cast<u32>(MemoryState::Unmapped); | 1094 | Memory::Write32(page_info_address, 0); |
| 1095 | } | ||
| 1096 | 1095 | ||
| 1097 | return RESULT_SUCCESS; | 1096 | return RESULT_SUCCESS; |
| 1098 | } | 1097 | } |
| 1099 | 1098 | ||
| 1100 | /// Query memory | 1099 | static ResultCode QueryMemory(VAddr memory_info_address, VAddr page_info_address, |
| 1101 | static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAddr addr) { | 1100 | VAddr query_address) { |
| 1102 | LOG_TRACE(Kernel_SVC, "called, addr={:X}", addr); | 1101 | LOG_TRACE(Kernel_SVC, |
| 1103 | return QueryProcessMemory(memory_info, page_info, CurrentProcess, addr); | 1102 | "called, memory_info_address=0x{:016X}, page_info_address=0x{:016X}, " |
| 1103 | "query_address=0x{:016X}", | ||
| 1104 | memory_info_address, page_info_address, query_address); | ||
| 1105 | |||
| 1106 | return QueryProcessMemory(memory_info_address, page_info_address, CurrentProcess, | ||
| 1107 | query_address); | ||
| 1104 | } | 1108 | } |
| 1105 | 1109 | ||
| 1106 | /// Exits the current process | 1110 | /// Exits the current process |
| @@ -1907,7 +1911,7 @@ static const FunctionDef SVC_Table[] = { | |||
| 1907 | {0x73, nullptr, "SetProcessMemoryPermission"}, | 1911 | {0x73, nullptr, "SetProcessMemoryPermission"}, |
| 1908 | {0x74, nullptr, "MapProcessMemory"}, | 1912 | {0x74, nullptr, "MapProcessMemory"}, |
| 1909 | {0x75, nullptr, "UnmapProcessMemory"}, | 1913 | {0x75, nullptr, "UnmapProcessMemory"}, |
| 1910 | {0x76, nullptr, "QueryProcessMemory"}, | 1914 | {0x76, SvcWrap<QueryProcessMemory>, "QueryProcessMemory"}, |
| 1911 | {0x77, nullptr, "MapProcessCodeMemory"}, | 1915 | {0x77, nullptr, "MapProcessCodeMemory"}, |
| 1912 | {0x78, nullptr, "UnmapProcessCodeMemory"}, | 1916 | {0x78, nullptr, "UnmapProcessCodeMemory"}, |
| 1913 | {0x79, nullptr, "CreateProcess"}, | 1917 | {0x79, nullptr, "CreateProcess"}, |
diff --git a/src/core/hle/kernel/svc.h b/src/core/hle/kernel/svc.h index b06aac4ec..c37ae0f98 100644 --- a/src/core/hle/kernel/svc.h +++ b/src/core/hle/kernel/svc.h | |||
| @@ -8,22 +8,6 @@ | |||
| 8 | 8 | ||
| 9 | namespace Kernel { | 9 | namespace Kernel { |
| 10 | 10 | ||
| 11 | struct MemoryInfo { | ||
| 12 | u64 base_address; | ||
| 13 | u64 size; | ||
| 14 | u32 type; | ||
| 15 | u32 attributes; | ||
| 16 | u32 permission; | ||
| 17 | u32 device_refcount; | ||
| 18 | u32 ipc_refcount; | ||
| 19 | INSERT_PADDING_WORDS(1); | ||
| 20 | }; | ||
| 21 | static_assert(sizeof(MemoryInfo) == 0x28, "MemoryInfo has incorrect size."); | ||
| 22 | |||
| 23 | struct PageInfo { | ||
| 24 | u64 flags; | ||
| 25 | }; | ||
| 26 | |||
| 27 | void CallSVC(u32 immediate); | 11 | void CallSVC(u32 immediate); |
| 28 | 12 | ||
| 29 | } // namespace Kernel | 13 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index f38e0cb6f..2f758b959 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h | |||
| @@ -7,9 +7,7 @@ | |||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | #include "core/arm/arm_interface.h" | 8 | #include "core/arm/arm_interface.h" |
| 9 | #include "core/core.h" | 9 | #include "core/core.h" |
| 10 | #include "core/hle/kernel/svc.h" | ||
| 11 | #include "core/hle/result.h" | 10 | #include "core/hle/result.h" |
| 12 | #include "core/memory.h" | ||
| 13 | 11 | ||
| 14 | namespace Kernel { | 12 | namespace Kernel { |
| 15 | 13 | ||
| @@ -132,6 +130,11 @@ void SvcWrap() { | |||
| 132 | func(Param(0), Param(1), static_cast<u32>(Param(2)), static_cast<u32>(Param(3))).raw); | 130 | func(Param(0), Param(1), static_cast<u32>(Param(2)), static_cast<u32>(Param(3))).raw); |
| 133 | } | 131 | } |
| 134 | 132 | ||
| 133 | template <ResultCode func(u64, u64, u32, u64)> | ||
| 134 | void SvcWrap() { | ||
| 135 | FuncReturn(func(Param(0), Param(1), static_cast<u32>(Param(2)), Param(3)).raw); | ||
| 136 | } | ||
| 137 | |||
| 135 | template <ResultCode func(u32, u64, u32)> | 138 | template <ResultCode func(u32, u64, u32)> |
| 136 | void SvcWrap() { | 139 | void SvcWrap() { |
| 137 | FuncReturn(func(static_cast<u32>(Param(0)), Param(1), static_cast<u32>(Param(2))).raw); | 140 | FuncReturn(func(static_cast<u32>(Param(0)), Param(1), static_cast<u32>(Param(2))).raw); |
| @@ -191,21 +194,6 @@ void SvcWrap() { | |||
| 191 | FuncReturn(retval); | 194 | FuncReturn(retval); |
| 192 | } | 195 | } |
| 193 | 196 | ||
| 194 | template <ResultCode func(MemoryInfo*, PageInfo*, u64)> | ||
| 195 | void SvcWrap() { | ||
| 196 | MemoryInfo memory_info = {}; | ||
| 197 | PageInfo page_info = {}; | ||
| 198 | u32 retval = func(&memory_info, &page_info, Param(2)).raw; | ||
| 199 | |||
| 200 | Memory::Write64(Param(0), memory_info.base_address); | ||
| 201 | Memory::Write64(Param(0) + 8, memory_info.size); | ||
| 202 | Memory::Write32(Param(0) + 16, memory_info.type); | ||
| 203 | Memory::Write32(Param(0) + 20, memory_info.attributes); | ||
| 204 | Memory::Write32(Param(0) + 24, memory_info.permission); | ||
| 205 | |||
| 206 | FuncReturn(retval); | ||
| 207 | } | ||
| 208 | |||
| 209 | template <ResultCode func(u32*, u64, u64, u32)> | 197 | template <ResultCode func(u32*, u64, u64, u32)> |
| 210 | void SvcWrap() { | 198 | void SvcWrap() { |
| 211 | u32 param_1 = 0; | 199 | u32 param_1 = 0; |
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 6187993ce..d3b55a51e 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp | |||
| @@ -25,14 +25,14 @@ static const char* GetMemoryStateName(MemoryState state) { | |||
| 25 | "CodeMutable", "Heap", | 25 | "CodeMutable", "Heap", |
| 26 | "Shared", "Unknown1", | 26 | "Shared", "Unknown1", |
| 27 | "ModuleCodeStatic", "ModuleCodeMutable", | 27 | "ModuleCodeStatic", "ModuleCodeMutable", |
| 28 | "IpcBuffer0", "Mapped", | 28 | "IpcBuffer0", "Stack", |
| 29 | "ThreadLocal", "TransferMemoryIsolated", | 29 | "ThreadLocal", "TransferMemoryIsolated", |
| 30 | "TransferMemory", "ProcessMemory", | 30 | "TransferMemory", "ProcessMemory", |
| 31 | "Unknown2", "IpcBuffer1", | 31 | "Inaccessible", "IpcBuffer1", |
| 32 | "IpcBuffer3", "KernelStack", | 32 | "IpcBuffer3", "KernelStack", |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | return names[static_cast<int>(state)]; | 35 | return names[ToSvcMemoryState(state)]; |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const { | 38 | bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const { |
| @@ -302,6 +302,25 @@ ResultCode VMManager::HeapFree(VAddr target, u64 size) { | |||
| 302 | return RESULT_SUCCESS; | 302 | return RESULT_SUCCESS; |
| 303 | } | 303 | } |
| 304 | 304 | ||
| 305 | MemoryInfo VMManager::QueryMemory(VAddr address) const { | ||
| 306 | const auto vma = FindVMA(address); | ||
| 307 | MemoryInfo memory_info{}; | ||
| 308 | |||
| 309 | if (IsValidHandle(vma)) { | ||
| 310 | memory_info.base_address = vma->second.base; | ||
| 311 | memory_info.permission = static_cast<u32>(vma->second.permissions); | ||
| 312 | memory_info.size = vma->second.size; | ||
| 313 | memory_info.state = ToSvcMemoryState(vma->second.meminfo_state); | ||
| 314 | } else { | ||
| 315 | memory_info.base_address = address_space_end; | ||
| 316 | memory_info.permission = static_cast<u32>(VMAPermission::None); | ||
| 317 | memory_info.size = 0 - address_space_end; | ||
| 318 | memory_info.state = static_cast<u32>(MemoryState::Inaccessible); | ||
| 319 | } | ||
| 320 | |||
| 321 | return memory_info; | ||
| 322 | } | ||
| 323 | |||
| 305 | ResultCode VMManager::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, MemoryState state) { | 324 | ResultCode VMManager::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, MemoryState state) { |
| 306 | const auto vma = FindVMA(src_addr); | 325 | const auto vma = FindVMA(src_addr); |
| 307 | 326 | ||
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index a12419d1e..10bacac3e 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h | |||
| @@ -43,26 +43,129 @@ enum class VMAPermission : u8 { | |||
| 43 | ReadWriteExecute = Read | Write | Execute, | 43 | ReadWriteExecute = Read | Write | Execute, |
| 44 | }; | 44 | }; |
| 45 | 45 | ||
| 46 | /// Set of values returned in MemoryInfo.state by svcQueryMemory. | 46 | // clang-format off |
| 47 | /// Represents memory states and any relevant flags, as used by the kernel. | ||
| 48 | /// svcQueryMemory interprets these by masking away all but the first eight | ||
| 49 | /// bits when storing memory state into a MemoryInfo instance. | ||
| 47 | enum class MemoryState : u32 { | 50 | enum class MemoryState : u32 { |
| 48 | Unmapped = 0x0, | 51 | Mask = 0xFF, |
| 49 | Io = 0x1, | 52 | FlagProtect = 1U << 8, |
| 50 | Normal = 0x2, | 53 | FlagDebug = 1U << 9, |
| 51 | CodeStatic = 0x3, | 54 | FlagIPC0 = 1U << 10, |
| 52 | CodeMutable = 0x4, | 55 | FlagIPC3 = 1U << 11, |
| 53 | Heap = 0x5, | 56 | FlagIPC1 = 1U << 12, |
| 54 | Shared = 0x6, | 57 | FlagMapped = 1U << 13, |
| 55 | ModuleCodeStatic = 0x8, | 58 | FlagCode = 1U << 14, |
| 56 | ModuleCodeMutable = 0x9, | 59 | FlagAlias = 1U << 15, |
| 57 | IpcBuffer0 = 0xA, | 60 | FlagModule = 1U << 16, |
| 58 | Mapped = 0xB, | 61 | FlagTransfer = 1U << 17, |
| 59 | ThreadLocal = 0xC, | 62 | FlagQueryPhysicalAddressAllowed = 1U << 18, |
| 60 | TransferMemoryIsolated = 0xD, | 63 | FlagSharedDevice = 1U << 19, |
| 61 | TransferMemory = 0xE, | 64 | FlagSharedDeviceAligned = 1U << 20, |
| 62 | ProcessMemory = 0xF, | 65 | FlagIPCBuffer = 1U << 21, |
| 63 | IpcBuffer1 = 0x11, | 66 | FlagMemoryPoolAllocated = 1U << 22, |
| 64 | IpcBuffer3 = 0x12, | 67 | FlagMapProcess = 1U << 23, |
| 65 | KernelStack = 0x13, | 68 | FlagUncached = 1U << 24, |
| 69 | FlagCodeMemory = 1U << 25, | ||
| 70 | |||
| 71 | // Convenience flag sets to reduce repetition | ||
| 72 | IPCFlags = FlagIPC0 | FlagIPC3 | FlagIPC1, | ||
| 73 | |||
| 74 | CodeFlags = FlagDebug | IPCFlags | FlagMapped | FlagCode | FlagQueryPhysicalAddressAllowed | | ||
| 75 | FlagSharedDevice | FlagSharedDeviceAligned | FlagMemoryPoolAllocated, | ||
| 76 | |||
| 77 | DataFlags = FlagProtect | IPCFlags | FlagMapped | FlagAlias | FlagTransfer | | ||
| 78 | FlagQueryPhysicalAddressAllowed | FlagSharedDevice | FlagSharedDeviceAligned | | ||
| 79 | FlagMemoryPoolAllocated | FlagIPCBuffer | FlagUncached, | ||
| 80 | |||
| 81 | Unmapped = 0x00, | ||
| 82 | Io = 0x01 | FlagMapped, | ||
| 83 | Normal = 0x02 | FlagMapped | FlagQueryPhysicalAddressAllowed, | ||
| 84 | CodeStatic = 0x03 | CodeFlags | FlagMapProcess, | ||
| 85 | CodeMutable = 0x04 | CodeFlags | FlagMapProcess | FlagCodeMemory, | ||
| 86 | Heap = 0x05 | DataFlags | FlagCodeMemory, | ||
| 87 | Shared = 0x06 | FlagMapped | FlagMemoryPoolAllocated, | ||
| 88 | ModuleCodeStatic = 0x08 | CodeFlags | FlagModule | FlagMapProcess, | ||
| 89 | ModuleCodeMutable = 0x09 | DataFlags | FlagModule | FlagMapProcess | FlagCodeMemory, | ||
| 90 | |||
| 91 | IpcBuffer0 = 0x0A | FlagMapped | FlagQueryPhysicalAddressAllowed | FlagMemoryPoolAllocated | | ||
| 92 | IPCFlags | FlagSharedDevice | FlagSharedDeviceAligned, | ||
| 93 | |||
| 94 | Stack = 0x0B | FlagMapped | IPCFlags | FlagQueryPhysicalAddressAllowed | | ||
| 95 | FlagSharedDevice | FlagSharedDeviceAligned | FlagMemoryPoolAllocated, | ||
| 96 | |||
| 97 | ThreadLocal = 0x0C | FlagMapped | FlagMemoryPoolAllocated, | ||
| 98 | |||
| 99 | TransferMemoryIsolated = 0x0D | IPCFlags | FlagMapped | FlagQueryPhysicalAddressAllowed | | ||
| 100 | FlagSharedDevice | FlagSharedDeviceAligned | FlagMemoryPoolAllocated | | ||
| 101 | FlagUncached, | ||
| 102 | |||
| 103 | TransferMemory = 0x0E | FlagIPC3 | FlagIPC1 | FlagMapped | FlagQueryPhysicalAddressAllowed | | ||
| 104 | FlagSharedDevice | FlagSharedDeviceAligned | FlagMemoryPoolAllocated, | ||
| 105 | |||
| 106 | ProcessMemory = 0x0F | FlagIPC3 | FlagIPC1 | FlagMapped | FlagMemoryPoolAllocated, | ||
| 107 | |||
| 108 | // Used to signify an inaccessible or invalid memory region with memory queries | ||
| 109 | Inaccessible = 0x10, | ||
| 110 | |||
| 111 | IpcBuffer1 = 0x11 | FlagIPC3 | FlagIPC1 | FlagMapped | FlagQueryPhysicalAddressAllowed | | ||
| 112 | FlagSharedDevice | FlagSharedDeviceAligned | FlagMemoryPoolAllocated, | ||
| 113 | |||
| 114 | IpcBuffer3 = 0x12 | FlagIPC3 | FlagMapped | FlagQueryPhysicalAddressAllowed | | ||
| 115 | FlagSharedDeviceAligned | FlagMemoryPoolAllocated, | ||
| 116 | |||
| 117 | KernelStack = 0x13 | FlagMapped, | ||
| 118 | }; | ||
| 119 | // clang-format on | ||
| 120 | |||
| 121 | constexpr MemoryState operator|(MemoryState lhs, MemoryState rhs) { | ||
| 122 | return static_cast<MemoryState>(u32(lhs) | u32(rhs)); | ||
| 123 | } | ||
| 124 | |||
| 125 | constexpr MemoryState operator&(MemoryState lhs, MemoryState rhs) { | ||
| 126 | return static_cast<MemoryState>(u32(lhs) & u32(rhs)); | ||
| 127 | } | ||
| 128 | |||
| 129 | constexpr MemoryState operator^(MemoryState lhs, MemoryState rhs) { | ||
| 130 | return static_cast<MemoryState>(u32(lhs) ^ u32(rhs)); | ||
| 131 | } | ||
| 132 | |||
| 133 | constexpr MemoryState operator~(MemoryState lhs) { | ||
| 134 | return static_cast<MemoryState>(~u32(lhs)); | ||
| 135 | } | ||
| 136 | |||
| 137 | constexpr MemoryState& operator|=(MemoryState& lhs, MemoryState rhs) { | ||
| 138 | lhs = lhs | rhs; | ||
| 139 | return lhs; | ||
| 140 | } | ||
| 141 | |||
| 142 | constexpr MemoryState& operator&=(MemoryState& lhs, MemoryState rhs) { | ||
| 143 | lhs = lhs & rhs; | ||
| 144 | return lhs; | ||
| 145 | } | ||
| 146 | |||
| 147 | constexpr MemoryState& operator^=(MemoryState& lhs, MemoryState rhs) { | ||
| 148 | lhs = lhs ^ rhs; | ||
| 149 | return lhs; | ||
| 150 | } | ||
| 151 | |||
| 152 | constexpr u32 ToSvcMemoryState(MemoryState state) { | ||
| 153 | return static_cast<u32>(state & MemoryState::Mask); | ||
| 154 | } | ||
| 155 | |||
| 156 | struct MemoryInfo { | ||
| 157 | u64 base_address; | ||
| 158 | u64 size; | ||
| 159 | u32 state; | ||
| 160 | u32 attributes; | ||
| 161 | u32 permission; | ||
| 162 | u32 ipc_ref_count; | ||
| 163 | u32 device_ref_count; | ||
| 164 | }; | ||
| 165 | static_assert(sizeof(MemoryInfo) == 0x28, "MemoryInfo has incorrect size."); | ||
| 166 | |||
| 167 | struct PageInfo { | ||
| 168 | u32 flags; | ||
| 66 | }; | 169 | }; |
| 67 | 170 | ||
| 68 | /** | 171 | /** |
| @@ -186,8 +289,15 @@ public: | |||
| 186 | ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms); | 289 | ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms); |
| 187 | ResultCode HeapFree(VAddr target, u64 size); | 290 | ResultCode HeapFree(VAddr target, u64 size); |
| 188 | 291 | ||
| 189 | ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, | 292 | ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, MemoryState state); |
| 190 | MemoryState state = MemoryState::Mapped); | 293 | |
| 294 | /// Queries the memory manager for information about the given address. | ||
| 295 | /// | ||
| 296 | /// @param address The address to query the memory manager about for information. | ||
| 297 | /// | ||
| 298 | /// @return A MemoryInfo instance containing information about the given address. | ||
| 299 | /// | ||
| 300 | MemoryInfo QueryMemory(VAddr address) const; | ||
| 191 | 301 | ||
| 192 | /** | 302 | /** |
| 193 | * Scans all VMAs and updates the page table range of any that use the given vector as backing | 303 | * Scans all VMAs and updates the page table range of any that use the given vector as backing |