summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/kernel/init/init_slab_setup.cpp74
-rw-r--r--src/core/hle/kernel/init/init_slab_setup.h2
-rw-r--r--src/core/hle/kernel/k_page_table.cpp12
-rw-r--r--src/core/hle/kernel/k_page_table.h42
-rw-r--r--src/core/hle/kernel/k_process.cpp4
-rw-r--r--src/core/hle/kernel/kernel.cpp121
-rw-r--r--src/core/hle/kernel/kernel.h23
7 files changed, 209 insertions, 69 deletions
diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp
index 477e4e407..aa2dddcc6 100644
--- a/src/core/hle/kernel/init/init_slab_setup.cpp
+++ b/src/core/hle/kernel/init/init_slab_setup.cpp
@@ -10,7 +10,9 @@
10#include "core/hardware_properties.h" 10#include "core/hardware_properties.h"
11#include "core/hle/kernel/init/init_slab_setup.h" 11#include "core/hle/kernel/init/init_slab_setup.h"
12#include "core/hle/kernel/k_code_memory.h" 12#include "core/hle/kernel/k_code_memory.h"
13#include "core/hle/kernel/k_debug.h"
13#include "core/hle/kernel/k_event.h" 14#include "core/hle/kernel/k_event.h"
15#include "core/hle/kernel/k_event_info.h"
14#include "core/hle/kernel/k_memory_layout.h" 16#include "core/hle/kernel/k_memory_layout.h"
15#include "core/hle/kernel/k_memory_manager.h" 17#include "core/hle/kernel/k_memory_manager.h"
16#include "core/hle/kernel/k_page_buffer.h" 18#include "core/hle/kernel/k_page_buffer.h"
@@ -22,6 +24,7 @@
22#include "core/hle/kernel/k_shared_memory.h" 24#include "core/hle/kernel/k_shared_memory.h"
23#include "core/hle/kernel/k_shared_memory_info.h" 25#include "core/hle/kernel/k_shared_memory_info.h"
24#include "core/hle/kernel/k_system_control.h" 26#include "core/hle/kernel/k_system_control.h"
27#include "core/hle/kernel/k_system_resource.h"
25#include "core/hle/kernel/k_thread.h" 28#include "core/hle/kernel/k_thread.h"
26#include "core/hle/kernel/k_thread_local_page.h" 29#include "core/hle/kernel/k_thread_local_page.h"
27#include "core/hle/kernel/k_transfer_memory.h" 30#include "core/hle/kernel/k_transfer_memory.h"
@@ -44,7 +47,10 @@ namespace Kernel::Init {
44 HANDLER(KThreadLocalPage, \ 47 HANDLER(KThreadLocalPage, \
45 (SLAB_COUNT(KProcess) + (SLAB_COUNT(KProcess) + SLAB_COUNT(KThread)) / 8), \ 48 (SLAB_COUNT(KProcess) + (SLAB_COUNT(KProcess) + SLAB_COUNT(KThread)) / 8), \
46 ##__VA_ARGS__) \ 49 ##__VA_ARGS__) \
47 HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ##__VA_ARGS__) 50 HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ##__VA_ARGS__) \
51 HANDLER(KEventInfo, (SLAB_COUNT(KThread) + SLAB_COUNT(KDebug)), ##__VA_ARGS__) \
52 HANDLER(KDebug, (SLAB_COUNT(KDebug)), ##__VA_ARGS__) \
53 HANDLER(KSecureSystemResource, (SLAB_COUNT(KProcess)), ##__VA_ARGS__)
48 54
49namespace { 55namespace {
50 56
@@ -73,8 +79,20 @@ constexpr size_t SlabCountKResourceLimit = 5;
73constexpr size_t SlabCountKDebug = Core::Hardware::NUM_CPU_CORES; 79constexpr size_t SlabCountKDebug = Core::Hardware::NUM_CPU_CORES;
74constexpr size_t SlabCountKIoPool = 1; 80constexpr size_t SlabCountKIoPool = 1;
75constexpr size_t SlabCountKIoRegion = 6; 81constexpr size_t SlabCountKIoRegion = 6;
82constexpr size_t SlabcountKSessionRequestMappings = 40;
76 83
77constexpr size_t SlabCountExtraKThread = 160; 84constexpr size_t SlabCountExtraKThread = (1024 + 256 + 256) - SlabCountKThread;
85
86namespace test {
87
88static_assert(KernelPageBufferHeapSize ==
89 2 * PageSize + (SlabCountKProcess + SlabCountKThread +
90 (SlabCountKProcess + SlabCountKThread) / 8) *
91 PageSize);
92static_assert(KernelPageBufferAdditionalSize ==
93 (SlabCountExtraKThread + (SlabCountExtraKThread / 8)) * PageSize);
94
95} // namespace test
78 96
79/// Helper function to translate from the slab virtual address to the reserved location in physical 97/// Helper function to translate from the slab virtual address to the reserved location in physical
80/// memory. 98/// memory.
@@ -109,7 +127,7 @@ VAddr InitializeSlabHeap(Core::System& system, KMemoryLayout& memory_layout, VAd
109} 127}
110 128
111size_t CalculateSlabHeapGapSize() { 129size_t CalculateSlabHeapGapSize() {
112 constexpr size_t KernelSlabHeapGapSize = 2_MiB - 296_KiB; 130 constexpr size_t KernelSlabHeapGapSize = 2_MiB - 320_KiB;
113 static_assert(KernelSlabHeapGapSize <= KernelSlabHeapGapsSizeMax); 131 static_assert(KernelSlabHeapGapSize <= KernelSlabHeapGapsSizeMax);
114 return KernelSlabHeapGapSize; 132 return KernelSlabHeapGapSize;
115} 133}
@@ -134,6 +152,7 @@ KSlabResourceCounts KSlabResourceCounts::CreateDefault() {
134 .num_KDebug = SlabCountKDebug, 152 .num_KDebug = SlabCountKDebug,
135 .num_KIoPool = SlabCountKIoPool, 153 .num_KIoPool = SlabCountKIoPool,
136 .num_KIoRegion = SlabCountKIoRegion, 154 .num_KIoRegion = SlabCountKIoRegion,
155 .num_KSessionRequestMappings = SlabcountKSessionRequestMappings,
137 }; 156 };
138} 157}
139 158
@@ -164,29 +183,6 @@ size_t CalculateTotalSlabHeapSize(const KernelCore& kernel) {
164 return size; 183 return size;
165} 184}
166 185
167void InitializeKPageBufferSlabHeap(Core::System& system) {
168 auto& kernel = system.Kernel();
169
170 const auto& counts = kernel.SlabResourceCounts();
171 const size_t num_pages =
172 counts.num_KProcess + counts.num_KThread + (counts.num_KProcess + counts.num_KThread) / 8;
173 const size_t slab_size = num_pages * PageSize;
174
175 // Reserve memory from the system resource limit.
176 ASSERT(kernel.GetSystemResourceLimit()->Reserve(LimitableResource::PhysicalMemory, slab_size));
177
178 // Allocate memory for the slab.
179 constexpr auto AllocateOption = KMemoryManager::EncodeOption(
180 KMemoryManager::Pool::System, KMemoryManager::Direction::FromFront);
181 const PAddr slab_address =
182 kernel.MemoryManager().AllocateAndOpenContinuous(num_pages, 1, AllocateOption);
183 ASSERT(slab_address != 0);
184
185 // Initialize the slabheap.
186 KPageBuffer::InitializeSlabHeap(kernel, system.DeviceMemory().GetPointer<void>(slab_address),
187 slab_size);
188}
189
190void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) { 186void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) {
191 auto& kernel = system.Kernel(); 187 auto& kernel = system.Kernel();
192 188
@@ -258,3 +254,29 @@ void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) {
258} 254}
259 255
260} // namespace Kernel::Init 256} // namespace Kernel::Init
257
258namespace Kernel {
259
260void KPageBufferSlabHeap::Initialize(Core::System& system) {
261 auto& kernel = system.Kernel();
262 const auto& counts = kernel.SlabResourceCounts();
263 const size_t num_pages =
264 counts.num_KProcess + counts.num_KThread + (counts.num_KProcess + counts.num_KThread) / 8;
265 const size_t slab_size = num_pages * PageSize;
266
267 // Reserve memory from the system resource limit.
268 ASSERT(kernel.GetSystemResourceLimit()->Reserve(LimitableResource::PhysicalMemory, slab_size));
269
270 // Allocate memory for the slab.
271 constexpr auto AllocateOption = KMemoryManager::EncodeOption(
272 KMemoryManager::Pool::System, KMemoryManager::Direction::FromFront);
273 const PAddr slab_address =
274 kernel.MemoryManager().AllocateAndOpenContinuous(num_pages, 1, AllocateOption);
275 ASSERT(slab_address != 0);
276
277 // Initialize the slabheap.
278 KPageBuffer::InitializeSlabHeap(kernel, system.DeviceMemory().GetPointer<void>(slab_address),
279 slab_size);
280}
281
282} // namespace Kernel
diff --git a/src/core/hle/kernel/init/init_slab_setup.h b/src/core/hle/kernel/init/init_slab_setup.h
index 13be63c87..5e22821bc 100644
--- a/src/core/hle/kernel/init/init_slab_setup.h
+++ b/src/core/hle/kernel/init/init_slab_setup.h
@@ -33,11 +33,11 @@ struct KSlabResourceCounts {
33 size_t num_KDebug; 33 size_t num_KDebug;
34 size_t num_KIoPool; 34 size_t num_KIoPool;
35 size_t num_KIoRegion; 35 size_t num_KIoRegion;
36 size_t num_KSessionRequestMappings;
36}; 37};
37 38
38void InitializeSlabResourceCounts(KernelCore& kernel); 39void InitializeSlabResourceCounts(KernelCore& kernel);
39size_t CalculateTotalSlabHeapSize(const KernelCore& kernel); 40size_t CalculateTotalSlabHeapSize(const KernelCore& kernel);
40void InitializeKPageBufferSlabHeap(Core::System& system);
41void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout); 41void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout);
42 42
43} // namespace Kernel::Init 43} // namespace Kernel::Init
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp
index 307e491cb..c513e790e 100644
--- a/src/core/hle/kernel/k_page_table.cpp
+++ b/src/core/hle/kernel/k_page_table.cpp
@@ -15,6 +15,7 @@
15#include "core/hle/kernel/k_resource_limit.h" 15#include "core/hle/kernel/k_resource_limit.h"
16#include "core/hle/kernel/k_scoped_resource_reservation.h" 16#include "core/hle/kernel/k_scoped_resource_reservation.h"
17#include "core/hle/kernel/k_system_control.h" 17#include "core/hle/kernel/k_system_control.h"
18#include "core/hle/kernel/k_system_resource.h"
18#include "core/hle/kernel/kernel.h" 19#include "core/hle/kernel/kernel.h"
19#include "core/hle/kernel/svc_results.h" 20#include "core/hle/kernel/svc_results.h"
20#include "core/memory.h" 21#include "core/memory.h"
@@ -49,9 +50,10 @@ KPageTable::KPageTable(Core::System& system_)
49KPageTable::~KPageTable() = default; 50KPageTable::~KPageTable() = default;
50 51
51Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr, 52Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr,
52 VAddr code_addr, size_t code_size, 53 bool enable_das_merge, bool from_back,
53 KMemoryBlockSlabManager* mem_block_slab_manager, 54 KMemoryManager::Pool pool, VAddr code_addr,
54 KMemoryManager::Pool pool) { 55 size_t code_size, KSystemResource* system_resource,
56 KResourceLimit* resource_limit) {
55 57
56 const auto GetSpaceStart = [this](KAddressSpaceInfo::Type type) { 58 const auto GetSpaceStart = [this](KAddressSpaceInfo::Type type) {
57 return KAddressSpaceInfo::GetAddressSpaceStart(m_address_space_width, type); 59 return KAddressSpaceInfo::GetAddressSpaceStart(m_address_space_width, type);
@@ -116,7 +118,9 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type
116 m_address_space_start = start; 118 m_address_space_start = start;
117 m_address_space_end = end; 119 m_address_space_end = end;
118 m_is_kernel = false; 120 m_is_kernel = false;
119 m_memory_block_slab_manager = mem_block_slab_manager; 121 m_memory_block_slab_manager = system_resource->GetMemoryBlockSlabManagerPointer();
122 m_block_info_manager = system_resource->GetBlockInfoManagerPointer();
123 m_resource_limit = resource_limit;
120 124
121 // Determine the region we can place our undetermineds in 125 // Determine the region we can place our undetermineds in
122 VAddr alloc_start{}; 126 VAddr alloc_start{};
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h
index c6aeacd96..753e07c94 100644
--- a/src/core/hle/kernel/k_page_table.h
+++ b/src/core/hle/kernel/k_page_table.h
@@ -23,7 +23,10 @@ class System;
23 23
24namespace Kernel { 24namespace Kernel {
25 25
26class KBlockInfoManager;
26class KMemoryBlockManager; 27class KMemoryBlockManager;
28class KResourceLimit;
29class KSystemResource;
27 30
28class KPageTable final { 31class KPageTable final {
29public: 32public:
@@ -36,9 +39,9 @@ public:
36 ~KPageTable(); 39 ~KPageTable();
37 40
38 Result InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr, 41 Result InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr,
39 VAddr code_addr, size_t code_size, 42 bool enable_das_merge, bool from_back, KMemoryManager::Pool pool,
40 KMemoryBlockSlabManager* mem_block_slab_manager, 43 VAddr code_addr, size_t code_size, KSystemResource* system_resource,
41 KMemoryManager::Pool pool); 44 KResourceLimit* resource_limit);
42 45
43 void Finalize(); 46 void Finalize();
44 47
@@ -74,9 +77,9 @@ public:
74 KMemoryState state, KMemoryPermission perm, 77 KMemoryState state, KMemoryPermission perm,
75 PAddr map_addr = 0); 78 PAddr map_addr = 0);
76 79
77 Result LockForMapDeviceAddressSpace(VAddr address, size_t size, KMemoryPermission perm, 80 Result LockForMapDeviceAddressSpace(bool* out_is_io, VAddr address, size_t size,
78 bool is_aligned); 81 KMemoryPermission perm, bool is_aligned, bool check_heap);
79 Result LockForUnmapDeviceAddressSpace(VAddr address, size_t size); 82 Result LockForUnmapDeviceAddressSpace(VAddr address, size_t size, bool check_heap);
80 83
81 Result UnlockForDeviceAddressSpace(VAddr addr, size_t size); 84 Result UnlockForDeviceAddressSpace(VAddr addr, size_t size);
82 85
@@ -99,11 +102,13 @@ public:
99 102
100private: 103private:
101 enum class OperationType : u32 { 104 enum class OperationType : u32 {
102 Map, 105 Map = 0,
103 MapGroup, 106 MapFirst = 1,
104 Unmap, 107 MapGroup = 2,
105 ChangePermissions, 108 Unmap = 3,
106 ChangePermissionsAndRefresh, 109 ChangePermissions = 4,
110 ChangePermissionsAndRefresh = 5,
111 Separate = 6,
107 }; 112 };
108 113
109 static constexpr KMemoryAttribute DefaultMemoryIgnoreAttr = 114 static constexpr KMemoryAttribute DefaultMemoryIgnoreAttr =
@@ -199,6 +204,10 @@ private:
199 return *out != 0; 204 return *out != 0;
200 } 205 }
201 206
207 // HACK: These will be removed once we automatically manage page reference counts.
208 void HACK_OpenPages(PAddr phys_addr, size_t num_pages);
209 void HACK_ClosePages(VAddr virt_addr, size_t num_pages);
210
202 mutable KLightLock m_general_lock; 211 mutable KLightLock m_general_lock;
203 mutable KLightLock m_map_physical_memory_lock; 212 mutable KLightLock m_map_physical_memory_lock;
204 213
@@ -347,20 +356,27 @@ private:
347 VAddr m_alias_code_region_start{}; 356 VAddr m_alias_code_region_start{};
348 VAddr m_alias_code_region_end{}; 357 VAddr m_alias_code_region_end{};
349 358
350 size_t m_mapped_physical_memory_size{};
351 size_t m_max_heap_size{}; 359 size_t m_max_heap_size{};
352 size_t m_max_physical_memory_size{}; 360 size_t m_mapped_physical_memory_size{};
361 size_t m_mapped_unsafe_physical_memory{};
362 size_t m_mapped_insecure_memory{};
363 size_t m_mapped_ipc_server_memory{};
353 size_t m_address_space_width{}; 364 size_t m_address_space_width{};
354 365
355 KMemoryBlockManager m_memory_block_manager; 366 KMemoryBlockManager m_memory_block_manager;
367 u32 m_allocate_option{};
356 368
357 bool m_is_kernel{}; 369 bool m_is_kernel{};
358 bool m_enable_aslr{}; 370 bool m_enable_aslr{};
359 bool m_enable_device_address_space_merge{}; 371 bool m_enable_device_address_space_merge{};
360 372
361 KMemoryBlockSlabManager* m_memory_block_slab_manager{}; 373 KMemoryBlockSlabManager* m_memory_block_slab_manager{};
374 KBlockInfoManager* m_block_info_manager{};
375 KResourceLimit* m_resource_limit{};
362 376
363 u32 m_heap_fill_value{}; 377 u32 m_heap_fill_value{};
378 u32 m_ipc_fill_value{};
379 u32 m_stack_fill_value{};
364 const KMemoryRegion* m_cached_physical_heap_region{}; 380 const KMemoryRegion* m_cached_physical_heap_region{};
365 381
366 KMemoryManager::Pool m_memory_pool{KMemoryManager::Pool::Application}; 382 KMemoryManager::Pool m_memory_pool{KMemoryManager::Pool::Application};
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 8c3495e5a..4ddeea73b 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -358,8 +358,8 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
358 } 358 }
359 // Initialize proces address space 359 // Initialize proces address space
360 if (const Result result{page_table.InitializeForProcess( 360 if (const Result result{page_table.InitializeForProcess(
361 metadata.GetAddressSpaceType(), false, 0x8000000, code_size, 361 metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application,
362 &kernel.GetApplicationMemoryBlockManager(), KMemoryManager::Pool::Application)}; 362 0x8000000, code_size, &kernel.GetSystemSystemResource(), resource_limit)};
363 result.IsError()) { 363 result.IsError()) {
364 R_RETURN(result); 364 R_RETURN(result);
365 } 365 }
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index fc94cb22c..eda4e9e1c 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -28,10 +28,12 @@
28#include "core/hle/kernel/k_handle_table.h" 28#include "core/hle/kernel/k_handle_table.h"
29#include "core/hle/kernel/k_memory_layout.h" 29#include "core/hle/kernel/k_memory_layout.h"
30#include "core/hle/kernel/k_memory_manager.h" 30#include "core/hle/kernel/k_memory_manager.h"
31#include "core/hle/kernel/k_page_buffer.h"
31#include "core/hle/kernel/k_process.h" 32#include "core/hle/kernel/k_process.h"
32#include "core/hle/kernel/k_resource_limit.h" 33#include "core/hle/kernel/k_resource_limit.h"
33#include "core/hle/kernel/k_scheduler.h" 34#include "core/hle/kernel/k_scheduler.h"
34#include "core/hle/kernel/k_shared_memory.h" 35#include "core/hle/kernel/k_shared_memory.h"
36#include "core/hle/kernel/k_system_resource.h"
35#include "core/hle/kernel/k_thread.h" 37#include "core/hle/kernel/k_thread.h"
36#include "core/hle/kernel/k_worker_task_manager.h" 38#include "core/hle/kernel/k_worker_task_manager.h"
37#include "core/hle/kernel/kernel.h" 39#include "core/hle/kernel/kernel.h"
@@ -47,6 +49,11 @@ MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
47namespace Kernel { 49namespace Kernel {
48 50
49struct KernelCore::Impl { 51struct KernelCore::Impl {
52 static constexpr size_t ApplicationMemoryBlockSlabHeapSize = 20000;
53 static constexpr size_t SystemMemoryBlockSlabHeapSize = 10000;
54 static constexpr size_t BlockInfoSlabHeapSize = 4000;
55 static constexpr size_t ReservedDynamicPageCount = 64;
56
50 explicit Impl(Core::System& system_, KernelCore& kernel_) 57 explicit Impl(Core::System& system_, KernelCore& kernel_)
51 : time_manager{system_}, service_threads_manager{1, "ServiceThreadsManager"}, 58 : time_manager{system_}, service_threads_manager{1, "ServiceThreadsManager"},
52 service_thread_barrier{2}, system{system_} {} 59 service_thread_barrier{2}, system{system_} {}
@@ -72,7 +79,6 @@ struct KernelCore::Impl {
72 // Initialize kernel memory and resources. 79 // Initialize kernel memory and resources.
73 InitializeSystemResourceLimit(kernel, system.CoreTiming()); 80 InitializeSystemResourceLimit(kernel, system.CoreTiming());
74 InitializeMemoryLayout(); 81 InitializeMemoryLayout();
75 Init::InitializeKPageBufferSlabHeap(system);
76 InitializeShutdownThreads(); 82 InitializeShutdownThreads();
77 InitializePhysicalCores(); 83 InitializePhysicalCores();
78 InitializePreemption(kernel); 84 InitializePreemption(kernel);
@@ -82,7 +88,8 @@ struct KernelCore::Impl {
82 const auto& pt_heap_region = memory_layout->GetPageTableHeapRegion(); 88 const auto& pt_heap_region = memory_layout->GetPageTableHeapRegion();
83 ASSERT(pt_heap_region.GetEndAddress() != 0); 89 ASSERT(pt_heap_region.GetEndAddress() != 0);
84 90
85 InitializeResourceManagers(pt_heap_region.GetAddress(), pt_heap_region.GetSize()); 91 InitializeResourceManagers(kernel, pt_heap_region.GetAddress(),
92 pt_heap_region.GetSize());
86 } 93 }
87 94
88 RegisterHostThread(); 95 RegisterHostThread();
@@ -263,16 +270,82 @@ struct KernelCore::Impl {
263 system.CoreTiming().ScheduleLoopingEvent(time_interval, time_interval, preemption_event); 270 system.CoreTiming().ScheduleLoopingEvent(time_interval, time_interval, preemption_event);
264 } 271 }
265 272
266 void InitializeResourceManagers(VAddr address, size_t size) { 273 void InitializeResourceManagers(KernelCore& kernel, VAddr address, size_t size) {
267 dynamic_page_manager = std::make_unique<KDynamicPageManager>(); 274 // Ensure that the buffer is suitable for our use.
268 memory_block_heap = std::make_unique<KMemoryBlockSlabHeap>(); 275 ASSERT(Common::IsAligned(address, PageSize));
276 ASSERT(Common::IsAligned(size, PageSize));
277
278 // Ensure that we have space for our reference counts.
279 const size_t rc_size =
280 Common::AlignUp(KPageTableSlabHeap::CalculateReferenceCountSize(size), PageSize);
281 ASSERT(rc_size < size);
282 size -= rc_size;
283
284 // Initialize the resource managers' shared page manager.
285 resource_manager_page_manager = std::make_unique<KDynamicPageManager>();
286 resource_manager_page_manager->Initialize(
287 address, size, std::max<size_t>(PageSize, KPageBufferSlabHeap::BufferSize));
288
289 // Initialize the KPageBuffer slab heap.
290 page_buffer_slab_heap.Initialize(system);
291
292 // Initialize the fixed-size slabheaps.
293 app_memory_block_heap = std::make_unique<KMemoryBlockSlabHeap>();
294 sys_memory_block_heap = std::make_unique<KMemoryBlockSlabHeap>();
295 block_info_heap = std::make_unique<KBlockInfoSlabHeap>();
296 app_memory_block_heap->Initialize(resource_manager_page_manager.get(),
297 ApplicationMemoryBlockSlabHeapSize);
298 sys_memory_block_heap->Initialize(resource_manager_page_manager.get(),
299 SystemMemoryBlockSlabHeapSize);
300 block_info_heap->Initialize(resource_manager_page_manager.get(), BlockInfoSlabHeapSize);
301
302 // Reserve all but a fixed number of remaining pages for the page table heap.
303 const size_t num_pt_pages = resource_manager_page_manager->GetCount() -
304 resource_manager_page_manager->GetUsed() -
305 ReservedDynamicPageCount;
306 page_table_heap = std::make_unique<KPageTableSlabHeap>();
307
308 // TODO(bunnei): Pass in address once we support kernel virtual memory allocations.
309 page_table_heap->Initialize(
310 resource_manager_page_manager.get(), num_pt_pages,
311 /*GetPointer<KPageTableManager::RefCount>(address + size)*/ nullptr);
312
313 // Setup the slab managers.
314 KDynamicPageManager* const app_dynamic_page_manager = nullptr;
315 KDynamicPageManager* const sys_dynamic_page_manager =
316 /*KTargetSystem::IsDynamicResourceLimitsEnabled()*/ true
317 ? resource_manager_page_manager.get()
318 : nullptr;
269 app_memory_block_manager = std::make_unique<KMemoryBlockSlabManager>(); 319 app_memory_block_manager = std::make_unique<KMemoryBlockSlabManager>();
270 320 sys_memory_block_manager = std::make_unique<KMemoryBlockSlabManager>();
271 dynamic_page_manager->Initialize(address, size); 321 app_block_info_manager = std::make_unique<KBlockInfoManager>();
272 static constexpr size_t ApplicationMemoryBlockSlabHeapSize = 20000; 322 sys_block_info_manager = std::make_unique<KBlockInfoManager>();
273 memory_block_heap->Initialize(dynamic_page_manager.get(), 323 app_page_table_manager = std::make_unique<KPageTableManager>();
274 ApplicationMemoryBlockSlabHeapSize); 324 sys_page_table_manager = std::make_unique<KPageTableManager>();
275 app_memory_block_manager->Initialize(nullptr, memory_block_heap.get()); 325
326 app_memory_block_manager->Initialize(app_dynamic_page_manager, app_memory_block_heap.get());
327 sys_memory_block_manager->Initialize(sys_dynamic_page_manager, sys_memory_block_heap.get());
328
329 app_block_info_manager->Initialize(app_dynamic_page_manager, block_info_heap.get());
330 sys_block_info_manager->Initialize(sys_dynamic_page_manager, block_info_heap.get());
331
332 app_page_table_manager->Initialize(app_dynamic_page_manager, page_table_heap.get());
333 sys_page_table_manager->Initialize(sys_dynamic_page_manager, page_table_heap.get());
334
335 // Check that we have the correct number of dynamic pages available.
336 ASSERT(resource_manager_page_manager->GetCount() -
337 resource_manager_page_manager->GetUsed() ==
338 ReservedDynamicPageCount);
339
340 // Create the system page table managers.
341 app_system_resource = std::make_unique<KSystemResource>(kernel);
342 sys_system_resource = std::make_unique<KSystemResource>(kernel);
343
344 // Set the managers for the system resources.
345 app_system_resource->SetManagers(*app_memory_block_manager, *app_block_info_manager,
346 *app_page_table_manager);
347 sys_system_resource->SetManagers(*sys_memory_block_manager, *sys_block_info_manager,
348 *sys_page_table_manager);
276 } 349 }
277 350
278 void InitializeShutdownThreads() { 351 void InitializeShutdownThreads() {
@@ -767,6 +840,8 @@ struct KernelCore::Impl {
767 Init::KSlabResourceCounts slab_resource_counts{}; 840 Init::KSlabResourceCounts slab_resource_counts{};
768 KResourceLimit* system_resource_limit{}; 841 KResourceLimit* system_resource_limit{};
769 842
843 KPageBufferSlabHeap page_buffer_slab_heap;
844
770 std::shared_ptr<Core::Timing::EventType> preemption_event; 845 std::shared_ptr<Core::Timing::EventType> preemption_event;
771 846
772 // This is the kernel's handle table or supervisor handle table which 847 // This is the kernel's handle table or supervisor handle table which
@@ -792,10 +867,20 @@ struct KernelCore::Impl {
792 // Kernel memory management 867 // Kernel memory management
793 std::unique_ptr<KMemoryManager> memory_manager; 868 std::unique_ptr<KMemoryManager> memory_manager;
794 869
795 // Dynamic slab managers 870 // Resource managers
796 std::unique_ptr<KDynamicPageManager> dynamic_page_manager; 871 std::unique_ptr<KDynamicPageManager> resource_manager_page_manager;
797 std::unique_ptr<KMemoryBlockSlabHeap> memory_block_heap; 872 std::unique_ptr<KPageTableSlabHeap> page_table_heap;
873 std::unique_ptr<KMemoryBlockSlabHeap> app_memory_block_heap;
874 std::unique_ptr<KMemoryBlockSlabHeap> sys_memory_block_heap;
875 std::unique_ptr<KBlockInfoSlabHeap> block_info_heap;
876 std::unique_ptr<KPageTableManager> app_page_table_manager;
877 std::unique_ptr<KPageTableManager> sys_page_table_manager;
798 std::unique_ptr<KMemoryBlockSlabManager> app_memory_block_manager; 878 std::unique_ptr<KMemoryBlockSlabManager> app_memory_block_manager;
879 std::unique_ptr<KMemoryBlockSlabManager> sys_memory_block_manager;
880 std::unique_ptr<KBlockInfoManager> app_block_info_manager;
881 std::unique_ptr<KBlockInfoManager> sys_block_info_manager;
882 std::unique_ptr<KSystemResource> app_system_resource;
883 std::unique_ptr<KSystemResource> sys_system_resource;
799 884
800 // Shared memory for services 885 // Shared memory for services
801 Kernel::KSharedMemory* hid_shared_mem{}; 886 Kernel::KSharedMemory* hid_shared_mem{};
@@ -1073,12 +1158,12 @@ const KMemoryManager& KernelCore::MemoryManager() const {
1073 return *impl->memory_manager; 1158 return *impl->memory_manager;
1074} 1159}
1075 1160
1076KMemoryBlockSlabManager& KernelCore::GetApplicationMemoryBlockManager() { 1161KSystemResource& KernelCore::GetSystemSystemResource() {
1077 return *impl->app_memory_block_manager; 1162 return *impl->sys_system_resource;
1078} 1163}
1079 1164
1080const KMemoryBlockSlabManager& KernelCore::GetApplicationMemoryBlockManager() const { 1165const KSystemResource& KernelCore::GetSystemSystemResource() const {
1081 return *impl->app_memory_block_manager; 1166 return *impl->sys_system_resource;
1082} 1167}
1083 1168
1084Kernel::KSharedMemory& KernelCore::GetHidSharedMem() { 1169Kernel::KSharedMemory& KernelCore::GetHidSharedMem() {
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 266be2bc4..2549503fc 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -34,13 +34,16 @@ class KClientPort;
34class GlobalSchedulerContext; 34class GlobalSchedulerContext;
35class KAutoObjectWithListContainer; 35class KAutoObjectWithListContainer;
36class KClientSession; 36class KClientSession;
37class KDebug;
38class KDynamicPageManager;
37class KEvent; 39class KEvent;
40class KEventInfo;
38class KHandleTable; 41class KHandleTable;
39class KLinkedListNode; 42class KLinkedListNode;
40class KMemoryBlockSlabManager;
41class KMemoryLayout; 43class KMemoryLayout;
42class KMemoryManager; 44class KMemoryManager;
43class KPageBuffer; 45class KPageBuffer;
46class KPageBufferSlabHeap;
44class KPort; 47class KPort;
45class KProcess; 48class KProcess;
46class KResourceLimit; 49class KResourceLimit;
@@ -50,6 +53,7 @@ class KSession;
50class KSessionRequest; 53class KSessionRequest;
51class KSharedMemory; 54class KSharedMemory;
52class KSharedMemoryInfo; 55class KSharedMemoryInfo;
56class KSecureSystemResource;
53class KThread; 57class KThread;
54class KThreadLocalPage; 58class KThreadLocalPage;
55class KTransferMemory; 59class KTransferMemory;
@@ -243,11 +247,11 @@ public:
243 /// Gets the virtual memory manager for the kernel. 247 /// Gets the virtual memory manager for the kernel.
244 const KMemoryManager& MemoryManager() const; 248 const KMemoryManager& MemoryManager() const;
245 249
246 /// Gets the application memory block manager for the kernel. 250 /// Gets the system resource manager.
247 KMemoryBlockSlabManager& GetApplicationMemoryBlockManager(); 251 KSystemResource& GetSystemSystemResource();
248 252
249 /// Gets the application memory block manager for the kernel. 253 /// Gets the system resource manager.
250 const KMemoryBlockSlabManager& GetApplicationMemoryBlockManager() const; 254 const KSystemResource& GetSystemSystemResource() const;
251 255
252 /// Gets the shared memory object for HID services. 256 /// Gets the shared memory object for HID services.
253 Kernel::KSharedMemory& GetHidSharedMem(); 257 Kernel::KSharedMemory& GetHidSharedMem();
@@ -363,6 +367,12 @@ public:
363 return slab_heap_container->thread_local_page; 367 return slab_heap_container->thread_local_page;
364 } else if constexpr (std::is_same_v<T, KSessionRequest>) { 368 } else if constexpr (std::is_same_v<T, KSessionRequest>) {
365 return slab_heap_container->session_request; 369 return slab_heap_container->session_request;
370 } else if constexpr (std::is_same_v<T, KSecureSystemResource>) {
371 return slab_heap_container->secure_system_resource;
372 } else if constexpr (std::is_same_v<T, KEventInfo>) {
373 return slab_heap_container->event_info;
374 } else if constexpr (std::is_same_v<T, KDebug>) {
375 return slab_heap_container->debug;
366 } 376 }
367 } 377 }
368 378
@@ -426,6 +436,9 @@ private:
426 KSlabHeap<KPageBuffer> page_buffer; 436 KSlabHeap<KPageBuffer> page_buffer;
427 KSlabHeap<KThreadLocalPage> thread_local_page; 437 KSlabHeap<KThreadLocalPage> thread_local_page;
428 KSlabHeap<KSessionRequest> session_request; 438 KSlabHeap<KSessionRequest> session_request;
439 KSlabHeap<KSecureSystemResource> secure_system_resource;
440 KSlabHeap<KEventInfo> event_info;
441 KSlabHeap<KDebug> debug;
429 }; 442 };
430 443
431 std::unique_ptr<SlabHeapContainer> slab_heap_container; 444 std::unique_ptr<SlabHeapContainer> slab_heap_container;