diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/k_memory_block.h | 36 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_page_table.cpp | 201 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_page_table.h | 44 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc_types.h | 1 |
4 files changed, 166 insertions, 116 deletions
diff --git a/src/core/hle/kernel/k_memory_block.h b/src/core/hle/kernel/k_memory_block.h index 9e51c33ce..dcca47f1b 100644 --- a/src/core/hle/kernel/k_memory_block.h +++ b/src/core/hle/kernel/k_memory_block.h | |||
| @@ -70,12 +70,12 @@ enum class KMemoryState : u32 { | |||
| 70 | ThreadLocal = | 70 | ThreadLocal = |
| 71 | static_cast<u32>(Svc::MemoryState::ThreadLocal) | FlagMapped | FlagReferenceCounted, | 71 | static_cast<u32>(Svc::MemoryState::ThreadLocal) | FlagMapped | FlagReferenceCounted, |
| 72 | 72 | ||
| 73 | Transferred = static_cast<u32>(Svc::MemoryState::Transferred) | FlagsMisc | | 73 | Transfered = static_cast<u32>(Svc::MemoryState::Transferred) | FlagsMisc | |
| 74 | FlagCanAlignedDeviceMap | FlagCanChangeAttribute | FlagCanUseIpc | | 74 | FlagCanAlignedDeviceMap | FlagCanChangeAttribute | FlagCanUseIpc | |
| 75 | FlagCanUseNonSecureIpc | FlagCanUseNonDeviceIpc, | 75 | FlagCanUseNonSecureIpc | FlagCanUseNonDeviceIpc, |
| 76 | 76 | ||
| 77 | SharedTransferred = static_cast<u32>(Svc::MemoryState::SharedTransferred) | FlagsMisc | | 77 | SharedTransfered = static_cast<u32>(Svc::MemoryState::SharedTransferred) | FlagsMisc | |
| 78 | FlagCanAlignedDeviceMap | FlagCanUseNonSecureIpc | FlagCanUseNonDeviceIpc, | 78 | FlagCanAlignedDeviceMap | FlagCanUseNonSecureIpc | FlagCanUseNonDeviceIpc, |
| 79 | 79 | ||
| 80 | SharedCode = static_cast<u32>(Svc::MemoryState::SharedCode) | FlagMapped | | 80 | SharedCode = static_cast<u32>(Svc::MemoryState::SharedCode) | FlagMapped | |
| 81 | FlagReferenceCounted | FlagCanUseNonSecureIpc | FlagCanUseNonDeviceIpc, | 81 | FlagReferenceCounted | FlagCanUseNonSecureIpc | FlagCanUseNonDeviceIpc, |
| @@ -93,6 +93,8 @@ enum class KMemoryState : u32 { | |||
| 93 | GeneratedCode = static_cast<u32>(Svc::MemoryState::GeneratedCode) | FlagMapped | | 93 | GeneratedCode = static_cast<u32>(Svc::MemoryState::GeneratedCode) | FlagMapped | |
| 94 | FlagReferenceCounted | FlagCanDebug, | 94 | FlagReferenceCounted | FlagCanDebug, |
| 95 | CodeOut = static_cast<u32>(Svc::MemoryState::CodeOut) | FlagMapped | FlagReferenceCounted, | 95 | CodeOut = static_cast<u32>(Svc::MemoryState::CodeOut) | FlagMapped | FlagReferenceCounted, |
| 96 | |||
| 97 | Coverage = static_cast<u32>(Svc::MemoryState::Coverage) | FlagMapped, | ||
| 96 | }; | 98 | }; |
| 97 | DECLARE_ENUM_FLAG_OPERATORS(KMemoryState); | 99 | DECLARE_ENUM_FLAG_OPERATORS(KMemoryState); |
| 98 | 100 | ||
| @@ -108,8 +110,8 @@ static_assert(static_cast<u32>(KMemoryState::AliasCodeData) == 0x03FFBD09); | |||
| 108 | static_assert(static_cast<u32>(KMemoryState::Ipc) == 0x005C3C0A); | 110 | static_assert(static_cast<u32>(KMemoryState::Ipc) == 0x005C3C0A); |
| 109 | static_assert(static_cast<u32>(KMemoryState::Stack) == 0x005C3C0B); | 111 | static_assert(static_cast<u32>(KMemoryState::Stack) == 0x005C3C0B); |
| 110 | static_assert(static_cast<u32>(KMemoryState::ThreadLocal) == 0x0040200C); | 112 | static_assert(static_cast<u32>(KMemoryState::ThreadLocal) == 0x0040200C); |
| 111 | static_assert(static_cast<u32>(KMemoryState::Transferred) == 0x015C3C0D); | 113 | static_assert(static_cast<u32>(KMemoryState::Transfered) == 0x015C3C0D); |
| 112 | static_assert(static_cast<u32>(KMemoryState::SharedTransferred) == 0x005C380E); | 114 | static_assert(static_cast<u32>(KMemoryState::SharedTransfered) == 0x005C380E); |
| 113 | static_assert(static_cast<u32>(KMemoryState::SharedCode) == 0x0040380F); | 115 | static_assert(static_cast<u32>(KMemoryState::SharedCode) == 0x0040380F); |
| 114 | static_assert(static_cast<u32>(KMemoryState::Inaccessible) == 0x00000010); | 116 | static_assert(static_cast<u32>(KMemoryState::Inaccessible) == 0x00000010); |
| 115 | static_assert(static_cast<u32>(KMemoryState::NonSecureIpc) == 0x005C3811); | 117 | static_assert(static_cast<u32>(KMemoryState::NonSecureIpc) == 0x005C3811); |
| @@ -117,6 +119,7 @@ static_assert(static_cast<u32>(KMemoryState::NonDeviceIpc) == 0x004C2812); | |||
| 117 | static_assert(static_cast<u32>(KMemoryState::Kernel) == 0x00002013); | 119 | static_assert(static_cast<u32>(KMemoryState::Kernel) == 0x00002013); |
| 118 | static_assert(static_cast<u32>(KMemoryState::GeneratedCode) == 0x00402214); | 120 | static_assert(static_cast<u32>(KMemoryState::GeneratedCode) == 0x00402214); |
| 119 | static_assert(static_cast<u32>(KMemoryState::CodeOut) == 0x00402015); | 121 | static_assert(static_cast<u32>(KMemoryState::CodeOut) == 0x00402015); |
| 122 | static_assert(static_cast<u32>(KMemoryState::Coverage) == 0x00002016); | ||
| 120 | 123 | ||
| 121 | enum class KMemoryPermission : u8 { | 124 | enum class KMemoryPermission : u8 { |
| 122 | None = 0, | 125 | None = 0, |
| @@ -155,7 +158,13 @@ enum class KMemoryPermission : u8 { | |||
| 155 | DECLARE_ENUM_FLAG_OPERATORS(KMemoryPermission); | 158 | DECLARE_ENUM_FLAG_OPERATORS(KMemoryPermission); |
| 156 | 159 | ||
| 157 | constexpr KMemoryPermission ConvertToKMemoryPermission(Svc::MemoryPermission perm) { | 160 | constexpr KMemoryPermission ConvertToKMemoryPermission(Svc::MemoryPermission perm) { |
| 158 | return static_cast<KMemoryPermission>(perm); | 161 | return static_cast<KMemoryPermission>( |
| 162 | (static_cast<KMemoryPermission>(perm) & KMemoryPermission::UserMask) | | ||
| 163 | KMemoryPermission::KernelRead | | ||
| 164 | ((static_cast<KMemoryPermission>(perm) & KMemoryPermission::UserWrite) | ||
| 165 | << KMemoryPermission::KernelShift) | | ||
| 166 | (perm == Svc::MemoryPermission::None ? KMemoryPermission::NotMapped | ||
| 167 | : KMemoryPermission::None)); | ||
| 159 | } | 168 | } |
| 160 | 169 | ||
| 161 | enum class KMemoryAttribute : u8 { | 170 | enum class KMemoryAttribute : u8 { |
| @@ -169,6 +178,8 @@ enum class KMemoryAttribute : u8 { | |||
| 169 | DeviceShared = static_cast<u8>(Svc::MemoryAttribute::DeviceShared), | 178 | DeviceShared = static_cast<u8>(Svc::MemoryAttribute::DeviceShared), |
| 170 | Uncached = static_cast<u8>(Svc::MemoryAttribute::Uncached), | 179 | Uncached = static_cast<u8>(Svc::MemoryAttribute::Uncached), |
| 171 | 180 | ||
| 181 | SetMask = Uncached, | ||
| 182 | |||
| 172 | IpcAndDeviceMapped = IpcLocked | DeviceShared, | 183 | IpcAndDeviceMapped = IpcLocked | DeviceShared, |
| 173 | LockedAndIpcLocked = Locked | IpcLocked, | 184 | LockedAndIpcLocked = Locked | IpcLocked, |
| 174 | DeviceSharedAndUncached = DeviceShared | Uncached | 185 | DeviceSharedAndUncached = DeviceShared | Uncached |
| @@ -215,6 +226,15 @@ struct KMemoryInfo { | |||
| 215 | constexpr VAddr GetLastAddress() const { | 226 | constexpr VAddr GetLastAddress() const { |
| 216 | return GetEndAddress() - 1; | 227 | return GetEndAddress() - 1; |
| 217 | } | 228 | } |
| 229 | constexpr KMemoryState GetState() const { | ||
| 230 | return state; | ||
| 231 | } | ||
| 232 | constexpr KMemoryAttribute GetAttribute() const { | ||
| 233 | return attribute; | ||
| 234 | } | ||
| 235 | constexpr KMemoryPermission GetPermission() const { | ||
| 236 | return perm; | ||
| 237 | } | ||
| 218 | }; | 238 | }; |
| 219 | 239 | ||
| 220 | class KMemoryBlock final { | 240 | class KMemoryBlock final { |
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp index 4da509224..e86ded58b 100644 --- a/src/core/hle/kernel/k_page_table.cpp +++ b/src/core/hle/kernel/k_page_table.cpp | |||
| @@ -305,8 +305,8 @@ ResultCode KPageTable::MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std: | |||
| 305 | 305 | ||
| 306 | KMemoryState state{}; | 306 | KMemoryState state{}; |
| 307 | KMemoryPermission perm{}; | 307 | KMemoryPermission perm{}; |
| 308 | CASCADE_CODE(CheckMemoryState(&state, &perm, nullptr, src_addr, size, KMemoryState::All, | 308 | CASCADE_CODE(CheckMemoryState(&state, &perm, nullptr, nullptr, src_addr, size, |
| 309 | KMemoryState::Normal, KMemoryPermission::All, | 309 | KMemoryState::All, KMemoryState::Normal, KMemoryPermission::All, |
| 310 | KMemoryPermission::ReadAndWrite, KMemoryAttribute::Mask, | 310 | KMemoryPermission::ReadAndWrite, KMemoryAttribute::Mask, |
| 311 | KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); | 311 | KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); |
| 312 | 312 | ||
| @@ -344,14 +344,14 @@ ResultCode KPageTable::UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, st | |||
| 344 | 344 | ||
| 345 | const std::size_t num_pages{size / PageSize}; | 345 | const std::size_t num_pages{size / PageSize}; |
| 346 | 346 | ||
| 347 | CASCADE_CODE(CheckMemoryState(nullptr, nullptr, nullptr, src_addr, size, KMemoryState::All, | 347 | CASCADE_CODE(CheckMemoryState(nullptr, nullptr, nullptr, nullptr, src_addr, size, |
| 348 | KMemoryState::Normal, KMemoryPermission::None, | 348 | KMemoryState::All, KMemoryState::Normal, KMemoryPermission::None, |
| 349 | KMemoryPermission::None, KMemoryAttribute::Mask, | 349 | KMemoryPermission::None, KMemoryAttribute::Mask, |
| 350 | KMemoryAttribute::Locked, KMemoryAttribute::IpcAndDeviceMapped)); | 350 | KMemoryAttribute::Locked, KMemoryAttribute::IpcAndDeviceMapped)); |
| 351 | 351 | ||
| 352 | KMemoryState state{}; | 352 | KMemoryState state{}; |
| 353 | CASCADE_CODE(CheckMemoryState( | 353 | CASCADE_CODE(CheckMemoryState( |
| 354 | &state, nullptr, nullptr, dst_addr, PageSize, KMemoryState::FlagCanCodeAlias, | 354 | &state, nullptr, nullptr, nullptr, dst_addr, PageSize, KMemoryState::FlagCanCodeAlias, |
| 355 | KMemoryState::FlagCanCodeAlias, KMemoryPermission::None, KMemoryPermission::None, | 355 | KMemoryState::FlagCanCodeAlias, KMemoryPermission::None, KMemoryPermission::None, |
| 356 | KMemoryAttribute::Mask, KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); | 356 | KMemoryAttribute::Mask, KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); |
| 357 | CASCADE_CODE(CheckMemoryState(dst_addr, size, KMemoryState::All, state, KMemoryPermission::None, | 357 | CASCADE_CODE(CheckMemoryState(dst_addr, size, KMemoryState::All, state, KMemoryPermission::None, |
| @@ -553,7 +553,7 @@ ResultCode KPageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) { | |||
| 553 | 553 | ||
| 554 | KMemoryState src_state{}; | 554 | KMemoryState src_state{}; |
| 555 | CASCADE_CODE(CheckMemoryState( | 555 | CASCADE_CODE(CheckMemoryState( |
| 556 | &src_state, nullptr, nullptr, src_addr, size, KMemoryState::FlagCanAlias, | 556 | &src_state, nullptr, nullptr, nullptr, src_addr, size, KMemoryState::FlagCanAlias, |
| 557 | KMemoryState::FlagCanAlias, KMemoryPermission::All, KMemoryPermission::ReadAndWrite, | 557 | KMemoryState::FlagCanAlias, KMemoryPermission::All, KMemoryPermission::ReadAndWrite, |
| 558 | KMemoryAttribute::Mask, KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); | 558 | KMemoryAttribute::Mask, KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); |
| 559 | 559 | ||
| @@ -592,13 +592,13 @@ ResultCode KPageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) { | |||
| 592 | 592 | ||
| 593 | KMemoryState src_state{}; | 593 | KMemoryState src_state{}; |
| 594 | CASCADE_CODE(CheckMemoryState( | 594 | CASCADE_CODE(CheckMemoryState( |
| 595 | &src_state, nullptr, nullptr, src_addr, size, KMemoryState::FlagCanAlias, | 595 | &src_state, nullptr, nullptr, nullptr, src_addr, size, KMemoryState::FlagCanAlias, |
| 596 | KMemoryState::FlagCanAlias, KMemoryPermission::All, KMemoryPermission::None, | 596 | KMemoryState::FlagCanAlias, KMemoryPermission::All, KMemoryPermission::None, |
| 597 | KMemoryAttribute::Mask, KMemoryAttribute::Locked, KMemoryAttribute::IpcAndDeviceMapped)); | 597 | KMemoryAttribute::Mask, KMemoryAttribute::Locked, KMemoryAttribute::IpcAndDeviceMapped)); |
| 598 | 598 | ||
| 599 | KMemoryPermission dst_perm{}; | 599 | KMemoryPermission dst_perm{}; |
| 600 | CASCADE_CODE(CheckMemoryState(nullptr, &dst_perm, nullptr, dst_addr, size, KMemoryState::All, | 600 | CASCADE_CODE(CheckMemoryState(nullptr, &dst_perm, nullptr, nullptr, dst_addr, size, |
| 601 | KMemoryState::Stack, KMemoryPermission::None, | 601 | KMemoryState::All, KMemoryState::Stack, KMemoryPermission::None, |
| 602 | KMemoryPermission::None, KMemoryAttribute::Mask, | 602 | KMemoryPermission::None, KMemoryAttribute::Mask, |
| 603 | KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); | 603 | KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); |
| 604 | 604 | ||
| @@ -721,7 +721,7 @@ ResultCode KPageTable::SetProcessMemoryPermission(VAddr addr, std::size_t size, | |||
| 721 | KMemoryPermission prev_perm{}; | 721 | KMemoryPermission prev_perm{}; |
| 722 | 722 | ||
| 723 | CASCADE_CODE(CheckMemoryState( | 723 | CASCADE_CODE(CheckMemoryState( |
| 724 | &prev_state, &prev_perm, nullptr, addr, size, KMemoryState::FlagCode, | 724 | &prev_state, &prev_perm, nullptr, nullptr, addr, size, KMemoryState::FlagCode, |
| 725 | KMemoryState::FlagCode, KMemoryPermission::None, KMemoryPermission::None, | 725 | KMemoryState::FlagCode, KMemoryPermission::None, KMemoryPermission::None, |
| 726 | KMemoryAttribute::Mask, KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); | 726 | KMemoryAttribute::Mask, KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); |
| 727 | 727 | ||
| @@ -782,7 +782,7 @@ ResultCode KPageTable::ReserveTransferMemory(VAddr addr, std::size_t size, KMemo | |||
| 782 | KMemoryAttribute attribute{}; | 782 | KMemoryAttribute attribute{}; |
| 783 | 783 | ||
| 784 | CASCADE_CODE(CheckMemoryState( | 784 | CASCADE_CODE(CheckMemoryState( |
| 785 | &state, nullptr, &attribute, addr, size, | 785 | &state, nullptr, &attribute, nullptr, addr, size, |
| 786 | KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted, | 786 | KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted, |
| 787 | KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted, KMemoryPermission::All, | 787 | KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted, KMemoryPermission::All, |
| 788 | KMemoryPermission::ReadAndWrite, KMemoryAttribute::Mask, KMemoryAttribute::None, | 788 | KMemoryPermission::ReadAndWrite, KMemoryAttribute::Mask, KMemoryAttribute::None, |
| @@ -799,7 +799,7 @@ ResultCode KPageTable::ResetTransferMemory(VAddr addr, std::size_t size) { | |||
| 799 | KMemoryState state{}; | 799 | KMemoryState state{}; |
| 800 | 800 | ||
| 801 | CASCADE_CODE( | 801 | CASCADE_CODE( |
| 802 | CheckMemoryState(&state, nullptr, nullptr, addr, size, | 802 | CheckMemoryState(&state, nullptr, nullptr, nullptr, addr, size, |
| 803 | KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted, | 803 | KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted, |
| 804 | KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted, | 804 | KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted, |
| 805 | KMemoryPermission::None, KMemoryPermission::None, KMemoryAttribute::Mask, | 805 | KMemoryPermission::None, KMemoryPermission::None, KMemoryAttribute::Mask, |
| @@ -820,7 +820,7 @@ ResultCode KPageTable::SetMemoryPermission(VAddr addr, std::size_t size, | |||
| 820 | KMemoryState old_state; | 820 | KMemoryState old_state; |
| 821 | KMemoryPermission old_perm; | 821 | KMemoryPermission old_perm; |
| 822 | R_TRY(this->CheckMemoryState( | 822 | R_TRY(this->CheckMemoryState( |
| 823 | std::addressof(old_state), std::addressof(old_perm), nullptr, addr, size, | 823 | std::addressof(old_state), std::addressof(old_perm), nullptr, nullptr, addr, size, |
| 824 | KMemoryState::FlagCanReprotect, KMemoryState::FlagCanReprotect, KMemoryPermission::None, | 824 | KMemoryState::FlagCanReprotect, KMemoryState::FlagCanReprotect, KMemoryPermission::None, |
| 825 | KMemoryPermission::None, KMemoryAttribute::All, KMemoryAttribute::None)); | 825 | KMemoryPermission::None, KMemoryAttribute::All, KMemoryAttribute::None)); |
| 826 | 826 | ||
| @@ -846,7 +846,7 @@ ResultCode KPageTable::SetMemoryAttribute(VAddr addr, std::size_t size, KMemoryA | |||
| 846 | KMemoryAttribute attribute{}; | 846 | KMemoryAttribute attribute{}; |
| 847 | 847 | ||
| 848 | CASCADE_CODE(CheckMemoryState( | 848 | CASCADE_CODE(CheckMemoryState( |
| 849 | &state, &perm, &attribute, addr, size, KMemoryState::FlagCanChangeAttribute, | 849 | &state, &perm, &attribute, nullptr, addr, size, KMemoryState::FlagCanChangeAttribute, |
| 850 | KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None, | 850 | KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None, |
| 851 | KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None, | 851 | KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None, |
| 852 | KMemoryAttribute::DeviceSharedAndUncached)); | 852 | KMemoryAttribute::DeviceSharedAndUncached)); |
| @@ -1019,7 +1019,7 @@ ResultCode KPageTable::LockForDeviceAddressSpace(VAddr addr, std::size_t size) { | |||
| 1019 | 1019 | ||
| 1020 | KMemoryPermission perm{}; | 1020 | KMemoryPermission perm{}; |
| 1021 | if (const ResultCode result{CheckMemoryState( | 1021 | if (const ResultCode result{CheckMemoryState( |
| 1022 | nullptr, &perm, nullptr, addr, size, KMemoryState::FlagCanChangeAttribute, | 1022 | nullptr, &perm, nullptr, nullptr, addr, size, KMemoryState::FlagCanChangeAttribute, |
| 1023 | KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None, | 1023 | KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None, |
| 1024 | KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None, | 1024 | KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None, |
| 1025 | KMemoryAttribute::DeviceSharedAndUncached)}; | 1025 | KMemoryAttribute::DeviceSharedAndUncached)}; |
| @@ -1042,7 +1042,7 @@ ResultCode KPageTable::UnlockForDeviceAddressSpace(VAddr addr, std::size_t size) | |||
| 1042 | 1042 | ||
| 1043 | KMemoryPermission perm{}; | 1043 | KMemoryPermission perm{}; |
| 1044 | if (const ResultCode result{CheckMemoryState( | 1044 | if (const ResultCode result{CheckMemoryState( |
| 1045 | nullptr, &perm, nullptr, addr, size, KMemoryState::FlagCanChangeAttribute, | 1045 | nullptr, &perm, nullptr, nullptr, addr, size, KMemoryState::FlagCanChangeAttribute, |
| 1046 | KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None, | 1046 | KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None, |
| 1047 | KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None, | 1047 | KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None, |
| 1048 | KMemoryAttribute::DeviceSharedAndUncached)}; | 1048 | KMemoryAttribute::DeviceSharedAndUncached)}; |
| @@ -1068,7 +1068,7 @@ ResultCode KPageTable::LockForCodeMemory(VAddr addr, std::size_t size) { | |||
| 1068 | KMemoryPermission old_perm{}; | 1068 | KMemoryPermission old_perm{}; |
| 1069 | 1069 | ||
| 1070 | if (const ResultCode result{CheckMemoryState( | 1070 | if (const ResultCode result{CheckMemoryState( |
| 1071 | nullptr, &old_perm, nullptr, addr, size, KMemoryState::FlagCanCodeMemory, | 1071 | nullptr, &old_perm, nullptr, nullptr, addr, size, KMemoryState::FlagCanCodeMemory, |
| 1072 | KMemoryState::FlagCanCodeMemory, KMemoryPermission::All, | 1072 | KMemoryState::FlagCanCodeMemory, KMemoryPermission::All, |
| 1073 | KMemoryPermission::UserReadWrite, KMemoryAttribute::All, KMemoryAttribute::None)}; | 1073 | KMemoryPermission::UserReadWrite, KMemoryAttribute::All, KMemoryAttribute::None)}; |
| 1074 | result.IsError()) { | 1074 | result.IsError()) { |
| @@ -1095,7 +1095,7 @@ ResultCode KPageTable::UnlockForCodeMemory(VAddr addr, std::size_t size) { | |||
| 1095 | KMemoryPermission old_perm{}; | 1095 | KMemoryPermission old_perm{}; |
| 1096 | 1096 | ||
| 1097 | if (const ResultCode result{CheckMemoryState( | 1097 | if (const ResultCode result{CheckMemoryState( |
| 1098 | nullptr, &old_perm, nullptr, addr, size, KMemoryState::FlagCanCodeMemory, | 1098 | nullptr, &old_perm, nullptr, nullptr, addr, size, KMemoryState::FlagCanCodeMemory, |
| 1099 | KMemoryState::FlagCanCodeMemory, KMemoryPermission::None, KMemoryPermission::None, | 1099 | KMemoryState::FlagCanCodeMemory, KMemoryPermission::None, KMemoryPermission::None, |
| 1100 | KMemoryAttribute::All, KMemoryAttribute::Locked)}; | 1100 | KMemoryAttribute::All, KMemoryAttribute::Locked)}; |
| 1101 | result.IsError()) { | 1101 | result.IsError()) { |
| @@ -1225,18 +1225,19 @@ constexpr VAddr KPageTable::GetRegionAddress(KMemoryState state) const { | |||
| 1225 | return alias_region_start; | 1225 | return alias_region_start; |
| 1226 | case KMemoryState::Stack: | 1226 | case KMemoryState::Stack: |
| 1227 | return stack_region_start; | 1227 | return stack_region_start; |
| 1228 | case KMemoryState::Io: | ||
| 1229 | case KMemoryState::Static: | 1228 | case KMemoryState::Static: |
| 1230 | case KMemoryState::ThreadLocal: | 1229 | case KMemoryState::ThreadLocal: |
| 1231 | return kernel_map_region_start; | 1230 | return kernel_map_region_start; |
| 1231 | case KMemoryState::Io: | ||
| 1232 | case KMemoryState::Shared: | 1232 | case KMemoryState::Shared: |
| 1233 | case KMemoryState::AliasCode: | 1233 | case KMemoryState::AliasCode: |
| 1234 | case KMemoryState::AliasCodeData: | 1234 | case KMemoryState::AliasCodeData: |
| 1235 | case KMemoryState::Transferred: | 1235 | case KMemoryState::Transfered: |
| 1236 | case KMemoryState::SharedTransferred: | 1236 | case KMemoryState::SharedTransfered: |
| 1237 | case KMemoryState::SharedCode: | 1237 | case KMemoryState::SharedCode: |
| 1238 | case KMemoryState::GeneratedCode: | 1238 | case KMemoryState::GeneratedCode: |
| 1239 | case KMemoryState::CodeOut: | 1239 | case KMemoryState::CodeOut: |
| 1240 | case KMemoryState::Coverage: | ||
| 1240 | return alias_code_region_start; | 1241 | return alias_code_region_start; |
| 1241 | case KMemoryState::Code: | 1242 | case KMemoryState::Code: |
| 1242 | case KMemoryState::CodeData: | 1243 | case KMemoryState::CodeData: |
| @@ -1260,18 +1261,19 @@ constexpr std::size_t KPageTable::GetRegionSize(KMemoryState state) const { | |||
| 1260 | return alias_region_end - alias_region_start; | 1261 | return alias_region_end - alias_region_start; |
| 1261 | case KMemoryState::Stack: | 1262 | case KMemoryState::Stack: |
| 1262 | return stack_region_end - stack_region_start; | 1263 | return stack_region_end - stack_region_start; |
| 1263 | case KMemoryState::Io: | ||
| 1264 | case KMemoryState::Static: | 1264 | case KMemoryState::Static: |
| 1265 | case KMemoryState::ThreadLocal: | 1265 | case KMemoryState::ThreadLocal: |
| 1266 | return kernel_map_region_end - kernel_map_region_start; | 1266 | return kernel_map_region_end - kernel_map_region_start; |
| 1267 | case KMemoryState::Io: | ||
| 1267 | case KMemoryState::Shared: | 1268 | case KMemoryState::Shared: |
| 1268 | case KMemoryState::AliasCode: | 1269 | case KMemoryState::AliasCode: |
| 1269 | case KMemoryState::AliasCodeData: | 1270 | case KMemoryState::AliasCodeData: |
| 1270 | case KMemoryState::Transferred: | 1271 | case KMemoryState::Transfered: |
| 1271 | case KMemoryState::SharedTransferred: | 1272 | case KMemoryState::SharedTransfered: |
| 1272 | case KMemoryState::SharedCode: | 1273 | case KMemoryState::SharedCode: |
| 1273 | case KMemoryState::GeneratedCode: | 1274 | case KMemoryState::GeneratedCode: |
| 1274 | case KMemoryState::CodeOut: | 1275 | case KMemoryState::CodeOut: |
| 1276 | case KMemoryState::Coverage: | ||
| 1275 | return alias_code_region_end - alias_code_region_start; | 1277 | return alias_code_region_end - alias_code_region_start; |
| 1276 | case KMemoryState::Code: | 1278 | case KMemoryState::Code: |
| 1277 | case KMemoryState::CodeData: | 1279 | case KMemoryState::CodeData: |
| @@ -1283,15 +1285,18 @@ constexpr std::size_t KPageTable::GetRegionSize(KMemoryState state) const { | |||
| 1283 | } | 1285 | } |
| 1284 | 1286 | ||
| 1285 | bool KPageTable::CanContain(VAddr addr, std::size_t size, KMemoryState state) const { | 1287 | bool KPageTable::CanContain(VAddr addr, std::size_t size, KMemoryState state) const { |
| 1286 | const VAddr end{addr + size}; | 1288 | const VAddr end = addr + size; |
| 1287 | const VAddr last{end - 1}; | 1289 | const VAddr last = end - 1; |
| 1288 | const VAddr region_start{GetRegionAddress(state)}; | 1290 | |
| 1289 | const std::size_t region_size{GetRegionSize(state)}; | 1291 | const VAddr region_start = this->GetRegionAddress(state); |
| 1290 | const bool is_in_region{region_start <= addr && addr < end && | 1292 | const size_t region_size = this->GetRegionSize(state); |
| 1291 | last <= region_start + region_size - 1}; | 1293 | |
| 1292 | const bool is_in_heap{!(end <= heap_region_start || heap_region_end <= addr)}; | 1294 | const bool is_in_region = |
| 1293 | const bool is_in_alias{!(end <= alias_region_start || alias_region_end <= addr)}; | 1295 | region_start <= addr && addr < end && last <= region_start + region_size - 1; |
| 1294 | 1296 | const bool is_in_heap = !(end <= heap_region_start || heap_region_end <= addr || | |
| 1297 | heap_region_start == heap_region_end); | ||
| 1298 | const bool is_in_alias = !(end <= alias_region_start || alias_region_end <= addr || | ||
| 1299 | alias_region_start == alias_region_end); | ||
| 1295 | switch (state) { | 1300 | switch (state) { |
| 1296 | case KMemoryState::Free: | 1301 | case KMemoryState::Free: |
| 1297 | case KMemoryState::Kernel: | 1302 | case KMemoryState::Kernel: |
| @@ -1305,11 +1310,12 @@ bool KPageTable::CanContain(VAddr addr, std::size_t size, KMemoryState state) co | |||
| 1305 | case KMemoryState::AliasCodeData: | 1310 | case KMemoryState::AliasCodeData: |
| 1306 | case KMemoryState::Stack: | 1311 | case KMemoryState::Stack: |
| 1307 | case KMemoryState::ThreadLocal: | 1312 | case KMemoryState::ThreadLocal: |
| 1308 | case KMemoryState::Transferred: | 1313 | case KMemoryState::Transfered: |
| 1309 | case KMemoryState::SharedTransferred: | 1314 | case KMemoryState::SharedTransfered: |
| 1310 | case KMemoryState::SharedCode: | 1315 | case KMemoryState::SharedCode: |
| 1311 | case KMemoryState::GeneratedCode: | 1316 | case KMemoryState::GeneratedCode: |
| 1312 | case KMemoryState::CodeOut: | 1317 | case KMemoryState::CodeOut: |
| 1318 | case KMemoryState::Coverage: | ||
| 1313 | return is_in_region && !is_in_heap && !is_in_alias; | 1319 | return is_in_region && !is_in_heap && !is_in_alias; |
| 1314 | case KMemoryState::Normal: | 1320 | case KMemoryState::Normal: |
| 1315 | ASSERT(is_in_heap); | 1321 | ASSERT(is_in_heap); |
| @@ -1324,100 +1330,91 @@ bool KPageTable::CanContain(VAddr addr, std::size_t size, KMemoryState state) co | |||
| 1324 | } | 1330 | } |
| 1325 | } | 1331 | } |
| 1326 | 1332 | ||
| 1327 | constexpr ResultCode KPageTable::CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask, | 1333 | ResultCode KPageTable::CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask, |
| 1328 | KMemoryState state, KMemoryPermission perm_mask, | 1334 | KMemoryState state, KMemoryPermission perm_mask, |
| 1329 | KMemoryPermission perm, | 1335 | KMemoryPermission perm, KMemoryAttribute attr_mask, |
| 1330 | KMemoryAttribute attr_mask, | 1336 | KMemoryAttribute attr) const { |
| 1331 | KMemoryAttribute attr) const { | 1337 | // Validate the states match expectation. |
| 1332 | // Validate the states match expectation | 1338 | R_UNLESS((info.state & state_mask) == state, ResultInvalidCurrentMemory); |
| 1333 | if ((info.state & state_mask) != state) { | 1339 | R_UNLESS((info.perm & perm_mask) == perm, ResultInvalidCurrentMemory); |
| 1334 | return ResultInvalidCurrentMemory; | 1340 | R_UNLESS((info.attribute & attr_mask) == attr, ResultInvalidCurrentMemory); |
| 1335 | } | ||
| 1336 | if ((info.perm & perm_mask) != perm) { | ||
| 1337 | return ResultInvalidCurrentMemory; | ||
| 1338 | } | ||
| 1339 | if ((info.attribute & attr_mask) != attr) { | ||
| 1340 | return ResultInvalidCurrentMemory; | ||
| 1341 | } | ||
| 1342 | 1341 | ||
| 1343 | return ResultSuccess; | 1342 | return ResultSuccess; |
| 1344 | } | 1343 | } |
| 1345 | 1344 | ||
| 1346 | ResultCode KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, | 1345 | ResultCode KPageTable::CheckMemoryStateContiguous(std::size_t* out_blocks_needed, VAddr addr, |
| 1347 | KMemoryAttribute* out_attr, VAddr addr, std::size_t size, | 1346 | std::size_t size, KMemoryState state_mask, |
| 1348 | KMemoryState state_mask, KMemoryState state, | 1347 | KMemoryState state, KMemoryPermission perm_mask, |
| 1349 | KMemoryPermission perm_mask, KMemoryPermission perm, | 1348 | KMemoryPermission perm, |
| 1350 | KMemoryAttribute attr_mask, KMemoryAttribute attr, | 1349 | KMemoryAttribute attr_mask, |
| 1351 | KMemoryAttribute ignore_attr) { | 1350 | KMemoryAttribute attr) const { |
| 1352 | std::lock_guard lock{page_table_lock}; | 1351 | ASSERT(this->IsLockedByCurrentThread()); |
| 1353 | 1352 | ||
| 1354 | // Get information about the first block | 1353 | // Get information about the first block. |
| 1355 | const VAddr last_addr{addr + size - 1}; | 1354 | const VAddr last_addr = addr + size - 1; |
| 1356 | KMemoryBlockManager::const_iterator it{block_manager->FindIterator(addr)}; | 1355 | KMemoryBlockManager::const_iterator it = block_manager->FindIterator(addr); |
| 1357 | KMemoryInfo info{it->GetMemoryInfo()}; | 1356 | KMemoryInfo info = it->GetMemoryInfo(); |
| 1358 | 1357 | ||
| 1359 | // Validate all blocks in the range have correct state | 1358 | // If the start address isn't aligned, we need a block. |
| 1360 | const KMemoryState first_state{info.state}; | 1359 | const size_t blocks_for_start_align = |
| 1361 | const KMemoryPermission first_perm{info.perm}; | 1360 | (Common::AlignDown(addr, PageSize) != info.GetAddress()) ? 1 : 0; |
| 1362 | const KMemoryAttribute first_attr{info.attribute}; | ||
| 1363 | 1361 | ||
| 1364 | while (true) { | 1362 | while (true) { |
| 1365 | // Validate the current block | 1363 | // Validate against the provided masks. |
| 1366 | if (!(info.state == first_state)) { | 1364 | R_TRY(this->CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr)); |
| 1367 | return ResultInvalidCurrentMemory; | ||
| 1368 | } | ||
| 1369 | if (!(info.perm == first_perm)) { | ||
| 1370 | return ResultInvalidCurrentMemory; | ||
| 1371 | } | ||
| 1372 | if (!((info.attribute | static_cast<KMemoryAttribute>(ignore_attr)) == | ||
| 1373 | (first_attr | static_cast<KMemoryAttribute>(ignore_attr)))) { | ||
| 1374 | return ResultInvalidCurrentMemory; | ||
| 1375 | } | ||
| 1376 | |||
| 1377 | // Validate against the provided masks | ||
| 1378 | CASCADE_CODE(CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr)); | ||
| 1379 | 1365 | ||
| 1380 | // Break once we're done | 1366 | // Break once we're done. |
| 1381 | if (last_addr <= info.GetLastAddress()) { | 1367 | if (last_addr <= info.GetLastAddress()) { |
| 1382 | break; | 1368 | break; |
| 1383 | } | 1369 | } |
| 1384 | 1370 | ||
| 1385 | // Advance our iterator | 1371 | // Advance our iterator. |
| 1386 | it++; | 1372 | it++; |
| 1387 | ASSERT(it != block_manager->cend()); | 1373 | ASSERT(it != block_manager->cend()); |
| 1388 | info = it->GetMemoryInfo(); | 1374 | info = it->GetMemoryInfo(); |
| 1389 | } | 1375 | } |
| 1390 | 1376 | ||
| 1391 | // Write output state | 1377 | // If the end address isn't aligned, we need a block. |
| 1392 | if (out_state) { | 1378 | const size_t blocks_for_end_align = |
| 1393 | *out_state = first_state; | 1379 | (Common::AlignUp(addr + size, PageSize) != info.GetEndAddress()) ? 1 : 0; |
| 1394 | } | 1380 | |
| 1395 | if (out_perm) { | 1381 | if (out_blocks_needed != nullptr) { |
| 1396 | *out_perm = first_perm; | 1382 | *out_blocks_needed = blocks_for_start_align + blocks_for_end_align; |
| 1397 | } | ||
| 1398 | if (out_attr) { | ||
| 1399 | *out_attr = first_attr & static_cast<KMemoryAttribute>(~ignore_attr); | ||
| 1400 | } | 1383 | } |
| 1401 | 1384 | ||
| 1402 | return ResultSuccess; | 1385 | return ResultSuccess; |
| 1403 | } | 1386 | } |
| 1404 | 1387 | ||
| 1405 | ResultCode KPageTable::CheckMemoryState(size_t* out_blocks_needed, VAddr addr, size_t size, | 1388 | ResultCode KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, |
| 1406 | KMemoryState state_mask, KMemoryState state, | 1389 | KMemoryAttribute* out_attr, std::size_t* out_blocks_needed, |
| 1407 | KMemoryPermission perm_mask, KMemoryPermission perm, | 1390 | VAddr addr, std::size_t size, KMemoryState state_mask, |
| 1408 | KMemoryAttribute attr_mask, KMemoryAttribute attr) const { | 1391 | KMemoryState state, KMemoryPermission perm_mask, |
| 1392 | KMemoryPermission perm, KMemoryAttribute attr_mask, | ||
| 1393 | KMemoryAttribute attr, KMemoryAttribute ignore_attr) const { | ||
| 1394 | ASSERT(this->IsLockedByCurrentThread()); | ||
| 1395 | |||
| 1409 | // Get information about the first block. | 1396 | // Get information about the first block. |
| 1410 | const VAddr last_addr = addr + size - 1; | 1397 | const VAddr last_addr = addr + size - 1; |
| 1411 | KMemoryBlockManager::const_iterator it{block_manager->FindIterator(addr)}; | 1398 | KMemoryBlockManager::const_iterator it = block_manager->FindIterator(addr); |
| 1412 | KMemoryInfo info = it->GetMemoryInfo(); | 1399 | KMemoryInfo info = it->GetMemoryInfo(); |
| 1413 | 1400 | ||
| 1414 | // If the start address isn't aligned, we need a block. | 1401 | // If the start address isn't aligned, we need a block. |
| 1415 | const size_t blocks_for_start_align = | 1402 | const size_t blocks_for_start_align = |
| 1416 | (Common::AlignDown(addr, PageSize) != info.GetAddress()) ? 1 : 0; | 1403 | (Common::AlignDown(addr, PageSize) != info.GetAddress()) ? 1 : 0; |
| 1417 | 1404 | ||
| 1405 | // Validate all blocks in the range have correct state. | ||
| 1406 | const KMemoryState first_state = info.state; | ||
| 1407 | const KMemoryPermission first_perm = info.perm; | ||
| 1408 | const KMemoryAttribute first_attr = info.attribute; | ||
| 1418 | while (true) { | 1409 | while (true) { |
| 1410 | // Validate the current block. | ||
| 1411 | R_UNLESS(info.state == first_state, ResultInvalidCurrentMemory); | ||
| 1412 | R_UNLESS(info.perm == first_perm, ResultInvalidCurrentMemory); | ||
| 1413 | R_UNLESS((info.attribute | ignore_attr) == (first_attr | ignore_attr), | ||
| 1414 | ResultInvalidCurrentMemory); | ||
| 1415 | |||
| 1419 | // Validate against the provided masks. | 1416 | // Validate against the provided masks. |
| 1420 | R_TRY(CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr)); | 1417 | R_TRY(this->CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr)); |
| 1421 | 1418 | ||
| 1422 | // Break once we're done. | 1419 | // Break once we're done. |
| 1423 | if (last_addr <= info.GetLastAddress()) { | 1420 | if (last_addr <= info.GetLastAddress()) { |
| @@ -1426,6 +1423,7 @@ ResultCode KPageTable::CheckMemoryState(size_t* out_blocks_needed, VAddr addr, s | |||
| 1426 | 1423 | ||
| 1427 | // Advance our iterator. | 1424 | // Advance our iterator. |
| 1428 | it++; | 1425 | it++; |
| 1426 | ASSERT(it != block_manager->cend()); | ||
| 1429 | info = it->GetMemoryInfo(); | 1427 | info = it->GetMemoryInfo(); |
| 1430 | } | 1428 | } |
| 1431 | 1429 | ||
| @@ -1433,10 +1431,19 @@ ResultCode KPageTable::CheckMemoryState(size_t* out_blocks_needed, VAddr addr, s | |||
| 1433 | const size_t blocks_for_end_align = | 1431 | const size_t blocks_for_end_align = |
| 1434 | (Common::AlignUp(addr + size, PageSize) != info.GetEndAddress()) ? 1 : 0; | 1432 | (Common::AlignUp(addr + size, PageSize) != info.GetEndAddress()) ? 1 : 0; |
| 1435 | 1433 | ||
| 1434 | // Write output state. | ||
| 1435 | if (out_state != nullptr) { | ||
| 1436 | *out_state = first_state; | ||
| 1437 | } | ||
| 1438 | if (out_perm != nullptr) { | ||
| 1439 | *out_perm = first_perm; | ||
| 1440 | } | ||
| 1441 | if (out_attr != nullptr) { | ||
| 1442 | *out_attr = static_cast<KMemoryAttribute>(first_attr & ~ignore_attr); | ||
| 1443 | } | ||
| 1436 | if (out_blocks_needed != nullptr) { | 1444 | if (out_blocks_needed != nullptr) { |
| 1437 | *out_blocks_needed = blocks_for_start_align + blocks_for_end_align; | 1445 | *out_blocks_needed = blocks_for_start_align + blocks_for_end_align; |
| 1438 | } | 1446 | } |
| 1439 | |||
| 1440 | return ResultSuccess; | 1447 | return ResultSuccess; |
| 1441 | } | 1448 | } |
| 1442 | 1449 | ||
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h index 564410dca..07c1d18ac 100644 --- a/src/core/hle/kernel/k_page_table.h +++ b/src/core/hle/kernel/k_page_table.h | |||
| @@ -102,28 +102,50 @@ private: | |||
| 102 | constexpr VAddr GetRegionAddress(KMemoryState state) const; | 102 | constexpr VAddr GetRegionAddress(KMemoryState state) const; |
| 103 | constexpr std::size_t GetRegionSize(KMemoryState state) const; | 103 | constexpr std::size_t GetRegionSize(KMemoryState state) const; |
| 104 | 104 | ||
| 105 | constexpr ResultCode CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask, | 105 | ResultCode CheckMemoryStateContiguous(std::size_t* out_blocks_needed, VAddr addr, |
| 106 | std::size_t size, KMemoryState state_mask, | ||
| 106 | KMemoryState state, KMemoryPermission perm_mask, | 107 | KMemoryState state, KMemoryPermission perm_mask, |
| 107 | KMemoryPermission perm, KMemoryAttribute attr_mask, | 108 | KMemoryPermission perm, KMemoryAttribute attr_mask, |
| 108 | KMemoryAttribute attr) const; | 109 | KMemoryAttribute attr) const; |
| 110 | ResultCode CheckMemoryStateContiguous(VAddr addr, std::size_t size, KMemoryState state_mask, | ||
| 111 | KMemoryState state, KMemoryPermission perm_mask, | ||
| 112 | KMemoryPermission perm, KMemoryAttribute attr_mask, | ||
| 113 | KMemoryAttribute attr) const { | ||
| 114 | return this->CheckMemoryStateContiguous(nullptr, addr, size, state_mask, state, perm_mask, | ||
| 115 | perm, attr_mask, attr); | ||
| 116 | } | ||
| 117 | |||
| 118 | ResultCode CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask, | ||
| 119 | KMemoryState state, KMemoryPermission perm_mask, | ||
| 120 | KMemoryPermission perm, KMemoryAttribute attr_mask, | ||
| 121 | KMemoryAttribute attr) const; | ||
| 109 | ResultCode CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, | 122 | ResultCode CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, |
| 110 | KMemoryAttribute* out_attr, VAddr addr, std::size_t size, | 123 | KMemoryAttribute* out_attr, std::size_t* out_blocks_needed, |
| 124 | VAddr addr, std::size_t size, KMemoryState state_mask, | ||
| 125 | KMemoryState state, KMemoryPermission perm_mask, | ||
| 126 | KMemoryPermission perm, KMemoryAttribute attr_mask, | ||
| 127 | KMemoryAttribute attr, | ||
| 128 | KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const; | ||
| 129 | ResultCode CheckMemoryState(std::size_t* out_blocks_needed, VAddr addr, std::size_t size, | ||
| 111 | KMemoryState state_mask, KMemoryState state, | 130 | KMemoryState state_mask, KMemoryState state, |
| 112 | KMemoryPermission perm_mask, KMemoryPermission perm, | 131 | KMemoryPermission perm_mask, KMemoryPermission perm, |
| 113 | KMemoryAttribute attr_mask, KMemoryAttribute attr, | 132 | KMemoryAttribute attr_mask, KMemoryAttribute attr, |
| 114 | KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr); | 133 | KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const { |
| 115 | ResultCode CheckMemoryState(VAddr addr, std::size_t size, KMemoryState state_mask, | 134 | return CheckMemoryState(nullptr, nullptr, nullptr, out_blocks_needed, addr, size, |
| 135 | state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr); | ||
| 136 | } | ||
| 137 | ResultCode CheckMemoryState(VAddr addr, size_t size, KMemoryState state_mask, | ||
| 116 | KMemoryState state, KMemoryPermission perm_mask, | 138 | KMemoryState state, KMemoryPermission perm_mask, |
| 117 | KMemoryPermission perm, KMemoryAttribute attr_mask, | 139 | KMemoryPermission perm, KMemoryAttribute attr_mask, |
| 118 | KMemoryAttribute attr, | 140 | KMemoryAttribute attr, |
| 119 | KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) { | 141 | KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const { |
| 120 | return CheckMemoryState(nullptr, nullptr, nullptr, addr, size, state_mask, state, perm_mask, | 142 | return this->CheckMemoryState(nullptr, addr, size, state_mask, state, perm_mask, perm, |
| 121 | perm, attr_mask, attr, ignore_attr); | 143 | attr_mask, attr, ignore_attr); |
| 144 | } | ||
| 145 | |||
| 146 | bool IsLockedByCurrentThread() const { | ||
| 147 | return true; | ||
| 122 | } | 148 | } |
| 123 | ResultCode CheckMemoryState(size_t* out_blocks_needed, VAddr addr, size_t size, | ||
| 124 | KMemoryState state_mask, KMemoryState state, | ||
| 125 | KMemoryPermission perm_mask, KMemoryPermission perm, | ||
| 126 | KMemoryAttribute attr_mask, KMemoryAttribute attr) const; | ||
| 127 | 149 | ||
| 128 | std::recursive_mutex page_table_lock; | 150 | std::recursive_mutex page_table_lock; |
| 129 | std::unique_ptr<KMemoryBlockManager> block_manager; | 151 | std::unique_ptr<KMemoryBlockManager> block_manager; |
diff --git a/src/core/hle/kernel/svc_types.h b/src/core/hle/kernel/svc_types.h index ec463b97c..365e22e4e 100644 --- a/src/core/hle/kernel/svc_types.h +++ b/src/core/hle/kernel/svc_types.h | |||
| @@ -32,6 +32,7 @@ enum class MemoryState : u32 { | |||
| 32 | Kernel = 0x13, | 32 | Kernel = 0x13, |
| 33 | GeneratedCode = 0x14, | 33 | GeneratedCode = 0x14, |
| 34 | CodeOut = 0x15, | 34 | CodeOut = 0x15, |
| 35 | Coverage = 0x16, | ||
| 35 | }; | 36 | }; |
| 36 | DECLARE_ENUM_FLAG_OPERATORS(MemoryState); | 37 | DECLARE_ENUM_FLAG_OPERATORS(MemoryState); |
| 37 | 38 | ||