diff options
| author | 2021-02-12 17:02:51 -0800 | |
|---|---|---|
| committer | 2021-02-18 16:16:25 -0800 | |
| commit | 65e0178cc09299550aee949d7b89e211017bddee (patch) | |
| tree | 97abf71a48320fc5628b4946d793191f2fb9dbb0 | |
| parent | hle: kernel: Migrate SlabHeap to KSlabHeap. (diff) | |
| download | yuzu-65e0178cc09299550aee949d7b89e211017bddee.tar.gz yuzu-65e0178cc09299550aee949d7b89e211017bddee.tar.xz yuzu-65e0178cc09299550aee949d7b89e211017bddee.zip | |
hle: kernel: Migrate to KMemoryBlock, KMemoryBlockManager, and others.
Diffstat (limited to '')
18 files changed, 479 insertions, 476 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index a2dce69a7..a304dd935 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -166,6 +166,9 @@ add_library(core STATIC | |||
| 166 | hle/kernel/k_light_condition_variable.h | 166 | hle/kernel/k_light_condition_variable.h |
| 167 | hle/kernel/k_light_lock.cpp | 167 | hle/kernel/k_light_lock.cpp |
| 168 | hle/kernel/k_light_lock.h | 168 | hle/kernel/k_light_lock.h |
| 169 | hle/kernel/k_memory_block.h | ||
| 170 | hle/kernel/k_memory_block_manager.cpp | ||
| 171 | hle/kernel/k_memory_block_manager.h | ||
| 169 | hle/kernel/k_memory_layout.h | 172 | hle/kernel/k_memory_layout.h |
| 170 | hle/kernel/k_page_bitmap.h | 173 | hle/kernel/k_page_bitmap.h |
| 171 | hle/kernel/k_priority_queue.h | 174 | hle/kernel/k_priority_queue.h |
| @@ -195,12 +198,9 @@ add_library(core STATIC | |||
| 195 | hle/kernel/k_writable_event.h | 198 | hle/kernel/k_writable_event.h |
| 196 | hle/kernel/kernel.cpp | 199 | hle/kernel/kernel.cpp |
| 197 | hle/kernel/kernel.h | 200 | hle/kernel/kernel.h |
| 198 | hle/kernel/memory/memory_block.h | 201 | hle/kernel/memory_types.h |
| 199 | hle/kernel/memory/memory_block_manager.cpp | ||
| 200 | hle/kernel/memory/memory_block_manager.h | ||
| 201 | hle/kernel/memory/memory_manager.cpp | 202 | hle/kernel/memory/memory_manager.cpp |
| 202 | hle/kernel/memory/memory_manager.h | 203 | hle/kernel/memory/memory_manager.h |
| 203 | hle/kernel/memory/memory_types.h | ||
| 204 | hle/kernel/memory/page_linked_list.h | 204 | hle/kernel/memory/page_linked_list.h |
| 205 | hle/kernel/memory/page_heap.cpp | 205 | hle/kernel/memory/page_heap.cpp |
| 206 | hle/kernel/memory/page_heap.h | 206 | hle/kernel/memory/page_heap.h |
diff --git a/src/core/hle/kernel/memory/memory_block.h b/src/core/hle/kernel/k_memory_block.h index 83acece1e..c5b9c5e85 100644 --- a/src/core/hle/kernel/memory/memory_block.h +++ b/src/core/hle/kernel/k_memory_block.h | |||
| @@ -2,20 +2,17 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | // This file references various implementation details from Atmosphere, an open-source firmware for | ||
| 6 | // the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. | ||
| 7 | |||
| 8 | #pragma once | 5 | #pragma once |
| 9 | 6 | ||
| 10 | #include "common/alignment.h" | 7 | #include "common/alignment.h" |
| 11 | #include "common/assert.h" | 8 | #include "common/assert.h" |
| 12 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 13 | #include "core/hle/kernel/memory/memory_types.h" | 10 | #include "core/hle/kernel/memory_types.h" |
| 14 | #include "core/hle/kernel/svc_types.h" | 11 | #include "core/hle/kernel/svc_types.h" |
| 15 | 12 | ||
| 16 | namespace Kernel::Memory { | 13 | namespace Kernel { |
| 17 | 14 | ||
| 18 | enum class MemoryState : u32 { | 15 | enum class KMemoryState : u32 { |
| 19 | None = 0, | 16 | None = 0, |
| 20 | Mask = 0xFF, | 17 | Mask = 0xFF, |
| 21 | All = ~None, | 18 | All = ~None, |
| @@ -97,31 +94,31 @@ enum class MemoryState : u32 { | |||
| 97 | FlagReferenceCounted | FlagCanDebug, | 94 | FlagReferenceCounted | FlagCanDebug, |
| 98 | CodeOut = static_cast<u32>(Svc::MemoryState::CodeOut) | FlagMapped | FlagReferenceCounted, | 95 | CodeOut = static_cast<u32>(Svc::MemoryState::CodeOut) | FlagMapped | FlagReferenceCounted, |
| 99 | }; | 96 | }; |
| 100 | DECLARE_ENUM_FLAG_OPERATORS(MemoryState); | 97 | DECLARE_ENUM_FLAG_OPERATORS(KMemoryState); |
| 101 | 98 | ||
| 102 | static_assert(static_cast<u32>(MemoryState::Free) == 0x00000000); | 99 | static_assert(static_cast<u32>(KMemoryState::Free) == 0x00000000); |
| 103 | static_assert(static_cast<u32>(MemoryState::Io) == 0x00002001); | 100 | static_assert(static_cast<u32>(KMemoryState::Io) == 0x00002001); |
| 104 | static_assert(static_cast<u32>(MemoryState::Static) == 0x00042002); | 101 | static_assert(static_cast<u32>(KMemoryState::Static) == 0x00042002); |
| 105 | static_assert(static_cast<u32>(MemoryState::Code) == 0x00DC7E03); | 102 | static_assert(static_cast<u32>(KMemoryState::Code) == 0x00DC7E03); |
| 106 | static_assert(static_cast<u32>(MemoryState::CodeData) == 0x03FEBD04); | 103 | static_assert(static_cast<u32>(KMemoryState::CodeData) == 0x03FEBD04); |
| 107 | static_assert(static_cast<u32>(MemoryState::Normal) == 0x037EBD05); | 104 | static_assert(static_cast<u32>(KMemoryState::Normal) == 0x037EBD05); |
| 108 | static_assert(static_cast<u32>(MemoryState::Shared) == 0x00402006); | 105 | static_assert(static_cast<u32>(KMemoryState::Shared) == 0x00402006); |
| 109 | static_assert(static_cast<u32>(MemoryState::AliasCode) == 0x00DD7E08); | 106 | static_assert(static_cast<u32>(KMemoryState::AliasCode) == 0x00DD7E08); |
| 110 | static_assert(static_cast<u32>(MemoryState::AliasCodeData) == 0x03FFBD09); | 107 | static_assert(static_cast<u32>(KMemoryState::AliasCodeData) == 0x03FFBD09); |
| 111 | static_assert(static_cast<u32>(MemoryState::Ipc) == 0x005C3C0A); | 108 | static_assert(static_cast<u32>(KMemoryState::Ipc) == 0x005C3C0A); |
| 112 | static_assert(static_cast<u32>(MemoryState::Stack) == 0x005C3C0B); | 109 | static_assert(static_cast<u32>(KMemoryState::Stack) == 0x005C3C0B); |
| 113 | static_assert(static_cast<u32>(MemoryState::ThreadLocal) == 0x0040200C); | 110 | static_assert(static_cast<u32>(KMemoryState::ThreadLocal) == 0x0040200C); |
| 114 | static_assert(static_cast<u32>(MemoryState::Transferred) == 0x015C3C0D); | 111 | static_assert(static_cast<u32>(KMemoryState::Transferred) == 0x015C3C0D); |
| 115 | static_assert(static_cast<u32>(MemoryState::SharedTransferred) == 0x005C380E); | 112 | static_assert(static_cast<u32>(KMemoryState::SharedTransferred) == 0x005C380E); |
| 116 | static_assert(static_cast<u32>(MemoryState::SharedCode) == 0x0040380F); | 113 | static_assert(static_cast<u32>(KMemoryState::SharedCode) == 0x0040380F); |
| 117 | static_assert(static_cast<u32>(MemoryState::Inaccessible) == 0x00000010); | 114 | static_assert(static_cast<u32>(KMemoryState::Inaccessible) == 0x00000010); |
| 118 | static_assert(static_cast<u32>(MemoryState::NonSecureIpc) == 0x005C3811); | 115 | static_assert(static_cast<u32>(KMemoryState::NonSecureIpc) == 0x005C3811); |
| 119 | static_assert(static_cast<u32>(MemoryState::NonDeviceIpc) == 0x004C2812); | 116 | static_assert(static_cast<u32>(KMemoryState::NonDeviceIpc) == 0x004C2812); |
| 120 | static_assert(static_cast<u32>(MemoryState::Kernel) == 0x00002013); | 117 | static_assert(static_cast<u32>(KMemoryState::Kernel) == 0x00002013); |
| 121 | static_assert(static_cast<u32>(MemoryState::GeneratedCode) == 0x00402214); | 118 | static_assert(static_cast<u32>(KMemoryState::GeneratedCode) == 0x00402214); |
| 122 | static_assert(static_cast<u32>(MemoryState::CodeOut) == 0x00402015); | 119 | static_assert(static_cast<u32>(KMemoryState::CodeOut) == 0x00402015); |
| 123 | 120 | ||
| 124 | enum class MemoryPermission : u8 { | 121 | enum class KMemoryPermission : u8 { |
| 125 | None = 0, | 122 | None = 0, |
| 126 | Mask = static_cast<u8>(~None), | 123 | Mask = static_cast<u8>(~None), |
| 127 | 124 | ||
| @@ -135,9 +132,9 @@ enum class MemoryPermission : u8 { | |||
| 135 | UserMask = static_cast<u8>(Svc::MemoryPermission::Read | Svc::MemoryPermission::Write | | 132 | UserMask = static_cast<u8>(Svc::MemoryPermission::Read | Svc::MemoryPermission::Write | |
| 136 | Svc::MemoryPermission::Execute), | 133 | Svc::MemoryPermission::Execute), |
| 137 | }; | 134 | }; |
| 138 | DECLARE_ENUM_FLAG_OPERATORS(MemoryPermission); | 135 | DECLARE_ENUM_FLAG_OPERATORS(KMemoryPermission); |
| 139 | 136 | ||
| 140 | enum class MemoryAttribute : u8 { | 137 | enum class KMemoryAttribute : u8 { |
| 141 | None = 0x00, | 138 | None = 0x00, |
| 142 | Mask = 0x7F, | 139 | Mask = 0x7F, |
| 143 | All = Mask, | 140 | All = Mask, |
| @@ -152,18 +149,18 @@ enum class MemoryAttribute : u8 { | |||
| 152 | LockedAndIpcLocked = Locked | IpcLocked, | 149 | LockedAndIpcLocked = Locked | IpcLocked, |
| 153 | DeviceSharedAndUncached = DeviceShared | Uncached | 150 | DeviceSharedAndUncached = DeviceShared | Uncached |
| 154 | }; | 151 | }; |
| 155 | DECLARE_ENUM_FLAG_OPERATORS(MemoryAttribute); | 152 | DECLARE_ENUM_FLAG_OPERATORS(KMemoryAttribute); |
| 156 | 153 | ||
| 157 | static_assert((static_cast<u8>(MemoryAttribute::Mask) & | 154 | static_assert((static_cast<u8>(KMemoryAttribute::Mask) & |
| 158 | static_cast<u8>(MemoryAttribute::DontCareMask)) == 0); | 155 | static_cast<u8>(KMemoryAttribute::DontCareMask)) == 0); |
| 159 | 156 | ||
| 160 | struct MemoryInfo { | 157 | struct KMemoryInfo { |
| 161 | VAddr addr{}; | 158 | VAddr addr{}; |
| 162 | std::size_t size{}; | 159 | std::size_t size{}; |
| 163 | MemoryState state{}; | 160 | KMemoryState state{}; |
| 164 | MemoryPermission perm{}; | 161 | KMemoryPermission perm{}; |
| 165 | MemoryAttribute attribute{}; | 162 | KMemoryAttribute attribute{}; |
| 166 | MemoryPermission original_perm{}; | 163 | KMemoryPermission original_perm{}; |
| 167 | u16 ipc_lock_count{}; | 164 | u16 ipc_lock_count{}; |
| 168 | u16 device_use_count{}; | 165 | u16 device_use_count{}; |
| 169 | 166 | ||
| @@ -171,9 +168,9 @@ struct MemoryInfo { | |||
| 171 | return { | 168 | return { |
| 172 | addr, | 169 | addr, |
| 173 | size, | 170 | size, |
| 174 | static_cast<Svc::MemoryState>(state & MemoryState::Mask), | 171 | static_cast<Svc::MemoryState>(state & KMemoryState::Mask), |
| 175 | static_cast<Svc::MemoryAttribute>(attribute & MemoryAttribute::Mask), | 172 | static_cast<Svc::MemoryAttribute>(attribute & KMemoryAttribute::Mask), |
| 176 | static_cast<Svc::MemoryPermission>(perm & MemoryPermission::UserMask), | 173 | static_cast<Svc::MemoryPermission>(perm & KMemoryPermission::UserMask), |
| 177 | ipc_lock_count, | 174 | ipc_lock_count, |
| 178 | device_use_count, | 175 | device_use_count, |
| 179 | }; | 176 | }; |
| @@ -196,21 +193,21 @@ struct MemoryInfo { | |||
| 196 | } | 193 | } |
| 197 | }; | 194 | }; |
| 198 | 195 | ||
| 199 | class MemoryBlock final { | 196 | class KMemoryBlock final { |
| 200 | friend class MemoryBlockManager; | 197 | friend class KMemoryBlockManager; |
| 201 | 198 | ||
| 202 | private: | 199 | private: |
| 203 | VAddr addr{}; | 200 | VAddr addr{}; |
| 204 | std::size_t num_pages{}; | 201 | std::size_t num_pages{}; |
| 205 | MemoryState state{MemoryState::None}; | 202 | KMemoryState state{KMemoryState::None}; |
| 206 | u16 ipc_lock_count{}; | 203 | u16 ipc_lock_count{}; |
| 207 | u16 device_use_count{}; | 204 | u16 device_use_count{}; |
| 208 | MemoryPermission perm{MemoryPermission::None}; | 205 | KMemoryPermission perm{KMemoryPermission::None}; |
| 209 | MemoryPermission original_perm{MemoryPermission::None}; | 206 | KMemoryPermission original_perm{KMemoryPermission::None}; |
| 210 | MemoryAttribute attribute{MemoryAttribute::None}; | 207 | KMemoryAttribute attribute{KMemoryAttribute::None}; |
| 211 | 208 | ||
| 212 | public: | 209 | public: |
| 213 | static constexpr int Compare(const MemoryBlock& lhs, const MemoryBlock& rhs) { | 210 | static constexpr int Compare(const KMemoryBlock& lhs, const KMemoryBlock& rhs) { |
| 214 | if (lhs.GetAddress() < rhs.GetAddress()) { | 211 | if (lhs.GetAddress() < rhs.GetAddress()) { |
| 215 | return -1; | 212 | return -1; |
| 216 | } else if (lhs.GetAddress() <= rhs.GetLastAddress()) { | 213 | } else if (lhs.GetAddress() <= rhs.GetLastAddress()) { |
| @@ -221,9 +218,9 @@ public: | |||
| 221 | } | 218 | } |
| 222 | 219 | ||
| 223 | public: | 220 | public: |
| 224 | constexpr MemoryBlock() = default; | 221 | constexpr KMemoryBlock() = default; |
| 225 | constexpr MemoryBlock(VAddr addr_, std::size_t num_pages_, MemoryState state_, | 222 | constexpr KMemoryBlock(VAddr addr_, std::size_t num_pages_, KMemoryState state_, |
| 226 | MemoryPermission perm_, MemoryAttribute attribute_) | 223 | KMemoryPermission perm_, KMemoryAttribute attribute_) |
| 227 | : addr{addr_}, num_pages(num_pages_), state{state_}, perm{perm_}, attribute{attribute_} {} | 224 | : addr{addr_}, num_pages(num_pages_), state{state_}, perm{perm_}, attribute{attribute_} {} |
| 228 | 225 | ||
| 229 | constexpr VAddr GetAddress() const { | 226 | constexpr VAddr GetAddress() const { |
| @@ -246,40 +243,40 @@ public: | |||
| 246 | return GetEndAddress() - 1; | 243 | return GetEndAddress() - 1; |
| 247 | } | 244 | } |
| 248 | 245 | ||
| 249 | constexpr MemoryInfo GetMemoryInfo() const { | 246 | constexpr KMemoryInfo GetMemoryInfo() const { |
| 250 | return { | 247 | return { |
| 251 | GetAddress(), GetSize(), state, perm, | 248 | GetAddress(), GetSize(), state, perm, |
| 252 | attribute, original_perm, ipc_lock_count, device_use_count, | 249 | attribute, original_perm, ipc_lock_count, device_use_count, |
| 253 | }; | 250 | }; |
| 254 | } | 251 | } |
| 255 | 252 | ||
| 256 | void ShareToDevice(MemoryPermission /*new_perm*/) { | 253 | void ShareToDevice(KMemoryPermission /*new_perm*/) { |
| 257 | ASSERT((attribute & MemoryAttribute::DeviceShared) == MemoryAttribute::DeviceShared || | 254 | ASSERT((attribute & KMemoryAttribute::DeviceShared) == KMemoryAttribute::DeviceShared || |
| 258 | device_use_count == 0); | 255 | device_use_count == 0); |
| 259 | attribute |= MemoryAttribute::DeviceShared; | 256 | attribute |= KMemoryAttribute::DeviceShared; |
| 260 | const u16 new_use_count{++device_use_count}; | 257 | const u16 new_use_count{++device_use_count}; |
| 261 | ASSERT(new_use_count > 0); | 258 | ASSERT(new_use_count > 0); |
| 262 | } | 259 | } |
| 263 | 260 | ||
| 264 | void UnshareToDevice(MemoryPermission /*new_perm*/) { | 261 | void UnshareToDevice(KMemoryPermission /*new_perm*/) { |
| 265 | ASSERT((attribute & MemoryAttribute::DeviceShared) == MemoryAttribute::DeviceShared); | 262 | ASSERT((attribute & KMemoryAttribute::DeviceShared) == KMemoryAttribute::DeviceShared); |
| 266 | const u16 prev_use_count{device_use_count--}; | 263 | const u16 prev_use_count{device_use_count--}; |
| 267 | ASSERT(prev_use_count > 0); | 264 | ASSERT(prev_use_count > 0); |
| 268 | if (prev_use_count == 1) { | 265 | if (prev_use_count == 1) { |
| 269 | attribute &= ~MemoryAttribute::DeviceShared; | 266 | attribute &= ~KMemoryAttribute::DeviceShared; |
| 270 | } | 267 | } |
| 271 | } | 268 | } |
| 272 | 269 | ||
| 273 | private: | 270 | private: |
| 274 | constexpr bool HasProperties(MemoryState s, MemoryPermission p, MemoryAttribute a) const { | 271 | constexpr bool HasProperties(KMemoryState s, KMemoryPermission p, KMemoryAttribute a) const { |
| 275 | constexpr MemoryAttribute AttributeIgnoreMask{MemoryAttribute::DontCareMask | | 272 | constexpr KMemoryAttribute AttributeIgnoreMask{KMemoryAttribute::DontCareMask | |
| 276 | MemoryAttribute::IpcLocked | | 273 | KMemoryAttribute::IpcLocked | |
| 277 | MemoryAttribute::DeviceShared}; | 274 | KMemoryAttribute::DeviceShared}; |
| 278 | return state == s && perm == p && | 275 | return state == s && perm == p && |
| 279 | (attribute | AttributeIgnoreMask) == (a | AttributeIgnoreMask); | 276 | (attribute | AttributeIgnoreMask) == (a | AttributeIgnoreMask); |
| 280 | } | 277 | } |
| 281 | 278 | ||
| 282 | constexpr bool HasSameProperties(const MemoryBlock& rhs) const { | 279 | constexpr bool HasSameProperties(const KMemoryBlock& rhs) const { |
| 283 | return state == rhs.state && perm == rhs.perm && original_perm == rhs.original_perm && | 280 | return state == rhs.state && perm == rhs.perm && original_perm == rhs.original_perm && |
| 284 | attribute == rhs.attribute && ipc_lock_count == rhs.ipc_lock_count && | 281 | attribute == rhs.attribute && ipc_lock_count == rhs.ipc_lock_count && |
| 285 | device_use_count == rhs.device_use_count; | 282 | device_use_count == rhs.device_use_count; |
| @@ -296,25 +293,25 @@ private: | |||
| 296 | num_pages += count; | 293 | num_pages += count; |
| 297 | } | 294 | } |
| 298 | 295 | ||
| 299 | constexpr void Update(MemoryState new_state, MemoryPermission new_perm, | 296 | constexpr void Update(KMemoryState new_state, KMemoryPermission new_perm, |
| 300 | MemoryAttribute new_attribute) { | 297 | KMemoryAttribute new_attribute) { |
| 301 | ASSERT(original_perm == MemoryPermission::None); | 298 | ASSERT(original_perm == KMemoryPermission::None); |
| 302 | ASSERT((attribute & MemoryAttribute::IpcLocked) == MemoryAttribute::None); | 299 | ASSERT((attribute & KMemoryAttribute::IpcLocked) == KMemoryAttribute::None); |
| 303 | 300 | ||
| 304 | state = new_state; | 301 | state = new_state; |
| 305 | perm = new_perm; | 302 | perm = new_perm; |
| 306 | 303 | ||
| 307 | attribute = static_cast<MemoryAttribute>( | 304 | attribute = static_cast<KMemoryAttribute>( |
| 308 | new_attribute | | 305 | new_attribute | |
| 309 | (attribute & (MemoryAttribute::IpcLocked | MemoryAttribute::DeviceShared))); | 306 | (attribute & (KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared))); |
| 310 | } | 307 | } |
| 311 | 308 | ||
| 312 | constexpr MemoryBlock Split(VAddr split_addr) { | 309 | constexpr KMemoryBlock Split(VAddr split_addr) { |
| 313 | ASSERT(GetAddress() < split_addr); | 310 | ASSERT(GetAddress() < split_addr); |
| 314 | ASSERT(Contains(split_addr)); | 311 | ASSERT(Contains(split_addr)); |
| 315 | ASSERT(Common::IsAligned(split_addr, PageSize)); | 312 | ASSERT(Common::IsAligned(split_addr, PageSize)); |
| 316 | 313 | ||
| 317 | MemoryBlock block; | 314 | KMemoryBlock block; |
| 318 | block.addr = addr; | 315 | block.addr = addr; |
| 319 | block.num_pages = (split_addr - GetAddress()) / PageSize; | 316 | block.num_pages = (split_addr - GetAddress()) / PageSize; |
| 320 | block.state = state; | 317 | block.state = state; |
| @@ -330,6 +327,6 @@ private: | |||
| 330 | return block; | 327 | return block; |
| 331 | } | 328 | } |
| 332 | }; | 329 | }; |
| 333 | static_assert(std::is_trivially_destructible<MemoryBlock>::value); | 330 | static_assert(std::is_trivially_destructible<KMemoryBlock>::value); |
| 334 | 331 | ||
| 335 | } // namespace Kernel::Memory | 332 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/memory/memory_block_manager.cpp b/src/core/hle/kernel/k_memory_block_manager.cpp index 0732fa5a1..4a2d88008 100644 --- a/src/core/hle/kernel/memory/memory_block_manager.cpp +++ b/src/core/hle/kernel/k_memory_block_manager.cpp | |||
| @@ -2,19 +2,19 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "core/hle/kernel/memory/memory_block_manager.h" | 5 | #include "core/hle/kernel/k_memory_block_manager.h" |
| 6 | #include "core/hle/kernel/memory/memory_types.h" | 6 | #include "core/hle/kernel/memory_types.h" |
| 7 | 7 | ||
| 8 | namespace Kernel::Memory { | 8 | namespace Kernel { |
| 9 | 9 | ||
| 10 | MemoryBlockManager::MemoryBlockManager(VAddr start_addr, VAddr end_addr) | 10 | KMemoryBlockManager::KMemoryBlockManager(VAddr start_addr, VAddr end_addr) |
| 11 | : start_addr{start_addr}, end_addr{end_addr} { | 11 | : start_addr{start_addr}, end_addr{end_addr} { |
| 12 | const u64 num_pages{(end_addr - start_addr) / PageSize}; | 12 | const u64 num_pages{(end_addr - start_addr) / PageSize}; |
| 13 | memory_block_tree.emplace_back(start_addr, num_pages, MemoryState::Free, MemoryPermission::None, | 13 | memory_block_tree.emplace_back(start_addr, num_pages, KMemoryState::Free, |
| 14 | MemoryAttribute::None); | 14 | KMemoryPermission::None, KMemoryAttribute::None); |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | MemoryBlockManager::iterator MemoryBlockManager::FindIterator(VAddr addr) { | 17 | KMemoryBlockManager::iterator KMemoryBlockManager::FindIterator(VAddr addr) { |
| 18 | auto node{memory_block_tree.begin()}; | 18 | auto node{memory_block_tree.begin()}; |
| 19 | while (node != end()) { | 19 | while (node != end()) { |
| 20 | const VAddr end_addr{node->GetNumPages() * PageSize + node->GetAddress()}; | 20 | const VAddr end_addr{node->GetNumPages() * PageSize + node->GetAddress()}; |
| @@ -26,9 +26,9 @@ MemoryBlockManager::iterator MemoryBlockManager::FindIterator(VAddr addr) { | |||
| 26 | return end(); | 26 | return end(); |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | VAddr MemoryBlockManager::FindFreeArea(VAddr region_start, std::size_t region_num_pages, | 29 | VAddr KMemoryBlockManager::FindFreeArea(VAddr region_start, std::size_t region_num_pages, |
| 30 | std::size_t num_pages, std::size_t align, std::size_t offset, | 30 | std::size_t num_pages, std::size_t align, |
| 31 | std::size_t guard_pages) { | 31 | std::size_t offset, std::size_t guard_pages) { |
| 32 | if (num_pages == 0) { | 32 | if (num_pages == 0) { |
| 33 | return {}; | 33 | return {}; |
| 34 | } | 34 | } |
| @@ -41,7 +41,7 @@ VAddr MemoryBlockManager::FindFreeArea(VAddr region_start, std::size_t region_nu | |||
| 41 | break; | 41 | break; |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | if (info.state != MemoryState::Free) { | 44 | if (info.state != KMemoryState::Free) { |
| 45 | continue; | 45 | continue; |
| 46 | } | 46 | } |
| 47 | 47 | ||
| @@ -63,17 +63,17 @@ VAddr MemoryBlockManager::FindFreeArea(VAddr region_start, std::size_t region_nu | |||
| 63 | return {}; | 63 | return {}; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | void MemoryBlockManager::Update(VAddr addr, std::size_t num_pages, MemoryState prev_state, | 66 | void KMemoryBlockManager::Update(VAddr addr, std::size_t num_pages, KMemoryState prev_state, |
| 67 | MemoryPermission prev_perm, MemoryAttribute prev_attribute, | 67 | KMemoryPermission prev_perm, KMemoryAttribute prev_attribute, |
| 68 | MemoryState state, MemoryPermission perm, | 68 | KMemoryState state, KMemoryPermission perm, |
| 69 | MemoryAttribute attribute) { | 69 | KMemoryAttribute attribute) { |
| 70 | const VAddr end_addr{addr + num_pages * PageSize}; | 70 | const VAddr end_addr{addr + num_pages * PageSize}; |
| 71 | iterator node{memory_block_tree.begin()}; | 71 | iterator node{memory_block_tree.begin()}; |
| 72 | 72 | ||
| 73 | prev_attribute |= MemoryAttribute::IpcAndDeviceMapped; | 73 | prev_attribute |= KMemoryAttribute::IpcAndDeviceMapped; |
| 74 | 74 | ||
| 75 | while (node != memory_block_tree.end()) { | 75 | while (node != memory_block_tree.end()) { |
| 76 | MemoryBlock* block{&(*node)}; | 76 | KMemoryBlock* block{&(*node)}; |
| 77 | iterator next_node{std::next(node)}; | 77 | iterator next_node{std::next(node)}; |
| 78 | const VAddr cur_addr{block->GetAddress()}; | 78 | const VAddr cur_addr{block->GetAddress()}; |
| 79 | const VAddr cur_end_addr{block->GetNumPages() * PageSize + cur_addr}; | 79 | const VAddr cur_end_addr{block->GetNumPages() * PageSize + cur_addr}; |
| @@ -106,13 +106,13 @@ void MemoryBlockManager::Update(VAddr addr, std::size_t num_pages, MemoryState p | |||
| 106 | } | 106 | } |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | void MemoryBlockManager::Update(VAddr addr, std::size_t num_pages, MemoryState state, | 109 | void KMemoryBlockManager::Update(VAddr addr, std::size_t num_pages, KMemoryState state, |
| 110 | MemoryPermission perm, MemoryAttribute attribute) { | 110 | KMemoryPermission perm, KMemoryAttribute attribute) { |
| 111 | const VAddr end_addr{addr + num_pages * PageSize}; | 111 | const VAddr end_addr{addr + num_pages * PageSize}; |
| 112 | iterator node{memory_block_tree.begin()}; | 112 | iterator node{memory_block_tree.begin()}; |
| 113 | 113 | ||
| 114 | while (node != memory_block_tree.end()) { | 114 | while (node != memory_block_tree.end()) { |
| 115 | MemoryBlock* block{&(*node)}; | 115 | KMemoryBlock* block{&(*node)}; |
| 116 | iterator next_node{std::next(node)}; | 116 | iterator next_node{std::next(node)}; |
| 117 | const VAddr cur_addr{block->GetAddress()}; | 117 | const VAddr cur_addr{block->GetAddress()}; |
| 118 | const VAddr cur_end_addr{block->GetNumPages() * PageSize + cur_addr}; | 118 | const VAddr cur_end_addr{block->GetNumPages() * PageSize + cur_addr}; |
| @@ -141,13 +141,13 @@ void MemoryBlockManager::Update(VAddr addr, std::size_t num_pages, MemoryState s | |||
| 141 | } | 141 | } |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | void MemoryBlockManager::UpdateLock(VAddr addr, std::size_t num_pages, LockFunc&& lock_func, | 144 | void KMemoryBlockManager::UpdateLock(VAddr addr, std::size_t num_pages, LockFunc&& lock_func, |
| 145 | MemoryPermission perm) { | 145 | KMemoryPermission perm) { |
| 146 | const VAddr end_addr{addr + num_pages * PageSize}; | 146 | const VAddr end_addr{addr + num_pages * PageSize}; |
| 147 | iterator node{memory_block_tree.begin()}; | 147 | iterator node{memory_block_tree.begin()}; |
| 148 | 148 | ||
| 149 | while (node != memory_block_tree.end()) { | 149 | while (node != memory_block_tree.end()) { |
| 150 | MemoryBlock* block{&(*node)}; | 150 | KMemoryBlock* block{&(*node)}; |
| 151 | iterator next_node{std::next(node)}; | 151 | iterator next_node{std::next(node)}; |
| 152 | const VAddr cur_addr{block->GetAddress()}; | 152 | const VAddr cur_addr{block->GetAddress()}; |
| 153 | const VAddr cur_end_addr{block->GetNumPages() * PageSize + cur_addr}; | 153 | const VAddr cur_end_addr{block->GetNumPages() * PageSize + cur_addr}; |
| @@ -176,9 +176,9 @@ void MemoryBlockManager::UpdateLock(VAddr addr, std::size_t num_pages, LockFunc& | |||
| 176 | } | 176 | } |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | void MemoryBlockManager::IterateForRange(VAddr start, VAddr end, IterateFunc&& func) { | 179 | void KMemoryBlockManager::IterateForRange(VAddr start, VAddr end, IterateFunc&& func) { |
| 180 | const_iterator it{FindIterator(start)}; | 180 | const_iterator it{FindIterator(start)}; |
| 181 | MemoryInfo info{}; | 181 | KMemoryInfo info{}; |
| 182 | do { | 182 | do { |
| 183 | info = it->GetMemoryInfo(); | 183 | info = it->GetMemoryInfo(); |
| 184 | func(info); | 184 | func(info); |
| @@ -186,8 +186,8 @@ void MemoryBlockManager::IterateForRange(VAddr start, VAddr end, IterateFunc&& f | |||
| 186 | } while (info.addr + info.size - 1 < end - 1 && it != cend()); | 186 | } while (info.addr + info.size - 1 < end - 1 && it != cend()); |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | void MemoryBlockManager::MergeAdjacent(iterator it, iterator& next_it) { | 189 | void KMemoryBlockManager::MergeAdjacent(iterator it, iterator& next_it) { |
| 190 | MemoryBlock* block{&(*it)}; | 190 | KMemoryBlock* block{&(*it)}; |
| 191 | 191 | ||
| 192 | auto EraseIt = [&](const iterator it_to_erase) { | 192 | auto EraseIt = [&](const iterator it_to_erase) { |
| 193 | if (next_it == it_to_erase) { | 193 | if (next_it == it_to_erase) { |
| @@ -197,7 +197,7 @@ void MemoryBlockManager::MergeAdjacent(iterator it, iterator& next_it) { | |||
| 197 | }; | 197 | }; |
| 198 | 198 | ||
| 199 | if (it != memory_block_tree.begin()) { | 199 | if (it != memory_block_tree.begin()) { |
| 200 | MemoryBlock* prev{&(*std::prev(it))}; | 200 | KMemoryBlock* prev{&(*std::prev(it))}; |
| 201 | 201 | ||
| 202 | if (block->HasSameProperties(*prev)) { | 202 | if (block->HasSameProperties(*prev)) { |
| 203 | const iterator prev_it{std::prev(it)}; | 203 | const iterator prev_it{std::prev(it)}; |
| @@ -211,7 +211,7 @@ void MemoryBlockManager::MergeAdjacent(iterator it, iterator& next_it) { | |||
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | if (it != cend()) { | 213 | if (it != cend()) { |
| 214 | const MemoryBlock* const next{&(*std::next(it))}; | 214 | const KMemoryBlock* const next{&(*std::next(it))}; |
| 215 | 215 | ||
| 216 | if (block->HasSameProperties(*next)) { | 216 | if (block->HasSameProperties(*next)) { |
| 217 | block->Add(next->GetNumPages()); | 217 | block->Add(next->GetNumPages()); |
| @@ -220,4 +220,4 @@ void MemoryBlockManager::MergeAdjacent(iterator it, iterator& next_it) { | |||
| 220 | } | 220 | } |
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | } // namespace Kernel::Memory | 223 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/memory/memory_block_manager.h b/src/core/hle/kernel/k_memory_block_manager.h index f57d1bbcc..e11cc70c8 100644 --- a/src/core/hle/kernel/memory/memory_block_manager.h +++ b/src/core/hle/kernel/k_memory_block_manager.h | |||
| @@ -8,18 +8,18 @@ | |||
| 8 | #include <list> | 8 | #include <list> |
| 9 | 9 | ||
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "core/hle/kernel/memory/memory_block.h" | 11 | #include "core/hle/kernel/k_memory_block.h" |
| 12 | 12 | ||
| 13 | namespace Kernel::Memory { | 13 | namespace Kernel { |
| 14 | 14 | ||
| 15 | class MemoryBlockManager final { | 15 | class KMemoryBlockManager final { |
| 16 | public: | 16 | public: |
| 17 | using MemoryBlockTree = std::list<MemoryBlock>; | 17 | using MemoryBlockTree = std::list<KMemoryBlock>; |
| 18 | using iterator = MemoryBlockTree::iterator; | 18 | using iterator = MemoryBlockTree::iterator; |
| 19 | using const_iterator = MemoryBlockTree::const_iterator; | 19 | using const_iterator = MemoryBlockTree::const_iterator; |
| 20 | 20 | ||
| 21 | public: | 21 | public: |
| 22 | MemoryBlockManager(VAddr start_addr, VAddr end_addr); | 22 | KMemoryBlockManager(VAddr start_addr, VAddr end_addr); |
| 23 | 23 | ||
| 24 | iterator end() { | 24 | iterator end() { |
| 25 | return memory_block_tree.end(); | 25 | return memory_block_tree.end(); |
| @@ -36,21 +36,22 @@ public: | |||
| 36 | VAddr FindFreeArea(VAddr region_start, std::size_t region_num_pages, std::size_t num_pages, | 36 | VAddr FindFreeArea(VAddr region_start, std::size_t region_num_pages, std::size_t num_pages, |
| 37 | std::size_t align, std::size_t offset, std::size_t guard_pages); | 37 | std::size_t align, std::size_t offset, std::size_t guard_pages); |
| 38 | 38 | ||
| 39 | void Update(VAddr addr, std::size_t num_pages, MemoryState prev_state, | 39 | void Update(VAddr addr, std::size_t num_pages, KMemoryState prev_state, |
| 40 | MemoryPermission prev_perm, MemoryAttribute prev_attribute, MemoryState state, | 40 | KMemoryPermission prev_perm, KMemoryAttribute prev_attribute, KMemoryState state, |
| 41 | MemoryPermission perm, MemoryAttribute attribute); | 41 | KMemoryPermission perm, KMemoryAttribute attribute); |
| 42 | 42 | ||
| 43 | void Update(VAddr addr, std::size_t num_pages, MemoryState state, | 43 | void Update(VAddr addr, std::size_t num_pages, KMemoryState state, |
| 44 | MemoryPermission perm = MemoryPermission::None, | 44 | KMemoryPermission perm = KMemoryPermission::None, |
| 45 | MemoryAttribute attribute = MemoryAttribute::None); | 45 | KMemoryAttribute attribute = KMemoryAttribute::None); |
| 46 | 46 | ||
| 47 | using LockFunc = std::function<void(iterator, MemoryPermission)>; | 47 | using LockFunc = std::function<void(iterator, KMemoryPermission)>; |
| 48 | void UpdateLock(VAddr addr, std::size_t num_pages, LockFunc&& lock_func, MemoryPermission perm); | 48 | void UpdateLock(VAddr addr, std::size_t num_pages, LockFunc&& lock_func, |
| 49 | KMemoryPermission perm); | ||
| 49 | 50 | ||
| 50 | using IterateFunc = std::function<void(const MemoryInfo&)>; | 51 | using IterateFunc = std::function<void(const KMemoryInfo&)>; |
| 51 | void IterateForRange(VAddr start, VAddr end, IterateFunc&& func); | 52 | void IterateForRange(VAddr start, VAddr end, IterateFunc&& func); |
| 52 | 53 | ||
| 53 | MemoryBlock& FindBlock(VAddr addr) { | 54 | KMemoryBlock& FindBlock(VAddr addr) { |
| 54 | return *FindIterator(addr); | 55 | return *FindIterator(addr); |
| 55 | } | 56 | } |
| 56 | 57 | ||
| @@ -63,4 +64,4 @@ private: | |||
| 63 | MemoryBlockTree memory_block_tree; | 64 | MemoryBlockTree memory_block_tree; |
| 64 | }; | 65 | }; |
| 65 | 66 | ||
| 66 | } // namespace Kernel::Memory | 67 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_shared_memory.cpp b/src/core/hle/kernel/k_shared_memory.cpp index dd82e0217..eb48afe9d 100644 --- a/src/core/hle/kernel/k_shared_memory.cpp +++ b/src/core/hle/kernel/k_shared_memory.cpp | |||
| @@ -20,8 +20,8 @@ KSharedMemory::~KSharedMemory() { | |||
| 20 | 20 | ||
| 21 | std::shared_ptr<KSharedMemory> KSharedMemory::Create( | 21 | std::shared_ptr<KSharedMemory> KSharedMemory::Create( |
| 22 | KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process, | 22 | KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process, |
| 23 | Memory::PageLinkedList&& page_list, Memory::MemoryPermission owner_permission, | 23 | Memory::PageLinkedList&& page_list, KMemoryPermission owner_permission, |
| 24 | Memory::MemoryPermission user_permission, PAddr physical_address, std::size_t size, | 24 | KMemoryPermission user_permission, PAddr physical_address, std::size_t size, |
| 25 | std::string name) { | 25 | std::string name) { |
| 26 | 26 | ||
| 27 | const auto resource_limit = kernel.GetSystemResourceLimit(); | 27 | const auto resource_limit = kernel.GetSystemResourceLimit(); |
| @@ -45,21 +45,21 @@ std::shared_ptr<KSharedMemory> KSharedMemory::Create( | |||
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | ResultCode KSharedMemory::Map(Process& target_process, VAddr address, std::size_t size, | 47 | ResultCode KSharedMemory::Map(Process& target_process, VAddr address, std::size_t size, |
| 48 | Memory::MemoryPermission permissions) { | 48 | KMemoryPermission permissions) { |
| 49 | const u64 page_count{(size + Memory::PageSize - 1) / Memory::PageSize}; | 49 | const u64 page_count{(size + PageSize - 1) / PageSize}; |
| 50 | 50 | ||
| 51 | if (page_list.GetNumPages() != page_count) { | 51 | if (page_list.GetNumPages() != page_count) { |
| 52 | UNIMPLEMENTED_MSG("Page count does not match"); | 52 | UNIMPLEMENTED_MSG("Page count does not match"); |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | const Memory::MemoryPermission expected = | 55 | const KMemoryPermission expected = |
| 56 | &target_process == owner_process ? owner_permission : user_permission; | 56 | &target_process == owner_process ? owner_permission : user_permission; |
| 57 | 57 | ||
| 58 | if (permissions != expected) { | 58 | if (permissions != expected) { |
| 59 | UNIMPLEMENTED_MSG("Permission does not match"); | 59 | UNIMPLEMENTED_MSG("Permission does not match"); |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | return target_process.PageTable().MapPages(address, page_list, Memory::MemoryState::Shared, | 62 | return target_process.PageTable().MapPages(address, page_list, KMemoryState::Shared, |
| 63 | permissions); | 63 | permissions); |
| 64 | } | 64 | } |
| 65 | 65 | ||
diff --git a/src/core/hle/kernel/k_shared_memory.h b/src/core/hle/kernel/k_shared_memory.h index 4d1354415..1ecb4f7dd 100644 --- a/src/core/hle/kernel/k_shared_memory.h +++ b/src/core/hle/kernel/k_shared_memory.h | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | 9 | ||
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "core/device_memory.h" | 11 | #include "core/device_memory.h" |
| 12 | #include "core/hle/kernel/memory/memory_block.h" | 12 | #include "core/hle/kernel/k_memory_block.h" |
| 13 | #include "core/hle/kernel/memory/page_linked_list.h" | 13 | #include "core/hle/kernel/memory/page_linked_list.h" |
| 14 | #include "core/hle/kernel/object.h" | 14 | #include "core/hle/kernel/object.h" |
| 15 | #include "core/hle/kernel/process.h" | 15 | #include "core/hle/kernel/process.h" |
| @@ -26,8 +26,8 @@ public: | |||
| 26 | 26 | ||
| 27 | static std::shared_ptr<KSharedMemory> Create( | 27 | static std::shared_ptr<KSharedMemory> Create( |
| 28 | KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process, | 28 | KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process, |
| 29 | Memory::PageLinkedList&& page_list, Memory::MemoryPermission owner_permission, | 29 | Memory::PageLinkedList&& page_list, KMemoryPermission owner_permission, |
| 30 | Memory::MemoryPermission user_permission, PAddr physical_address, std::size_t size, | 30 | KMemoryPermission user_permission, PAddr physical_address, std::size_t size, |
| 31 | std::string name); | 31 | std::string name); |
| 32 | 32 | ||
| 33 | std::string GetTypeName() const override { | 33 | std::string GetTypeName() const override { |
| @@ -51,7 +51,7 @@ public: | |||
| 51 | * @param permissions Memory block map permissions (specified by SVC field) | 51 | * @param permissions Memory block map permissions (specified by SVC field) |
| 52 | */ | 52 | */ |
| 53 | ResultCode Map(Process& target_process, VAddr address, std::size_t size, | 53 | ResultCode Map(Process& target_process, VAddr address, std::size_t size, |
| 54 | Memory::MemoryPermission permissions); | 54 | KMemoryPermission permissions); |
| 55 | 55 | ||
| 56 | /** | 56 | /** |
| 57 | * Gets a pointer to the shared memory block | 57 | * Gets a pointer to the shared memory block |
| @@ -77,8 +77,8 @@ private: | |||
| 77 | Core::DeviceMemory& device_memory; | 77 | Core::DeviceMemory& device_memory; |
| 78 | Process* owner_process{}; | 78 | Process* owner_process{}; |
| 79 | Memory::PageLinkedList page_list; | 79 | Memory::PageLinkedList page_list; |
| 80 | Memory::MemoryPermission owner_permission{}; | 80 | KMemoryPermission owner_permission{}; |
| 81 | Memory::MemoryPermission user_permission{}; | 81 | KMemoryPermission user_permission{}; |
| 82 | PAddr physical_address{}; | 82 | PAddr physical_address{}; |
| 83 | std::size_t size{}; | 83 | std::size_t size{}; |
| 84 | std::string name; | 84 | std::string name; |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index e4de3f3bf..eab73c46c 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -289,24 +289,24 @@ struct KernelCore::Impl { | |||
| 289 | layout.System().EndAddress()); | 289 | layout.System().EndAddress()); |
| 290 | 290 | ||
| 291 | hid_shared_mem = Kernel::KSharedMemory::Create( | 291 | hid_shared_mem = Kernel::KSharedMemory::Create( |
| 292 | system.Kernel(), system.DeviceMemory(), nullptr, | 292 | system.Kernel(), system.DeviceMemory(), nullptr, {hid_addr, hid_size / PageSize}, |
| 293 | {hid_addr, hid_size / Memory::PageSize}, Memory::MemoryPermission::None, | 293 | KMemoryPermission::None, KMemoryPermission::Read, hid_addr, hid_size, |
| 294 | Memory::MemoryPermission::Read, hid_addr, hid_size, "HID:SharedMemory"); | 294 | "HID:SharedMemory"); |
| 295 | font_shared_mem = Kernel::KSharedMemory::Create( | 295 | font_shared_mem = Kernel::KSharedMemory::Create( |
| 296 | system.Kernel(), system.DeviceMemory(), nullptr, | 296 | system.Kernel(), system.DeviceMemory(), nullptr, {font_pa, font_size / PageSize}, |
| 297 | {font_pa, font_size / Memory::PageSize}, Memory::MemoryPermission::None, | 297 | KMemoryPermission::None, KMemoryPermission::Read, font_pa, font_size, |
| 298 | Memory::MemoryPermission::Read, font_pa, font_size, "Font:SharedMemory"); | 298 | "Font:SharedMemory"); |
| 299 | irs_shared_mem = Kernel::KSharedMemory::Create( | 299 | irs_shared_mem = Kernel::KSharedMemory::Create( |
| 300 | system.Kernel(), system.DeviceMemory(), nullptr, | 300 | system.Kernel(), system.DeviceMemory(), nullptr, {irs_addr, irs_size / PageSize}, |
| 301 | {irs_addr, irs_size / Memory::PageSize}, Memory::MemoryPermission::None, | 301 | KMemoryPermission::None, KMemoryPermission::Read, irs_addr, irs_size, |
| 302 | Memory::MemoryPermission::Read, irs_addr, irs_size, "IRS:SharedMemory"); | 302 | "IRS:SharedMemory"); |
| 303 | time_shared_mem = Kernel::KSharedMemory::Create( | 303 | time_shared_mem = Kernel::KSharedMemory::Create( |
| 304 | system.Kernel(), system.DeviceMemory(), nullptr, | 304 | system.Kernel(), system.DeviceMemory(), nullptr, {time_addr, time_size / PageSize}, |
| 305 | {time_addr, time_size / Memory::PageSize}, Memory::MemoryPermission::None, | 305 | KMemoryPermission::None, KMemoryPermission::Read, time_addr, time_size, |
| 306 | Memory::MemoryPermission::Read, time_addr, time_size, "Time:SharedMemory"); | 306 | "Time:SharedMemory"); |
| 307 | 307 | ||
| 308 | // Allocate slab heaps | 308 | // Allocate slab heaps |
| 309 | user_slab_heap_pages = std::make_unique<KSlabHeap<Memory::Page>>(); | 309 | user_slab_heap_pages = std::make_unique<KSlabHeap<Page>>(); |
| 310 | 310 | ||
| 311 | constexpr u64 user_slab_heap_size{0x1ef000}; | 311 | constexpr u64 user_slab_heap_size{0x1ef000}; |
| 312 | // Reserve slab heaps | 312 | // Reserve slab heaps |
| @@ -349,7 +349,7 @@ struct KernelCore::Impl { | |||
| 349 | 349 | ||
| 350 | // Kernel memory management | 350 | // Kernel memory management |
| 351 | std::unique_ptr<Memory::MemoryManager> memory_manager; | 351 | std::unique_ptr<Memory::MemoryManager> memory_manager; |
| 352 | std::unique_ptr<KSlabHeap<Memory::Page>> user_slab_heap_pages; | 352 | std::unique_ptr<KSlabHeap<Page>> user_slab_heap_pages; |
| 353 | 353 | ||
| 354 | // Shared memory for services | 354 | // Shared memory for services |
| 355 | std::shared_ptr<Kernel::KSharedMemory> hid_shared_mem; | 355 | std::shared_ptr<Kernel::KSharedMemory> hid_shared_mem; |
| @@ -581,11 +581,11 @@ const Memory::MemoryManager& KernelCore::MemoryManager() const { | |||
| 581 | return *impl->memory_manager; | 581 | return *impl->memory_manager; |
| 582 | } | 582 | } |
| 583 | 583 | ||
| 584 | KSlabHeap<Memory::Page>& KernelCore::GetUserSlabHeapPages() { | 584 | KSlabHeap<Page>& KernelCore::GetUserSlabHeapPages() { |
| 585 | return *impl->user_slab_heap_pages; | 585 | return *impl->user_slab_heap_pages; |
| 586 | } | 586 | } |
| 587 | 587 | ||
| 588 | const KSlabHeap<Memory::Page>& KernelCore::GetUserSlabHeapPages() const { | 588 | const KSlabHeap<Page>& KernelCore::GetUserSlabHeapPages() const { |
| 589 | return *impl->user_slab_heap_pages; | 589 | return *impl->user_slab_heap_pages; |
| 590 | } | 590 | } |
| 591 | 591 | ||
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 5488c962a..498f94417 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | #include <vector> | 11 | #include <vector> |
| 12 | #include "core/arm/cpu_interrupt_handler.h" | 12 | #include "core/arm/cpu_interrupt_handler.h" |
| 13 | #include "core/hardware_properties.h" | 13 | #include "core/hardware_properties.h" |
| 14 | #include "core/hle/kernel/memory/memory_types.h" | 14 | #include "core/hle/kernel/memory_types.h" |
| 15 | #include "core/hle/kernel/object.h" | 15 | #include "core/hle/kernel/object.h" |
| 16 | 16 | ||
| 17 | namespace Core { | 17 | namespace Core { |
| @@ -186,10 +186,10 @@ public: | |||
| 186 | const Memory::MemoryManager& MemoryManager() const; | 186 | const Memory::MemoryManager& MemoryManager() const; |
| 187 | 187 | ||
| 188 | /// Gets the slab heap allocated for user space pages. | 188 | /// Gets the slab heap allocated for user space pages. |
| 189 | KSlabHeap<Memory::Page>& GetUserSlabHeapPages(); | 189 | KSlabHeap<Page>& GetUserSlabHeapPages(); |
| 190 | 190 | ||
| 191 | /// Gets the slab heap allocated for user space pages. | 191 | /// Gets the slab heap allocated for user space pages. |
| 192 | const KSlabHeap<Memory::Page>& GetUserSlabHeapPages() const; | 192 | const KSlabHeap<Page>& GetUserSlabHeapPages() const; |
| 193 | 193 | ||
| 194 | /// Gets the shared memory object for HID services. | 194 | /// Gets the shared memory object for HID services. |
| 195 | Kernel::KSharedMemory& GetHidSharedMem(); | 195 | Kernel::KSharedMemory& GetHidSharedMem(); |
diff --git a/src/core/hle/kernel/memory/page_heap.h b/src/core/hle/kernel/memory/page_heap.h index ee339f329..e21d60a54 100644 --- a/src/core/hle/kernel/memory/page_heap.h +++ b/src/core/hle/kernel/memory/page_heap.h | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | #include "common/common_funcs.h" | 16 | #include "common/common_funcs.h" |
| 17 | #include "common/common_types.h" | 17 | #include "common/common_types.h" |
| 18 | #include "core/hle/kernel/k_page_bitmap.h" | 18 | #include "core/hle/kernel/k_page_bitmap.h" |
| 19 | #include "core/hle/kernel/memory/memory_types.h" | 19 | #include "core/hle/kernel/memory_types.h" |
| 20 | 20 | ||
| 21 | namespace Kernel::Memory { | 21 | namespace Kernel::Memory { |
| 22 | 22 | ||
diff --git a/src/core/hle/kernel/memory/page_linked_list.h b/src/core/hle/kernel/memory/page_linked_list.h index 45dc13eaf..9b871f15b 100644 --- a/src/core/hle/kernel/memory/page_linked_list.h +++ b/src/core/hle/kernel/memory/page_linked_list.h | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | 8 | ||
| 9 | #include "common/assert.h" | 9 | #include "common/assert.h" |
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "core/hle/kernel/memory/memory_types.h" | 11 | #include "core/hle/kernel/memory_types.h" |
| 12 | #include "core/hle/result.h" | 12 | #include "core/hle/result.h" |
| 13 | 13 | ||
| 14 | namespace Kernel::Memory { | 14 | namespace Kernel::Memory { |
diff --git a/src/core/hle/kernel/memory/page_table.cpp b/src/core/hle/kernel/memory/page_table.cpp index 02a17a695..183482648 100644 --- a/src/core/hle/kernel/memory/page_table.cpp +++ b/src/core/hle/kernel/memory/page_table.cpp | |||
| @@ -7,12 +7,12 @@ | |||
| 7 | #include "common/scope_exit.h" | 7 | #include "common/scope_exit.h" |
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/hle/kernel/k_address_space_info.h" | 9 | #include "core/hle/kernel/k_address_space_info.h" |
| 10 | #include "core/hle/kernel/k_memory_block.h" | ||
| 11 | #include "core/hle/kernel/k_memory_block_manager.h" | ||
| 10 | #include "core/hle/kernel/k_resource_limit.h" | 12 | #include "core/hle/kernel/k_resource_limit.h" |
| 11 | #include "core/hle/kernel/k_scoped_resource_reservation.h" | 13 | #include "core/hle/kernel/k_scoped_resource_reservation.h" |
| 12 | #include "core/hle/kernel/k_system_control.h" | 14 | #include "core/hle/kernel/k_system_control.h" |
| 13 | #include "core/hle/kernel/kernel.h" | 15 | #include "core/hle/kernel/kernel.h" |
| 14 | #include "core/hle/kernel/memory/memory_block.h" | ||
| 15 | #include "core/hle/kernel/memory/memory_block_manager.h" | ||
| 16 | #include "core/hle/kernel/memory/page_linked_list.h" | 16 | #include "core/hle/kernel/memory/page_linked_list.h" |
| 17 | #include "core/hle/kernel/memory/page_table.h" | 17 | #include "core/hle/kernel/memory/page_table.h" |
| 18 | #include "core/hle/kernel/process.h" | 18 | #include "core/hle/kernel/process.h" |
| @@ -38,14 +38,14 @@ constexpr std::size_t GetAddressSpaceWidthFromType(FileSys::ProgramAddressSpaceT | |||
| 38 | } | 38 | } |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | constexpr u64 GetAddressInRange(const MemoryInfo& info, VAddr addr) { | 41 | constexpr u64 GetAddressInRange(const KMemoryInfo& info, VAddr addr) { |
| 42 | if (info.GetAddress() < addr) { | 42 | if (info.GetAddress() < addr) { |
| 43 | return addr; | 43 | return addr; |
| 44 | } | 44 | } |
| 45 | return info.GetAddress(); | 45 | return info.GetAddress(); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | constexpr std::size_t GetSizeInRange(const MemoryInfo& info, VAddr start, VAddr end) { | 48 | constexpr std::size_t GetSizeInRange(const KMemoryInfo& info, VAddr start, VAddr end) { |
| 49 | std::size_t size{info.GetSize()}; | 49 | std::size_t size{info.GetSize()}; |
| 50 | if (info.GetAddress() < start) { | 50 | if (info.GetAddress() < start) { |
| 51 | size -= start - info.GetAddress(); | 51 | size -= start - info.GetAddress(); |
| @@ -271,8 +271,8 @@ ResultCode PageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_t | |||
| 271 | return InitializeMemoryLayout(start, end); | 271 | return InitializeMemoryLayout(start, end); |
| 272 | } | 272 | } |
| 273 | 273 | ||
| 274 | ResultCode PageTable::MapProcessCode(VAddr addr, std::size_t num_pages, MemoryState state, | 274 | ResultCode PageTable::MapProcessCode(VAddr addr, std::size_t num_pages, KMemoryState state, |
| 275 | MemoryPermission perm) { | 275 | KMemoryPermission perm) { |
| 276 | std::lock_guard lock{page_table_lock}; | 276 | std::lock_guard lock{page_table_lock}; |
| 277 | 277 | ||
| 278 | const u64 size{num_pages * PageSize}; | 278 | const u64 size{num_pages * PageSize}; |
| @@ -300,12 +300,12 @@ ResultCode PageTable::MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std:: | |||
| 300 | 300 | ||
| 301 | const std::size_t num_pages{size / PageSize}; | 301 | const std::size_t num_pages{size / PageSize}; |
| 302 | 302 | ||
| 303 | MemoryState state{}; | 303 | KMemoryState state{}; |
| 304 | MemoryPermission perm{}; | 304 | KMemoryPermission perm{}; |
| 305 | CASCADE_CODE(CheckMemoryState(&state, &perm, nullptr, src_addr, size, MemoryState::All, | 305 | CASCADE_CODE(CheckMemoryState(&state, &perm, nullptr, src_addr, size, KMemoryState::All, |
| 306 | MemoryState::Normal, MemoryPermission::Mask, | 306 | KMemoryState::Normal, KMemoryPermission::Mask, |
| 307 | MemoryPermission::ReadAndWrite, MemoryAttribute::Mask, | 307 | KMemoryPermission::ReadAndWrite, KMemoryAttribute::Mask, |
| 308 | MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); | 308 | KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); |
| 309 | 309 | ||
| 310 | if (IsRegionMapped(dst_addr, size)) { | 310 | if (IsRegionMapped(dst_addr, size)) { |
| 311 | return ResultInvalidCurrentMemory; | 311 | return ResultInvalidCurrentMemory; |
| @@ -318,16 +318,16 @@ ResultCode PageTable::MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std:: | |||
| 318 | auto block_guard = detail::ScopeExit( | 318 | auto block_guard = detail::ScopeExit( |
| 319 | [&] { Operate(src_addr, num_pages, perm, OperationType::ChangePermissions); }); | 319 | [&] { Operate(src_addr, num_pages, perm, OperationType::ChangePermissions); }); |
| 320 | 320 | ||
| 321 | CASCADE_CODE( | 321 | CASCADE_CODE(Operate(src_addr, num_pages, KMemoryPermission::None, |
| 322 | Operate(src_addr, num_pages, MemoryPermission::None, OperationType::ChangePermissions)); | 322 | OperationType::ChangePermissions)); |
| 323 | CASCADE_CODE(MapPages(dst_addr, page_linked_list, MemoryPermission::None)); | 323 | CASCADE_CODE(MapPages(dst_addr, page_linked_list, KMemoryPermission::None)); |
| 324 | 324 | ||
| 325 | block_guard.Cancel(); | 325 | block_guard.Cancel(); |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | block_manager->Update(src_addr, num_pages, state, MemoryPermission::None, | 328 | block_manager->Update(src_addr, num_pages, state, KMemoryPermission::None, |
| 329 | MemoryAttribute::Locked); | 329 | KMemoryAttribute::Locked); |
| 330 | block_manager->Update(dst_addr, num_pages, MemoryState::AliasCode); | 330 | block_manager->Update(dst_addr, num_pages, KMemoryState::AliasCode); |
| 331 | 331 | ||
| 332 | return RESULT_SUCCESS; | 332 | return RESULT_SUCCESS; |
| 333 | } | 333 | } |
| @@ -341,23 +341,24 @@ ResultCode PageTable::UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std | |||
| 341 | 341 | ||
| 342 | const std::size_t num_pages{size / PageSize}; | 342 | const std::size_t num_pages{size / PageSize}; |
| 343 | 343 | ||
| 344 | CASCADE_CODE(CheckMemoryState(nullptr, nullptr, nullptr, src_addr, size, MemoryState::All, | 344 | CASCADE_CODE(CheckMemoryState(nullptr, nullptr, nullptr, src_addr, size, KMemoryState::All, |
| 345 | MemoryState::Normal, MemoryPermission::None, | 345 | KMemoryState::Normal, KMemoryPermission::None, |
| 346 | MemoryPermission::None, MemoryAttribute::Mask, | 346 | KMemoryPermission::None, KMemoryAttribute::Mask, |
| 347 | MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)); | 347 | KMemoryAttribute::Locked, KMemoryAttribute::IpcAndDeviceMapped)); |
| 348 | 348 | ||
| 349 | MemoryState state{}; | 349 | KMemoryState state{}; |
| 350 | CASCADE_CODE(CheckMemoryState( | 350 | CASCADE_CODE(CheckMemoryState( |
| 351 | &state, nullptr, nullptr, dst_addr, PageSize, MemoryState::FlagCanCodeAlias, | 351 | &state, nullptr, nullptr, dst_addr, PageSize, KMemoryState::FlagCanCodeAlias, |
| 352 | MemoryState::FlagCanCodeAlias, MemoryPermission::None, MemoryPermission::None, | 352 | KMemoryState::FlagCanCodeAlias, KMemoryPermission::None, KMemoryPermission::None, |
| 353 | MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); | 353 | KMemoryAttribute::Mask, KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); |
| 354 | CASCADE_CODE(CheckMemoryState(dst_addr, size, MemoryState::All, state, MemoryPermission::None, | 354 | CASCADE_CODE(CheckMemoryState(dst_addr, size, KMemoryState::All, state, KMemoryPermission::None, |
| 355 | MemoryPermission::None, MemoryAttribute::Mask, | 355 | KMemoryPermission::None, KMemoryAttribute::Mask, |
| 356 | MemoryAttribute::None)); | 356 | KMemoryAttribute::None)); |
| 357 | CASCADE_CODE(Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap)); | 357 | CASCADE_CODE(Operate(dst_addr, num_pages, KMemoryPermission::None, OperationType::Unmap)); |
| 358 | 358 | ||
| 359 | block_manager->Update(dst_addr, num_pages, MemoryState::Free); | 359 | block_manager->Update(dst_addr, num_pages, KMemoryState::Free); |
| 360 | block_manager->Update(src_addr, num_pages, MemoryState::Normal, MemoryPermission::ReadAndWrite); | 360 | block_manager->Update(src_addr, num_pages, KMemoryState::Normal, |
| 361 | KMemoryPermission::ReadAndWrite); | ||
| 361 | 362 | ||
| 362 | return RESULT_SUCCESS; | 363 | return RESULT_SUCCESS; |
| 363 | } | 364 | } |
| @@ -367,8 +368,8 @@ void PageTable::MapPhysicalMemory(PageLinkedList& page_linked_list, VAddr start, | |||
| 367 | PAddr map_addr{node->GetAddress()}; | 368 | PAddr map_addr{node->GetAddress()}; |
| 368 | std::size_t src_num_pages{node->GetNumPages()}; | 369 | std::size_t src_num_pages{node->GetNumPages()}; |
| 369 | 370 | ||
| 370 | block_manager->IterateForRange(start, end, [&](const MemoryInfo& info) { | 371 | block_manager->IterateForRange(start, end, [&](const KMemoryInfo& info) { |
| 371 | if (info.state != MemoryState::Free) { | 372 | if (info.state != KMemoryState::Free) { |
| 372 | return; | 373 | return; |
| 373 | } | 374 | } |
| 374 | 375 | ||
| @@ -383,7 +384,7 @@ void PageTable::MapPhysicalMemory(PageLinkedList& page_linked_list, VAddr start, | |||
| 383 | } | 384 | } |
| 384 | 385 | ||
| 385 | const std::size_t num_pages{std::min(src_num_pages, dst_num_pages)}; | 386 | const std::size_t num_pages{std::min(src_num_pages, dst_num_pages)}; |
| 386 | Operate(dst_addr, num_pages, MemoryPermission::ReadAndWrite, OperationType::Map, | 387 | Operate(dst_addr, num_pages, KMemoryPermission::ReadAndWrite, OperationType::Map, |
| 387 | map_addr); | 388 | map_addr); |
| 388 | 389 | ||
| 389 | dst_addr += num_pages * PageSize; | 390 | dst_addr += num_pages * PageSize; |
| @@ -400,8 +401,8 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) { | |||
| 400 | std::size_t mapped_size{}; | 401 | std::size_t mapped_size{}; |
| 401 | const VAddr end_addr{addr + size}; | 402 | const VAddr end_addr{addr + size}; |
| 402 | 403 | ||
| 403 | block_manager->IterateForRange(addr, end_addr, [&](const MemoryInfo& info) { | 404 | block_manager->IterateForRange(addr, end_addr, [&](const KMemoryInfo& info) { |
| 404 | if (info.state != MemoryState::Free) { | 405 | if (info.state != KMemoryState::Free) { |
| 405 | mapped_size += GetSizeInRange(info, addr, end_addr); | 406 | mapped_size += GetSizeInRange(info, addr, end_addr); |
| 406 | } | 407 | } |
| 407 | }); | 408 | }); |
| @@ -435,9 +436,9 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) { | |||
| 435 | physical_memory_usage += remaining_size; | 436 | physical_memory_usage += remaining_size; |
| 436 | 437 | ||
| 437 | const std::size_t num_pages{size / PageSize}; | 438 | const std::size_t num_pages{size / PageSize}; |
| 438 | block_manager->Update(addr, num_pages, MemoryState::Free, MemoryPermission::None, | 439 | block_manager->Update(addr, num_pages, KMemoryState::Free, KMemoryPermission::None, |
| 439 | MemoryAttribute::None, MemoryState::Normal, | 440 | KMemoryAttribute::None, KMemoryState::Normal, |
| 440 | MemoryPermission::ReadAndWrite, MemoryAttribute::None); | 441 | KMemoryPermission::ReadAndWrite, KMemoryAttribute::None); |
| 441 | 442 | ||
| 442 | return RESULT_SUCCESS; | 443 | return RESULT_SUCCESS; |
| 443 | } | 444 | } |
| @@ -450,14 +451,14 @@ ResultCode PageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) { | |||
| 450 | std::size_t mapped_size{}; | 451 | std::size_t mapped_size{}; |
| 451 | 452 | ||
| 452 | // Verify that the region can be unmapped | 453 | // Verify that the region can be unmapped |
| 453 | block_manager->IterateForRange(addr, end_addr, [&](const MemoryInfo& info) { | 454 | block_manager->IterateForRange(addr, end_addr, [&](const KMemoryInfo& info) { |
| 454 | if (info.state == MemoryState::Normal) { | 455 | if (info.state == KMemoryState::Normal) { |
| 455 | if (info.attribute != MemoryAttribute::None) { | 456 | if (info.attribute != KMemoryAttribute::None) { |
| 456 | result = ResultInvalidCurrentMemory; | 457 | result = ResultInvalidCurrentMemory; |
| 457 | return; | 458 | return; |
| 458 | } | 459 | } |
| 459 | mapped_size += GetSizeInRange(info, addr, end_addr); | 460 | mapped_size += GetSizeInRange(info, addr, end_addr); |
| 460 | } else if (info.state != MemoryState::Free) { | 461 | } else if (info.state != KMemoryState::Free) { |
| 461 | result = ResultInvalidCurrentMemory; | 462 | result = ResultInvalidCurrentMemory; |
| 462 | } | 463 | } |
| 463 | }); | 464 | }); |
| @@ -487,15 +488,15 @@ ResultCode PageTable::UnmapMemory(VAddr addr, std::size_t size) { | |||
| 487 | PageLinkedList page_linked_list; | 488 | PageLinkedList page_linked_list; |
| 488 | 489 | ||
| 489 | // Unmap each region within the range | 490 | // Unmap each region within the range |
| 490 | block_manager->IterateForRange(addr, end_addr, [&](const MemoryInfo& info) { | 491 | block_manager->IterateForRange(addr, end_addr, [&](const KMemoryInfo& info) { |
| 491 | if (info.state == MemoryState::Normal) { | 492 | if (info.state == KMemoryState::Normal) { |
| 492 | const std::size_t block_size{GetSizeInRange(info, addr, end_addr)}; | 493 | const std::size_t block_size{GetSizeInRange(info, addr, end_addr)}; |
| 493 | const std::size_t block_num_pages{block_size / PageSize}; | 494 | const std::size_t block_num_pages{block_size / PageSize}; |
| 494 | const VAddr block_addr{GetAddressInRange(info, addr)}; | 495 | const VAddr block_addr{GetAddressInRange(info, addr)}; |
| 495 | 496 | ||
| 496 | AddRegionToPages(block_addr, block_size / PageSize, page_linked_list); | 497 | AddRegionToPages(block_addr, block_size / PageSize, page_linked_list); |
| 497 | 498 | ||
| 498 | if (result = Operate(block_addr, block_num_pages, MemoryPermission::None, | 499 | if (result = Operate(block_addr, block_num_pages, KMemoryPermission::None, |
| 499 | OperationType::Unmap); | 500 | OperationType::Unmap); |
| 500 | result.IsError()) { | 501 | result.IsError()) { |
| 501 | return; | 502 | return; |
| @@ -510,7 +511,7 @@ ResultCode PageTable::UnmapMemory(VAddr addr, std::size_t size) { | |||
| 510 | const std::size_t num_pages{size / PageSize}; | 511 | const std::size_t num_pages{size / PageSize}; |
| 511 | system.Kernel().MemoryManager().Free(page_linked_list, num_pages, memory_pool); | 512 | system.Kernel().MemoryManager().Free(page_linked_list, num_pages, memory_pool); |
| 512 | 513 | ||
| 513 | block_manager->Update(addr, num_pages, MemoryState::Free); | 514 | block_manager->Update(addr, num_pages, KMemoryState::Free); |
| 514 | 515 | ||
| 515 | return RESULT_SUCCESS; | 516 | return RESULT_SUCCESS; |
| 516 | } | 517 | } |
| @@ -518,11 +519,11 @@ ResultCode PageTable::UnmapMemory(VAddr addr, std::size_t size) { | |||
| 518 | ResultCode PageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) { | 519 | ResultCode PageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) { |
| 519 | std::lock_guard lock{page_table_lock}; | 520 | std::lock_guard lock{page_table_lock}; |
| 520 | 521 | ||
| 521 | MemoryState src_state{}; | 522 | KMemoryState src_state{}; |
| 522 | CASCADE_CODE(CheckMemoryState( | 523 | CASCADE_CODE(CheckMemoryState( |
| 523 | &src_state, nullptr, nullptr, src_addr, size, MemoryState::FlagCanAlias, | 524 | &src_state, nullptr, nullptr, src_addr, size, KMemoryState::FlagCanAlias, |
| 524 | MemoryState::FlagCanAlias, MemoryPermission::Mask, MemoryPermission::ReadAndWrite, | 525 | KMemoryState::FlagCanAlias, KMemoryPermission::Mask, KMemoryPermission::ReadAndWrite, |
| 525 | MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); | 526 | KMemoryAttribute::Mask, KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); |
| 526 | 527 | ||
| 527 | if (IsRegionMapped(dst_addr, size)) { | 528 | if (IsRegionMapped(dst_addr, size)) { |
| 528 | return ResultInvalidCurrentMemory; | 529 | return ResultInvalidCurrentMemory; |
| @@ -535,20 +536,21 @@ ResultCode PageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) { | |||
| 535 | 536 | ||
| 536 | { | 537 | { |
| 537 | auto block_guard = detail::ScopeExit([&] { | 538 | auto block_guard = detail::ScopeExit([&] { |
| 538 | Operate(src_addr, num_pages, MemoryPermission::ReadAndWrite, | 539 | Operate(src_addr, num_pages, KMemoryPermission::ReadAndWrite, |
| 539 | OperationType::ChangePermissions); | 540 | OperationType::ChangePermissions); |
| 540 | }); | 541 | }); |
| 541 | 542 | ||
| 542 | CASCADE_CODE( | 543 | CASCADE_CODE(Operate(src_addr, num_pages, KMemoryPermission::None, |
| 543 | Operate(src_addr, num_pages, MemoryPermission::None, OperationType::ChangePermissions)); | 544 | OperationType::ChangePermissions)); |
| 544 | CASCADE_CODE(MapPages(dst_addr, page_linked_list, MemoryPermission::ReadAndWrite)); | 545 | CASCADE_CODE(MapPages(dst_addr, page_linked_list, KMemoryPermission::ReadAndWrite)); |
| 545 | 546 | ||
| 546 | block_guard.Cancel(); | 547 | block_guard.Cancel(); |
| 547 | } | 548 | } |
| 548 | 549 | ||
| 549 | block_manager->Update(src_addr, num_pages, src_state, MemoryPermission::None, | 550 | block_manager->Update(src_addr, num_pages, src_state, KMemoryPermission::None, |
| 550 | MemoryAttribute::Locked); | 551 | KMemoryAttribute::Locked); |
| 551 | block_manager->Update(dst_addr, num_pages, MemoryState::Stack, MemoryPermission::ReadAndWrite); | 552 | block_manager->Update(dst_addr, num_pages, KMemoryState::Stack, |
| 553 | KMemoryPermission::ReadAndWrite); | ||
| 552 | 554 | ||
| 553 | return RESULT_SUCCESS; | 555 | return RESULT_SUCCESS; |
| 554 | } | 556 | } |
| @@ -556,17 +558,17 @@ ResultCode PageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) { | |||
| 556 | ResultCode PageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) { | 558 | ResultCode PageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) { |
| 557 | std::lock_guard lock{page_table_lock}; | 559 | std::lock_guard lock{page_table_lock}; |
| 558 | 560 | ||
| 559 | MemoryState src_state{}; | 561 | KMemoryState src_state{}; |
| 560 | CASCADE_CODE(CheckMemoryState( | 562 | CASCADE_CODE(CheckMemoryState( |
| 561 | &src_state, nullptr, nullptr, src_addr, size, MemoryState::FlagCanAlias, | 563 | &src_state, nullptr, nullptr, src_addr, size, KMemoryState::FlagCanAlias, |
| 562 | MemoryState::FlagCanAlias, MemoryPermission::Mask, MemoryPermission::None, | 564 | KMemoryState::FlagCanAlias, KMemoryPermission::Mask, KMemoryPermission::None, |
| 563 | MemoryAttribute::Mask, MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)); | 565 | KMemoryAttribute::Mask, KMemoryAttribute::Locked, KMemoryAttribute::IpcAndDeviceMapped)); |
| 564 | 566 | ||
| 565 | MemoryPermission dst_perm{}; | 567 | KMemoryPermission dst_perm{}; |
| 566 | CASCADE_CODE(CheckMemoryState(nullptr, &dst_perm, nullptr, dst_addr, size, MemoryState::All, | 568 | CASCADE_CODE(CheckMemoryState(nullptr, &dst_perm, nullptr, dst_addr, size, KMemoryState::All, |
| 567 | MemoryState::Stack, MemoryPermission::None, | 569 | KMemoryState::Stack, KMemoryPermission::None, |
| 568 | MemoryPermission::None, MemoryAttribute::Mask, | 570 | KMemoryPermission::None, KMemoryAttribute::Mask, |
| 569 | MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); | 571 | KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); |
| 570 | 572 | ||
| 571 | PageLinkedList src_pages; | 573 | PageLinkedList src_pages; |
| 572 | PageLinkedList dst_pages; | 574 | PageLinkedList dst_pages; |
| @@ -582,21 +584,21 @@ ResultCode PageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) { | |||
| 582 | { | 584 | { |
| 583 | auto block_guard = detail::ScopeExit([&] { MapPages(dst_addr, dst_pages, dst_perm); }); | 585 | auto block_guard = detail::ScopeExit([&] { MapPages(dst_addr, dst_pages, dst_perm); }); |
| 584 | 586 | ||
| 585 | CASCADE_CODE(Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap)); | 587 | CASCADE_CODE(Operate(dst_addr, num_pages, KMemoryPermission::None, OperationType::Unmap)); |
| 586 | CASCADE_CODE(Operate(src_addr, num_pages, MemoryPermission::ReadAndWrite, | 588 | CASCADE_CODE(Operate(src_addr, num_pages, KMemoryPermission::ReadAndWrite, |
| 587 | OperationType::ChangePermissions)); | 589 | OperationType::ChangePermissions)); |
| 588 | 590 | ||
| 589 | block_guard.Cancel(); | 591 | block_guard.Cancel(); |
| 590 | } | 592 | } |
| 591 | 593 | ||
| 592 | block_manager->Update(src_addr, num_pages, src_state, MemoryPermission::ReadAndWrite); | 594 | block_manager->Update(src_addr, num_pages, src_state, KMemoryPermission::ReadAndWrite); |
| 593 | block_manager->Update(dst_addr, num_pages, MemoryState::Free); | 595 | block_manager->Update(dst_addr, num_pages, KMemoryState::Free); |
| 594 | 596 | ||
| 595 | return RESULT_SUCCESS; | 597 | return RESULT_SUCCESS; |
| 596 | } | 598 | } |
| 597 | 599 | ||
| 598 | ResultCode PageTable::MapPages(VAddr addr, const PageLinkedList& page_linked_list, | 600 | ResultCode PageTable::MapPages(VAddr addr, const PageLinkedList& page_linked_list, |
| 599 | MemoryPermission perm) { | 601 | KMemoryPermission perm) { |
| 600 | VAddr cur_addr{addr}; | 602 | VAddr cur_addr{addr}; |
| 601 | 603 | ||
| 602 | for (const auto& node : page_linked_list.Nodes()) { | 604 | for (const auto& node : page_linked_list.Nodes()) { |
| @@ -605,8 +607,8 @@ ResultCode PageTable::MapPages(VAddr addr, const PageLinkedList& page_linked_lis | |||
| 605 | result.IsError()) { | 607 | result.IsError()) { |
| 606 | const std::size_t num_pages{(addr - cur_addr) / PageSize}; | 608 | const std::size_t num_pages{(addr - cur_addr) / PageSize}; |
| 607 | 609 | ||
| 608 | ASSERT( | 610 | ASSERT(Operate(addr, num_pages, KMemoryPermission::None, OperationType::Unmap) |
| 609 | Operate(addr, num_pages, MemoryPermission::None, OperationType::Unmap).IsSuccess()); | 611 | .IsSuccess()); |
| 610 | 612 | ||
| 611 | return result; | 613 | return result; |
| 612 | } | 614 | } |
| @@ -617,8 +619,8 @@ ResultCode PageTable::MapPages(VAddr addr, const PageLinkedList& page_linked_lis | |||
| 617 | return RESULT_SUCCESS; | 619 | return RESULT_SUCCESS; |
| 618 | } | 620 | } |
| 619 | 621 | ||
| 620 | ResultCode PageTable::MapPages(VAddr addr, PageLinkedList& page_linked_list, MemoryState state, | 622 | ResultCode PageTable::MapPages(VAddr addr, PageLinkedList& page_linked_list, KMemoryState state, |
| 621 | MemoryPermission perm) { | 623 | KMemoryPermission perm) { |
| 622 | std::lock_guard lock{page_table_lock}; | 624 | std::lock_guard lock{page_table_lock}; |
| 623 | 625 | ||
| 624 | const std::size_t num_pages{page_linked_list.GetNumPages()}; | 626 | const std::size_t num_pages{page_linked_list.GetNumPages()}; |
| @@ -639,26 +641,27 @@ ResultCode PageTable::MapPages(VAddr addr, PageLinkedList& page_linked_list, Mem | |||
| 639 | return RESULT_SUCCESS; | 641 | return RESULT_SUCCESS; |
| 640 | } | 642 | } |
| 641 | 643 | ||
| 642 | ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, MemoryPermission perm) { | 644 | ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, |
| 645 | KMemoryPermission perm) { | ||
| 643 | 646 | ||
| 644 | std::lock_guard lock{page_table_lock}; | 647 | std::lock_guard lock{page_table_lock}; |
| 645 | 648 | ||
| 646 | MemoryState prev_state{}; | 649 | KMemoryState prev_state{}; |
| 647 | MemoryPermission prev_perm{}; | 650 | KMemoryPermission prev_perm{}; |
| 648 | 651 | ||
| 649 | CASCADE_CODE(CheckMemoryState( | 652 | CASCADE_CODE(CheckMemoryState( |
| 650 | &prev_state, &prev_perm, nullptr, addr, size, MemoryState::FlagCode, MemoryState::FlagCode, | 653 | &prev_state, &prev_perm, nullptr, addr, size, KMemoryState::FlagCode, |
| 651 | MemoryPermission::None, MemoryPermission::None, MemoryAttribute::Mask, | 654 | KMemoryState::FlagCode, KMemoryPermission::None, KMemoryPermission::None, |
| 652 | MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); | 655 | KMemoryAttribute::Mask, KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); |
| 653 | 656 | ||
| 654 | MemoryState state{prev_state}; | 657 | KMemoryState state{prev_state}; |
| 655 | 658 | ||
| 656 | // Ensure state is mutable if permission allows write | 659 | // Ensure state is mutable if permission allows write |
| 657 | if ((perm & MemoryPermission::Write) != MemoryPermission::None) { | 660 | if ((perm & KMemoryPermission::Write) != KMemoryPermission::None) { |
| 658 | if (prev_state == MemoryState::Code) { | 661 | if (prev_state == KMemoryState::Code) { |
| 659 | state = MemoryState::CodeData; | 662 | state = KMemoryState::CodeData; |
| 660 | } else if (prev_state == MemoryState::AliasCode) { | 663 | } else if (prev_state == KMemoryState::AliasCode) { |
| 661 | state = MemoryState::AliasCodeData; | 664 | state = KMemoryState::AliasCodeData; |
| 662 | } else { | 665 | } else { |
| 663 | UNREACHABLE(); | 666 | UNREACHABLE(); |
| 664 | } | 667 | } |
| @@ -669,13 +672,13 @@ ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, Memo | |||
| 669 | return RESULT_SUCCESS; | 672 | return RESULT_SUCCESS; |
| 670 | } | 673 | } |
| 671 | 674 | ||
| 672 | if ((prev_perm & MemoryPermission::Execute) != (perm & MemoryPermission::Execute)) { | 675 | if ((prev_perm & KMemoryPermission::Execute) != (perm & KMemoryPermission::Execute)) { |
| 673 | // Memory execution state is changing, invalidate CPU cache range | 676 | // Memory execution state is changing, invalidate CPU cache range |
| 674 | system.InvalidateCpuInstructionCacheRange(addr, size); | 677 | system.InvalidateCpuInstructionCacheRange(addr, size); |
| 675 | } | 678 | } |
| 676 | 679 | ||
| 677 | const std::size_t num_pages{size / PageSize}; | 680 | const std::size_t num_pages{size / PageSize}; |
| 678 | const OperationType operation{(perm & MemoryPermission::Execute) != MemoryPermission::None | 681 | const OperationType operation{(perm & KMemoryPermission::Execute) != KMemoryPermission::None |
| 679 | ? OperationType::ChangePermissionsAndRefresh | 682 | ? OperationType::ChangePermissionsAndRefresh |
| 680 | : OperationType::ChangePermissions}; | 683 | : OperationType::ChangePermissions}; |
| 681 | 684 | ||
| @@ -686,35 +689,35 @@ ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, Memo | |||
| 686 | return RESULT_SUCCESS; | 689 | return RESULT_SUCCESS; |
| 687 | } | 690 | } |
| 688 | 691 | ||
| 689 | MemoryInfo PageTable::QueryInfoImpl(VAddr addr) { | 692 | KMemoryInfo PageTable::QueryInfoImpl(VAddr addr) { |
| 690 | std::lock_guard lock{page_table_lock}; | 693 | std::lock_guard lock{page_table_lock}; |
| 691 | 694 | ||
| 692 | return block_manager->FindBlock(addr).GetMemoryInfo(); | 695 | return block_manager->FindBlock(addr).GetMemoryInfo(); |
| 693 | } | 696 | } |
| 694 | 697 | ||
| 695 | MemoryInfo PageTable::QueryInfo(VAddr addr) { | 698 | KMemoryInfo PageTable::QueryInfo(VAddr addr) { |
| 696 | if (!Contains(addr, 1)) { | 699 | if (!Contains(addr, 1)) { |
| 697 | return {address_space_end, 0 - address_space_end, MemoryState::Inaccessible, | 700 | return {address_space_end, 0 - address_space_end, KMemoryState::Inaccessible, |
| 698 | MemoryPermission::None, MemoryAttribute::None, MemoryPermission::None}; | 701 | KMemoryPermission::None, KMemoryAttribute::None, KMemoryPermission::None}; |
| 699 | } | 702 | } |
| 700 | 703 | ||
| 701 | return QueryInfoImpl(addr); | 704 | return QueryInfoImpl(addr); |
| 702 | } | 705 | } |
| 703 | 706 | ||
| 704 | ResultCode PageTable::ReserveTransferMemory(VAddr addr, std::size_t size, MemoryPermission perm) { | 707 | ResultCode PageTable::ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm) { |
| 705 | std::lock_guard lock{page_table_lock}; | 708 | std::lock_guard lock{page_table_lock}; |
| 706 | 709 | ||
| 707 | MemoryState state{}; | 710 | KMemoryState state{}; |
| 708 | MemoryAttribute attribute{}; | 711 | KMemoryAttribute attribute{}; |
| 709 | 712 | ||
| 710 | CASCADE_CODE(CheckMemoryState(&state, nullptr, &attribute, addr, size, | 713 | CASCADE_CODE(CheckMemoryState( |
| 711 | MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, | 714 | &state, nullptr, &attribute, addr, size, |
| 712 | MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, | 715 | KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted, |
| 713 | MemoryPermission::Mask, MemoryPermission::ReadAndWrite, | 716 | KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted, KMemoryPermission::Mask, |
| 714 | MemoryAttribute::Mask, MemoryAttribute::None, | 717 | KMemoryPermission::ReadAndWrite, KMemoryAttribute::Mask, KMemoryAttribute::None, |
| 715 | MemoryAttribute::IpcAndDeviceMapped)); | 718 | KMemoryAttribute::IpcAndDeviceMapped)); |
| 716 | 719 | ||
| 717 | block_manager->Update(addr, size / PageSize, state, perm, attribute | MemoryAttribute::Locked); | 720 | block_manager->Update(addr, size / PageSize, state, perm, attribute | KMemoryAttribute::Locked); |
| 718 | 721 | ||
| 719 | return RESULT_SUCCESS; | 722 | return RESULT_SUCCESS; |
| 720 | } | 723 | } |
| @@ -722,33 +725,33 @@ ResultCode PageTable::ReserveTransferMemory(VAddr addr, std::size_t size, Memory | |||
| 722 | ResultCode PageTable::ResetTransferMemory(VAddr addr, std::size_t size) { | 725 | ResultCode PageTable::ResetTransferMemory(VAddr addr, std::size_t size) { |
| 723 | std::lock_guard lock{page_table_lock}; | 726 | std::lock_guard lock{page_table_lock}; |
| 724 | 727 | ||
| 725 | MemoryState state{}; | 728 | KMemoryState state{}; |
| 726 | 729 | ||
| 727 | CASCADE_CODE(CheckMemoryState(&state, nullptr, nullptr, addr, size, | 730 | CASCADE_CODE( |
| 728 | MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, | 731 | CheckMemoryState(&state, nullptr, nullptr, addr, size, |
| 729 | MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, | 732 | KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted, |
| 730 | MemoryPermission::None, MemoryPermission::None, | 733 | KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted, |
| 731 | MemoryAttribute::Mask, MemoryAttribute::Locked, | 734 | KMemoryPermission::None, KMemoryPermission::None, KMemoryAttribute::Mask, |
| 732 | MemoryAttribute::IpcAndDeviceMapped)); | 735 | KMemoryAttribute::Locked, KMemoryAttribute::IpcAndDeviceMapped)); |
| 733 | 736 | ||
| 734 | block_manager->Update(addr, size / PageSize, state, MemoryPermission::ReadAndWrite); | 737 | block_manager->Update(addr, size / PageSize, state, KMemoryPermission::ReadAndWrite); |
| 735 | 738 | ||
| 736 | return RESULT_SUCCESS; | 739 | return RESULT_SUCCESS; |
| 737 | } | 740 | } |
| 738 | 741 | ||
| 739 | ResultCode PageTable::SetMemoryAttribute(VAddr addr, std::size_t size, MemoryAttribute mask, | 742 | ResultCode PageTable::SetMemoryAttribute(VAddr addr, std::size_t size, KMemoryAttribute mask, |
| 740 | MemoryAttribute value) { | 743 | KMemoryAttribute value) { |
| 741 | std::lock_guard lock{page_table_lock}; | 744 | std::lock_guard lock{page_table_lock}; |
| 742 | 745 | ||
| 743 | MemoryState state{}; | 746 | KMemoryState state{}; |
| 744 | MemoryPermission perm{}; | 747 | KMemoryPermission perm{}; |
| 745 | MemoryAttribute attribute{}; | 748 | KMemoryAttribute attribute{}; |
| 746 | 749 | ||
| 747 | CASCADE_CODE(CheckMemoryState(&state, &perm, &attribute, addr, size, | 750 | CASCADE_CODE(CheckMemoryState( |
| 748 | MemoryState::FlagCanChangeAttribute, | 751 | &state, &perm, &attribute, addr, size, KMemoryState::FlagCanChangeAttribute, |
| 749 | MemoryState::FlagCanChangeAttribute, MemoryPermission::None, | 752 | KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None, |
| 750 | MemoryPermission::None, MemoryAttribute::LockedAndIpcLocked, | 753 | KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None, |
| 751 | MemoryAttribute::None, MemoryAttribute::DeviceSharedAndUncached)); | 754 | KMemoryAttribute::DeviceSharedAndUncached)); |
| 752 | 755 | ||
| 753 | attribute = attribute & ~mask; | 756 | attribute = attribute & ~mask; |
| 754 | attribute = attribute | (mask & value); | 757 | attribute = attribute | (mask & value); |
| @@ -806,8 +809,8 @@ ResultVal<VAddr> PageTable::SetHeapSize(std::size_t size) { | |||
| 806 | // Succeeded in allocation, commit the resource reservation | 809 | // Succeeded in allocation, commit the resource reservation |
| 807 | memory_reservation.Commit(); | 810 | memory_reservation.Commit(); |
| 808 | 811 | ||
| 809 | block_manager->Update(current_heap_addr, num_pages, MemoryState::Normal, | 812 | block_manager->Update(current_heap_addr, num_pages, KMemoryState::Normal, |
| 810 | MemoryPermission::ReadAndWrite); | 813 | KMemoryPermission::ReadAndWrite); |
| 811 | 814 | ||
| 812 | current_heap_addr = heap_region_start + size; | 815 | current_heap_addr = heap_region_start + size; |
| 813 | } | 816 | } |
| @@ -817,8 +820,8 @@ ResultVal<VAddr> PageTable::SetHeapSize(std::size_t size) { | |||
| 817 | 820 | ||
| 818 | ResultVal<VAddr> PageTable::AllocateAndMapMemory(std::size_t needed_num_pages, std::size_t align, | 821 | ResultVal<VAddr> PageTable::AllocateAndMapMemory(std::size_t needed_num_pages, std::size_t align, |
| 819 | bool is_map_only, VAddr region_start, | 822 | bool is_map_only, VAddr region_start, |
| 820 | std::size_t region_num_pages, MemoryState state, | 823 | std::size_t region_num_pages, KMemoryState state, |
| 821 | MemoryPermission perm, PAddr map_addr) { | 824 | KMemoryPermission perm, PAddr map_addr) { |
| 822 | std::lock_guard lock{page_table_lock}; | 825 | std::lock_guard lock{page_table_lock}; |
| 823 | 826 | ||
| 824 | if (!CanContain(region_start, region_num_pages * PageSize, state)) { | 827 | if (!CanContain(region_start, region_num_pages * PageSize, state)) { |
| @@ -852,19 +855,19 @@ ResultVal<VAddr> PageTable::AllocateAndMapMemory(std::size_t needed_num_pages, s | |||
| 852 | ResultCode PageTable::LockForDeviceAddressSpace(VAddr addr, std::size_t size) { | 855 | ResultCode PageTable::LockForDeviceAddressSpace(VAddr addr, std::size_t size) { |
| 853 | std::lock_guard lock{page_table_lock}; | 856 | std::lock_guard lock{page_table_lock}; |
| 854 | 857 | ||
| 855 | MemoryPermission perm{}; | 858 | KMemoryPermission perm{}; |
| 856 | if (const ResultCode result{CheckMemoryState( | 859 | if (const ResultCode result{CheckMemoryState( |
| 857 | nullptr, &perm, nullptr, addr, size, MemoryState::FlagCanChangeAttribute, | 860 | nullptr, &perm, nullptr, addr, size, KMemoryState::FlagCanChangeAttribute, |
| 858 | MemoryState::FlagCanChangeAttribute, MemoryPermission::None, MemoryPermission::None, | 861 | KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None, |
| 859 | MemoryAttribute::LockedAndIpcLocked, MemoryAttribute::None, | 862 | KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None, |
| 860 | MemoryAttribute::DeviceSharedAndUncached)}; | 863 | KMemoryAttribute::DeviceSharedAndUncached)}; |
| 861 | result.IsError()) { | 864 | result.IsError()) { |
| 862 | return result; | 865 | return result; |
| 863 | } | 866 | } |
| 864 | 867 | ||
| 865 | block_manager->UpdateLock( | 868 | block_manager->UpdateLock( |
| 866 | addr, size / PageSize, | 869 | addr, size / PageSize, |
| 867 | [](MemoryBlockManager::iterator block, MemoryPermission perm) { | 870 | [](KMemoryBlockManager::iterator block, KMemoryPermission perm) { |
| 868 | block->ShareToDevice(perm); | 871 | block->ShareToDevice(perm); |
| 869 | }, | 872 | }, |
| 870 | perm); | 873 | perm); |
| @@ -875,19 +878,19 @@ ResultCode PageTable::LockForDeviceAddressSpace(VAddr addr, std::size_t size) { | |||
| 875 | ResultCode PageTable::UnlockForDeviceAddressSpace(VAddr addr, std::size_t size) { | 878 | ResultCode PageTable::UnlockForDeviceAddressSpace(VAddr addr, std::size_t size) { |
| 876 | std::lock_guard lock{page_table_lock}; | 879 | std::lock_guard lock{page_table_lock}; |
| 877 | 880 | ||
| 878 | MemoryPermission perm{}; | 881 | KMemoryPermission perm{}; |
| 879 | if (const ResultCode result{CheckMemoryState( | 882 | if (const ResultCode result{CheckMemoryState( |
| 880 | nullptr, &perm, nullptr, addr, size, MemoryState::FlagCanChangeAttribute, | 883 | nullptr, &perm, nullptr, addr, size, KMemoryState::FlagCanChangeAttribute, |
| 881 | MemoryState::FlagCanChangeAttribute, MemoryPermission::None, MemoryPermission::None, | 884 | KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None, |
| 882 | MemoryAttribute::LockedAndIpcLocked, MemoryAttribute::None, | 885 | KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None, |
| 883 | MemoryAttribute::DeviceSharedAndUncached)}; | 886 | KMemoryAttribute::DeviceSharedAndUncached)}; |
| 884 | result.IsError()) { | 887 | result.IsError()) { |
| 885 | return result; | 888 | return result; |
| 886 | } | 889 | } |
| 887 | 890 | ||
| 888 | block_manager->UpdateLock( | 891 | block_manager->UpdateLock( |
| 889 | addr, size / PageSize, | 892 | addr, size / PageSize, |
| 890 | [](MemoryBlockManager::iterator block, MemoryPermission perm) { | 893 | [](KMemoryBlockManager::iterator block, KMemoryPermission perm) { |
| 891 | block->UnshareToDevice(perm); | 894 | block->UnshareToDevice(perm); |
| 892 | }, | 895 | }, |
| 893 | perm); | 896 | perm); |
| @@ -896,15 +899,16 @@ ResultCode PageTable::UnlockForDeviceAddressSpace(VAddr addr, std::size_t size) | |||
| 896 | } | 899 | } |
| 897 | 900 | ||
| 898 | ResultCode PageTable::InitializeMemoryLayout(VAddr start, VAddr end) { | 901 | ResultCode PageTable::InitializeMemoryLayout(VAddr start, VAddr end) { |
| 899 | block_manager = std::make_unique<MemoryBlockManager>(start, end); | 902 | block_manager = std::make_unique<KMemoryBlockManager>(start, end); |
| 900 | 903 | ||
| 901 | return RESULT_SUCCESS; | 904 | return RESULT_SUCCESS; |
| 902 | } | 905 | } |
| 903 | 906 | ||
| 904 | bool PageTable::IsRegionMapped(VAddr address, u64 size) { | 907 | bool PageTable::IsRegionMapped(VAddr address, u64 size) { |
| 905 | return CheckMemoryState(address, size, MemoryState::All, MemoryState::Free, | 908 | return CheckMemoryState(address, size, KMemoryState::All, KMemoryState::Free, |
| 906 | MemoryPermission::Mask, MemoryPermission::None, MemoryAttribute::Mask, | 909 | KMemoryPermission::Mask, KMemoryPermission::None, |
| 907 | MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped) | 910 | KMemoryAttribute::Mask, KMemoryAttribute::None, |
| 911 | KMemoryAttribute::IpcAndDeviceMapped) | ||
| 908 | .IsError(); | 912 | .IsError(); |
| 909 | } | 913 | } |
| 910 | 914 | ||
| @@ -966,7 +970,7 @@ ResultCode PageTable::Operate(VAddr addr, std::size_t num_pages, const PageLinke | |||
| 966 | return RESULT_SUCCESS; | 970 | return RESULT_SUCCESS; |
| 967 | } | 971 | } |
| 968 | 972 | ||
| 969 | ResultCode PageTable::Operate(VAddr addr, std::size_t num_pages, MemoryPermission perm, | 973 | ResultCode PageTable::Operate(VAddr addr, std::size_t num_pages, KMemoryPermission perm, |
| 970 | OperationType operation, PAddr map_addr) { | 974 | OperationType operation, PAddr map_addr) { |
| 971 | std::lock_guard lock{page_table_lock}; | 975 | std::lock_guard lock{page_table_lock}; |
| 972 | 976 | ||
| @@ -993,34 +997,34 @@ ResultCode PageTable::Operate(VAddr addr, std::size_t num_pages, MemoryPermissio | |||
| 993 | return RESULT_SUCCESS; | 997 | return RESULT_SUCCESS; |
| 994 | } | 998 | } |
| 995 | 999 | ||
| 996 | constexpr VAddr PageTable::GetRegionAddress(MemoryState state) const { | 1000 | constexpr VAddr PageTable::GetRegionAddress(KMemoryState state) const { |
| 997 | switch (state) { | 1001 | switch (state) { |
| 998 | case MemoryState::Free: | 1002 | case KMemoryState::Free: |
| 999 | case MemoryState::Kernel: | 1003 | case KMemoryState::Kernel: |
| 1000 | return address_space_start; | 1004 | return address_space_start; |
| 1001 | case MemoryState::Normal: | 1005 | case KMemoryState::Normal: |
| 1002 | return heap_region_start; | 1006 | return heap_region_start; |
| 1003 | case MemoryState::Ipc: | 1007 | case KMemoryState::Ipc: |
| 1004 | case MemoryState::NonSecureIpc: | 1008 | case KMemoryState::NonSecureIpc: |
| 1005 | case MemoryState::NonDeviceIpc: | 1009 | case KMemoryState::NonDeviceIpc: |
| 1006 | return alias_region_start; | 1010 | return alias_region_start; |
| 1007 | case MemoryState::Stack: | 1011 | case KMemoryState::Stack: |
| 1008 | return stack_region_start; | 1012 | return stack_region_start; |
| 1009 | case MemoryState::Io: | 1013 | case KMemoryState::Io: |
| 1010 | case MemoryState::Static: | 1014 | case KMemoryState::Static: |
| 1011 | case MemoryState::ThreadLocal: | 1015 | case KMemoryState::ThreadLocal: |
| 1012 | return kernel_map_region_start; | 1016 | return kernel_map_region_start; |
| 1013 | case MemoryState::Shared: | 1017 | case KMemoryState::Shared: |
| 1014 | case MemoryState::AliasCode: | 1018 | case KMemoryState::AliasCode: |
| 1015 | case MemoryState::AliasCodeData: | 1019 | case KMemoryState::AliasCodeData: |
| 1016 | case MemoryState::Transferred: | 1020 | case KMemoryState::Transferred: |
| 1017 | case MemoryState::SharedTransferred: | 1021 | case KMemoryState::SharedTransferred: |
| 1018 | case MemoryState::SharedCode: | 1022 | case KMemoryState::SharedCode: |
| 1019 | case MemoryState::GeneratedCode: | 1023 | case KMemoryState::GeneratedCode: |
| 1020 | case MemoryState::CodeOut: | 1024 | case KMemoryState::CodeOut: |
| 1021 | return alias_code_region_start; | 1025 | return alias_code_region_start; |
| 1022 | case MemoryState::Code: | 1026 | case KMemoryState::Code: |
| 1023 | case MemoryState::CodeData: | 1027 | case KMemoryState::CodeData: |
| 1024 | return code_region_start; | 1028 | return code_region_start; |
| 1025 | default: | 1029 | default: |
| 1026 | UNREACHABLE(); | 1030 | UNREACHABLE(); |
| @@ -1028,34 +1032,34 @@ constexpr VAddr PageTable::GetRegionAddress(MemoryState state) const { | |||
| 1028 | } | 1032 | } |
| 1029 | } | 1033 | } |
| 1030 | 1034 | ||
| 1031 | constexpr std::size_t PageTable::GetRegionSize(MemoryState state) const { | 1035 | constexpr std::size_t PageTable::GetRegionSize(KMemoryState state) const { |
| 1032 | switch (state) { | 1036 | switch (state) { |
| 1033 | case MemoryState::Free: | 1037 | case KMemoryState::Free: |
| 1034 | case MemoryState::Kernel: | 1038 | case KMemoryState::Kernel: |
| 1035 | return address_space_end - address_space_start; | 1039 | return address_space_end - address_space_start; |
| 1036 | case MemoryState::Normal: | 1040 | case KMemoryState::Normal: |
| 1037 | return heap_region_end - heap_region_start; | 1041 | return heap_region_end - heap_region_start; |
| 1038 | case MemoryState::Ipc: | 1042 | case KMemoryState::Ipc: |
| 1039 | case MemoryState::NonSecureIpc: | 1043 | case KMemoryState::NonSecureIpc: |
| 1040 | case MemoryState::NonDeviceIpc: | 1044 | case KMemoryState::NonDeviceIpc: |
| 1041 | return alias_region_end - alias_region_start; | 1045 | return alias_region_end - alias_region_start; |
| 1042 | case MemoryState::Stack: | 1046 | case KMemoryState::Stack: |
| 1043 | return stack_region_end - stack_region_start; | 1047 | return stack_region_end - stack_region_start; |
| 1044 | case MemoryState::Io: | 1048 | case KMemoryState::Io: |
| 1045 | case MemoryState::Static: | 1049 | case KMemoryState::Static: |
| 1046 | case MemoryState::ThreadLocal: | 1050 | case KMemoryState::ThreadLocal: |
| 1047 | return kernel_map_region_end - kernel_map_region_start; | 1051 | return kernel_map_region_end - kernel_map_region_start; |
| 1048 | case MemoryState::Shared: | 1052 | case KMemoryState::Shared: |
| 1049 | case MemoryState::AliasCode: | 1053 | case KMemoryState::AliasCode: |
| 1050 | case MemoryState::AliasCodeData: | 1054 | case KMemoryState::AliasCodeData: |
| 1051 | case MemoryState::Transferred: | 1055 | case KMemoryState::Transferred: |
| 1052 | case MemoryState::SharedTransferred: | 1056 | case KMemoryState::SharedTransferred: |
| 1053 | case MemoryState::SharedCode: | 1057 | case KMemoryState::SharedCode: |
| 1054 | case MemoryState::GeneratedCode: | 1058 | case KMemoryState::GeneratedCode: |
| 1055 | case MemoryState::CodeOut: | 1059 | case KMemoryState::CodeOut: |
| 1056 | return alias_code_region_end - alias_code_region_start; | 1060 | return alias_code_region_end - alias_code_region_start; |
| 1057 | case MemoryState::Code: | 1061 | case KMemoryState::Code: |
| 1058 | case MemoryState::CodeData: | 1062 | case KMemoryState::CodeData: |
| 1059 | return code_region_end - code_region_start; | 1063 | return code_region_end - code_region_start; |
| 1060 | default: | 1064 | default: |
| 1061 | UNREACHABLE(); | 1065 | UNREACHABLE(); |
| @@ -1063,7 +1067,7 @@ constexpr std::size_t PageTable::GetRegionSize(MemoryState state) const { | |||
| 1063 | } | 1067 | } |
| 1064 | } | 1068 | } |
| 1065 | 1069 | ||
| 1066 | constexpr bool PageTable::CanContain(VAddr addr, std::size_t size, MemoryState state) const { | 1070 | constexpr bool PageTable::CanContain(VAddr addr, std::size_t size, KMemoryState state) const { |
| 1067 | const VAddr end{addr + size}; | 1071 | const VAddr end{addr + size}; |
| 1068 | const VAddr last{end - 1}; | 1072 | const VAddr last{end - 1}; |
| 1069 | const VAddr region_start{GetRegionAddress(state)}; | 1073 | const VAddr region_start{GetRegionAddress(state)}; |
| @@ -1074,30 +1078,30 @@ constexpr bool PageTable::CanContain(VAddr addr, std::size_t size, MemoryState s | |||
| 1074 | const bool is_in_alias{!(end <= alias_region_start || alias_region_end <= addr)}; | 1078 | const bool is_in_alias{!(end <= alias_region_start || alias_region_end <= addr)}; |
| 1075 | 1079 | ||
| 1076 | switch (state) { | 1080 | switch (state) { |
| 1077 | case MemoryState::Free: | 1081 | case KMemoryState::Free: |
| 1078 | case MemoryState::Kernel: | 1082 | case KMemoryState::Kernel: |
| 1079 | return is_in_region; | 1083 | return is_in_region; |
| 1080 | case MemoryState::Io: | 1084 | case KMemoryState::Io: |
| 1081 | case MemoryState::Static: | 1085 | case KMemoryState::Static: |
| 1082 | case MemoryState::Code: | 1086 | case KMemoryState::Code: |
| 1083 | case MemoryState::CodeData: | 1087 | case KMemoryState::CodeData: |
| 1084 | case MemoryState::Shared: | 1088 | case KMemoryState::Shared: |
| 1085 | case MemoryState::AliasCode: | 1089 | case KMemoryState::AliasCode: |
| 1086 | case MemoryState::AliasCodeData: | 1090 | case KMemoryState::AliasCodeData: |
| 1087 | case MemoryState::Stack: | 1091 | case KMemoryState::Stack: |
| 1088 | case MemoryState::ThreadLocal: | 1092 | case KMemoryState::ThreadLocal: |
| 1089 | case MemoryState::Transferred: | 1093 | case KMemoryState::Transferred: |
| 1090 | case MemoryState::SharedTransferred: | 1094 | case KMemoryState::SharedTransferred: |
| 1091 | case MemoryState::SharedCode: | 1095 | case KMemoryState::SharedCode: |
| 1092 | case MemoryState::GeneratedCode: | 1096 | case KMemoryState::GeneratedCode: |
| 1093 | case MemoryState::CodeOut: | 1097 | case KMemoryState::CodeOut: |
| 1094 | return is_in_region && !is_in_heap && !is_in_alias; | 1098 | return is_in_region && !is_in_heap && !is_in_alias; |
| 1095 | case MemoryState::Normal: | 1099 | case KMemoryState::Normal: |
| 1096 | ASSERT(is_in_heap); | 1100 | ASSERT(is_in_heap); |
| 1097 | return is_in_region && !is_in_alias; | 1101 | return is_in_region && !is_in_alias; |
| 1098 | case MemoryState::Ipc: | 1102 | case KMemoryState::Ipc: |
| 1099 | case MemoryState::NonSecureIpc: | 1103 | case KMemoryState::NonSecureIpc: |
| 1100 | case MemoryState::NonDeviceIpc: | 1104 | case KMemoryState::NonDeviceIpc: |
| 1101 | ASSERT(is_in_alias); | 1105 | ASSERT(is_in_alias); |
| 1102 | return is_in_region && !is_in_heap; | 1106 | return is_in_region && !is_in_heap; |
| 1103 | default: | 1107 | default: |
| @@ -1105,10 +1109,10 @@ constexpr bool PageTable::CanContain(VAddr addr, std::size_t size, MemoryState s | |||
| 1105 | } | 1109 | } |
| 1106 | } | 1110 | } |
| 1107 | 1111 | ||
| 1108 | constexpr ResultCode PageTable::CheckMemoryState(const MemoryInfo& info, MemoryState state_mask, | 1112 | constexpr ResultCode PageTable::CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask, |
| 1109 | MemoryState state, MemoryPermission perm_mask, | 1113 | KMemoryState state, KMemoryPermission perm_mask, |
| 1110 | MemoryPermission perm, MemoryAttribute attr_mask, | 1114 | KMemoryPermission perm, KMemoryAttribute attr_mask, |
| 1111 | MemoryAttribute attr) const { | 1115 | KMemoryAttribute attr) const { |
| 1112 | // Validate the states match expectation | 1116 | // Validate the states match expectation |
| 1113 | if ((info.state & state_mask) != state) { | 1117 | if ((info.state & state_mask) != state) { |
| 1114 | return ResultInvalidCurrentMemory; | 1118 | return ResultInvalidCurrentMemory; |
| @@ -1123,23 +1127,23 @@ constexpr ResultCode PageTable::CheckMemoryState(const MemoryInfo& info, MemoryS | |||
| 1123 | return RESULT_SUCCESS; | 1127 | return RESULT_SUCCESS; |
| 1124 | } | 1128 | } |
| 1125 | 1129 | ||
| 1126 | ResultCode PageTable::CheckMemoryState(MemoryState* out_state, MemoryPermission* out_perm, | 1130 | ResultCode PageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, |
| 1127 | MemoryAttribute* out_attr, VAddr addr, std::size_t size, | 1131 | KMemoryAttribute* out_attr, VAddr addr, std::size_t size, |
| 1128 | MemoryState state_mask, MemoryState state, | 1132 | KMemoryState state_mask, KMemoryState state, |
| 1129 | MemoryPermission perm_mask, MemoryPermission perm, | 1133 | KMemoryPermission perm_mask, KMemoryPermission perm, |
| 1130 | MemoryAttribute attr_mask, MemoryAttribute attr, | 1134 | KMemoryAttribute attr_mask, KMemoryAttribute attr, |
| 1131 | MemoryAttribute ignore_attr) { | 1135 | KMemoryAttribute ignore_attr) { |
| 1132 | std::lock_guard lock{page_table_lock}; | 1136 | std::lock_guard lock{page_table_lock}; |
| 1133 | 1137 | ||
| 1134 | // Get information about the first block | 1138 | // Get information about the first block |
| 1135 | const VAddr last_addr{addr + size - 1}; | 1139 | const VAddr last_addr{addr + size - 1}; |
| 1136 | MemoryBlockManager::const_iterator it{block_manager->FindIterator(addr)}; | 1140 | KMemoryBlockManager::const_iterator it{block_manager->FindIterator(addr)}; |
| 1137 | MemoryInfo info{it->GetMemoryInfo()}; | 1141 | KMemoryInfo info{it->GetMemoryInfo()}; |
| 1138 | 1142 | ||
| 1139 | // Validate all blocks in the range have correct state | 1143 | // Validate all blocks in the range have correct state |
| 1140 | const MemoryState first_state{info.state}; | 1144 | const KMemoryState first_state{info.state}; |
| 1141 | const MemoryPermission first_perm{info.perm}; | 1145 | const KMemoryPermission first_perm{info.perm}; |
| 1142 | const MemoryAttribute first_attr{info.attribute}; | 1146 | const KMemoryAttribute first_attr{info.attribute}; |
| 1143 | 1147 | ||
| 1144 | while (true) { | 1148 | while (true) { |
| 1145 | // Validate the current block | 1149 | // Validate the current block |
| @@ -1149,8 +1153,8 @@ ResultCode PageTable::CheckMemoryState(MemoryState* out_state, MemoryPermission* | |||
| 1149 | if (!(info.perm == first_perm)) { | 1153 | if (!(info.perm == first_perm)) { |
| 1150 | return ResultInvalidCurrentMemory; | 1154 | return ResultInvalidCurrentMemory; |
| 1151 | } | 1155 | } |
| 1152 | if (!((info.attribute | static_cast<MemoryAttribute>(ignore_attr)) == | 1156 | if (!((info.attribute | static_cast<KMemoryAttribute>(ignore_attr)) == |
| 1153 | (first_attr | static_cast<MemoryAttribute>(ignore_attr)))) { | 1157 | (first_attr | static_cast<KMemoryAttribute>(ignore_attr)))) { |
| 1154 | return ResultInvalidCurrentMemory; | 1158 | return ResultInvalidCurrentMemory; |
| 1155 | } | 1159 | } |
| 1156 | 1160 | ||
| @@ -1176,7 +1180,7 @@ ResultCode PageTable::CheckMemoryState(MemoryState* out_state, MemoryPermission* | |||
| 1176 | *out_perm = first_perm; | 1180 | *out_perm = first_perm; |
| 1177 | } | 1181 | } |
| 1178 | if (out_attr) { | 1182 | if (out_attr) { |
| 1179 | *out_attr = first_attr & static_cast<MemoryAttribute>(~ignore_attr); | 1183 | *out_attr = first_attr & static_cast<KMemoryAttribute>(~ignore_attr); |
| 1180 | } | 1184 | } |
| 1181 | 1185 | ||
| 1182 | return RESULT_SUCCESS; | 1186 | return RESULT_SUCCESS; |
diff --git a/src/core/hle/kernel/memory/page_table.h b/src/core/hle/kernel/memory/page_table.h index ce0d38849..a4914d050 100644 --- a/src/core/hle/kernel/memory/page_table.h +++ b/src/core/hle/kernel/memory/page_table.h | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "common/page_table.h" | 11 | #include "common/page_table.h" |
| 12 | #include "core/file_sys/program_metadata.h" | 12 | #include "core/file_sys/program_metadata.h" |
| 13 | #include "core/hle/kernel/memory/memory_block.h" | 13 | #include "core/hle/kernel/k_memory_block.h" |
| 14 | #include "core/hle/kernel/memory/memory_manager.h" | 14 | #include "core/hle/kernel/memory/memory_manager.h" |
| 15 | #include "core/hle/result.h" | 15 | #include "core/hle/result.h" |
| 16 | 16 | ||
| @@ -18,9 +18,11 @@ namespace Core { | |||
| 18 | class System; | 18 | class System; |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | namespace Kernel::Memory { | 21 | namespace Kernel { |
| 22 | class KMemoryBlockManager; | ||
| 23 | } | ||
| 22 | 24 | ||
| 23 | class MemoryBlockManager; | 25 | namespace Kernel::Memory { |
| 24 | 26 | ||
| 25 | class PageTable final : NonCopyable { | 27 | class PageTable final : NonCopyable { |
| 26 | public: | 28 | public: |
| @@ -29,8 +31,8 @@ public: | |||
| 29 | ResultCode InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr, | 31 | ResultCode InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr, |
| 30 | VAddr code_addr, std::size_t code_size, | 32 | VAddr code_addr, std::size_t code_size, |
| 31 | Memory::MemoryManager::Pool pool); | 33 | Memory::MemoryManager::Pool pool); |
| 32 | ResultCode MapProcessCode(VAddr addr, std::size_t pages_count, MemoryState state, | 34 | ResultCode MapProcessCode(VAddr addr, std::size_t pages_count, KMemoryState state, |
| 33 | MemoryPermission perm); | 35 | KMemoryPermission perm); |
| 34 | ResultCode MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size); | 36 | ResultCode MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size); |
| 35 | ResultCode UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size); | 37 | ResultCode UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size); |
| 36 | ResultCode MapPhysicalMemory(VAddr addr, std::size_t size); | 38 | ResultCode MapPhysicalMemory(VAddr addr, std::size_t size); |
| @@ -38,20 +40,20 @@ public: | |||
| 38 | ResultCode UnmapMemory(VAddr addr, std::size_t size); | 40 | ResultCode UnmapMemory(VAddr addr, std::size_t size); |
| 39 | ResultCode Map(VAddr dst_addr, VAddr src_addr, std::size_t size); | 41 | ResultCode Map(VAddr dst_addr, VAddr src_addr, std::size_t size); |
| 40 | ResultCode Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size); | 42 | ResultCode Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size); |
| 41 | ResultCode MapPages(VAddr addr, PageLinkedList& page_linked_list, MemoryState state, | 43 | ResultCode MapPages(VAddr addr, PageLinkedList& page_linked_list, KMemoryState state, |
| 42 | MemoryPermission perm); | 44 | KMemoryPermission perm); |
| 43 | ResultCode SetCodeMemoryPermission(VAddr addr, std::size_t size, MemoryPermission perm); | 45 | ResultCode SetCodeMemoryPermission(VAddr addr, std::size_t size, KMemoryPermission perm); |
| 44 | MemoryInfo QueryInfo(VAddr addr); | 46 | KMemoryInfo QueryInfo(VAddr addr); |
| 45 | ResultCode ReserveTransferMemory(VAddr addr, std::size_t size, MemoryPermission perm); | 47 | ResultCode ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm); |
| 46 | ResultCode ResetTransferMemory(VAddr addr, std::size_t size); | 48 | ResultCode ResetTransferMemory(VAddr addr, std::size_t size); |
| 47 | ResultCode SetMemoryAttribute(VAddr addr, std::size_t size, MemoryAttribute mask, | 49 | ResultCode SetMemoryAttribute(VAddr addr, std::size_t size, KMemoryAttribute mask, |
| 48 | MemoryAttribute value); | 50 | KMemoryAttribute value); |
| 49 | ResultCode SetHeapCapacity(std::size_t new_heap_capacity); | 51 | ResultCode SetHeapCapacity(std::size_t new_heap_capacity); |
| 50 | ResultVal<VAddr> SetHeapSize(std::size_t size); | 52 | ResultVal<VAddr> SetHeapSize(std::size_t size); |
| 51 | ResultVal<VAddr> AllocateAndMapMemory(std::size_t needed_num_pages, std::size_t align, | 53 | ResultVal<VAddr> AllocateAndMapMemory(std::size_t needed_num_pages, std::size_t align, |
| 52 | bool is_map_only, VAddr region_start, | 54 | bool is_map_only, VAddr region_start, |
| 53 | std::size_t region_num_pages, MemoryState state, | 55 | std::size_t region_num_pages, KMemoryState state, |
| 54 | MemoryPermission perm, PAddr map_addr = 0); | 56 | KMemoryPermission perm, PAddr map_addr = 0); |
| 55 | ResultCode LockForDeviceAddressSpace(VAddr addr, std::size_t size); | 57 | ResultCode LockForDeviceAddressSpace(VAddr addr, std::size_t size); |
| 56 | ResultCode UnlockForDeviceAddressSpace(VAddr addr, std::size_t size); | 58 | ResultCode UnlockForDeviceAddressSpace(VAddr addr, std::size_t size); |
| 57 | 59 | ||
| @@ -72,47 +74,48 @@ private: | |||
| 72 | ChangePermissionsAndRefresh, | 74 | ChangePermissionsAndRefresh, |
| 73 | }; | 75 | }; |
| 74 | 76 | ||
| 75 | static constexpr MemoryAttribute DefaultMemoryIgnoreAttr = | 77 | static constexpr KMemoryAttribute DefaultMemoryIgnoreAttr = KMemoryAttribute::DontCareMask | |
| 76 | MemoryAttribute::DontCareMask | MemoryAttribute::IpcLocked | MemoryAttribute::DeviceShared; | 78 | KMemoryAttribute::IpcLocked | |
| 79 | KMemoryAttribute::DeviceShared; | ||
| 77 | 80 | ||
| 78 | ResultCode InitializeMemoryLayout(VAddr start, VAddr end); | 81 | ResultCode InitializeMemoryLayout(VAddr start, VAddr end); |
| 79 | ResultCode MapPages(VAddr addr, const PageLinkedList& page_linked_list, MemoryPermission perm); | 82 | ResultCode MapPages(VAddr addr, const PageLinkedList& page_linked_list, KMemoryPermission perm); |
| 80 | void MapPhysicalMemory(PageLinkedList& page_linked_list, VAddr start, VAddr end); | 83 | void MapPhysicalMemory(PageLinkedList& page_linked_list, VAddr start, VAddr end); |
| 81 | bool IsRegionMapped(VAddr address, u64 size); | 84 | bool IsRegionMapped(VAddr address, u64 size); |
| 82 | bool IsRegionContiguous(VAddr addr, u64 size) const; | 85 | bool IsRegionContiguous(VAddr addr, u64 size) const; |
| 83 | void AddRegionToPages(VAddr start, std::size_t num_pages, PageLinkedList& page_linked_list); | 86 | void AddRegionToPages(VAddr start, std::size_t num_pages, PageLinkedList& page_linked_list); |
| 84 | MemoryInfo QueryInfoImpl(VAddr addr); | 87 | KMemoryInfo QueryInfoImpl(VAddr addr); |
| 85 | VAddr AllocateVirtualMemory(VAddr start, std::size_t region_num_pages, u64 needed_num_pages, | 88 | VAddr AllocateVirtualMemory(VAddr start, std::size_t region_num_pages, u64 needed_num_pages, |
| 86 | std::size_t align); | 89 | std::size_t align); |
| 87 | ResultCode Operate(VAddr addr, std::size_t num_pages, const PageLinkedList& page_group, | 90 | ResultCode Operate(VAddr addr, std::size_t num_pages, const PageLinkedList& page_group, |
| 88 | OperationType operation); | 91 | OperationType operation); |
| 89 | ResultCode Operate(VAddr addr, std::size_t num_pages, MemoryPermission perm, | 92 | ResultCode Operate(VAddr addr, std::size_t num_pages, KMemoryPermission perm, |
| 90 | OperationType operation, PAddr map_addr = 0); | 93 | OperationType operation, PAddr map_addr = 0); |
| 91 | constexpr VAddr GetRegionAddress(MemoryState state) const; | 94 | constexpr VAddr GetRegionAddress(KMemoryState state) const; |
| 92 | constexpr std::size_t GetRegionSize(MemoryState state) const; | 95 | constexpr std::size_t GetRegionSize(KMemoryState state) const; |
| 93 | constexpr bool CanContain(VAddr addr, std::size_t size, MemoryState state) const; | 96 | constexpr bool CanContain(VAddr addr, std::size_t size, KMemoryState state) const; |
| 94 | 97 | ||
| 95 | constexpr ResultCode CheckMemoryState(const MemoryInfo& info, MemoryState state_mask, | 98 | constexpr ResultCode CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask, |
| 96 | MemoryState state, MemoryPermission perm_mask, | 99 | KMemoryState state, KMemoryPermission perm_mask, |
| 97 | MemoryPermission perm, MemoryAttribute attr_mask, | 100 | KMemoryPermission perm, KMemoryAttribute attr_mask, |
| 98 | MemoryAttribute attr) const; | 101 | KMemoryAttribute attr) const; |
| 99 | ResultCode CheckMemoryState(MemoryState* out_state, MemoryPermission* out_perm, | 102 | ResultCode CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, |
| 100 | MemoryAttribute* out_attr, VAddr addr, std::size_t size, | 103 | KMemoryAttribute* out_attr, VAddr addr, std::size_t size, |
| 101 | MemoryState state_mask, MemoryState state, | 104 | KMemoryState state_mask, KMemoryState state, |
| 102 | MemoryPermission perm_mask, MemoryPermission perm, | 105 | KMemoryPermission perm_mask, KMemoryPermission perm, |
| 103 | MemoryAttribute attr_mask, MemoryAttribute attr, | 106 | KMemoryAttribute attr_mask, KMemoryAttribute attr, |
| 104 | MemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr); | 107 | KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr); |
| 105 | ResultCode CheckMemoryState(VAddr addr, std::size_t size, MemoryState state_mask, | 108 | ResultCode CheckMemoryState(VAddr addr, std::size_t size, KMemoryState state_mask, |
| 106 | MemoryState state, MemoryPermission perm_mask, | 109 | KMemoryState state, KMemoryPermission perm_mask, |
| 107 | MemoryPermission perm, MemoryAttribute attr_mask, | 110 | KMemoryPermission perm, KMemoryAttribute attr_mask, |
| 108 | MemoryAttribute attr, | 111 | KMemoryAttribute attr, |
| 109 | MemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) { | 112 | KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) { |
| 110 | return CheckMemoryState(nullptr, nullptr, nullptr, addr, size, state_mask, state, perm_mask, | 113 | return CheckMemoryState(nullptr, nullptr, nullptr, addr, size, state_mask, state, perm_mask, |
| 111 | perm, attr_mask, attr, ignore_attr); | 114 | perm, attr_mask, attr, ignore_attr); |
| 112 | } | 115 | } |
| 113 | 116 | ||
| 114 | std::recursive_mutex page_table_lock; | 117 | std::recursive_mutex page_table_lock; |
| 115 | std::unique_ptr<MemoryBlockManager> block_manager; | 118 | std::unique_ptr<KMemoryBlockManager> block_manager; |
| 116 | 119 | ||
| 117 | public: | 120 | public: |
| 118 | constexpr VAddr GetAddressSpaceStart() const { | 121 | constexpr VAddr GetAddressSpaceStart() const { |
| @@ -212,7 +215,7 @@ public: | |||
| 212 | return !IsOutsideASLRRegion(address, size); | 215 | return !IsOutsideASLRRegion(address, size); |
| 213 | } | 216 | } |
| 214 | constexpr PAddr GetPhysicalAddr(VAddr addr) { | 217 | constexpr PAddr GetPhysicalAddr(VAddr addr) { |
| 215 | return page_table_impl.backing_addr[addr >> Memory::PageBits] + addr; | 218 | return page_table_impl.backing_addr[addr >> PageBits] + addr; |
| 216 | } | 219 | } |
| 217 | 220 | ||
| 218 | private: | 221 | private: |
diff --git a/src/core/hle/kernel/memory/memory_types.h b/src/core/hle/kernel/memory_types.h index a75bf77c0..d458f0eca 100644 --- a/src/core/hle/kernel/memory/memory_types.h +++ b/src/core/hle/kernel/memory_types.h | |||
| @@ -8,11 +8,11 @@ | |||
| 8 | 8 | ||
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | 10 | ||
| 11 | namespace Kernel::Memory { | 11 | namespace Kernel { |
| 12 | 12 | ||
| 13 | constexpr std::size_t PageBits{12}; | 13 | constexpr std::size_t PageBits{12}; |
| 14 | constexpr std::size_t PageSize{1 << PageBits}; | 14 | constexpr std::size_t PageSize{1 << PageBits}; |
| 15 | 15 | ||
| 16 | using Page = std::array<u8, PageSize>; | 16 | using Page = std::array<u8, PageSize>; |
| 17 | 17 | ||
| 18 | } // namespace Kernel::Memory | 18 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 47b3ac57b..f83977a8e 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -14,14 +14,14 @@ | |||
| 14 | #include "core/device_memory.h" | 14 | #include "core/device_memory.h" |
| 15 | #include "core/file_sys/program_metadata.h" | 15 | #include "core/file_sys/program_metadata.h" |
| 16 | #include "core/hle/kernel/code_set.h" | 16 | #include "core/hle/kernel/code_set.h" |
| 17 | #include "core/hle/kernel/k_memory_block_manager.h" | ||
| 17 | #include "core/hle/kernel/k_resource_limit.h" | 18 | #include "core/hle/kernel/k_resource_limit.h" |
| 18 | #include "core/hle/kernel/k_scheduler.h" | 19 | #include "core/hle/kernel/k_scheduler.h" |
| 19 | #include "core/hle/kernel/k_scoped_resource_reservation.h" | 20 | #include "core/hle/kernel/k_scoped_resource_reservation.h" |
| 21 | #include "core/hle/kernel/k_slab_heap.h" | ||
| 20 | #include "core/hle/kernel/k_thread.h" | 22 | #include "core/hle/kernel/k_thread.h" |
| 21 | #include "core/hle/kernel/kernel.h" | 23 | #include "core/hle/kernel/kernel.h" |
| 22 | #include "core/hle/kernel/memory/memory_block_manager.h" | ||
| 23 | #include "core/hle/kernel/memory/page_table.h" | 24 | #include "core/hle/kernel/memory/page_table.h" |
| 24 | #include "core/hle/kernel/memory/slab_heap.h" | ||
| 25 | #include "core/hle/kernel/process.h" | 25 | #include "core/hle/kernel/process.h" |
| 26 | #include "core/hle/kernel/svc_results.h" | 26 | #include "core/hle/kernel/svc_results.h" |
| 27 | #include "core/hle/lock.h" | 27 | #include "core/hle/lock.h" |
| @@ -291,9 +291,9 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, | |||
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | // Map process code region | 293 | // Map process code region |
| 294 | if (const ResultCode result{page_table->MapProcessCode( | 294 | if (const ResultCode result{page_table->MapProcessCode(page_table->GetCodeRegionStart(), |
| 295 | page_table->GetCodeRegionStart(), code_size / Memory::PageSize, | 295 | code_size / PageSize, KMemoryState::Code, |
| 296 | Memory::MemoryState::Code, Memory::MemoryPermission::None)}; | 296 | KMemoryPermission::None)}; |
| 297 | result.IsError()) { | 297 | result.IsError()) { |
| 298 | return result; | 298 | return result; |
| 299 | } | 299 | } |
| @@ -400,22 +400,22 @@ VAddr Process::CreateTLSRegion() { | |||
| 400 | return *tls_page_iter->ReserveSlot(); | 400 | return *tls_page_iter->ReserveSlot(); |
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | Memory::Page* const tls_page_ptr{kernel.GetUserSlabHeapPages().Allocate()}; | 403 | Page* const tls_page_ptr{kernel.GetUserSlabHeapPages().Allocate()}; |
| 404 | ASSERT(tls_page_ptr); | 404 | ASSERT(tls_page_ptr); |
| 405 | 405 | ||
| 406 | const VAddr start{page_table->GetKernelMapRegionStart()}; | 406 | const VAddr start{page_table->GetKernelMapRegionStart()}; |
| 407 | const VAddr size{page_table->GetKernelMapRegionEnd() - start}; | 407 | const VAddr size{page_table->GetKernelMapRegionEnd() - start}; |
| 408 | const PAddr tls_map_addr{system.DeviceMemory().GetPhysicalAddr(tls_page_ptr)}; | 408 | const PAddr tls_map_addr{system.DeviceMemory().GetPhysicalAddr(tls_page_ptr)}; |
| 409 | const VAddr tls_page_addr{ | 409 | const VAddr tls_page_addr{page_table |
| 410 | page_table | 410 | ->AllocateAndMapMemory(1, PageSize, true, start, size / PageSize, |
| 411 | ->AllocateAndMapMemory(1, Memory::PageSize, true, start, size / Memory::PageSize, | 411 | KMemoryState::ThreadLocal, |
| 412 | Memory::MemoryState::ThreadLocal, | 412 | KMemoryPermission::ReadAndWrite, |
| 413 | Memory::MemoryPermission::ReadAndWrite, tls_map_addr) | 413 | tls_map_addr) |
| 414 | .ValueOr(0)}; | 414 | .ValueOr(0)}; |
| 415 | 415 | ||
| 416 | ASSERT(tls_page_addr); | 416 | ASSERT(tls_page_addr); |
| 417 | 417 | ||
| 418 | std::memset(tls_page_ptr, 0, Memory::PageSize); | 418 | std::memset(tls_page_ptr, 0, PageSize); |
| 419 | tls_pages.emplace_back(tls_page_addr); | 419 | tls_pages.emplace_back(tls_page_addr); |
| 420 | 420 | ||
| 421 | const auto reserve_result{tls_pages.back().ReserveSlot()}; | 421 | const auto reserve_result{tls_pages.back().ReserveSlot()}; |
| @@ -442,15 +442,15 @@ void Process::FreeTLSRegion(VAddr tls_address) { | |||
| 442 | void Process::LoadModule(CodeSet code_set, VAddr base_addr) { | 442 | void Process::LoadModule(CodeSet code_set, VAddr base_addr) { |
| 443 | std::lock_guard lock{HLE::g_hle_lock}; | 443 | std::lock_guard lock{HLE::g_hle_lock}; |
| 444 | const auto ReprotectSegment = [&](const CodeSet::Segment& segment, | 444 | const auto ReprotectSegment = [&](const CodeSet::Segment& segment, |
| 445 | Memory::MemoryPermission permission) { | 445 | KMemoryPermission permission) { |
| 446 | page_table->SetCodeMemoryPermission(segment.addr + base_addr, segment.size, permission); | 446 | page_table->SetCodeMemoryPermission(segment.addr + base_addr, segment.size, permission); |
| 447 | }; | 447 | }; |
| 448 | 448 | ||
| 449 | system.Memory().WriteBlock(*this, base_addr, code_set.memory.data(), code_set.memory.size()); | 449 | system.Memory().WriteBlock(*this, base_addr, code_set.memory.data(), code_set.memory.size()); |
| 450 | 450 | ||
| 451 | ReprotectSegment(code_set.CodeSegment(), Memory::MemoryPermission::ReadAndExecute); | 451 | ReprotectSegment(code_set.CodeSegment(), KMemoryPermission::ReadAndExecute); |
| 452 | ReprotectSegment(code_set.RODataSegment(), Memory::MemoryPermission::Read); | 452 | ReprotectSegment(code_set.RODataSegment(), KMemoryPermission::Read); |
| 453 | ReprotectSegment(code_set.DataSegment(), Memory::MemoryPermission::ReadAndWrite); | 453 | ReprotectSegment(code_set.DataSegment(), KMemoryPermission::ReadAndWrite); |
| 454 | } | 454 | } |
| 455 | 455 | ||
| 456 | bool Process::IsSignaled() const { | 456 | bool Process::IsSignaled() const { |
| @@ -479,16 +479,15 @@ ResultCode Process::AllocateMainThreadStack(std::size_t stack_size) { | |||
| 479 | ASSERT(stack_size); | 479 | ASSERT(stack_size); |
| 480 | 480 | ||
| 481 | // The kernel always ensures that the given stack size is page aligned. | 481 | // The kernel always ensures that the given stack size is page aligned. |
| 482 | main_thread_stack_size = Common::AlignUp(stack_size, Memory::PageSize); | 482 | main_thread_stack_size = Common::AlignUp(stack_size, PageSize); |
| 483 | 483 | ||
| 484 | const VAddr start{page_table->GetStackRegionStart()}; | 484 | const VAddr start{page_table->GetStackRegionStart()}; |
| 485 | const std::size_t size{page_table->GetStackRegionEnd() - start}; | 485 | const std::size_t size{page_table->GetStackRegionEnd() - start}; |
| 486 | 486 | ||
| 487 | CASCADE_RESULT(main_thread_stack_top, | 487 | CASCADE_RESULT(main_thread_stack_top, |
| 488 | page_table->AllocateAndMapMemory( | 488 | page_table->AllocateAndMapMemory( |
| 489 | main_thread_stack_size / Memory::PageSize, Memory::PageSize, false, start, | 489 | main_thread_stack_size / PageSize, PageSize, false, start, size / PageSize, |
| 490 | size / Memory::PageSize, Memory::MemoryState::Stack, | 490 | KMemoryState::Stack, KMemoryPermission::ReadAndWrite)); |
| 491 | Memory::MemoryPermission::ReadAndWrite)); | ||
| 492 | 491 | ||
| 493 | main_thread_stack_top += main_thread_stack_size; | 492 | main_thread_stack_top += main_thread_stack_size; |
| 494 | 493 | ||
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 12cfdcf2c..4ffd65d33 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include "core/hle/kernel/k_address_arbiter.h" | 27 | #include "core/hle/kernel/k_address_arbiter.h" |
| 28 | #include "core/hle/kernel/k_condition_variable.h" | 28 | #include "core/hle/kernel/k_condition_variable.h" |
| 29 | #include "core/hle/kernel/k_event.h" | 29 | #include "core/hle/kernel/k_event.h" |
| 30 | #include "core/hle/kernel/k_memory_block.h" | ||
| 30 | #include "core/hle/kernel/k_memory_layout.h" | 31 | #include "core/hle/kernel/k_memory_layout.h" |
| 31 | #include "core/hle/kernel/k_readable_event.h" | 32 | #include "core/hle/kernel/k_readable_event.h" |
| 32 | #include "core/hle/kernel/k_resource_limit.h" | 33 | #include "core/hle/kernel/k_resource_limit.h" |
| @@ -38,7 +39,6 @@ | |||
| 38 | #include "core/hle/kernel/k_thread.h" | 39 | #include "core/hle/kernel/k_thread.h" |
| 39 | #include "core/hle/kernel/k_writable_event.h" | 40 | #include "core/hle/kernel/k_writable_event.h" |
| 40 | #include "core/hle/kernel/kernel.h" | 41 | #include "core/hle/kernel/kernel.h" |
| 41 | #include "core/hle/kernel/memory/memory_block.h" | ||
| 42 | #include "core/hle/kernel/memory/page_table.h" | 42 | #include "core/hle/kernel/memory/page_table.h" |
| 43 | #include "core/hle/kernel/physical_core.h" | 43 | #include "core/hle/kernel/physical_core.h" |
| 44 | #include "core/hle/kernel/process.h" | 44 | #include "core/hle/kernel/process.h" |
| @@ -230,9 +230,9 @@ static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 si | |||
| 230 | return ResultInvalidCurrentMemory; | 230 | return ResultInvalidCurrentMemory; |
| 231 | } | 231 | } |
| 232 | 232 | ||
| 233 | const auto attributes{static_cast<Memory::MemoryAttribute>(mask | attribute)}; | 233 | const auto attributes{static_cast<MemoryAttribute>(mask | attribute)}; |
| 234 | if (attributes != static_cast<Memory::MemoryAttribute>(mask) || | 234 | if (attributes != static_cast<MemoryAttribute>(mask) || |
| 235 | (attributes | Memory::MemoryAttribute::Uncached) != Memory::MemoryAttribute::Uncached) { | 235 | (attributes | MemoryAttribute::Uncached) != MemoryAttribute::Uncached) { |
| 236 | LOG_ERROR(Kernel_SVC, | 236 | LOG_ERROR(Kernel_SVC, |
| 237 | "Memory attribute doesn't match the given mask (Attribute: 0x{:X}, Mask: {:X}", | 237 | "Memory attribute doesn't match the given mask (Attribute: 0x{:X}, Mask: {:X}", |
| 238 | attribute, mask); | 238 | attribute, mask); |
| @@ -241,8 +241,8 @@ static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 si | |||
| 241 | 241 | ||
| 242 | auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; | 242 | auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; |
| 243 | 243 | ||
| 244 | return page_table.SetMemoryAttribute(address, size, static_cast<Memory::MemoryAttribute>(mask), | 244 | return page_table.SetMemoryAttribute(address, size, static_cast<KMemoryAttribute>(mask), |
| 245 | static_cast<Memory::MemoryAttribute>(attribute)); | 245 | static_cast<KMemoryAttribute>(attribute)); |
| 246 | } | 246 | } |
| 247 | 247 | ||
| 248 | static ResultCode SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask, | 248 | static ResultCode SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask, |
| @@ -1231,9 +1231,8 @@ static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_han | |||
| 1231 | return ResultInvalidCurrentMemory; | 1231 | return ResultInvalidCurrentMemory; |
| 1232 | } | 1232 | } |
| 1233 | 1233 | ||
| 1234 | const auto permission_type = static_cast<Memory::MemoryPermission>(permissions); | 1234 | const auto permission_type = static_cast<MemoryPermission>(permissions); |
| 1235 | if ((permission_type | Memory::MemoryPermission::Write) != | 1235 | if ((permission_type | MemoryPermission::Write) != MemoryPermission::ReadWrite) { |
| 1236 | Memory::MemoryPermission::ReadAndWrite) { | ||
| 1237 | LOG_ERROR(Kernel_SVC, "Expected Read or ReadWrite permission but got permissions=0x{:08X}", | 1236 | LOG_ERROR(Kernel_SVC, "Expected Read or ReadWrite permission but got permissions=0x{:08X}", |
| 1238 | permissions); | 1237 | permissions); |
| 1239 | return ResultInvalidMemoryPermissions; | 1238 | return ResultInvalidMemoryPermissions; |
| @@ -1273,7 +1272,8 @@ static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_han | |||
| 1273 | return ResultInvalidHandle; | 1272 | return ResultInvalidHandle; |
| 1274 | } | 1273 | } |
| 1275 | 1274 | ||
| 1276 | return shared_memory->Map(*current_process, addr, size, permission_type); | 1275 | return shared_memory->Map(*current_process, addr, size, |
| 1276 | static_cast<KMemoryPermission>(permission_type)); | ||
| 1277 | } | 1277 | } |
| 1278 | 1278 | ||
| 1279 | static ResultCode MapSharedMemory32(Core::System& system, Handle shared_memory_handle, u32 addr, | 1279 | static ResultCode MapSharedMemory32(Core::System& system, Handle shared_memory_handle, u32 addr, |
| @@ -1886,9 +1886,8 @@ static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAd | |||
| 1886 | return ResultInvalidCurrentMemory; | 1886 | return ResultInvalidCurrentMemory; |
| 1887 | } | 1887 | } |
| 1888 | 1888 | ||
| 1889 | const auto perms{static_cast<Memory::MemoryPermission>(permissions)}; | 1889 | const auto perms{static_cast<MemoryPermission>(permissions)}; |
| 1890 | if (perms > Memory::MemoryPermission::ReadAndWrite || | 1890 | if (perms > MemoryPermission::ReadWrite || perms == MemoryPermission::Write) { |
| 1891 | perms == Memory::MemoryPermission::Write) { | ||
| 1892 | LOG_ERROR(Kernel_SVC, "Invalid memory permissions for transfer memory! (perms={:08X})", | 1891 | LOG_ERROR(Kernel_SVC, "Invalid memory permissions for transfer memory! (perms={:08X})", |
| 1893 | permissions); | 1892 | permissions); |
| 1894 | return ResultInvalidMemoryPermissions; | 1893 | return ResultInvalidMemoryPermissions; |
| @@ -1902,7 +1901,8 @@ static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAd | |||
| 1902 | LOG_ERROR(Kernel_SVC, "Could not reserve a new transfer memory"); | 1901 | LOG_ERROR(Kernel_SVC, "Could not reserve a new transfer memory"); |
| 1903 | return ResultResourceLimitedExceeded; | 1902 | return ResultResourceLimitedExceeded; |
| 1904 | } | 1903 | } |
| 1905 | auto transfer_mem_handle = TransferMemory::Create(kernel, system.Memory(), addr, size, perms); | 1904 | auto transfer_mem_handle = TransferMemory::Create(kernel, system.Memory(), addr, size, |
| 1905 | static_cast<KMemoryPermission>(perms)); | ||
| 1906 | 1906 | ||
| 1907 | if (const auto reserve_result{transfer_mem_handle->Reserve()}; reserve_result.IsError()) { | 1907 | if (const auto reserve_result{transfer_mem_handle->Reserve()}; reserve_result.IsError()) { |
| 1908 | return reserve_result; | 1908 | return reserve_result; |
diff --git a/src/core/hle/kernel/transfer_memory.cpp b/src/core/hle/kernel/transfer_memory.cpp index 6b0fc1591..b92559616 100644 --- a/src/core/hle/kernel/transfer_memory.cpp +++ b/src/core/hle/kernel/transfer_memory.cpp | |||
| @@ -24,7 +24,7 @@ TransferMemory::~TransferMemory() { | |||
| 24 | std::shared_ptr<TransferMemory> TransferMemory::Create(KernelCore& kernel, | 24 | std::shared_ptr<TransferMemory> TransferMemory::Create(KernelCore& kernel, |
| 25 | Core::Memory::Memory& memory, | 25 | Core::Memory::Memory& memory, |
| 26 | VAddr base_address, std::size_t size, | 26 | VAddr base_address, std::size_t size, |
| 27 | Memory::MemoryPermission permissions) { | 27 | KMemoryPermission permissions) { |
| 28 | std::shared_ptr<TransferMemory> transfer_memory{ | 28 | std::shared_ptr<TransferMemory> transfer_memory{ |
| 29 | std::make_shared<TransferMemory>(kernel, memory)}; | 29 | std::make_shared<TransferMemory>(kernel, memory)}; |
| 30 | 30 | ||
diff --git a/src/core/hle/kernel/transfer_memory.h b/src/core/hle/kernel/transfer_memory.h index 777799d12..521951424 100644 --- a/src/core/hle/kernel/transfer_memory.h +++ b/src/core/hle/kernel/transfer_memory.h | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | 8 | ||
| 9 | #include "core/hle/kernel/memory/memory_block.h" | 9 | #include "core/hle/kernel/k_memory_block.h" |
| 10 | #include "core/hle/kernel/object.h" | 10 | #include "core/hle/kernel/object.h" |
| 11 | #include "core/hle/kernel/physical_memory.h" | 11 | #include "core/hle/kernel/physical_memory.h" |
| 12 | 12 | ||
| @@ -36,7 +36,7 @@ public: | |||
| 36 | 36 | ||
| 37 | static std::shared_ptr<TransferMemory> Create(KernelCore& kernel, Core::Memory::Memory& memory, | 37 | static std::shared_ptr<TransferMemory> Create(KernelCore& kernel, Core::Memory::Memory& memory, |
| 38 | VAddr base_address, std::size_t size, | 38 | VAddr base_address, std::size_t size, |
| 39 | Memory::MemoryPermission permissions); | 39 | KMemoryPermission permissions); |
| 40 | 40 | ||
| 41 | TransferMemory(const TransferMemory&) = delete; | 41 | TransferMemory(const TransferMemory&) = delete; |
| 42 | TransferMemory& operator=(const TransferMemory&) = delete; | 42 | TransferMemory& operator=(const TransferMemory&) = delete; |
| @@ -82,7 +82,7 @@ private: | |||
| 82 | std::size_t size{}; | 82 | std::size_t size{}; |
| 83 | 83 | ||
| 84 | /// The memory permissions that are applied to this instance. | 84 | /// The memory permissions that are applied to this instance. |
| 85 | Memory::MemoryPermission owner_permissions{}; | 85 | KMemoryPermission owner_permissions{}; |
| 86 | 86 | ||
| 87 | /// The process that this transfer memory instance was created under. | 87 | /// The process that this transfer memory instance was created under. |
| 88 | Process* owner_process{}; | 88 | Process* owner_process{}; |
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index d3cd25ff8..b42184a3b 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp | |||
| @@ -289,10 +289,10 @@ public: | |||
| 289 | 289 | ||
| 290 | bool ValidateRegionForMap(Kernel::Memory::PageTable& page_table, VAddr start, | 290 | bool ValidateRegionForMap(Kernel::Memory::PageTable& page_table, VAddr start, |
| 291 | std::size_t size) const { | 291 | std::size_t size) const { |
| 292 | constexpr std::size_t padding_size{4 * Kernel::Memory::PageSize}; | 292 | constexpr std::size_t padding_size{4 * Kernel::PageSize}; |
| 293 | const auto start_info{page_table.QueryInfo(start - 1)}; | 293 | const auto start_info{page_table.QueryInfo(start - 1)}; |
| 294 | 294 | ||
| 295 | if (start_info.state != Kernel::Memory::MemoryState::Free) { | 295 | if (start_info.state != Kernel::KMemoryState::Free) { |
| 296 | return {}; | 296 | return {}; |
| 297 | } | 297 | } |
| 298 | 298 | ||
| @@ -302,7 +302,7 @@ public: | |||
| 302 | 302 | ||
| 303 | const auto end_info{page_table.QueryInfo(start + size)}; | 303 | const auto end_info{page_table.QueryInfo(start + size)}; |
| 304 | 304 | ||
| 305 | if (end_info.state != Kernel::Memory::MemoryState::Free) { | 305 | if (end_info.state != Kernel::KMemoryState::Free) { |
| 306 | return {}; | 306 | return {}; |
| 307 | } | 307 | } |
| 308 | 308 | ||
| @@ -312,11 +312,10 @@ public: | |||
| 312 | VAddr GetRandomMapRegion(const Kernel::Memory::PageTable& page_table, std::size_t size) const { | 312 | VAddr GetRandomMapRegion(const Kernel::Memory::PageTable& page_table, std::size_t size) const { |
| 313 | VAddr addr{}; | 313 | VAddr addr{}; |
| 314 | const std::size_t end_pages{(page_table.GetAliasCodeRegionSize() - size) >> | 314 | const std::size_t end_pages{(page_table.GetAliasCodeRegionSize() - size) >> |
| 315 | Kernel::Memory::PageBits}; | 315 | Kernel::PageBits}; |
| 316 | do { | 316 | do { |
| 317 | addr = page_table.GetAliasCodeRegionStart() + | 317 | addr = page_table.GetAliasCodeRegionStart() + |
| 318 | (Kernel::KSystemControl::GenerateRandomRange(0, end_pages) | 318 | (Kernel::KSystemControl::GenerateRandomRange(0, end_pages) << Kernel::PageBits); |
| 319 | << Kernel::Memory::PageBits); | ||
| 320 | } while (!page_table.IsInsideAddressSpace(addr, size) || | 319 | } while (!page_table.IsInsideAddressSpace(addr, size) || |
| 321 | page_table.IsInsideHeapRegion(addr, size) || | 320 | page_table.IsInsideHeapRegion(addr, size) || |
| 322 | page_table.IsInsideAliasRegion(addr, size)); | 321 | page_table.IsInsideAliasRegion(addr, size)); |
| @@ -387,7 +386,7 @@ public: | |||
| 387 | const VAddr data_start{start + nro_header.segment_headers[DATA_INDEX].memory_offset}; | 386 | const VAddr data_start{start + nro_header.segment_headers[DATA_INDEX].memory_offset}; |
| 388 | const VAddr bss_start{data_start + nro_header.segment_headers[DATA_INDEX].memory_size}; | 387 | const VAddr bss_start{data_start + nro_header.segment_headers[DATA_INDEX].memory_size}; |
| 389 | const VAddr bss_end_addr{ | 388 | const VAddr bss_end_addr{ |
| 390 | Common::AlignUp(bss_start + nro_header.bss_size, Kernel::Memory::PageSize)}; | 389 | Common::AlignUp(bss_start + nro_header.bss_size, Kernel::PageSize)}; |
| 391 | 390 | ||
| 392 | auto CopyCode{[&](VAddr src_addr, VAddr dst_addr, u64 size) { | 391 | auto CopyCode{[&](VAddr src_addr, VAddr dst_addr, u64 size) { |
| 393 | std::vector<u8> source_data(size); | 392 | std::vector<u8> source_data(size); |
| @@ -402,12 +401,12 @@ public: | |||
| 402 | nro_header.segment_headers[DATA_INDEX].memory_size); | 401 | nro_header.segment_headers[DATA_INDEX].memory_size); |
| 403 | 402 | ||
| 404 | CASCADE_CODE(process->PageTable().SetCodeMemoryPermission( | 403 | CASCADE_CODE(process->PageTable().SetCodeMemoryPermission( |
| 405 | text_start, ro_start - text_start, Kernel::Memory::MemoryPermission::ReadAndExecute)); | 404 | text_start, ro_start - text_start, Kernel::KMemoryPermission::ReadAndExecute)); |
| 406 | CASCADE_CODE(process->PageTable().SetCodeMemoryPermission( | 405 | CASCADE_CODE(process->PageTable().SetCodeMemoryPermission(ro_start, data_start - ro_start, |
| 407 | ro_start, data_start - ro_start, Kernel::Memory::MemoryPermission::Read)); | 406 | Kernel::KMemoryPermission::Read)); |
| 408 | 407 | ||
| 409 | return process->PageTable().SetCodeMemoryPermission( | 408 | return process->PageTable().SetCodeMemoryPermission( |
| 410 | data_start, bss_end_addr - data_start, Kernel::Memory::MemoryPermission::ReadAndWrite); | 409 | data_start, bss_end_addr - data_start, Kernel::KMemoryPermission::ReadAndWrite); |
| 411 | } | 410 | } |
| 412 | 411 | ||
| 413 | void LoadNro(Kernel::HLERequestContext& ctx) { | 412 | void LoadNro(Kernel::HLERequestContext& ctx) { |