diff options
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 121 |
1 files changed, 103 insertions, 18 deletions
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() { |