diff options
| author | 2021-05-07 23:30:17 -0700 | |
|---|---|---|
| committer | 2021-05-07 23:30:17 -0700 | |
| commit | faa067f175cbf5e916ed75776817f0046e6731c4 (patch) | |
| tree | 8ab02a72a6e4d6578848c8da2c02af02684aeec7 /src/core/hle/kernel/kernel.cpp | |
| parent | Merge pull request #6287 from lioncash/ldr-copy (diff) | |
| parent | hle: kernel: KPageTable: CanContain should not be constexpr. (diff) | |
| download | yuzu-faa067f175cbf5e916ed75776817f0046e6731c4.tar.gz yuzu-faa067f175cbf5e916ed75776817f0046e6731c4.tar.xz yuzu-faa067f175cbf5e916ed75776817f0046e6731c4.zip | |
Merge pull request #6266 from bunnei/kautoobject-refactor
Kernel Rework: Migrate kernel objects to KAutoObject
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 237 |
1 files changed, 149 insertions, 88 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 5c4f45ab4..32bbf2d9b 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -26,10 +26,12 @@ | |||
| 26 | #include "core/cpu_manager.h" | 26 | #include "core/cpu_manager.h" |
| 27 | #include "core/device_memory.h" | 27 | #include "core/device_memory.h" |
| 28 | #include "core/hardware_properties.h" | 28 | #include "core/hardware_properties.h" |
| 29 | #include "core/hle/kernel/client_port.h" | 29 | #include "core/hle/kernel/init/init_slab_setup.h" |
| 30 | #include "core/hle/kernel/handle_table.h" | 30 | #include "core/hle/kernel/k_client_port.h" |
| 31 | #include "core/hle/kernel/k_handle_table.h" | ||
| 31 | #include "core/hle/kernel/k_memory_layout.h" | 32 | #include "core/hle/kernel/k_memory_layout.h" |
| 32 | #include "core/hle/kernel/k_memory_manager.h" | 33 | #include "core/hle/kernel/k_memory_manager.h" |
| 34 | #include "core/hle/kernel/k_process.h" | ||
| 33 | #include "core/hle/kernel/k_resource_limit.h" | 35 | #include "core/hle/kernel/k_resource_limit.h" |
| 34 | #include "core/hle/kernel/k_scheduler.h" | 36 | #include "core/hle/kernel/k_scheduler.h" |
| 35 | #include "core/hle/kernel/k_shared_memory.h" | 37 | #include "core/hle/kernel/k_shared_memory.h" |
| @@ -37,7 +39,6 @@ | |||
| 37 | #include "core/hle/kernel/k_thread.h" | 39 | #include "core/hle/kernel/k_thread.h" |
| 38 | #include "core/hle/kernel/kernel.h" | 40 | #include "core/hle/kernel/kernel.h" |
| 39 | #include "core/hle/kernel/physical_core.h" | 41 | #include "core/hle/kernel/physical_core.h" |
| 40 | #include "core/hle/kernel/process.h" | ||
| 41 | #include "core/hle/kernel/service_thread.h" | 42 | #include "core/hle/kernel/service_thread.h" |
| 42 | #include "core/hle/kernel/svc_results.h" | 43 | #include "core/hle/kernel/svc_results.h" |
| 43 | #include "core/hle/kernel/time_manager.h" | 44 | #include "core/hle/kernel/time_manager.h" |
| @@ -51,7 +52,7 @@ namespace Kernel { | |||
| 51 | 52 | ||
| 52 | struct KernelCore::Impl { | 53 | struct KernelCore::Impl { |
| 53 | explicit Impl(Core::System& system, KernelCore& kernel) | 54 | explicit Impl(Core::System& system, KernelCore& kernel) |
| 54 | : time_manager{system}, global_handle_table{kernel}, system{system} {} | 55 | : time_manager{system}, object_list_container{kernel}, system{system} {} |
| 55 | 56 | ||
| 56 | void SetMulticore(bool is_multicore) { | 57 | void SetMulticore(bool is_multicore) { |
| 57 | this->is_multicore = is_multicore; | 58 | this->is_multicore = is_multicore; |
| @@ -59,8 +60,7 @@ struct KernelCore::Impl { | |||
| 59 | 60 | ||
| 60 | void Initialize(KernelCore& kernel) { | 61 | void Initialize(KernelCore& kernel) { |
| 61 | global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel); | 62 | global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel); |
| 62 | 63 | global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel); | |
| 63 | RegisterHostThread(); | ||
| 64 | 64 | ||
| 65 | service_thread_manager = | 65 | service_thread_manager = |
| 66 | std::make_unique<Common::ThreadWorker>(1, "yuzu:ServiceThreadManager"); | 66 | std::make_unique<Common::ThreadWorker>(1, "yuzu:ServiceThreadManager"); |
| @@ -69,14 +69,20 @@ struct KernelCore::Impl { | |||
| 69 | InitializePhysicalCores(); | 69 | InitializePhysicalCores(); |
| 70 | 70 | ||
| 71 | // Derive the initial memory layout from the emulated board | 71 | // Derive the initial memory layout from the emulated board |
| 72 | Init::InitializeSlabResourceCounts(kernel); | ||
| 72 | KMemoryLayout memory_layout; | 73 | KMemoryLayout memory_layout; |
| 73 | DeriveInitialMemoryLayout(memory_layout); | 74 | DeriveInitialMemoryLayout(memory_layout); |
| 74 | InitializeMemoryLayout(memory_layout); | 75 | Init::InitializeSlabHeaps(system, memory_layout); |
| 76 | |||
| 77 | // Initialize kernel memory and resources. | ||
| 75 | InitializeSystemResourceLimit(kernel, system.CoreTiming(), memory_layout); | 78 | InitializeSystemResourceLimit(kernel, system.CoreTiming(), memory_layout); |
| 76 | InitializeSlabHeaps(); | 79 | InitializeMemoryLayout(memory_layout); |
| 80 | InitializePageSlab(); | ||
| 77 | InitializeSchedulers(); | 81 | InitializeSchedulers(); |
| 78 | InitializeSuspendThreads(); | 82 | InitializeSuspendThreads(); |
| 79 | InitializePreemption(kernel); | 83 | InitializePreemption(kernel); |
| 84 | |||
| 85 | RegisterHostThread(); | ||
| 80 | } | 86 | } |
| 81 | 87 | ||
| 82 | void InitializeCores() { | 88 | void InitializeCores() { |
| @@ -93,34 +99,49 @@ struct KernelCore::Impl { | |||
| 93 | service_threads.clear(); | 99 | service_threads.clear(); |
| 94 | 100 | ||
| 95 | next_object_id = 0; | 101 | next_object_id = 0; |
| 96 | next_kernel_process_id = Process::InitialKIPIDMin; | 102 | next_kernel_process_id = KProcess::InitialKIPIDMin; |
| 97 | next_user_process_id = Process::ProcessIDMin; | 103 | next_user_process_id = KProcess::ProcessIDMin; |
| 98 | next_thread_id = 1; | 104 | next_thread_id = 1; |
| 99 | 105 | ||
| 100 | for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { | 106 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { |
| 101 | if (suspend_threads[i]) { | 107 | if (suspend_threads[core_id]) { |
| 102 | suspend_threads[i].reset(); | 108 | suspend_threads[core_id]->Close(); |
| 109 | suspend_threads[core_id] = nullptr; | ||
| 103 | } | 110 | } |
| 111 | |||
| 112 | schedulers[core_id].reset(); | ||
| 104 | } | 113 | } |
| 105 | 114 | ||
| 106 | cores.clear(); | 115 | cores.clear(); |
| 107 | 116 | ||
| 108 | current_process = nullptr; | 117 | if (current_process) { |
| 118 | current_process->Close(); | ||
| 119 | current_process = nullptr; | ||
| 120 | } | ||
| 109 | 121 | ||
| 110 | global_handle_table.Clear(); | 122 | global_handle_table.reset(); |
| 111 | 123 | ||
| 112 | preemption_event = nullptr; | 124 | preemption_event = nullptr; |
| 113 | 125 | ||
| 126 | for (auto& iter : named_ports) { | ||
| 127 | iter.second->Close(); | ||
| 128 | } | ||
| 114 | named_ports.clear(); | 129 | named_ports.clear(); |
| 115 | 130 | ||
| 116 | exclusive_monitor.reset(); | 131 | exclusive_monitor.reset(); |
| 117 | 132 | ||
| 118 | hid_shared_mem = nullptr; | 133 | // Cleanup persistent kernel objects |
| 119 | font_shared_mem = nullptr; | 134 | auto CleanupObject = [](KAutoObject* obj) { |
| 120 | irs_shared_mem = nullptr; | 135 | if (obj) { |
| 121 | time_shared_mem = nullptr; | 136 | obj->Close(); |
| 122 | 137 | obj = nullptr; | |
| 123 | system_resource_limit = nullptr; | 138 | } |
| 139 | }; | ||
| 140 | CleanupObject(hid_shared_mem); | ||
| 141 | CleanupObject(font_shared_mem); | ||
| 142 | CleanupObject(irs_shared_mem); | ||
| 143 | CleanupObject(time_shared_mem); | ||
| 144 | CleanupObject(system_resource_limit); | ||
| 124 | 145 | ||
| 125 | // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others | 146 | // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others |
| 126 | next_host_thread_id = Core::Hardware::NUM_CPU_CORES; | 147 | next_host_thread_id = Core::Hardware::NUM_CPU_CORES; |
| @@ -145,7 +166,9 @@ struct KernelCore::Impl { | |||
| 145 | void InitializeSystemResourceLimit(KernelCore& kernel, | 166 | void InitializeSystemResourceLimit(KernelCore& kernel, |
| 146 | const Core::Timing::CoreTiming& core_timing, | 167 | const Core::Timing::CoreTiming& core_timing, |
| 147 | const KMemoryLayout& memory_layout) { | 168 | const KMemoryLayout& memory_layout) { |
| 148 | system_resource_limit = std::make_shared<KResourceLimit>(kernel, core_timing); | 169 | system_resource_limit = KResourceLimit::Create(system.Kernel()); |
| 170 | system_resource_limit->Initialize(&core_timing); | ||
| 171 | |||
| 149 | const auto [total_size, kernel_size] = memory_layout.GetTotalAndKernelMemorySizes(); | 172 | const auto [total_size, kernel_size] = memory_layout.GetTotalAndKernelMemorySizes(); |
| 150 | 173 | ||
| 151 | // If setting the default system values fails, then something seriously wrong has occurred. | 174 | // If setting the default system values fails, then something seriously wrong has occurred. |
| @@ -189,19 +212,16 @@ struct KernelCore::Impl { | |||
| 189 | } | 212 | } |
| 190 | 213 | ||
| 191 | void InitializeSuspendThreads() { | 214 | void InitializeSuspendThreads() { |
| 192 | for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { | 215 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { |
| 193 | std::string name = "Suspend Thread Id:" + std::to_string(i); | 216 | suspend_threads[core_id] = KThread::Create(system.Kernel()); |
| 194 | std::function<void(void*)> init_func = Core::CpuManager::GetSuspendThreadStartFunc(); | 217 | ASSERT(KThread::InitializeHighPriorityThread(system, suspend_threads[core_id], {}, {}, |
| 195 | void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); | 218 | core_id) |
| 196 | auto thread_res = KThread::CreateThread( | 219 | .IsSuccess()); |
| 197 | system, ThreadType::HighPriority, std::move(name), 0, 0, 0, static_cast<u32>(i), 0, | 220 | suspend_threads[core_id]->SetName(fmt::format("SuspendThread:{}", core_id)); |
| 198 | nullptr, std::move(init_func), init_func_parameter); | ||
| 199 | |||
| 200 | suspend_threads[i] = std::move(thread_res).Unwrap(); | ||
| 201 | } | 221 | } |
| 202 | } | 222 | } |
| 203 | 223 | ||
| 204 | void MakeCurrentProcess(Process* process) { | 224 | void MakeCurrentProcess(KProcess* process) { |
| 205 | current_process = process; | 225 | current_process = process; |
| 206 | if (process == nullptr) { | 226 | if (process == nullptr) { |
| 207 | return; | 227 | return; |
| @@ -232,11 +252,15 @@ struct KernelCore::Impl { | |||
| 232 | 252 | ||
| 233 | // Gets the dummy KThread for the caller, allocating a new one if this is the first time | 253 | // Gets the dummy KThread for the caller, allocating a new one if this is the first time |
| 234 | KThread* GetHostDummyThread() { | 254 | KThread* GetHostDummyThread() { |
| 235 | const thread_local auto thread = | 255 | auto make_thread = [this]() { |
| 236 | KThread::CreateThread( | 256 | std::unique_ptr<KThread> thread = std::make_unique<KThread>(system.Kernel()); |
| 237 | system, ThreadType::Main, fmt::format("DummyThread:{}", GetHostThreadId()), 0, | 257 | KAutoObject::Create(thread.get()); |
| 238 | KThread::DefaultThreadPriority, 0, static_cast<u32>(3), 0, nullptr) | 258 | ASSERT(KThread::InitializeDummyThread(thread.get()).IsSuccess()); |
| 239 | .Unwrap(); | 259 | thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId())); |
| 260 | return std::move(thread); | ||
| 261 | }; | ||
| 262 | |||
| 263 | thread_local auto thread = make_thread(); | ||
| 240 | return thread.get(); | 264 | return thread.get(); |
| 241 | } | 265 | } |
| 242 | 266 | ||
| @@ -371,7 +395,8 @@ struct KernelCore::Impl { | |||
| 371 | const size_t resource_region_size = memory_layout.GetResourceRegionSizeForInit(); | 395 | const size_t resource_region_size = memory_layout.GetResourceRegionSizeForInit(); |
| 372 | 396 | ||
| 373 | // Determine the size of the slab region. | 397 | // Determine the size of the slab region. |
| 374 | const size_t slab_region_size = Common::AlignUp(KernelSlabHeapSize, PageSize); | 398 | const size_t slab_region_size = |
| 399 | Common::AlignUp(Init::CalculateTotalSlabHeapSize(system.Kernel()), PageSize); | ||
| 375 | ASSERT(slab_region_size <= resource_region_size); | 400 | ASSERT(slab_region_size <= resource_region_size); |
| 376 | 401 | ||
| 377 | // Setup the slab region. | 402 | // Setup the slab region. |
| @@ -569,25 +594,30 @@ struct KernelCore::Impl { | |||
| 569 | const PAddr irs_phys_addr{system_pool.GetAddress() + hid_size + font_size}; | 594 | const PAddr irs_phys_addr{system_pool.GetAddress() + hid_size + font_size}; |
| 570 | const PAddr time_phys_addr{system_pool.GetAddress() + hid_size + font_size + irs_size}; | 595 | const PAddr time_phys_addr{system_pool.GetAddress() + hid_size + font_size + irs_size}; |
| 571 | 596 | ||
| 572 | hid_shared_mem = Kernel::KSharedMemory::Create( | 597 | hid_shared_mem = KSharedMemory::Create(system.Kernel()); |
| 573 | system.Kernel(), system.DeviceMemory(), nullptr, {hid_phys_addr, hid_size / PageSize}, | 598 | font_shared_mem = KSharedMemory::Create(system.Kernel()); |
| 574 | KMemoryPermission::None, KMemoryPermission::Read, hid_phys_addr, hid_size, | 599 | irs_shared_mem = KSharedMemory::Create(system.Kernel()); |
| 575 | "HID:SharedMemory"); | 600 | time_shared_mem = KSharedMemory::Create(system.Kernel()); |
| 576 | font_shared_mem = Kernel::KSharedMemory::Create( | 601 | |
| 577 | system.Kernel(), system.DeviceMemory(), nullptr, {font_phys_addr, font_size / PageSize}, | 602 | hid_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, |
| 578 | KMemoryPermission::None, KMemoryPermission::Read, font_phys_addr, font_size, | 603 | {hid_phys_addr, hid_size / PageSize}, |
| 579 | "Font:SharedMemory"); | 604 | Svc::MemoryPermission::None, Svc::MemoryPermission::Read, |
| 580 | irs_shared_mem = Kernel::KSharedMemory::Create( | 605 | hid_phys_addr, hid_size, "HID:SharedMemory"); |
| 581 | system.Kernel(), system.DeviceMemory(), nullptr, {irs_phys_addr, irs_size / PageSize}, | 606 | font_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, |
| 582 | KMemoryPermission::None, KMemoryPermission::Read, irs_phys_addr, irs_size, | 607 | {font_phys_addr, font_size / PageSize}, |
| 583 | "IRS:SharedMemory"); | 608 | Svc::MemoryPermission::None, Svc::MemoryPermission::Read, |
| 584 | time_shared_mem = Kernel::KSharedMemory::Create( | 609 | font_phys_addr, font_size, "Font:SharedMemory"); |
| 585 | system.Kernel(), system.DeviceMemory(), nullptr, {time_phys_addr, time_size / PageSize}, | 610 | irs_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, |
| 586 | KMemoryPermission::None, KMemoryPermission::Read, time_phys_addr, time_size, | 611 | {irs_phys_addr, irs_size / PageSize}, |
| 587 | "Time:SharedMemory"); | 612 | Svc::MemoryPermission::None, Svc::MemoryPermission::Read, |
| 613 | irs_phys_addr, irs_size, "IRS:SharedMemory"); | ||
| 614 | time_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, | ||
| 615 | {time_phys_addr, time_size / PageSize}, | ||
| 616 | Svc::MemoryPermission::None, Svc::MemoryPermission::Read, | ||
| 617 | time_phys_addr, time_size, "Time:SharedMemory"); | ||
| 588 | } | 618 | } |
| 589 | 619 | ||
| 590 | void InitializeSlabHeaps() { | 620 | void InitializePageSlab() { |
| 591 | // Allocate slab heaps | 621 | // Allocate slab heaps |
| 592 | user_slab_heap_pages = std::make_unique<KSlabHeap<Page>>(); | 622 | user_slab_heap_pages = std::make_unique<KSlabHeap<Page>>(); |
| 593 | 623 | ||
| @@ -596,30 +626,33 @@ struct KernelCore::Impl { | |||
| 596 | // Reserve slab heaps | 626 | // Reserve slab heaps |
| 597 | ASSERT( | 627 | ASSERT( |
| 598 | system_resource_limit->Reserve(LimitableResource::PhysicalMemory, user_slab_heap_size)); | 628 | system_resource_limit->Reserve(LimitableResource::PhysicalMemory, user_slab_heap_size)); |
| 599 | // Initialize slab heaps | 629 | // Initialize slab heap |
| 600 | user_slab_heap_pages->Initialize( | 630 | user_slab_heap_pages->Initialize( |
| 601 | system.DeviceMemory().GetPointer(Core::DramMemoryMap::SlabHeapBase), | 631 | system.DeviceMemory().GetPointer(Core::DramMemoryMap::SlabHeapBase), |
| 602 | user_slab_heap_size); | 632 | user_slab_heap_size); |
| 603 | } | 633 | } |
| 604 | 634 | ||
| 605 | std::atomic<u32> next_object_id{0}; | 635 | std::atomic<u32> next_object_id{0}; |
| 606 | std::atomic<u64> next_kernel_process_id{Process::InitialKIPIDMin}; | 636 | std::atomic<u64> next_kernel_process_id{KProcess::InitialKIPIDMin}; |
| 607 | std::atomic<u64> next_user_process_id{Process::ProcessIDMin}; | 637 | std::atomic<u64> next_user_process_id{KProcess::ProcessIDMin}; |
| 608 | std::atomic<u64> next_thread_id{1}; | 638 | std::atomic<u64> next_thread_id{1}; |
| 609 | 639 | ||
| 610 | // Lists all processes that exist in the current session. | 640 | // Lists all processes that exist in the current session. |
| 611 | std::vector<std::shared_ptr<Process>> process_list; | 641 | std::vector<KProcess*> process_list; |
| 612 | Process* current_process = nullptr; | 642 | KProcess* current_process{}; |
| 613 | std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context; | 643 | std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context; |
| 614 | Kernel::TimeManager time_manager; | 644 | Kernel::TimeManager time_manager; |
| 615 | 645 | ||
| 616 | std::shared_ptr<KResourceLimit> system_resource_limit; | 646 | Init::KSlabResourceCounts slab_resource_counts{}; |
| 647 | KResourceLimit* system_resource_limit{}; | ||
| 617 | 648 | ||
| 618 | std::shared_ptr<Core::Timing::EventType> preemption_event; | 649 | std::shared_ptr<Core::Timing::EventType> preemption_event; |
| 619 | 650 | ||
| 620 | // This is the kernel's handle table or supervisor handle table which | 651 | // This is the kernel's handle table or supervisor handle table which |
| 621 | // stores all the objects in place. | 652 | // stores all the objects in place. |
| 622 | HandleTable global_handle_table; | 653 | std::unique_ptr<KHandleTable> global_handle_table; |
| 654 | |||
| 655 | KAutoObjectWithListContainer object_list_container; | ||
| 623 | 656 | ||
| 624 | /// Map of named ports managed by the kernel, which can be retrieved using | 657 | /// Map of named ports managed by the kernel, which can be retrieved using |
| 625 | /// the ConnectToPort SVC. | 658 | /// the ConnectToPort SVC. |
| @@ -636,10 +669,10 @@ struct KernelCore::Impl { | |||
| 636 | std::unique_ptr<KSlabHeap<Page>> user_slab_heap_pages; | 669 | std::unique_ptr<KSlabHeap<Page>> user_slab_heap_pages; |
| 637 | 670 | ||
| 638 | // Shared memory for services | 671 | // Shared memory for services |
| 639 | std::shared_ptr<Kernel::KSharedMemory> hid_shared_mem; | 672 | Kernel::KSharedMemory* hid_shared_mem{}; |
| 640 | std::shared_ptr<Kernel::KSharedMemory> font_shared_mem; | 673 | Kernel::KSharedMemory* font_shared_mem{}; |
| 641 | std::shared_ptr<Kernel::KSharedMemory> irs_shared_mem; | 674 | Kernel::KSharedMemory* irs_shared_mem{}; |
| 642 | std::shared_ptr<Kernel::KSharedMemory> time_shared_mem; | 675 | Kernel::KSharedMemory* time_shared_mem{}; |
| 643 | 676 | ||
| 644 | // Threads used for services | 677 | // Threads used for services |
| 645 | std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads; | 678 | std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads; |
| @@ -648,7 +681,7 @@ struct KernelCore::Impl { | |||
| 648 | // the release of itself | 681 | // the release of itself |
| 649 | std::unique_ptr<Common::ThreadWorker> service_thread_manager; | 682 | std::unique_ptr<Common::ThreadWorker> service_thread_manager; |
| 650 | 683 | ||
| 651 | std::array<std::shared_ptr<KThread>, Core::Hardware::NUM_CPU_CORES> suspend_threads{}; | 684 | std::array<KThread*, Core::Hardware::NUM_CPU_CORES> suspend_threads; |
| 652 | std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; | 685 | std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; |
| 653 | std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; | 686 | std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; |
| 654 | 687 | ||
| @@ -663,15 +696,14 @@ struct KernelCore::Impl { | |||
| 663 | }; | 696 | }; |
| 664 | 697 | ||
| 665 | KernelCore::KernelCore(Core::System& system) : impl{std::make_unique<Impl>(system, *this)} {} | 698 | KernelCore::KernelCore(Core::System& system) : impl{std::make_unique<Impl>(system, *this)} {} |
| 666 | KernelCore::~KernelCore() { | 699 | KernelCore::~KernelCore() = default; |
| 667 | Shutdown(); | ||
| 668 | } | ||
| 669 | 700 | ||
| 670 | void KernelCore::SetMulticore(bool is_multicore) { | 701 | void KernelCore::SetMulticore(bool is_multicore) { |
| 671 | impl->SetMulticore(is_multicore); | 702 | impl->SetMulticore(is_multicore); |
| 672 | } | 703 | } |
| 673 | 704 | ||
| 674 | void KernelCore::Initialize() { | 705 | void KernelCore::Initialize() { |
| 706 | slab_heap_container = std::make_unique<SlabHeapContainer>(); | ||
| 675 | impl->Initialize(*this); | 707 | impl->Initialize(*this); |
| 676 | } | 708 | } |
| 677 | 709 | ||
| @@ -683,31 +715,35 @@ void KernelCore::Shutdown() { | |||
| 683 | impl->Shutdown(); | 715 | impl->Shutdown(); |
| 684 | } | 716 | } |
| 685 | 717 | ||
| 686 | std::shared_ptr<KResourceLimit> KernelCore::GetSystemResourceLimit() const { | 718 | const KResourceLimit* KernelCore::GetSystemResourceLimit() const { |
| 687 | return impl->system_resource_limit; | 719 | return impl->system_resource_limit; |
| 688 | } | 720 | } |
| 689 | 721 | ||
| 690 | std::shared_ptr<KThread> KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const { | 722 | KResourceLimit* KernelCore::GetSystemResourceLimit() { |
| 691 | return impl->global_handle_table.Get<KThread>(handle); | 723 | return impl->system_resource_limit; |
| 724 | } | ||
| 725 | |||
| 726 | KScopedAutoObject<KThread> KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const { | ||
| 727 | return impl->global_handle_table->GetObject<KThread>(handle); | ||
| 692 | } | 728 | } |
| 693 | 729 | ||
| 694 | void KernelCore::AppendNewProcess(std::shared_ptr<Process> process) { | 730 | void KernelCore::AppendNewProcess(KProcess* process) { |
| 695 | impl->process_list.push_back(std::move(process)); | 731 | impl->process_list.push_back(process); |
| 696 | } | 732 | } |
| 697 | 733 | ||
| 698 | void KernelCore::MakeCurrentProcess(Process* process) { | 734 | void KernelCore::MakeCurrentProcess(KProcess* process) { |
| 699 | impl->MakeCurrentProcess(process); | 735 | impl->MakeCurrentProcess(process); |
| 700 | } | 736 | } |
| 701 | 737 | ||
| 702 | Process* KernelCore::CurrentProcess() { | 738 | KProcess* KernelCore::CurrentProcess() { |
| 703 | return impl->current_process; | 739 | return impl->current_process; |
| 704 | } | 740 | } |
| 705 | 741 | ||
| 706 | const Process* KernelCore::CurrentProcess() const { | 742 | const KProcess* KernelCore::CurrentProcess() const { |
| 707 | return impl->current_process; | 743 | return impl->current_process; |
| 708 | } | 744 | } |
| 709 | 745 | ||
| 710 | const std::vector<std::shared_ptr<Process>>& KernelCore::GetProcessList() const { | 746 | const std::vector<KProcess*>& KernelCore::GetProcessList() const { |
| 711 | return impl->process_list; | 747 | return impl->process_list; |
| 712 | } | 748 | } |
| 713 | 749 | ||
| @@ -781,6 +817,14 @@ const Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() const { | |||
| 781 | return *impl->exclusive_monitor; | 817 | return *impl->exclusive_monitor; |
| 782 | } | 818 | } |
| 783 | 819 | ||
| 820 | KAutoObjectWithListContainer& KernelCore::ObjectListContainer() { | ||
| 821 | return impl->object_list_container; | ||
| 822 | } | ||
| 823 | |||
| 824 | const KAutoObjectWithListContainer& KernelCore::ObjectListContainer() const { | ||
| 825 | return impl->object_list_container; | ||
| 826 | } | ||
| 827 | |||
| 784 | void KernelCore::InvalidateAllInstructionCaches() { | 828 | void KernelCore::InvalidateAllInstructionCaches() { |
| 785 | for (auto& physical_core : impl->cores) { | 829 | for (auto& physical_core : impl->cores) { |
| 786 | physical_core.ArmInterface().ClearInstructionCache(); | 830 | physical_core.ArmInterface().ClearInstructionCache(); |
| @@ -800,8 +844,9 @@ void KernelCore::PrepareReschedule(std::size_t id) { | |||
| 800 | // TODO: Reimplement, this | 844 | // TODO: Reimplement, this |
| 801 | } | 845 | } |
| 802 | 846 | ||
| 803 | void KernelCore::AddNamedPort(std::string name, std::shared_ptr<ClientPort> port) { | 847 | void KernelCore::AddNamedPort(std::string name, KClientPort* port) { |
| 804 | impl->named_ports.emplace(std::move(name), std::move(port)); | 848 | port->Open(); |
| 849 | impl->named_ports.emplace(std::move(name), port); | ||
| 805 | } | 850 | } |
| 806 | 851 | ||
| 807 | KernelCore::NamedPortTable::iterator KernelCore::FindNamedPort(const std::string& name) { | 852 | KernelCore::NamedPortTable::iterator KernelCore::FindNamedPort(const std::string& name) { |
| @@ -833,12 +878,12 @@ u64 KernelCore::CreateNewUserProcessID() { | |||
| 833 | return impl->next_user_process_id++; | 878 | return impl->next_user_process_id++; |
| 834 | } | 879 | } |
| 835 | 880 | ||
| 836 | Kernel::HandleTable& KernelCore::GlobalHandleTable() { | 881 | KHandleTable& KernelCore::GlobalHandleTable() { |
| 837 | return impl->global_handle_table; | 882 | return *impl->global_handle_table; |
| 838 | } | 883 | } |
| 839 | 884 | ||
| 840 | const Kernel::HandleTable& KernelCore::GlobalHandleTable() const { | 885 | const KHandleTable& KernelCore::GlobalHandleTable() const { |
| 841 | return impl->global_handle_table; | 886 | return *impl->global_handle_table; |
| 842 | } | 887 | } |
| 843 | 888 | ||
| 844 | void KernelCore::RegisterCoreThread(std::size_t core_id) { | 889 | void KernelCore::RegisterCoreThread(std::size_t core_id) { |
| @@ -910,9 +955,9 @@ void KernelCore::Suspend(bool in_suspention) { | |||
| 910 | { | 955 | { |
| 911 | KScopedSchedulerLock lock(*this); | 956 | KScopedSchedulerLock lock(*this); |
| 912 | const auto state = should_suspend ? ThreadState::Runnable : ThreadState::Waiting; | 957 | const auto state = should_suspend ? ThreadState::Runnable : ThreadState::Waiting; |
| 913 | for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { | 958 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { |
| 914 | impl->suspend_threads[i]->SetState(state); | 959 | impl->suspend_threads[core_id]->SetState(state); |
| 915 | impl->suspend_threads[i]->SetWaitReasonForDebugging( | 960 | impl->suspend_threads[core_id]->SetWaitReasonForDebugging( |
| 916 | ThreadWaitReasonForDebugging::Suspended); | 961 | ThreadWaitReasonForDebugging::Suspended); |
| 917 | } | 962 | } |
| 918 | } | 963 | } |
| @@ -952,6 +997,14 @@ void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> servi | |||
| 952 | }); | 997 | }); |
| 953 | } | 998 | } |
| 954 | 999 | ||
| 1000 | Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() { | ||
| 1001 | return impl->slab_resource_counts; | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | const Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() const { | ||
| 1005 | return impl->slab_resource_counts; | ||
| 1006 | } | ||
| 1007 | |||
| 955 | bool KernelCore::IsPhantomModeForSingleCore() const { | 1008 | bool KernelCore::IsPhantomModeForSingleCore() const { |
| 956 | return impl->IsPhantomModeForSingleCore(); | 1009 | return impl->IsPhantomModeForSingleCore(); |
| 957 | } | 1010 | } |
| @@ -960,4 +1013,12 @@ void KernelCore::SetIsPhantomModeForSingleCore(bool value) { | |||
| 960 | impl->SetIsPhantomModeForSingleCore(value); | 1013 | impl->SetIsPhantomModeForSingleCore(value); |
| 961 | } | 1014 | } |
| 962 | 1015 | ||
| 1016 | Core::System& KernelCore::System() { | ||
| 1017 | return impl->system; | ||
| 1018 | } | ||
| 1019 | |||
| 1020 | const Core::System& KernelCore::System() const { | ||
| 1021 | return impl->system; | ||
| 1022 | } | ||
| 1023 | |||
| 963 | } // namespace Kernel | 1024 | } // namespace Kernel |