summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/kernel/k_memory_layout.cpp49
-rw-r--r--src/core/hle/kernel/k_memory_layout.h3
-rw-r--r--src/core/hle/kernel/k_memory_region.h30
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 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <array>
+
#include "common/alignment.h"
#include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_system_control.h"
@@ -10,42 +12,18 @@ namespace Kernel {
namespace {
-class KMemoryRegionAllocator final : NonCopyable {
-public:
- static constexpr size_t MaxMemoryRegions = 200;
-
-private:
- KMemoryRegion region_heap[MaxMemoryRegions]{};
- size_t num_regions{};
-
-public:
- constexpr KMemoryRegionAllocator() = default;
-
-public:
- template <typename... Args>
- KMemoryRegion* Allocate(Args&&... args) {
- // Ensure we stay within the bounds of our heap.
- ASSERT(this->num_regions < MaxMemoryRegions);
-
- // Create the new region.
- KMemoryRegion* region = std::addressof(this->region_heap[this->num_regions++]);
- new (region) KMemoryRegion(std::forward<Args>(args)...);
-
- return region;
- }
-};
-
-KMemoryRegionAllocator g_memory_region_allocator;
-
template <typename... Args>
-KMemoryRegion* AllocateRegion(Args&&... args) {
- return g_memory_region_allocator.Allocate(std::forward<Args>(args)...);
+KMemoryRegion* AllocateRegion(KMemoryRegionAllocator& memory_region_allocator, Args&&... args) {
+ return memory_region_allocator.Allocate(std::forward<Args>(args)...);
}
} // namespace
+KMemoryRegionTree::KMemoryRegionTree(KMemoryRegionAllocator& memory_region_allocator_)
+ : memory_region_allocator{memory_region_allocator_} {}
+
void KMemoryRegionTree::InsertDirectly(u64 address, u64 last_address, u32 attr, u32 type_id) {
- this->insert(*AllocateRegion(address, last_address, attr, type_id));
+ this->insert(*AllocateRegion(memory_region_allocator, address, last_address, attr, type_id));
}
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
const u64 new_pair = (old_pair != std::numeric_limits<u64>::max())
? old_pair + (address - old_address)
: old_pair;
- this->insert(*AllocateRegion(address, inserted_region_last, new_pair, new_attr, type_id));
+ this->insert(*AllocateRegion(memory_region_allocator, address, inserted_region_last,
+ new_pair, new_attr, type_id));
}
// 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
const u64 after_pair = (old_pair != std::numeric_limits<u64>::max())
? old_pair + (inserted_region_end - old_address)
: old_pair;
- this->insert(
- *AllocateRegion(inserted_region_end, old_last, after_pair, old_attr, old_type));
+ this->insert(*AllocateRegion(memory_region_allocator, inserted_region_end, old_last,
+ after_pair, old_attr, old_type));
}
return true;
@@ -147,6 +126,10 @@ VAddr KMemoryRegionTree::GetRandomAlignedRegion(size_t size, size_t alignment, u
}
}
+KMemoryLayout::KMemoryLayout()
+ : virtual_tree{memory_region_allocator}, physical_tree{memory_region_allocator},
+ virtual_linear_tree{memory_region_allocator}, physical_linear_tree{memory_region_allocator} {}
+
void KMemoryLayout::InitializeLinearMemoryRegionTrees(PAddr aligned_linear_phys_start,
VAddr linear_virtual_start) {
// 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) {
class KMemoryLayout final {
public:
- KMemoryLayout() = default;
+ KMemoryLayout();
KMemoryRegionTree& GetVirtualMemoryRegionTree() {
return virtual_tree;
@@ -376,6 +376,7 @@ private:
private:
u64 linear_phys_to_virt_diff{};
u64 linear_virt_to_phys_diff{};
+ KMemoryRegionAllocator memory_region_allocator;
KMemoryRegionTree virtual_tree;
KMemoryRegionTree physical_tree;
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 @@
namespace Kernel {
+class KMemoryRegionAllocator;
+
class KMemoryRegion final : public Common::IntrusiveRedBlackTreeBaseNode<KMemoryRegion>,
NonCopyable {
friend class KMemoryRegionTree;
@@ -155,9 +157,10 @@ public:
private:
TreeType m_tree{};
+ KMemoryRegionAllocator& memory_region_allocator;
public:
- constexpr KMemoryRegionTree() = default;
+ KMemoryRegionTree(KMemoryRegionAllocator& memory_region_allocator_);
public:
KMemoryRegion* FindModifiable(u64 address) {
@@ -321,4 +324,29 @@ public:
}
};
+class KMemoryRegionAllocator final : NonCopyable {
+public:
+ static constexpr size_t MaxMemoryRegions = 200;
+
+private:
+ std::array<KMemoryRegion, MaxMemoryRegions> region_heap{};
+ size_t num_regions{};
+
+public:
+ constexpr KMemoryRegionAllocator() = default;
+
+public:
+ template <typename... Args>
+ KMemoryRegion* Allocate(Args&&... args) {
+ // Ensure we stay within the bounds of our heap.
+ ASSERT(this->num_regions < MaxMemoryRegions);
+
+ // Create the new region.
+ KMemoryRegion* region = std::addressof(this->region_heap[this->num_regions++]);
+ new (region) KMemoryRegion(std::forward<Args>(args)...);
+
+ return region;
+ }
+};
+
} // namespace Kernel