diff options
author | bunnei <bunneidev@gmail.com> | 2021-05-07 23:30:17 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-07 23:30:17 -0700 |
commit | faa067f175cbf5e916ed75776817f0046e6731c4 (patch) | |
tree | 8ab02a72a6e4d6578848c8da2c02af02684aeec7 /src/core/hle/kernel/kernel.cpp | |
parent | 8acf739b3fac78d25dc60e1a7d1252c05afadd57 (diff) | |
parent | d57b12193b12f7b6e3565d29f7bc3d7584632768 (diff) |
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 5c4f45ab4a..32bbf2d9be 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -26,10 +26,12 @@ #include "core/cpu_manager.h" #include "core/device_memory.h" #include "core/hardware_properties.h" -#include "core/hle/kernel/client_port.h" -#include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/init/init_slab_setup.h" +#include "core/hle/kernel/k_client_port.h" +#include "core/hle/kernel/k_handle_table.h" #include "core/hle/kernel/k_memory_layout.h" #include "core/hle/kernel/k_memory_manager.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_shared_memory.h" @@ -37,7 +39,6 @@ #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/physical_core.h" -#include "core/hle/kernel/process.h" #include "core/hle/kernel/service_thread.h" #include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/time_manager.h" @@ -51,7 +52,7 @@ namespace Kernel { struct KernelCore::Impl { explicit Impl(Core::System& system, KernelCore& kernel) - : time_manager{system}, global_handle_table{kernel}, system{system} {} + : time_manager{system}, object_list_container{kernel}, system{system} {} void SetMulticore(bool is_multicore) { this->is_multicore = is_multicore; @@ -59,8 +60,7 @@ struct KernelCore::Impl { void Initialize(KernelCore& kernel) { global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel); - - RegisterHostThread(); + global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel); service_thread_manager = std::make_unique<Common::ThreadWorker>(1, "yuzu:ServiceThreadManager"); @@ -69,14 +69,20 @@ struct KernelCore::Impl { InitializePhysicalCores(); // Derive the initial memory layout from the emulated board + Init::InitializeSlabResourceCounts(kernel); KMemoryLayout memory_layout; DeriveInitialMemoryLayout(memory_layout); - InitializeMemoryLayout(memory_layout); + Init::InitializeSlabHeaps(system, memory_layout); + + // Initialize kernel memory and resources. InitializeSystemResourceLimit(kernel, system.CoreTiming(), memory_layout); - InitializeSlabHeaps(); + InitializeMemoryLayout(memory_layout); + InitializePageSlab(); InitializeSchedulers(); InitializeSuspendThreads(); InitializePreemption(kernel); + + RegisterHostThread(); } void InitializeCores() { @@ -93,34 +99,49 @@ struct KernelCore::Impl { service_threads.clear(); next_object_id = 0; - next_kernel_process_id = Process::InitialKIPIDMin; - next_user_process_id = Process::ProcessIDMin; + next_kernel_process_id = KProcess::InitialKIPIDMin; + next_user_process_id = KProcess::ProcessIDMin; next_thread_id = 1; - for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { - if (suspend_threads[i]) { - suspend_threads[i].reset(); + for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { + if (suspend_threads[core_id]) { + suspend_threads[core_id]->Close(); + suspend_threads[core_id] = nullptr; } + + schedulers[core_id].reset(); } cores.clear(); - current_process = nullptr; + if (current_process) { + current_process->Close(); + current_process = nullptr; + } - global_handle_table.Clear(); + global_handle_table.reset(); preemption_event = nullptr; + for (auto& iter : named_ports) { + iter.second->Close(); + } named_ports.clear(); exclusive_monitor.reset(); - hid_shared_mem = nullptr; - font_shared_mem = nullptr; - irs_shared_mem = nullptr; - time_shared_mem = nullptr; - - system_resource_limit = nullptr; + // Cleanup persistent kernel objects + auto CleanupObject = [](KAutoObject* obj) { + if (obj) { + obj->Close(); + obj = nullptr; + } + }; + CleanupObject(hid_shared_mem); + CleanupObject(font_shared_mem); + CleanupObject(irs_shared_mem); + CleanupObject(time_shared_mem); + CleanupObject(system_resource_limit); // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others next_host_thread_id = Core::Hardware::NUM_CPU_CORES; @@ -145,7 +166,9 @@ struct KernelCore::Impl { void InitializeSystemResourceLimit(KernelCore& kernel, const Core::Timing::CoreTiming& core_timing, const KMemoryLayout& memory_layout) { - system_resource_limit = std::make_shared<KResourceLimit>(kernel, core_timing); + system_resource_limit = KResourceLimit::Create(system.Kernel()); + system_resource_limit->Initialize(&core_timing); + const auto [total_size, kernel_size] = memory_layout.GetTotalAndKernelMemorySizes(); // If setting the default system values fails, then something seriously wrong has occurred. @@ -189,19 +212,16 @@ struct KernelCore::Impl { } void InitializeSuspendThreads() { - for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { - std::string name = "Suspend Thread Id:" + std::to_string(i); - std::function<void(void*)> init_func = Core::CpuManager::GetSuspendThreadStartFunc(); - void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); - auto thread_res = KThread::CreateThread( - system, ThreadType::HighPriority, std::move(name), 0, 0, 0, static_cast<u32>(i), 0, - nullptr, std::move(init_func), init_func_parameter); - - suspend_threads[i] = std::move(thread_res).Unwrap(); + for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { + suspend_threads[core_id] = KThread::Create(system.Kernel()); + ASSERT(KThread::InitializeHighPriorityThread(system, suspend_threads[core_id], {}, {}, + core_id) + .IsSuccess()); + suspend_threads[core_id]->SetName(fmt::format("SuspendThread:{}", core_id)); } } - void MakeCurrentProcess(Process* process) { + void MakeCurrentProcess(KProcess* process) { current_process = process; if (process == nullptr) { return; @@ -232,11 +252,15 @@ struct KernelCore::Impl { // Gets the dummy KThread for the caller, allocating a new one if this is the first time KThread* GetHostDummyThread() { - const thread_local auto thread = - KThread::CreateThread( - system, ThreadType::Main, fmt::format("DummyThread:{}", GetHostThreadId()), 0, - KThread::DefaultThreadPriority, 0, static_cast<u32>(3), 0, nullptr) - .Unwrap(); + auto make_thread = [this]() { + std::unique_ptr<KThread> thread = std::make_unique<KThread>(system.Kernel()); + KAutoObject::Create(thread.get()); + ASSERT(KThread::InitializeDummyThread(thread.get()).IsSuccess()); + thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId())); + return std::move(thread); + }; + + thread_local auto thread = make_thread(); return thread.get(); } @@ -371,7 +395,8 @@ struct KernelCore::Impl { const size_t resource_region_size = memory_layout.GetResourceRegionSizeForInit(); // Determine the size of the slab region. - const size_t slab_region_size = Common::AlignUp(KernelSlabHeapSize, PageSize); + const size_t slab_region_size = + Common::AlignUp(Init::CalculateTotalSlabHeapSize(system.Kernel()), PageSize); ASSERT(slab_region_size <= resource_region_size); // Setup the slab region. @@ -569,25 +594,30 @@ struct KernelCore::Impl { const PAddr irs_phys_addr{system_pool.GetAddress() + hid_size + font_size}; const PAddr time_phys_addr{system_pool.GetAddress() + hid_size + font_size + irs_size}; - hid_shared_mem = Kernel::KSharedMemory::Create( - system.Kernel(), system.DeviceMemory(), nullptr, {hid_phys_addr, hid_size / PageSize}, - KMemoryPermission::None, KMemoryPermission::Read, hid_phys_addr, hid_size, - "HID:SharedMemory"); - font_shared_mem = Kernel::KSharedMemory::Create( - system.Kernel(), system.DeviceMemory(), nullptr, {font_phys_addr, font_size / PageSize}, - KMemoryPermission::None, KMemoryPermission::Read, font_phys_addr, font_size, - "Font:SharedMemory"); - irs_shared_mem = Kernel::KSharedMemory::Create( - system.Kernel(), system.DeviceMemory(), nullptr, {irs_phys_addr, irs_size / PageSize}, - KMemoryPermission::None, KMemoryPermission::Read, irs_phys_addr, irs_size, - "IRS:SharedMemory"); - time_shared_mem = Kernel::KSharedMemory::Create( - system.Kernel(), system.DeviceMemory(), nullptr, {time_phys_addr, time_size / PageSize}, - KMemoryPermission::None, KMemoryPermission::Read, time_phys_addr, time_size, - "Time:SharedMemory"); + hid_shared_mem = KSharedMemory::Create(system.Kernel()); + font_shared_mem = KSharedMemory::Create(system.Kernel()); + irs_shared_mem = KSharedMemory::Create(system.Kernel()); + time_shared_mem = KSharedMemory::Create(system.Kernel()); + + hid_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, + {hid_phys_addr, hid_size / PageSize}, + Svc::MemoryPermission::None, Svc::MemoryPermission::Read, + hid_phys_addr, hid_size, "HID:SharedMemory"); + font_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, + {font_phys_addr, font_size / PageSize}, + Svc::MemoryPermission::None, Svc::MemoryPermission::Read, + font_phys_addr, font_size, "Font:SharedMemory"); + irs_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, + {irs_phys_addr, irs_size / PageSize}, + Svc::MemoryPermission::None, Svc::MemoryPermission::Read, + irs_phys_addr, irs_size, "IRS:SharedMemory"); + time_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, + {time_phys_addr, time_size / PageSize}, + Svc::MemoryPermission::None, Svc::MemoryPermission::Read, + time_phys_addr, time_size, "Time:SharedMemory"); } - void InitializeSlabHeaps() { + void InitializePageSlab() { // Allocate slab heaps user_slab_heap_pages = std::make_unique<KSlabHeap<Page>>(); @@ -596,30 +626,33 @@ struct KernelCore::Impl { // Reserve slab heaps ASSERT( system_resource_limit->Reserve(LimitableResource::PhysicalMemory, user_slab_heap_size)); - // Initialize slab heaps + // Initialize slab heap user_slab_heap_pages->Initialize( system.DeviceMemory().GetPointer(Core::DramMemoryMap::SlabHeapBase), user_slab_heap_size); } std::atomic<u32> next_object_id{0}; - std::atomic<u64> next_kernel_process_id{Process::InitialKIPIDMin}; - std::atomic<u64> next_user_process_id{Process::ProcessIDMin}; + std::atomic<u64> next_kernel_process_id{KProcess::InitialKIPIDMin}; + std::atomic<u64> next_user_process_id{KProcess::ProcessIDMin}; std::atomic<u64> next_thread_id{1}; // Lists all processes that exist in the current session. - std::vector<std::shared_ptr<Process>> process_list; - Process* current_process = nullptr; + std::vector<KProcess*> process_list; + KProcess* current_process{}; std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context; Kernel::TimeManager time_manager; - std::shared_ptr<KResourceLimit> system_resource_limit; + Init::KSlabResourceCounts slab_resource_counts{}; + KResourceLimit* system_resource_limit{}; std::shared_ptr<Core::Timing::EventType> preemption_event; // This is the kernel's handle table or supervisor handle table which // stores all the objects in place. - HandleTable global_handle_table; + std::unique_ptr<KHandleTable> global_handle_table; + + KAutoObjectWithListContainer object_list_container; /// Map of named ports managed by the kernel, which can be retrieved using /// the ConnectToPort SVC. @@ -636,10 +669,10 @@ struct KernelCore::Impl { std::unique_ptr<KSlabHeap<Page>> user_slab_heap_pages; // Shared memory for services - std::shared_ptr<Kernel::KSharedMemory> hid_shared_mem; - std::shared_ptr<Kernel::KSharedMemory> font_shared_mem; - std::shared_ptr<Kernel::KSharedMemory> irs_shared_mem; - std::shared_ptr<Kernel::KSharedMemory> time_shared_mem; + Kernel::KSharedMemory* hid_shared_mem{}; + Kernel::KSharedMemory* font_shared_mem{}; + Kernel::KSharedMemory* irs_shared_mem{}; + Kernel::KSharedMemory* time_shared_mem{}; // Threads used for services std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads; @@ -648,7 +681,7 @@ struct KernelCore::Impl { // the release of itself std::unique_ptr<Common::ThreadWorker> service_thread_manager; - std::array<std::shared_ptr<KThread>, Core::Hardware::NUM_CPU_CORES> suspend_threads{}; + std::array<KThread*, Core::Hardware::NUM_CPU_CORES> suspend_threads; std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; @@ -663,15 +696,14 @@ struct KernelCore::Impl { }; KernelCore::KernelCore(Core::System& system) : impl{std::make_unique<Impl>(system, *this)} {} -KernelCore::~KernelCore() { - Shutdown(); -} +KernelCore::~KernelCore() = default; void KernelCore::SetMulticore(bool is_multicore) { impl->SetMulticore(is_multicore); } void KernelCore::Initialize() { + slab_heap_container = std::make_unique<SlabHeapContainer>(); impl->Initialize(*this); } @@ -683,31 +715,35 @@ void KernelCore::Shutdown() { impl->Shutdown(); } -std::shared_ptr<KResourceLimit> KernelCore::GetSystemResourceLimit() const { +const KResourceLimit* KernelCore::GetSystemResourceLimit() const { return impl->system_resource_limit; } -std::shared_ptr<KThread> KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const { - return impl->global_handle_table.Get<KThread>(handle); +KResourceLimit* KernelCore::GetSystemResourceLimit() { + return impl->system_resource_limit; +} + +KScopedAutoObject<KThread> KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const { + return impl->global_handle_table->GetObject<KThread>(handle); } -void KernelCore::AppendNewProcess(std::shared_ptr<Process> process) { - impl->process_list.push_back(std::move(process)); +void KernelCore::AppendNewProcess(KProcess* process) { + impl->process_list.push_back(process); } -void KernelCore::MakeCurrentProcess(Process* process) { +void KernelCore::MakeCurrentProcess(KProcess* process) { impl->MakeCurrentProcess(process); } -Process* KernelCore::CurrentProcess() { +KProcess* KernelCore::CurrentProcess() { return impl->current_process; } -const Process* KernelCore::CurrentProcess() const { +const KProcess* KernelCore::CurrentProcess() const { return impl->current_process; } -const std::vector<std::shared_ptr<Process>>& KernelCore::GetProcessList() const { +const std::vector<KProcess*>& KernelCore::GetProcessList() const { return impl->process_list; } @@ -781,6 +817,14 @@ const Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() const { return *impl->exclusive_monitor; } +KAutoObjectWithListContainer& KernelCore::ObjectListContainer() { + return impl->object_list_container; +} + +const KAutoObjectWithListContainer& KernelCore::ObjectListContainer() const { + return impl->object_list_container; +} + void KernelCore::InvalidateAllInstructionCaches() { for (auto& physical_core : impl->cores) { physical_core.ArmInterface().ClearInstructionCache(); @@ -800,8 +844,9 @@ void KernelCore::PrepareReschedule(std::size_t id) { // TODO: Reimplement, this } -void KernelCore::AddNamedPort(std::string name, std::shared_ptr<ClientPort> port) { - impl->named_ports.emplace(std::move(name), std::move(port)); +void KernelCore::AddNamedPort(std::string name, KClientPort* port) { + port->Open(); + impl->named_ports.emplace(std::move(name), port); } KernelCore::NamedPortTable::iterator KernelCore::FindNamedPort(const std::string& name) { @@ -833,12 +878,12 @@ u64 KernelCore::CreateNewUserProcessID() { return impl->next_user_process_id++; } -Kernel::HandleTable& KernelCore::GlobalHandleTable() { - return impl->global_handle_table; +KHandleTable& KernelCore::GlobalHandleTable() { + return *impl->global_handle_table; } -const Kernel::HandleTable& KernelCore::GlobalHandleTable() const { - return impl->global_handle_table; +const KHandleTable& KernelCore::GlobalHandleTable() const { + return *impl->global_handle_table; } void KernelCore::RegisterCoreThread(std::size_t core_id) { @@ -910,9 +955,9 @@ void KernelCore::Suspend(bool in_suspention) { { KScopedSchedulerLock lock(*this); const auto state = should_suspend ? ThreadState::Runnable : ThreadState::Waiting; - for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { - impl->suspend_threads[i]->SetState(state); - impl->suspend_threads[i]->SetWaitReasonForDebugging( + for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { + impl->suspend_threads[core_id]->SetState(state); + impl->suspend_threads[core_id]->SetWaitReasonForDebugging( ThreadWaitReasonForDebugging::Suspended); } } @@ -952,6 +997,14 @@ void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> servi }); } +Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() { + return impl->slab_resource_counts; +} + +const Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() const { + return impl->slab_resource_counts; +} + bool KernelCore::IsPhantomModeForSingleCore() const { return impl->IsPhantomModeForSingleCore(); } @@ -960,4 +1013,12 @@ void KernelCore::SetIsPhantomModeForSingleCore(bool value) { impl->SetIsPhantomModeForSingleCore(value); } +Core::System& KernelCore::System() { + return impl->system; +} + +const Core::System& KernelCore::System() const { + return impl->system; +} + } // namespace Kernel |