summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel/kernel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
-rw-r--r--src/core/hle/kernel/kernel.cpp237
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 @@
#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