diff options
| author | 2021-03-21 14:36:26 -0700 | |
|---|---|---|
| committer | 2021-03-21 14:45:13 -0700 | |
| commit | 1996cae9cbcddadeb42db571e9c491efd91374b9 (patch) | |
| tree | 63694005b8e9fb8006260c698f1598d89f984ec5 /src | |
| parent | hle: kernel: k_memory_layout: Derive memory regions based on board layout. (diff) | |
| download | yuzu-1996cae9cbcddadeb42db571e9c491efd91374b9.tar.gz yuzu-1996cae9cbcddadeb42db571e9c491efd91374b9.tar.xz yuzu-1996cae9cbcddadeb42db571e9c491efd91374b9.zip | |
hle: kernel: k_memory_layout: Move KMemoryRegionAllocator out of global.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/k_memory_layout.cpp | 49 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_memory_layout.h | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_memory_region.h | 30 |
3 files changed, 47 insertions, 35 deletions
diff --git a/src/core/hle/kernel/k_memory_layout.cpp b/src/core/hle/kernel/k_memory_layout.cpp index 58fe4a133..fb1e2435f 100644 --- a/src/core/hle/kernel/k_memory_layout.cpp +++ b/src/core/hle/kernel/k_memory_layout.cpp | |||
| @@ -2,6 +2,8 @@ | |||
| 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 <array> | ||
| 6 | |||
| 5 | #include "common/alignment.h" | 7 | #include "common/alignment.h" |
| 6 | #include "core/hle/kernel/k_memory_layout.h" | 8 | #include "core/hle/kernel/k_memory_layout.h" |
| 7 | #include "core/hle/kernel/k_system_control.h" | 9 | #include "core/hle/kernel/k_system_control.h" |
| @@ -10,42 +12,18 @@ namespace Kernel { | |||
| 10 | 12 | ||
| 11 | namespace { | 13 | namespace { |
| 12 | 14 | ||
| 13 | class KMemoryRegionAllocator final : NonCopyable { | ||
| 14 | public: | ||
| 15 | static constexpr size_t MaxMemoryRegions = 200; | ||
| 16 | |||
| 17 | private: | ||
| 18 | KMemoryRegion region_heap[MaxMemoryRegions]{}; | ||
| 19 | size_t num_regions{}; | ||
| 20 | |||
| 21 | public: | ||
| 22 | constexpr KMemoryRegionAllocator() = default; | ||
| 23 | |||
| 24 | public: | ||
| 25 | template <typename... Args> | ||
| 26 | KMemoryRegion* Allocate(Args&&... args) { | ||
| 27 | // Ensure we stay within the bounds of our heap. | ||
| 28 | ASSERT(this->num_regions < MaxMemoryRegions); | ||
| 29 | |||
| 30 | // Create the new region. | ||
| 31 | KMemoryRegion* region = std::addressof(this->region_heap[this->num_regions++]); | ||
| 32 | new (region) KMemoryRegion(std::forward<Args>(args)...); | ||
| 33 | |||
| 34 | return region; | ||
| 35 | } | ||
| 36 | }; | ||
| 37 | |||
| 38 | KMemoryRegionAllocator g_memory_region_allocator; | ||
| 39 | |||
| 40 | template <typename... Args> | 15 | template <typename... Args> |
| 41 | KMemoryRegion* AllocateRegion(Args&&... args) { | 16 | KMemoryRegion* AllocateRegion(KMemoryRegionAllocator& memory_region_allocator, Args&&... args) { |
| 42 | return g_memory_region_allocator.Allocate(std::forward<Args>(args)...); | 17 | return memory_region_allocator.Allocate(std::forward<Args>(args)...); |
| 43 | } | 18 | } |
| 44 | 19 | ||
| 45 | } // namespace | 20 | } // namespace |
| 46 | 21 | ||
| 22 | KMemoryRegionTree::KMemoryRegionTree(KMemoryRegionAllocator& memory_region_allocator_) | ||
| 23 | : memory_region_allocator{memory_region_allocator_} {} | ||
| 24 | |||
| 47 | void KMemoryRegionTree::InsertDirectly(u64 address, u64 last_address, u32 attr, u32 type_id) { | 25 | void KMemoryRegionTree::InsertDirectly(u64 address, u64 last_address, u32 attr, u32 type_id) { |
| 48 | this->insert(*AllocateRegion(address, last_address, attr, type_id)); | 26 | this->insert(*AllocateRegion(memory_region_allocator, address, last_address, attr, type_id)); |
| 49 | } | 27 | } |
| 50 | 28 | ||
| 51 | bool KMemoryRegionTree::Insert(u64 address, size_t size, u32 type_id, u32 new_attr, u32 old_attr) { | 29 | bool KMemoryRegionTree::Insert(u64 address, size_t size, u32 type_id, u32 new_attr, u32 old_attr) { |
| @@ -92,7 +70,8 @@ bool KMemoryRegionTree::Insert(u64 address, size_t size, u32 type_id, u32 new_at | |||
| 92 | const u64 new_pair = (old_pair != std::numeric_limits<u64>::max()) | 70 | const u64 new_pair = (old_pair != std::numeric_limits<u64>::max()) |
| 93 | ? old_pair + (address - old_address) | 71 | ? old_pair + (address - old_address) |
| 94 | : old_pair; | 72 | : old_pair; |
| 95 | this->insert(*AllocateRegion(address, inserted_region_last, new_pair, new_attr, type_id)); | 73 | this->insert(*AllocateRegion(memory_region_allocator, address, inserted_region_last, |
| 74 | new_pair, new_attr, type_id)); | ||
| 96 | } | 75 | } |
| 97 | 76 | ||
| 98 | // If we need to insert a region after the region, do so. | 77 | // If we need to insert a region after the region, do so. |
| @@ -100,8 +79,8 @@ bool KMemoryRegionTree::Insert(u64 address, size_t size, u32 type_id, u32 new_at | |||
| 100 | const u64 after_pair = (old_pair != std::numeric_limits<u64>::max()) | 79 | const u64 after_pair = (old_pair != std::numeric_limits<u64>::max()) |
| 101 | ? old_pair + (inserted_region_end - old_address) | 80 | ? old_pair + (inserted_region_end - old_address) |
| 102 | : old_pair; | 81 | : old_pair; |
| 103 | this->insert( | 82 | this->insert(*AllocateRegion(memory_region_allocator, inserted_region_end, old_last, |
| 104 | *AllocateRegion(inserted_region_end, old_last, after_pair, old_attr, old_type)); | 83 | after_pair, old_attr, old_type)); |
| 105 | } | 84 | } |
| 106 | 85 | ||
| 107 | return true; | 86 | return true; |
| @@ -147,6 +126,10 @@ VAddr KMemoryRegionTree::GetRandomAlignedRegion(size_t size, size_t alignment, u | |||
| 147 | } | 126 | } |
| 148 | } | 127 | } |
| 149 | 128 | ||
| 129 | KMemoryLayout::KMemoryLayout() | ||
| 130 | : virtual_tree{memory_region_allocator}, physical_tree{memory_region_allocator}, | ||
| 131 | virtual_linear_tree{memory_region_allocator}, physical_linear_tree{memory_region_allocator} {} | ||
| 132 | |||
| 150 | void KMemoryLayout::InitializeLinearMemoryRegionTrees(PAddr aligned_linear_phys_start, | 133 | void KMemoryLayout::InitializeLinearMemoryRegionTrees(PAddr aligned_linear_phys_start, |
| 151 | VAddr linear_virtual_start) { | 134 | VAddr linear_virtual_start) { |
| 152 | // Set static differences. | 135 | // Set static differences. |
diff --git a/src/core/hle/kernel/k_memory_layout.h b/src/core/hle/kernel/k_memory_layout.h index f2b46c932..b3e057326 100644 --- a/src/core/hle/kernel/k_memory_layout.h +++ b/src/core/hle/kernel/k_memory_layout.h | |||
| @@ -73,7 +73,7 @@ constexpr bool IsKernelAddress(VAddr address) { | |||
| 73 | 73 | ||
| 74 | class KMemoryLayout final { | 74 | class KMemoryLayout final { |
| 75 | public: | 75 | public: |
| 76 | KMemoryLayout() = default; | 76 | KMemoryLayout(); |
| 77 | 77 | ||
| 78 | KMemoryRegionTree& GetVirtualMemoryRegionTree() { | 78 | KMemoryRegionTree& GetVirtualMemoryRegionTree() { |
| 79 | return virtual_tree; | 79 | return virtual_tree; |
| @@ -376,6 +376,7 @@ private: | |||
| 376 | private: | 376 | private: |
| 377 | u64 linear_phys_to_virt_diff{}; | 377 | u64 linear_phys_to_virt_diff{}; |
| 378 | u64 linear_virt_to_phys_diff{}; | 378 | u64 linear_virt_to_phys_diff{}; |
| 379 | KMemoryRegionAllocator memory_region_allocator; | ||
| 379 | KMemoryRegionTree virtual_tree; | 380 | KMemoryRegionTree virtual_tree; |
| 380 | KMemoryRegionTree physical_tree; | 381 | KMemoryRegionTree physical_tree; |
| 381 | KMemoryRegionTree virtual_linear_tree; | 382 | KMemoryRegionTree virtual_linear_tree; |
diff --git a/src/core/hle/kernel/k_memory_region.h b/src/core/hle/kernel/k_memory_region.h index 1d4fcde6f..374b24bd3 100644 --- a/src/core/hle/kernel/k_memory_region.h +++ b/src/core/hle/kernel/k_memory_region.h | |||
| @@ -11,6 +11,8 @@ | |||
| 11 | 11 | ||
| 12 | namespace Kernel { | 12 | namespace Kernel { |
| 13 | 13 | ||
| 14 | class KMemoryRegionAllocator; | ||
| 15 | |||
| 14 | class KMemoryRegion final : public Common::IntrusiveRedBlackTreeBaseNode<KMemoryRegion>, | 16 | class KMemoryRegion final : public Common::IntrusiveRedBlackTreeBaseNode<KMemoryRegion>, |
| 15 | NonCopyable { | 17 | NonCopyable { |
| 16 | friend class KMemoryRegionTree; | 18 | friend class KMemoryRegionTree; |
| @@ -155,9 +157,10 @@ public: | |||
| 155 | 157 | ||
| 156 | private: | 158 | private: |
| 157 | TreeType m_tree{}; | 159 | TreeType m_tree{}; |
| 160 | KMemoryRegionAllocator& memory_region_allocator; | ||
| 158 | 161 | ||
| 159 | public: | 162 | public: |
| 160 | constexpr KMemoryRegionTree() = default; | 163 | KMemoryRegionTree(KMemoryRegionAllocator& memory_region_allocator_); |
| 161 | 164 | ||
| 162 | public: | 165 | public: |
| 163 | KMemoryRegion* FindModifiable(u64 address) { | 166 | KMemoryRegion* FindModifiable(u64 address) { |
| @@ -321,4 +324,29 @@ public: | |||
| 321 | } | 324 | } |
| 322 | }; | 325 | }; |
| 323 | 326 | ||
| 327 | class KMemoryRegionAllocator final : NonCopyable { | ||
| 328 | public: | ||
| 329 | static constexpr size_t MaxMemoryRegions = 200; | ||
| 330 | |||
| 331 | private: | ||
| 332 | std::array<KMemoryRegion, MaxMemoryRegions> region_heap{}; | ||
| 333 | size_t num_regions{}; | ||
| 334 | |||
| 335 | public: | ||
| 336 | constexpr KMemoryRegionAllocator() = default; | ||
| 337 | |||
| 338 | public: | ||
| 339 | template <typename... Args> | ||
| 340 | KMemoryRegion* Allocate(Args&&... args) { | ||
| 341 | // Ensure we stay within the bounds of our heap. | ||
| 342 | ASSERT(this->num_regions < MaxMemoryRegions); | ||
| 343 | |||
| 344 | // Create the new region. | ||
| 345 | KMemoryRegion* region = std::addressof(this->region_heap[this->num_regions++]); | ||
| 346 | new (region) KMemoryRegion(std::forward<Args>(args)...); | ||
| 347 | |||
| 348 | return region; | ||
| 349 | } | ||
| 350 | }; | ||
| 351 | |||
| 324 | } // namespace Kernel | 352 | } // namespace Kernel |