diff options
| -rw-r--r-- | src/core/hle/kernel/init/init_slab_setup.cpp | 74 | ||||
| -rw-r--r-- | src/core/hle/kernel/init/init_slab_setup.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_page_table.cpp | 12 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_page_table.h | 42 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_process.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 121 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 23 |
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 | ||
| 49 | namespace { | 55 | namespace { |
| 50 | 56 | ||
| @@ -73,8 +79,20 @@ constexpr size_t SlabCountKResourceLimit = 5; | |||
| 73 | constexpr size_t SlabCountKDebug = Core::Hardware::NUM_CPU_CORES; | 79 | constexpr size_t SlabCountKDebug = Core::Hardware::NUM_CPU_CORES; |
| 74 | constexpr size_t SlabCountKIoPool = 1; | 80 | constexpr size_t SlabCountKIoPool = 1; |
| 75 | constexpr size_t SlabCountKIoRegion = 6; | 81 | constexpr size_t SlabCountKIoRegion = 6; |
| 82 | constexpr size_t SlabcountKSessionRequestMappings = 40; | ||
| 76 | 83 | ||
| 77 | constexpr size_t SlabCountExtraKThread = 160; | 84 | constexpr size_t SlabCountExtraKThread = (1024 + 256 + 256) - SlabCountKThread; |
| 85 | |||
| 86 | namespace test { | ||
| 87 | |||
| 88 | static_assert(KernelPageBufferHeapSize == | ||
| 89 | 2 * PageSize + (SlabCountKProcess + SlabCountKThread + | ||
| 90 | (SlabCountKProcess + SlabCountKThread) / 8) * | ||
| 91 | PageSize); | ||
| 92 | static_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 | ||
| 111 | size_t CalculateSlabHeapGapSize() { | 129 | size_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 | ||
| 167 | void 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 | |||
| 190 | void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) { | 186 | void 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 | |||
| 258 | namespace Kernel { | ||
| 259 | |||
| 260 | void 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 | ||
| 38 | void InitializeSlabResourceCounts(KernelCore& kernel); | 39 | void InitializeSlabResourceCounts(KernelCore& kernel); |
| 39 | size_t CalculateTotalSlabHeapSize(const KernelCore& kernel); | 40 | size_t CalculateTotalSlabHeapSize(const KernelCore& kernel); |
| 40 | void InitializeKPageBufferSlabHeap(Core::System& system); | ||
| 41 | void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout); | 41 | void 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_) | |||
| 49 | KPageTable::~KPageTable() = default; | 50 | KPageTable::~KPageTable() = default; |
| 50 | 51 | ||
| 51 | Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr, | 52 | Result 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 | ||
| 24 | namespace Kernel { | 24 | namespace Kernel { |
| 25 | 25 | ||
| 26 | class KBlockInfoManager; | ||
| 26 | class KMemoryBlockManager; | 27 | class KMemoryBlockManager; |
| 28 | class KResourceLimit; | ||
| 29 | class KSystemResource; | ||
| 27 | 30 | ||
| 28 | class KPageTable final { | 31 | class KPageTable final { |
| 29 | public: | 32 | public: |
| @@ -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 | ||
| 100 | private: | 103 | private: |
| 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)); | |||
| 47 | namespace Kernel { | 49 | namespace Kernel { |
| 48 | 50 | ||
| 49 | struct KernelCore::Impl { | 51 | struct 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 | ||
| 1076 | KMemoryBlockSlabManager& KernelCore::GetApplicationMemoryBlockManager() { | 1161 | KSystemResource& KernelCore::GetSystemSystemResource() { |
| 1077 | return *impl->app_memory_block_manager; | 1162 | return *impl->sys_system_resource; |
| 1078 | } | 1163 | } |
| 1079 | 1164 | ||
| 1080 | const KMemoryBlockSlabManager& KernelCore::GetApplicationMemoryBlockManager() const { | 1165 | const KSystemResource& KernelCore::GetSystemSystemResource() const { |
| 1081 | return *impl->app_memory_block_manager; | 1166 | return *impl->sys_system_resource; |
| 1082 | } | 1167 | } |
| 1083 | 1168 | ||
| 1084 | Kernel::KSharedMemory& KernelCore::GetHidSharedMem() { | 1169 | Kernel::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; | |||
| 34 | class GlobalSchedulerContext; | 34 | class GlobalSchedulerContext; |
| 35 | class KAutoObjectWithListContainer; | 35 | class KAutoObjectWithListContainer; |
| 36 | class KClientSession; | 36 | class KClientSession; |
| 37 | class KDebug; | ||
| 38 | class KDynamicPageManager; | ||
| 37 | class KEvent; | 39 | class KEvent; |
| 40 | class KEventInfo; | ||
| 38 | class KHandleTable; | 41 | class KHandleTable; |
| 39 | class KLinkedListNode; | 42 | class KLinkedListNode; |
| 40 | class KMemoryBlockSlabManager; | ||
| 41 | class KMemoryLayout; | 43 | class KMemoryLayout; |
| 42 | class KMemoryManager; | 44 | class KMemoryManager; |
| 43 | class KPageBuffer; | 45 | class KPageBuffer; |
| 46 | class KPageBufferSlabHeap; | ||
| 44 | class KPort; | 47 | class KPort; |
| 45 | class KProcess; | 48 | class KProcess; |
| 46 | class KResourceLimit; | 49 | class KResourceLimit; |
| @@ -50,6 +53,7 @@ class KSession; | |||
| 50 | class KSessionRequest; | 53 | class KSessionRequest; |
| 51 | class KSharedMemory; | 54 | class KSharedMemory; |
| 52 | class KSharedMemoryInfo; | 55 | class KSharedMemoryInfo; |
| 56 | class KSecureSystemResource; | ||
| 53 | class KThread; | 57 | class KThread; |
| 54 | class KThreadLocalPage; | 58 | class KThreadLocalPage; |
| 55 | class KTransferMemory; | 59 | class 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; |