diff options
| -rw-r--r-- | src/core/device_memory.h | 16 | ||||
| -rw-r--r-- | src/core/hle/kernel/memory/address_space_info.cpp | 22 | ||||
| -rw-r--r-- | src/core/hle/kernel/memory/memory_block_manager.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/memory/memory_manager.cpp | 29 | ||||
| -rw-r--r-- | src/core/hle/kernel/memory/page_heap.h | 48 | ||||
| -rw-r--r-- | src/core/hle/kernel/memory/page_table.cpp | 256 | ||||
| -rw-r--r-- | src/core/hle/kernel/memory/system_control.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/shared_memory.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/shared_memory.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/ldr/ldr.cpp | 13 |
11 files changed, 153 insertions, 251 deletions
diff --git a/src/core/device_memory.h b/src/core/device_memory.h index ff66e202d..9efa088d0 100644 --- a/src/core/device_memory.h +++ b/src/core/device_memory.h | |||
| @@ -13,13 +13,15 @@ namespace Core { | |||
| 13 | class System; | 13 | class System; |
| 14 | 14 | ||
| 15 | namespace DramMemoryMap { | 15 | namespace DramMemoryMap { |
| 16 | constexpr u64 Base = 0x80000000ULL; | 16 | enum : u64 { |
| 17 | constexpr u64 Size = 0x100000000ULL; | 17 | Base = 0x80000000ULL, |
| 18 | constexpr u64 End = Base + Size; | 18 | Size = 0x100000000ULL, |
| 19 | constexpr u64 KernelReserveBase = Base + 0x60000; | 19 | End = Base + Size, |
| 20 | constexpr u64 SlabHeapBase = KernelReserveBase + 0x85000; | 20 | KernelReserveBase = Base + 0x60000, |
| 21 | constexpr u64 SlapHeapSize = 0xa21000; | 21 | SlabHeapBase = KernelReserveBase + 0x85000, |
| 22 | constexpr u64 SlabHeapEnd = SlabHeapBase + SlapHeapSize; | 22 | SlapHeapSize = 0xa21000, |
| 23 | SlabHeapEnd = SlabHeapBase + SlapHeapSize, | ||
| 24 | }; | ||
| 23 | }; // namespace DramMemoryMap | 25 | }; // namespace DramMemoryMap |
| 24 | 26 | ||
| 25 | class DeviceMemory : NonCopyable { | 27 | class DeviceMemory : NonCopyable { |
diff --git a/src/core/hle/kernel/memory/address_space_info.cpp b/src/core/hle/kernel/memory/address_space_info.cpp index 6a267c951..27fae05e7 100644 --- a/src/core/hle/kernel/memory/address_space_info.cpp +++ b/src/core/hle/kernel/memory/address_space_info.cpp | |||
| @@ -14,16 +14,18 @@ namespace Kernel::Memory { | |||
| 14 | 14 | ||
| 15 | namespace { | 15 | namespace { |
| 16 | 16 | ||
| 17 | constexpr std::size_t Size_1_MB{0x100000}; | 17 | enum : u64 { |
| 18 | constexpr std::size_t Size_2_MB{2 * Size_1_MB}; | 18 | Size_1_MB = 0x100000, |
| 19 | constexpr std::size_t Size_128_MB{128 * Size_1_MB}; | 19 | Size_2_MB = 2 * Size_1_MB, |
| 20 | constexpr std::size_t Size_1_GB{0x40000000}; | 20 | Size_128_MB = 128 * Size_1_MB, |
| 21 | constexpr std::size_t Size_2_GB{2 * Size_1_GB}; | 21 | Size_1_GB = 0x40000000, |
| 22 | constexpr std::size_t Size_4_GB{4 * Size_1_GB}; | 22 | Size_2_GB = 2 * Size_1_GB, |
| 23 | constexpr std::size_t Size_6_GB{6 * Size_1_GB}; | 23 | Size_4_GB = 4 * Size_1_GB, |
| 24 | constexpr std::size_t Size_64_GB{64 * Size_1_GB}; | 24 | Size_6_GB = 6 * Size_1_GB, |
| 25 | constexpr std::size_t Size_512_GB{512 * Size_1_GB}; | 25 | Size_64_GB = 64 * Size_1_GB, |
| 26 | constexpr u64 Invalid{std::numeric_limits<u64>::max()}; | 26 | Size_512_GB = 512 * Size_1_GB, |
| 27 | Invalid = std::numeric_limits<u64>::max(), | ||
| 28 | }; | ||
| 27 | 29 | ||
| 28 | // clang-format off | 30 | // clang-format off |
| 29 | constexpr std::array<AddressSpaceInfo, 13> AddressSpaceInfos{{ | 31 | constexpr std::array<AddressSpaceInfo, 13> AddressSpaceInfos{{ |
diff --git a/src/core/hle/kernel/memory/memory_block_manager.cpp b/src/core/hle/kernel/memory/memory_block_manager.cpp index da009566f..1ebc126c0 100644 --- a/src/core/hle/kernel/memory/memory_block_manager.cpp +++ b/src/core/hle/kernel/memory/memory_block_manager.cpp | |||
| @@ -15,7 +15,7 @@ MemoryBlockManager::MemoryBlockManager(VAddr start_addr, VAddr end_addr) | |||
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | MemoryBlockManager::iterator MemoryBlockManager::FindIterator(VAddr addr) { | 17 | MemoryBlockManager::iterator MemoryBlockManager::FindIterator(VAddr addr) { |
| 18 | iterator 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()}; |
| 21 | if (node->GetAddress() <= addr && end_addr - 1 >= addr) { | 21 | if (node->GetAddress() <= addr && end_addr - 1 >= addr) { |
| @@ -35,8 +35,8 @@ VAddr MemoryBlockManager::FindFreeArea(VAddr region_start, std::size_t region_nu | |||
| 35 | 35 | ||
| 36 | const VAddr region_end{region_start + region_num_pages * PageSize}; | 36 | const VAddr region_end{region_start + region_num_pages * PageSize}; |
| 37 | const VAddr region_last{region_end - 1}; | 37 | const VAddr region_last{region_end - 1}; |
| 38 | for (const_iterator it{FindIterator(region_start)}; it != memory_block_tree.cend(); it++) { | 38 | for (auto it{FindIterator(region_start)}; it != memory_block_tree.cend(); it++) { |
| 39 | const MemoryInfo info{it->GetMemoryInfo()}; | 39 | const auto info{it->GetMemoryInfo()}; |
| 40 | if (region_last < info.GetAddress()) { | 40 | if (region_last < info.GetAddress()) { |
| 41 | break; | 41 | break; |
| 42 | } | 42 | } |
diff --git a/src/core/hle/kernel/memory/memory_manager.cpp b/src/core/hle/kernel/memory/memory_manager.cpp index 9c1bb981b..3cd4f9e85 100644 --- a/src/core/hle/kernel/memory/memory_manager.cpp +++ b/src/core/hle/kernel/memory/memory_manager.cpp | |||
| @@ -15,15 +15,14 @@ | |||
| 15 | namespace Kernel::Memory { | 15 | namespace Kernel::Memory { |
| 16 | 16 | ||
| 17 | std::size_t MemoryManager::Impl::Initialize(Pool new_pool, u64 start_address, u64 end_address) { | 17 | std::size_t MemoryManager::Impl::Initialize(Pool new_pool, u64 start_address, u64 end_address) { |
| 18 | const std::size_t size{end_address - start_address}; | 18 | const auto size{end_address - start_address}; |
| 19 | 19 | ||
| 20 | // Calculate metadata sizes | 20 | // Calculate metadata sizes |
| 21 | const std::size_t ref_count_size{(size / PageSize) * sizeof(u16)}; | 21 | const auto ref_count_size{(size / PageSize) * sizeof(u16)}; |
| 22 | const std::size_t optimize_map_size{(Common::AlignUp((size / PageSize), 64) / 64) * | 22 | const auto optimize_map_size{(Common::AlignUp((size / PageSize), 64) / 64) * sizeof(u64)}; |
| 23 | sizeof(u64)}; | 23 | const auto manager_size{Common::AlignUp(optimize_map_size + ref_count_size, PageSize)}; |
| 24 | const std::size_t manager_size{Common::AlignUp(optimize_map_size + ref_count_size, PageSize)}; | 24 | const auto page_heap_size{PageHeap::CalculateMetadataOverheadSize(size)}; |
| 25 | const std::size_t page_heap_size{PageHeap::CalculateMetadataOverheadSize(size)}; | 25 | const auto total_metadata_size{manager_size + page_heap_size}; |
| 26 | const std::size_t total_metadata_size{manager_size + page_heap_size}; | ||
| 27 | ASSERT(manager_size <= total_metadata_size); | 26 | ASSERT(manager_size <= total_metadata_size); |
| 28 | ASSERT(Common::IsAligned(total_metadata_size, PageSize)); | 27 | ASSERT(Common::IsAligned(total_metadata_size, PageSize)); |
| 29 | 28 | ||
| @@ -55,7 +54,7 @@ VAddr MemoryManager::AllocateContinuous(std::size_t num_pages, std::size_t align | |||
| 55 | } | 54 | } |
| 56 | 55 | ||
| 57 | // Lock the pool that we're allocating from | 56 | // Lock the pool that we're allocating from |
| 58 | const std::size_t pool_index{static_cast<std::size_t>(pool)}; | 57 | const auto pool_index{static_cast<std::size_t>(pool)}; |
| 59 | std::lock_guard lock{pool_locks[pool_index]}; | 58 | std::lock_guard lock{pool_locks[pool_index]}; |
| 60 | 59 | ||
| 61 | // Choose a heap based on our page size request | 60 | // Choose a heap based on our page size request |
| @@ -72,7 +71,7 @@ VAddr MemoryManager::AllocateContinuous(std::size_t num_pages, std::size_t align | |||
| 72 | } | 71 | } |
| 73 | 72 | ||
| 74 | // If we allocated more than we need, free some | 73 | // If we allocated more than we need, free some |
| 75 | const std::size_t allocated_pages{PageHeap::GetBlockNumPages(heap_index)}; | 74 | const auto allocated_pages{PageHeap::GetBlockNumPages(heap_index)}; |
| 76 | if (allocated_pages > num_pages) { | 75 | if (allocated_pages > num_pages) { |
| 77 | chosen_manager.Free(allocated_block + num_pages * PageSize, allocated_pages - num_pages); | 76 | chosen_manager.Free(allocated_block + num_pages * PageSize, allocated_pages - num_pages); |
| 78 | } | 77 | } |
| @@ -90,7 +89,7 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa | |||
| 90 | } | 89 | } |
| 91 | 90 | ||
| 92 | // Lock the pool that we're allocating from | 91 | // Lock the pool that we're allocating from |
| 93 | const std::size_t pool_index{static_cast<std::size_t>(pool)}; | 92 | const auto pool_index{static_cast<std::size_t>(pool)}; |
| 94 | std::lock_guard lock{pool_locks[pool_index]}; | 93 | std::lock_guard lock{pool_locks[pool_index]}; |
| 95 | 94 | ||
| 96 | // Choose a heap based on our page size request | 95 | // Choose a heap based on our page size request |
| @@ -105,7 +104,7 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa | |||
| 105 | // Ensure that we don't leave anything un-freed | 104 | // Ensure that we don't leave anything un-freed |
| 106 | auto group_guard = detail::ScopeExit([&] { | 105 | auto group_guard = detail::ScopeExit([&] { |
| 107 | for (const auto& it : page_list.Nodes()) { | 106 | for (const auto& it : page_list.Nodes()) { |
| 108 | const std::size_t num_pages{std::min( | 107 | const auto num_pages{std::min( |
| 109 | it.GetNumPages(), (chosen_manager.GetEndAddress() - it.GetAddress()) / PageSize)}; | 108 | it.GetNumPages(), (chosen_manager.GetEndAddress() - it.GetAddress()) / PageSize)}; |
| 110 | chosen_manager.Free(it.GetAddress(), num_pages); | 109 | chosen_manager.Free(it.GetAddress(), num_pages); |
| 111 | } | 110 | } |
| @@ -113,12 +112,12 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa | |||
| 113 | 112 | ||
| 114 | // Keep allocating until we've allocated all our pages | 113 | // Keep allocating until we've allocated all our pages |
| 115 | for (s32 index{heap_index}; index >= 0 && num_pages > 0; index--) { | 114 | for (s32 index{heap_index}; index >= 0 && num_pages > 0; index--) { |
| 116 | const std::size_t pages_per_alloc{PageHeap::GetBlockNumPages(index)}; | 115 | const auto pages_per_alloc{PageHeap::GetBlockNumPages(index)}; |
| 117 | 116 | ||
| 118 | while (num_pages >= pages_per_alloc) { | 117 | while (num_pages >= pages_per_alloc) { |
| 119 | // Allocate a block | 118 | // Allocate a block |
| 120 | VAddr allocated_block{chosen_manager.AllocateBlock(index)}; | 119 | VAddr allocated_block{chosen_manager.AllocateBlock(index)}; |
| 121 | if (allocated_block == 0) { | 120 | if (!allocated_block) { |
| 122 | break; | 121 | break; |
| 123 | } | 122 | } |
| 124 | 123 | ||
| @@ -158,7 +157,7 @@ ResultCode MemoryManager::Free(PageLinkedList& page_list, std::size_t num_pages, | |||
| 158 | } | 157 | } |
| 159 | 158 | ||
| 160 | // Lock the pool that we're freeing from | 159 | // Lock the pool that we're freeing from |
| 161 | const std::size_t pool_index{static_cast<std::size_t>(pool)}; | 160 | const auto pool_index{static_cast<std::size_t>(pool)}; |
| 162 | std::lock_guard lock{pool_locks[pool_index]}; | 161 | std::lock_guard lock{pool_locks[pool_index]}; |
| 163 | 162 | ||
| 164 | // TODO (bunnei): Support multiple managers | 163 | // TODO (bunnei): Support multiple managers |
| @@ -166,7 +165,7 @@ ResultCode MemoryManager::Free(PageLinkedList& page_list, std::size_t num_pages, | |||
| 166 | 165 | ||
| 167 | // Free all of the pages | 166 | // Free all of the pages |
| 168 | for (const auto& it : page_list.Nodes()) { | 167 | for (const auto& it : page_list.Nodes()) { |
| 169 | const std::size_t num_pages{std::min( | 168 | const auto num_pages{std::min( |
| 170 | it.GetNumPages(), (chosen_manager.GetEndAddress() - it.GetAddress()) / PageSize)}; | 169 | it.GetNumPages(), (chosen_manager.GetEndAddress() - it.GetAddress()) / PageSize)}; |
| 171 | chosen_manager.Free(it.GetAddress(), num_pages); | 170 | chosen_manager.Free(it.GetAddress(), num_pages); |
| 172 | } | 171 | } |
diff --git a/src/core/hle/kernel/memory/page_heap.h b/src/core/hle/kernel/memory/page_heap.h index 39ca45ab1..380c3f5a1 100644 --- a/src/core/hle/kernel/memory/page_heap.h +++ b/src/core/hle/kernel/memory/page_heap.h | |||
| @@ -22,9 +22,10 @@ namespace Kernel::Memory { | |||
| 22 | class PageHeap final : NonCopyable { | 22 | class PageHeap final : NonCopyable { |
| 23 | public: | 23 | public: |
| 24 | static constexpr s32 GetAlignedBlockIndex(std::size_t num_pages, std::size_t align_pages) { | 24 | static constexpr s32 GetAlignedBlockIndex(std::size_t num_pages, std::size_t align_pages) { |
| 25 | const std::size_t target_pages{std::max(num_pages, align_pages)}; | 25 | const auto target_pages{std::max(num_pages, align_pages)}; |
| 26 | for (std::size_t i = 0; i < NumMemoryBlockPageShifts; i++) { | 26 | for (std::size_t i = 0; i < NumMemoryBlockPageShifts; i++) { |
| 27 | if (target_pages <= (std::size_t(1) << MemoryBlockPageShifts[i]) / PageSize) { | 27 | if (target_pages <= |
| 28 | (static_cast<std::size_t>(1) << MemoryBlockPageShifts[i]) / PageSize) { | ||
| 28 | return static_cast<s32>(i); | 29 | return static_cast<s32>(i); |
| 29 | } | 30 | } |
| 30 | } | 31 | } |
| @@ -33,7 +34,7 @@ public: | |||
| 33 | 34 | ||
| 34 | static constexpr s32 GetBlockIndex(std::size_t num_pages) { | 35 | static constexpr s32 GetBlockIndex(std::size_t num_pages) { |
| 35 | for (s32 i{static_cast<s32>(NumMemoryBlockPageShifts) - 1}; i >= 0; i--) { | 36 | for (s32 i{static_cast<s32>(NumMemoryBlockPageShifts) - 1}; i >= 0; i--) { |
| 36 | if (num_pages >= (std::size_t(1) << MemoryBlockPageShifts[i]) / PageSize) { | 37 | if (num_pages >= (static_cast<std::size_t>(1) << MemoryBlockPageShifts[i]) / PageSize) { |
| 37 | return i; | 38 | return i; |
| 38 | } | 39 | } |
| 39 | } | 40 | } |
| @@ -41,7 +42,7 @@ public: | |||
| 41 | } | 42 | } |
| 42 | 43 | ||
| 43 | static constexpr std::size_t GetBlockSize(std::size_t index) { | 44 | static constexpr std::size_t GetBlockSize(std::size_t index) { |
| 44 | return std::size_t(1) << MemoryBlockPageShifts[index]; | 45 | return static_cast<std::size_t>(1) << MemoryBlockPageShifts[index]; |
| 45 | } | 46 | } |
| 46 | 47 | ||
| 47 | static constexpr std::size_t GetBlockNumPages(std::size_t index) { | 48 | static constexpr std::size_t GetBlockNumPages(std::size_t index) { |
| @@ -51,7 +52,8 @@ public: | |||
| 51 | private: | 52 | private: |
| 52 | static constexpr std::size_t NumMemoryBlockPageShifts{7}; | 53 | static constexpr std::size_t NumMemoryBlockPageShifts{7}; |
| 53 | static constexpr std::array<std::size_t, NumMemoryBlockPageShifts> MemoryBlockPageShifts{ | 54 | static constexpr std::array<std::size_t, NumMemoryBlockPageShifts> MemoryBlockPageShifts{ |
| 54 | 0xC, 0x10, 0x15, 0x16, 0x19, 0x1D, 0x1E}; | 55 | 0xC, 0x10, 0x15, 0x16, 0x19, 0x1D, 0x1E, |
| 56 | }; | ||
| 55 | 57 | ||
| 56 | class Block final : NonCopyable { | 58 | class Block final : NonCopyable { |
| 57 | private: | 59 | private: |
| @@ -122,13 +124,13 @@ private: | |||
| 122 | 124 | ||
| 123 | constexpr bool ClearRange(std::size_t offset, std::size_t count) { | 125 | constexpr bool ClearRange(std::size_t offset, std::size_t count) { |
| 124 | const s32 depth{GetHighestDepthIndex()}; | 126 | const s32 depth{GetHighestDepthIndex()}; |
| 125 | const std::size_t bit_ind{offset / 64}; | 127 | const auto bit_ind{offset / 64}; |
| 126 | u64* bits{bit_storages[depth]}; | 128 | u64* bits{bit_storages[depth]}; |
| 127 | if (count < 64) { | 129 | if (count < 64) { |
| 128 | const std::size_t shift{offset % 64}; | 130 | const auto shift{offset % 64}; |
| 129 | ASSERT(shift + count <= 64); | 131 | ASSERT(shift + count <= 64); |
| 130 | // Check that all the bits are set | 132 | // Check that all the bits are set |
| 131 | const u64 mask{((u64(1) << count) - 1) << shift}; | 133 | const u64 mask{((1ULL << count) - 1) << shift}; |
| 132 | u64 v{bits[bit_ind]}; | 134 | u64 v{bits[bit_ind]}; |
| 133 | if ((v & mask) != mask) { | 135 | if ((v & mask) != mask) { |
| 134 | return false; | 136 | return false; |
| @@ -171,9 +173,9 @@ private: | |||
| 171 | private: | 173 | private: |
| 172 | constexpr void SetBit(s32 depth, std::size_t offset) { | 174 | constexpr void SetBit(s32 depth, std::size_t offset) { |
| 173 | while (depth >= 0) { | 175 | while (depth >= 0) { |
| 174 | const std::size_t ind{offset / 64}; | 176 | const auto ind{offset / 64}; |
| 175 | const std::size_t which{offset % 64}; | 177 | const auto which{offset % 64}; |
| 176 | const u64 mask{u64(1) << which}; | 178 | const u64 mask{1ULL << which}; |
| 177 | 179 | ||
| 178 | u64* bit{std::addressof(bit_storages[depth][ind])}; | 180 | u64* bit{std::addressof(bit_storages[depth][ind])}; |
| 179 | const u64 v{*bit}; | 181 | const u64 v{*bit}; |
| @@ -189,9 +191,9 @@ private: | |||
| 189 | 191 | ||
| 190 | constexpr void ClearBit(s32 depth, std::size_t offset) { | 192 | constexpr void ClearBit(s32 depth, std::size_t offset) { |
| 191 | while (depth >= 0) { | 193 | while (depth >= 0) { |
| 192 | const std::size_t ind{offset / 64}; | 194 | const auto ind{offset / 64}; |
| 193 | const std::size_t which{offset % 64}; | 195 | const auto which{offset % 64}; |
| 194 | const u64 mask{u64(1) << which}; | 196 | const u64 mask{1ULL << which}; |
| 195 | 197 | ||
| 196 | u64* bit{std::addressof(bit_storages[depth][ind])}; | 198 | u64* bit{std::addressof(bit_storages[depth][ind])}; |
| 197 | u64 v{*bit}; | 199 | u64 v{*bit}; |
| @@ -246,7 +248,7 @@ private: | |||
| 246 | return next_block_shift; | 248 | return next_block_shift; |
| 247 | } | 249 | } |
| 248 | constexpr std::size_t GetSize() const { | 250 | constexpr std::size_t GetSize() const { |
| 249 | return std::size_t(1) << GetShift(); | 251 | return static_cast<std::size_t>(1) << GetShift(); |
| 250 | } | 252 | } |
| 251 | constexpr std::size_t GetNumPages() const { | 253 | constexpr std::size_t GetNumPages() const { |
| 252 | return GetSize() / PageSize; | 254 | return GetSize() / PageSize; |
| @@ -266,13 +268,13 @@ private: | |||
| 266 | 268 | ||
| 267 | // Align up the address | 269 | // Align up the address |
| 268 | VAddr end{addr + size}; | 270 | VAddr end{addr + size}; |
| 269 | const std::size_t align{(next_block_shift != 0) ? (u64(1) << next_block_shift) | 271 | const auto align{(next_block_shift != 0) ? (1ULL << next_block_shift) |
| 270 | : (u64(1) << block_shift)}; | 272 | : (1ULL << block_shift)}; |
| 271 | addr = Common::AlignDown((addr), align); | 273 | addr = Common::AlignDown((addr), align); |
| 272 | end = Common::AlignUp((end), align); | 274 | end = Common::AlignUp((end), align); |
| 273 | 275 | ||
| 274 | heap_address = addr; | 276 | heap_address = addr; |
| 275 | end_offset = (end - addr) / (u64(1) << block_shift); | 277 | end_offset = (end - addr) / (1ULL << block_shift); |
| 276 | return bitmap.Initialize(bit_storage, end_offset); | 278 | return bitmap.Initialize(bit_storage, end_offset); |
| 277 | } | 279 | } |
| 278 | 280 | ||
| @@ -283,7 +285,7 @@ private: | |||
| 283 | 285 | ||
| 284 | // If we have a next shift, try to clear the blocks below and return the address | 286 | // If we have a next shift, try to clear the blocks below and return the address |
| 285 | if (GetNextShift()) { | 287 | if (GetNextShift()) { |
| 286 | const std::size_t diff{u64(1) << (GetNextShift() - GetShift())}; | 288 | const auto diff{1ULL << (GetNextShift() - GetShift())}; |
| 287 | offset = Common::AlignDown(offset, diff); | 289 | offset = Common::AlignDown(offset, diff); |
| 288 | if (bitmap.ClearRange(offset, diff)) { | 290 | if (bitmap.ClearRange(offset, diff)) { |
| 289 | return heap_address + (offset << GetShift()); | 291 | return heap_address + (offset << GetShift()); |
| @@ -300,7 +302,7 @@ private: | |||
| 300 | if (soffset < 0) { | 302 | if (soffset < 0) { |
| 301 | return 0; | 303 | return 0; |
| 302 | } | 304 | } |
| 303 | const std::size_t offset{static_cast<std::size_t>(soffset)}; | 305 | const auto offset{static_cast<std::size_t>(soffset)}; |
| 304 | 306 | ||
| 305 | // Update our tracking and return it | 307 | // Update our tracking and return it |
| 306 | bitmap.ClearBit(offset); | 308 | bitmap.ClearBit(offset); |
| @@ -311,9 +313,9 @@ private: | |||
| 311 | static constexpr std::size_t CalculateMetadataOverheadSize(std::size_t region_size, | 313 | static constexpr std::size_t CalculateMetadataOverheadSize(std::size_t region_size, |
| 312 | std::size_t cur_block_shift, | 314 | std::size_t cur_block_shift, |
| 313 | std::size_t next_block_shift) { | 315 | std::size_t next_block_shift) { |
| 314 | const std::size_t cur_block_size{(u64(1) << cur_block_shift)}; | 316 | const auto cur_block_size{(1ULL << cur_block_shift)}; |
| 315 | const std::size_t next_block_size{(u64(1) << next_block_shift)}; | 317 | const auto next_block_size{(1ULL << next_block_shift)}; |
| 316 | const std::size_t align{(next_block_shift != 0) ? next_block_size : cur_block_size}; | 318 | const auto align{(next_block_shift != 0) ? next_block_size : cur_block_size}; |
| 317 | return Bitmap::CalculateMetadataOverheadSize( | 319 | return Bitmap::CalculateMetadataOverheadSize( |
| 318 | (align * 2 + Common::AlignUp(region_size, align)) / cur_block_size); | 320 | (align * 2 + Common::AlignUp(region_size, align)) / cur_block_size); |
| 319 | } | 321 | } |
diff --git a/src/core/hle/kernel/memory/page_table.cpp b/src/core/hle/kernel/memory/page_table.cpp index 941ecda21..091e52ca4 100644 --- a/src/core/hle/kernel/memory/page_table.cpp +++ b/src/core/hle/kernel/memory/page_table.cpp | |||
| @@ -64,10 +64,10 @@ ResultCode PageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_t | |||
| 64 | bool enable_aslr, VAddr code_addr, std::size_t code_size, | 64 | bool enable_aslr, VAddr code_addr, std::size_t code_size, |
| 65 | Memory::MemoryManager::Pool pool) { | 65 | Memory::MemoryManager::Pool pool) { |
| 66 | 66 | ||
| 67 | const auto GetSpaceStart = [&](AddressSpaceInfo::Type type) { | 67 | const auto GetSpaceStart = [this](AddressSpaceInfo::Type type) { |
| 68 | return AddressSpaceInfo::GetAddressSpaceStart(address_space_width, type); | 68 | return AddressSpaceInfo::GetAddressSpaceStart(address_space_width, type); |
| 69 | }; | 69 | }; |
| 70 | const auto GetSpaceSize = [&](AddressSpaceInfo::Type type) { | 70 | const auto GetSpaceSize = [this](AddressSpaceInfo::Type type) { |
| 71 | return AddressSpaceInfo::GetAddressSpaceSize(address_space_width, type); | 71 | return AddressSpaceInfo::GetAddressSpaceSize(address_space_width, type); |
| 72 | }; | 72 | }; |
| 73 | 73 | ||
| @@ -286,17 +286,9 @@ ResultCode PageTable::MapProcessCode(VAddr addr, std::size_t num_pages, MemorySt | |||
| 286 | } | 286 | } |
| 287 | 287 | ||
| 288 | PageLinkedList page_linked_list; | 288 | PageLinkedList page_linked_list; |
| 289 | if (const ResultCode result{ | 289 | CASCADE_CODE( |
| 290 | system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool)}; | 290 | system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool)); |
| 291 | result.IsError()) { | 291 | CASCADE_CODE(Operate(addr, num_pages, page_linked_list, OperationType::MapGroup)); |
| 292 | return result; | ||
| 293 | } | ||
| 294 | |||
| 295 | if (const ResultCode result{ | ||
| 296 | Operate(addr, num_pages, page_linked_list, OperationType::MapGroup)}; | ||
| 297 | result.IsError()) { | ||
| 298 | return result; | ||
| 299 | } | ||
| 300 | 292 | ||
| 301 | block_manager->Update(addr, num_pages, state, perm); | 293 | block_manager->Update(addr, num_pages, state, perm); |
| 302 | 294 | ||
| @@ -310,13 +302,10 @@ ResultCode PageTable::MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std:: | |||
| 310 | 302 | ||
| 311 | MemoryState state{}; | 303 | MemoryState state{}; |
| 312 | MemoryPermission perm{}; | 304 | MemoryPermission perm{}; |
| 313 | if (const ResultCode result{CheckMemoryState( | 305 | CASCADE_CODE(CheckMemoryState(&state, &perm, nullptr, src_addr, size, MemoryState::All, |
| 314 | &state, &perm, nullptr, src_addr, size, MemoryState::All, MemoryState::Normal, | 306 | MemoryState::Normal, MemoryPermission::Mask, |
| 315 | MemoryPermission::Mask, MemoryPermission::ReadAndWrite, MemoryAttribute::Mask, | 307 | MemoryPermission::ReadAndWrite, MemoryAttribute::Mask, |
| 316 | MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)}; | 308 | MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); |
| 317 | result.IsError()) { | ||
| 318 | return result; | ||
| 319 | } | ||
| 320 | 309 | ||
| 321 | if (IsRegionMapped(dst_addr, size)) { | 310 | if (IsRegionMapped(dst_addr, size)) { |
| 322 | return ERR_INVALID_ADDRESS_STATE; | 311 | return ERR_INVALID_ADDRESS_STATE; |
| @@ -329,16 +318,9 @@ ResultCode PageTable::MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std:: | |||
| 329 | auto block_guard = detail::ScopeExit( | 318 | auto block_guard = detail::ScopeExit( |
| 330 | [&] { Operate(src_addr, num_pages, perm, OperationType::ChangePermissions); }); | 319 | [&] { Operate(src_addr, num_pages, perm, OperationType::ChangePermissions); }); |
| 331 | 320 | ||
| 332 | if (const ResultCode result{Operate(src_addr, num_pages, MemoryPermission::None, | 321 | CASCADE_CODE( |
| 333 | OperationType::ChangePermissions)}; | 322 | Operate(src_addr, num_pages, MemoryPermission::None, OperationType::ChangePermissions)); |
| 334 | result.IsError()) { | 323 | CASCADE_CODE(MapPages(dst_addr, page_linked_list, MemoryPermission::None)); |
| 335 | return result; | ||
| 336 | } | ||
| 337 | |||
| 338 | if (const ResultCode result{MapPages(dst_addr, page_linked_list, MemoryPermission::None)}; | ||
| 339 | result.IsError()) { | ||
| 340 | return result; | ||
| 341 | } | ||
| 342 | 324 | ||
| 343 | block_guard.Cancel(); | 325 | block_guard.Cancel(); |
| 344 | } | 326 | } |
| @@ -359,35 +341,20 @@ ResultCode PageTable::UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std | |||
| 359 | 341 | ||
| 360 | const std::size_t num_pages{size / PageSize}; | 342 | const std::size_t num_pages{size / PageSize}; |
| 361 | 343 | ||
| 362 | if (const ResultCode result{CheckMemoryState( | 344 | CASCADE_CODE(CheckMemoryState(nullptr, nullptr, nullptr, src_addr, size, MemoryState::All, |
| 363 | nullptr, nullptr, nullptr, src_addr, size, MemoryState::All, MemoryState::Normal, | 345 | MemoryState::Normal, MemoryPermission::None, |
| 364 | MemoryPermission::None, MemoryPermission::None, MemoryAttribute::Mask, | 346 | MemoryPermission::None, MemoryAttribute::Mask, |
| 365 | MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)}; | 347 | MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)); |
| 366 | result.IsError()) { | ||
| 367 | return result; | ||
| 368 | } | ||
| 369 | 348 | ||
| 370 | MemoryState state{}; | 349 | MemoryState state{}; |
| 371 | if (const ResultCode result{CheckMemoryState( | 350 | CASCADE_CODE(CheckMemoryState( |
| 372 | &state, nullptr, nullptr, dst_addr, PageSize, MemoryState::FlagCanCodeAlias, | 351 | &state, nullptr, nullptr, dst_addr, PageSize, MemoryState::FlagCanCodeAlias, |
| 373 | MemoryState::FlagCanCodeAlias, MemoryPermission::None, MemoryPermission::None, | 352 | MemoryState::FlagCanCodeAlias, MemoryPermission::None, MemoryPermission::None, |
| 374 | MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)}; | 353 | MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); |
| 375 | result.IsError()) { | 354 | CASCADE_CODE(CheckMemoryState(dst_addr, size, MemoryState::All, state, MemoryPermission::None, |
| 376 | return result; | 355 | MemoryPermission::None, MemoryAttribute::Mask, |
| 377 | } | 356 | MemoryAttribute::None)); |
| 378 | 357 | CASCADE_CODE(Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap)); | |
| 379 | if (const ResultCode result{CheckMemoryState(dst_addr, size, MemoryState::All, state, | ||
| 380 | MemoryPermission::None, MemoryPermission::None, | ||
| 381 | MemoryAttribute::Mask, MemoryAttribute::None)}; | ||
| 382 | result.IsError()) { | ||
| 383 | return result; | ||
| 384 | } | ||
| 385 | |||
| 386 | if (const ResultCode result{ | ||
| 387 | Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap)}; | ||
| 388 | result.IsError()) { | ||
| 389 | return result; | ||
| 390 | } | ||
| 391 | 358 | ||
| 392 | block_manager->Update(dst_addr, num_pages, MemoryState::Free); | 359 | block_manager->Update(dst_addr, num_pages, MemoryState::Free); |
| 393 | block_manager->Update(src_addr, num_pages, MemoryState::Normal, MemoryPermission::ReadAndWrite); | 360 | block_manager->Update(src_addr, num_pages, MemoryState::Normal, MemoryPermission::ReadAndWrite); |
| @@ -459,11 +426,8 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) { | |||
| 459 | process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, remaining_size); | 426 | process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, remaining_size); |
| 460 | }); | 427 | }); |
| 461 | 428 | ||
| 462 | if (const ResultCode result{system.Kernel().MemoryManager().Allocate( | 429 | CASCADE_CODE(system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages, |
| 463 | page_linked_list, remaining_pages, memory_pool)}; | 430 | memory_pool)); |
| 464 | result.IsError()) { | ||
| 465 | return result; | ||
| 466 | } | ||
| 467 | 431 | ||
| 468 | block_guard.Cancel(); | 432 | block_guard.Cancel(); |
| 469 | } | 433 | } |
| @@ -508,9 +472,7 @@ ResultCode PageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) { | |||
| 508 | return RESULT_SUCCESS; | 472 | return RESULT_SUCCESS; |
| 509 | } | 473 | } |
| 510 | 474 | ||
| 511 | if (const ResultCode result{UnmapMemory(addr, size)}; result.IsError()) { | 475 | CASCADE_CODE(UnmapMemory(addr, size)); |
| 512 | return result; | ||
| 513 | } | ||
| 514 | 476 | ||
| 515 | auto process{system.Kernel().CurrentProcess()}; | 477 | auto process{system.Kernel().CurrentProcess()}; |
| 516 | process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, mapped_size); | 478 | process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, mapped_size); |
| @@ -559,13 +521,10 @@ ResultCode PageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) { | |||
| 559 | std::lock_guard lock{page_table_lock}; | 521 | std::lock_guard lock{page_table_lock}; |
| 560 | 522 | ||
| 561 | MemoryState src_state{}; | 523 | MemoryState src_state{}; |
| 562 | if (const ResultCode result{CheckMemoryState( | 524 | CASCADE_CODE(CheckMemoryState( |
| 563 | &src_state, nullptr, nullptr, src_addr, size, MemoryState::FlagCanAlias, | 525 | &src_state, nullptr, nullptr, src_addr, size, MemoryState::FlagCanAlias, |
| 564 | MemoryState::FlagCanAlias, MemoryPermission::Mask, MemoryPermission::ReadAndWrite, | 526 | MemoryState::FlagCanAlias, MemoryPermission::Mask, MemoryPermission::ReadAndWrite, |
| 565 | MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)}; | 527 | MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); |
| 566 | result.IsError()) { | ||
| 567 | return result; | ||
| 568 | } | ||
| 569 | 528 | ||
| 570 | if (IsRegionMapped(dst_addr, size)) { | 529 | if (IsRegionMapped(dst_addr, size)) { |
| 571 | return ERR_INVALID_ADDRESS_STATE; | 530 | return ERR_INVALID_ADDRESS_STATE; |
| @@ -582,17 +541,9 @@ ResultCode PageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) { | |||
| 582 | OperationType::ChangePermissions); | 541 | OperationType::ChangePermissions); |
| 583 | }); | 542 | }); |
| 584 | 543 | ||
| 585 | if (const ResultCode result{Operate(src_addr, num_pages, MemoryPermission::None, | 544 | CASCADE_CODE( |
| 586 | OperationType::ChangePermissions)}; | 545 | Operate(src_addr, num_pages, MemoryPermission::None, OperationType::ChangePermissions)); |
| 587 | result.IsError()) { | 546 | CASCADE_CODE(MapPages(dst_addr, page_linked_list, MemoryPermission::ReadAndWrite)); |
| 588 | return result; | ||
| 589 | } | ||
| 590 | |||
| 591 | if (const ResultCode result{ | ||
| 592 | MapPages(dst_addr, page_linked_list, MemoryPermission::ReadAndWrite)}; | ||
| 593 | result.IsError()) { | ||
| 594 | return result; | ||
| 595 | } | ||
| 596 | 547 | ||
| 597 | block_guard.Cancel(); | 548 | block_guard.Cancel(); |
| 598 | } | 549 | } |
| @@ -608,22 +559,16 @@ ResultCode PageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) { | |||
| 608 | std::lock_guard lock{page_table_lock}; | 559 | std::lock_guard lock{page_table_lock}; |
| 609 | 560 | ||
| 610 | MemoryState src_state{}; | 561 | MemoryState src_state{}; |
| 611 | if (const ResultCode result{CheckMemoryState( | 562 | CASCADE_CODE(CheckMemoryState( |
| 612 | &src_state, nullptr, nullptr, src_addr, size, MemoryState::FlagCanAlias, | 563 | &src_state, nullptr, nullptr, src_addr, size, MemoryState::FlagCanAlias, |
| 613 | MemoryState::FlagCanAlias, MemoryPermission::Mask, MemoryPermission::None, | 564 | MemoryState::FlagCanAlias, MemoryPermission::Mask, MemoryPermission::None, |
| 614 | MemoryAttribute::Mask, MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)}; | 565 | MemoryAttribute::Mask, MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)); |
| 615 | result.IsError()) { | ||
| 616 | return result; | ||
| 617 | } | ||
| 618 | 566 | ||
| 619 | MemoryPermission dst_perm{}; | 567 | MemoryPermission dst_perm{}; |
| 620 | if (const ResultCode result{CheckMemoryState( | 568 | CASCADE_CODE(CheckMemoryState(nullptr, &dst_perm, nullptr, dst_addr, size, MemoryState::All, |
| 621 | nullptr, &dst_perm, nullptr, dst_addr, size, MemoryState::All, MemoryState::Stack, | 569 | MemoryState::Stack, MemoryPermission::None, |
| 622 | MemoryPermission::None, MemoryPermission::None, MemoryAttribute::Mask, | 570 | MemoryPermission::None, MemoryAttribute::Mask, |
| 623 | MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)}; | 571 | MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); |
| 624 | result.IsError()) { | ||
| 625 | return result; | ||
| 626 | } | ||
| 627 | 572 | ||
| 628 | PageLinkedList src_pages; | 573 | PageLinkedList src_pages; |
| 629 | PageLinkedList dst_pages; | 574 | PageLinkedList dst_pages; |
| @@ -639,17 +584,9 @@ ResultCode PageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) { | |||
| 639 | { | 584 | { |
| 640 | 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); }); |
| 641 | 586 | ||
| 642 | if (const ResultCode result{ | 587 | CASCADE_CODE(Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap)); |
| 643 | Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap)}; | 588 | CASCADE_CODE(Operate(src_addr, num_pages, MemoryPermission::ReadAndWrite, |
| 644 | result.IsError()) { | 589 | OperationType::ChangePermissions)); |
| 645 | return result; | ||
| 646 | } | ||
| 647 | |||
| 648 | if (const ResultCode result{Operate(src_addr, num_pages, MemoryPermission::ReadAndWrite, | ||
| 649 | OperationType::ChangePermissions)}; | ||
| 650 | result.IsError()) { | ||
| 651 | return result; | ||
| 652 | } | ||
| 653 | 590 | ||
| 654 | block_guard.Cancel(); | 591 | block_guard.Cancel(); |
| 655 | } | 592 | } |
| @@ -665,7 +602,7 @@ ResultCode PageTable::MapPages(VAddr addr, const PageLinkedList& page_linked_lis | |||
| 665 | VAddr cur_addr{addr}; | 602 | VAddr cur_addr{addr}; |
| 666 | 603 | ||
| 667 | for (const auto& node : page_linked_list.Nodes()) { | 604 | for (const auto& node : page_linked_list.Nodes()) { |
| 668 | if (const ResultCode result{ | 605 | if (const auto result{ |
| 669 | Operate(cur_addr, node.GetNumPages(), perm, OperationType::Map, node.GetAddress())}; | 606 | Operate(cur_addr, node.GetNumPages(), perm, OperationType::Map, node.GetAddress())}; |
| 670 | result.IsError()) { | 607 | result.IsError()) { |
| 671 | const MemoryInfo info{block_manager->FindBlock(cur_addr).GetMemoryInfo()}; | 608 | const MemoryInfo info{block_manager->FindBlock(cur_addr).GetMemoryInfo()}; |
| @@ -698,9 +635,7 @@ ResultCode PageTable::MapPages(VAddr addr, PageLinkedList& page_linked_list, Mem | |||
| 698 | return ERR_INVALID_ADDRESS_STATE; | 635 | return ERR_INVALID_ADDRESS_STATE; |
| 699 | } | 636 | } |
| 700 | 637 | ||
| 701 | if (const ResultCode result{MapPages(addr, page_linked_list, perm)}; result.IsError()) { | 638 | CASCADE_CODE(MapPages(addr, page_linked_list, perm)); |
| 702 | return result; | ||
| 703 | } | ||
| 704 | 639 | ||
| 705 | block_manager->Update(addr, num_pages, state, perm); | 640 | block_manager->Update(addr, num_pages, state, perm); |
| 706 | 641 | ||
| @@ -714,13 +649,10 @@ ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, Memo | |||
| 714 | MemoryState prev_state{}; | 649 | MemoryState prev_state{}; |
| 715 | MemoryPermission prev_perm{}; | 650 | MemoryPermission prev_perm{}; |
| 716 | 651 | ||
| 717 | if (const ResultCode result{CheckMemoryState( | 652 | CASCADE_CODE(CheckMemoryState( |
| 718 | &prev_state, &prev_perm, nullptr, addr, size, MemoryState::FlagCode, | 653 | &prev_state, &prev_perm, nullptr, addr, size, MemoryState::FlagCode, MemoryState::FlagCode, |
| 719 | MemoryState::FlagCode, MemoryPermission::None, MemoryPermission::None, | 654 | MemoryPermission::None, MemoryPermission::None, MemoryAttribute::Mask, |
| 720 | MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)}; | 655 | MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); |
| 721 | result.IsError()) { | ||
| 722 | return result; | ||
| 723 | } | ||
| 724 | 656 | ||
| 725 | MemoryState state{prev_state}; | 657 | MemoryState state{prev_state}; |
| 726 | 658 | ||
| @@ -745,9 +677,7 @@ ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, Memo | |||
| 745 | ? OperationType::ChangePermissionsAndRefresh | 677 | ? OperationType::ChangePermissionsAndRefresh |
| 746 | : OperationType::ChangePermissions}; | 678 | : OperationType::ChangePermissions}; |
| 747 | 679 | ||
| 748 | if (const ResultCode result{Operate(addr, num_pages, perm, operation)}; result.IsError()) { | 680 | CASCADE_CODE(Operate(addr, num_pages, perm, operation)); |
| 749 | return result; | ||
| 750 | } | ||
| 751 | 681 | ||
| 752 | block_manager->Update(addr, num_pages, state, perm); | 682 | block_manager->Update(addr, num_pages, state, perm); |
| 753 | 683 | ||
| @@ -775,15 +705,12 @@ ResultCode PageTable::ReserveTransferMemory(VAddr addr, std::size_t size, Memory | |||
| 775 | MemoryState state{}; | 705 | MemoryState state{}; |
| 776 | MemoryAttribute attribute{}; | 706 | MemoryAttribute attribute{}; |
| 777 | 707 | ||
| 778 | if (const ResultCode result{CheckMemoryState( | 708 | CASCADE_CODE(CheckMemoryState(&state, nullptr, &attribute, addr, size, |
| 779 | &state, nullptr, &attribute, addr, size, | 709 | MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, |
| 780 | MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, | 710 | MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, |
| 781 | MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, | 711 | MemoryPermission::Mask, MemoryPermission::ReadAndWrite, |
| 782 | MemoryPermission::Mask, MemoryPermission::ReadAndWrite, MemoryAttribute::Mask, | 712 | MemoryAttribute::Mask, MemoryAttribute::None, |
| 783 | MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)}; | 713 | MemoryAttribute::IpcAndDeviceMapped)); |
| 784 | result.IsError()) { | ||
| 785 | return result; | ||
| 786 | } | ||
| 787 | 714 | ||
| 788 | block_manager->Update(addr, size / PageSize, state, perm, attribute | MemoryAttribute::Locked); | 715 | block_manager->Update(addr, size / PageSize, state, perm, attribute | MemoryAttribute::Locked); |
| 789 | 716 | ||
| @@ -795,15 +722,12 @@ ResultCode PageTable::ResetTransferMemory(VAddr addr, std::size_t size) { | |||
| 795 | 722 | ||
| 796 | MemoryState state{}; | 723 | MemoryState state{}; |
| 797 | 724 | ||
| 798 | if (const ResultCode result{ | 725 | CASCADE_CODE(CheckMemoryState(&state, nullptr, nullptr, addr, size, |
| 799 | CheckMemoryState(&state, nullptr, nullptr, addr, size, | 726 | MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, |
| 800 | MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, | 727 | MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, |
| 801 | MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, | 728 | MemoryPermission::None, MemoryPermission::None, |
| 802 | MemoryPermission::None, MemoryPermission::None, MemoryAttribute::Mask, | 729 | MemoryAttribute::Mask, MemoryAttribute::Locked, |
| 803 | MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)}; | 730 | MemoryAttribute::IpcAndDeviceMapped)); |
| 804 | result.IsError()) { | ||
| 805 | return result; | ||
| 806 | } | ||
| 807 | 731 | ||
| 808 | block_manager->Update(addr, size / PageSize, state, MemoryPermission::ReadAndWrite); | 732 | block_manager->Update(addr, size / PageSize, state, MemoryPermission::ReadAndWrite); |
| 809 | 733 | ||
| @@ -818,14 +742,11 @@ ResultCode PageTable::SetMemoryAttribute(VAddr addr, std::size_t size, MemoryAtt | |||
| 818 | MemoryPermission perm{}; | 742 | MemoryPermission perm{}; |
| 819 | MemoryAttribute attribute{}; | 743 | MemoryAttribute attribute{}; |
| 820 | 744 | ||
| 821 | if (const ResultCode result{CheckMemoryState( | 745 | CASCADE_CODE(CheckMemoryState(&state, &perm, &attribute, addr, size, |
| 822 | &state, &perm, &attribute, addr, size, MemoryState::FlagCanChangeAttribute, | 746 | MemoryState::FlagCanChangeAttribute, |
| 823 | MemoryState::FlagCanChangeAttribute, MemoryPermission::None, MemoryPermission::None, | 747 | MemoryState::FlagCanChangeAttribute, MemoryPermission::None, |
| 824 | MemoryAttribute::LockedAndIpcLocked, MemoryAttribute::None, | 748 | MemoryPermission::None, MemoryAttribute::LockedAndIpcLocked, |
| 825 | MemoryAttribute::DeviceSharedAndUncached)}; | 749 | MemoryAttribute::None, MemoryAttribute::DeviceSharedAndUncached)); |
| 826 | result.IsError()) { | ||
| 827 | return result; | ||
| 828 | } | ||
| 829 | 750 | ||
| 830 | attribute = attribute & ~mask; | 751 | attribute = attribute & ~mask; |
| 831 | attribute = attribute | (mask & value); | 752 | attribute = attribute | (mask & value); |
| @@ -866,21 +787,15 @@ ResultVal<VAddr> PageTable::SetHeapSize(std::size_t size) { | |||
| 866 | PageLinkedList page_linked_list; | 787 | PageLinkedList page_linked_list; |
| 867 | const std::size_t num_pages{delta / PageSize}; | 788 | const std::size_t num_pages{delta / PageSize}; |
| 868 | 789 | ||
| 869 | if (const ResultCode result{ | 790 | CASCADE_CODE( |
| 870 | system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool)}; | 791 | system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool)); |
| 871 | result.IsError()) { | ||
| 872 | return result; | ||
| 873 | } | ||
| 874 | 792 | ||
| 875 | if (IsRegionMapped(current_heap_addr, delta)) { | 793 | if (IsRegionMapped(current_heap_addr, delta)) { |
| 876 | return ERR_INVALID_ADDRESS_STATE; | 794 | return ERR_INVALID_ADDRESS_STATE; |
| 877 | } | 795 | } |
| 878 | 796 | ||
| 879 | if (const ResultCode result{ | 797 | CASCADE_CODE( |
| 880 | Operate(current_heap_addr, num_pages, page_linked_list, OperationType::MapGroup)}; | 798 | Operate(current_heap_addr, num_pages, page_linked_list, OperationType::MapGroup)); |
| 881 | result.IsError()) { | ||
| 882 | return result; | ||
| 883 | } | ||
| 884 | 799 | ||
| 885 | block_manager->Update(current_heap_addr, num_pages, MemoryState::Normal, | 800 | block_manager->Update(current_heap_addr, num_pages, MemoryState::Normal, |
| 886 | MemoryPermission::ReadAndWrite); | 801 | MemoryPermission::ReadAndWrite); |
| @@ -912,23 +827,12 @@ ResultVal<VAddr> PageTable::AllocateAndMapMemory(std::size_t needed_num_pages, s | |||
| 912 | } | 827 | } |
| 913 | 828 | ||
| 914 | if (is_map_only) { | 829 | if (is_map_only) { |
| 915 | if (const ResultCode result{ | 830 | CASCADE_CODE(Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr)); |
| 916 | Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr)}; | ||
| 917 | result.IsError()) { | ||
| 918 | return result; | ||
| 919 | } | ||
| 920 | } else { | 831 | } else { |
| 921 | PageLinkedList page_group; | 832 | PageLinkedList page_group; |
| 922 | if (const ResultCode result{system.Kernel().MemoryManager().Allocate( | 833 | CASCADE_CODE( |
| 923 | page_group, needed_num_pages, memory_pool)}; | 834 | system.Kernel().MemoryManager().Allocate(page_group, needed_num_pages, memory_pool)); |
| 924 | result.IsError()) { | 835 | CASCADE_CODE(Operate(addr, needed_num_pages, page_group, OperationType::MapGroup)); |
| 925 | return result; | ||
| 926 | } | ||
| 927 | if (const ResultCode result{ | ||
| 928 | Operate(addr, needed_num_pages, page_group, OperationType::MapGroup)}; | ||
| 929 | result.IsError()) { | ||
| 930 | return result; | ||
| 931 | } | ||
| 932 | } | 836 | } |
| 933 | 837 | ||
| 934 | block_manager->Update(addr, needed_num_pages, state, perm); | 838 | block_manager->Update(addr, needed_num_pages, state, perm); |
| @@ -1196,11 +1100,7 @@ ResultCode PageTable::CheckMemoryState(MemoryState* out_state, MemoryPermission* | |||
| 1196 | } | 1100 | } |
| 1197 | 1101 | ||
| 1198 | // Validate against the provided masks | 1102 | // Validate against the provided masks |
| 1199 | if (const ResultCode result{ | 1103 | CASCADE_CODE(CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr)); |
| 1200 | CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr)}; | ||
| 1201 | result.IsError()) { | ||
| 1202 | return result; | ||
| 1203 | } | ||
| 1204 | 1104 | ||
| 1205 | // Break once we're done | 1105 | // Break once we're done |
| 1206 | if (last_addr <= info.GetLastAddress()) { | 1106 | if (last_addr <= info.GetLastAddress()) { |
diff --git a/src/core/hle/kernel/memory/system_control.cpp b/src/core/hle/kernel/memory/system_control.cpp index e61522dc0..9cae3c6cb 100644 --- a/src/core/hle/kernel/memory/system_control.cpp +++ b/src/core/hle/kernel/memory/system_control.cpp | |||
| @@ -11,9 +11,9 @@ | |||
| 11 | namespace Kernel::Memory::SystemControl { | 11 | namespace Kernel::Memory::SystemControl { |
| 12 | 12 | ||
| 13 | u64 GenerateRandomU64ForInit() { | 13 | u64 GenerateRandomU64ForInit() { |
| 14 | std::random_device device; | 14 | static std::random_device device; |
| 15 | std::mt19937 gen(device()); | 15 | static std::mt19937 gen(device()); |
| 16 | std::uniform_int_distribution<u64> distribution(1, std::numeric_limits<u64>::max()); | 16 | static std::uniform_int_distribution<u64> distribution(1, std::numeric_limits<u64>::max()); |
| 17 | return distribution(gen); | 17 | return distribution(gen); |
| 18 | } | 18 | } |
| 19 | 19 | ||
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index e28da6869..c67696757 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp | |||
| @@ -40,14 +40,14 @@ ResultCode SharedMemory::Map(Process& target_process, VAddr address, std::size_t | |||
| 40 | const u64 page_count{(size + Memory::PageSize - 1) / Memory::PageSize}; | 40 | const u64 page_count{(size + Memory::PageSize - 1) / Memory::PageSize}; |
| 41 | 41 | ||
| 42 | if (page_list.GetNumPages() != page_count) { | 42 | if (page_list.GetNumPages() != page_count) { |
| 43 | UNIMPLEMENTED(); | 43 | UNIMPLEMENTED_MSG("Page count does not match"); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | Memory::MemoryPermission expected = | 46 | Memory::MemoryPermission expected = |
| 47 | &target_process == owner_process ? owner_permission : user_permission; | 47 | &target_process == owner_process ? owner_permission : user_permission; |
| 48 | 48 | ||
| 49 | if (permission != expected) { | 49 | if (permission != expected) { |
| 50 | UNIMPLEMENTED(); | 50 | UNIMPLEMENTED_MSG("Permission does not match"); |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | return target_process.PageTable().MapPages(address, page_list, Memory::MemoryState::Shared, | 53 | return target_process.PageTable().MapPages(address, page_list, Memory::MemoryState::Shared, |
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 06fe693de..cd16d6412 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h | |||
| @@ -28,7 +28,7 @@ public: | |||
| 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, Memory::MemoryPermission owner_permission, |
| 30 | Memory::MemoryPermission user_permission, PAddr physical_address, std::size_t size, | 30 | Memory::MemoryPermission user_permission, PAddr physical_address, std::size_t size, |
| 31 | std::string name = "Unknown"); | 31 | std::string name); |
| 32 | 32 | ||
| 33 | std::string GetTypeName() const override { | 33 | std::string GetTypeName() const override { |
| 34 | return "SharedMemory"; | 34 | return "SharedMemory"; |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 5914b5d39..4134acf65 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -1196,7 +1196,7 @@ static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_add | |||
| 1196 | } | 1196 | } |
| 1197 | 1197 | ||
| 1198 | auto& memory{system.Memory()}; | 1198 | auto& memory{system.Memory()}; |
| 1199 | const Svc::MemoryInfo memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()}; | 1199 | const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()}; |
| 1200 | 1200 | ||
| 1201 | memory.Write64(memory_info_address + 0x00, memory_info.addr); | 1201 | memory.Write64(memory_info_address + 0x00, memory_info.addr); |
| 1202 | memory.Write64(memory_info_address + 0x08, memory_info.size); | 1202 | memory.Write64(memory_info_address + 0x08, memory_info.size); |
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index 73a2bc770..0cde7a557 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp | |||
| @@ -298,9 +298,7 @@ public: | |||
| 298 | continue; | 298 | continue; |
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | if (result.IsError()) { | 301 | CASCADE_CODE(result); |
| 302 | return result; | ||
| 303 | } | ||
| 304 | 302 | ||
| 305 | if (ValidateRegionForMap(page_table, addr, size)) { | 303 | if (ValidateRegionForMap(page_table, addr, size)) { |
| 306 | return MakeResult<VAddr>(addr); | 304 | return MakeResult<VAddr>(addr); |
| @@ -470,16 +468,15 @@ public: | |||
| 470 | } | 468 | } |
| 471 | 469 | ||
| 472 | // Map memory for the NRO | 470 | // Map memory for the NRO |
| 473 | const ResultVal<VAddr> map_result{MapNro(system.CurrentProcess(), nro_address, nro_size, | 471 | const auto map_result{MapNro(system.CurrentProcess(), nro_address, nro_size, bss_address, |
| 474 | bss_address, bss_size, nro_size + bss_size)}; | 472 | bss_size, nro_size + bss_size)}; |
| 475 | if (map_result.Failed()) { | 473 | if (map_result.Failed()) { |
| 476 | IPC::ResponseBuilder rb{ctx, 2}; | 474 | IPC::ResponseBuilder rb{ctx, 2}; |
| 477 | rb.Push(map_result.Code()); | 475 | rb.Push(map_result.Code()); |
| 478 | } | 476 | } |
| 479 | 477 | ||
| 480 | // Load the NRO into the mapped memory | 478 | // Load the NRO into the mapped memory |
| 481 | if (const ResultCode result{ | 479 | if (const auto result{LoadNro(system.CurrentProcess(), header, nro_address, *map_result)}; |
| 482 | LoadNro(system.CurrentProcess(), header, nro_address, *map_result)}; | ||
| 483 | result.IsError()) { | 480 | result.IsError()) { |
| 484 | IPC::ResponseBuilder rb{ctx, 2}; | 481 | IPC::ResponseBuilder rb{ctx, 2}; |
| 485 | rb.Push(map_result.Code()); | 482 | rb.Push(map_result.Code()); |
| @@ -551,7 +548,7 @@ public: | |||
| 551 | return; | 548 | return; |
| 552 | } | 549 | } |
| 553 | 550 | ||
| 554 | const ResultCode result{UnmapNro(iter->second)}; | 551 | const auto result{UnmapNro(iter->second)}; |
| 555 | 552 | ||
| 556 | system.InvalidateCpuInstructionCaches(); | 553 | system.InvalidateCpuInstructionCaches(); |
| 557 | 554 | ||