diff --git a/libmesosphere/include/mesosphere/arch/arm64/kern_k_interrupt_controller.hpp b/libmesosphere/include/mesosphere/arch/arm64/kern_k_interrupt_controller.hpp index 68f63332..4051d4c5 100644 --- a/libmesosphere/include/mesosphere/arch/arm64/kern_k_interrupt_controller.hpp +++ b/libmesosphere/include/mesosphere/arch/arm64/kern_k_interrupt_controller.hpp @@ -222,8 +222,6 @@ namespace ams::kern::arch::arm64 { const s32 num_interrupts = std::min(32 + 32 * (this->gicd->typer & 0x1F), static_cast(NumInterrupts)); return (0 <= irq && irq < num_interrupts); } - - /* TODO: Implement more KInterruptController functionality. */ public: static constexpr ALWAYS_INLINE bool IsSoftware(s32 id) { MESOSPHERE_ASSERT(0 <= id && id < NumInterrupts); diff --git a/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp b/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp index f49e0b12..c882adc6 100644 --- a/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp +++ b/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp @@ -266,7 +266,6 @@ namespace ams::kern::arch::arm64 { u32 GetAllocateOption() const { return this->page_table.GetAllocateOption(); } KPhysicalAddress GetHeapPhysicalAddress(KVirtualAddress address) const { - /* TODO: Better way to convert address type? */ return this->page_table.GetHeapPhysicalAddress(address); } diff --git a/libmesosphere/include/mesosphere/arch/arm64/kern_k_thread_context.hpp b/libmesosphere/include/mesosphere/arch/arm64/kern_k_thread_context.hpp index 5cd31514..47ef49aa 100644 --- a/libmesosphere/include/mesosphere/arch/arm64/kern_k_thread_context.hpp +++ b/libmesosphere/include/mesosphere/arch/arm64/kern_k_thread_context.hpp @@ -75,8 +75,8 @@ namespace ams::kern::arch::arm64 { void CloneFpuStatus(); const u128 *GetFpuRegisters() const { return this->fpu_registers; } - - /* TODO: More methods (especially FPU management) */ + public: + static void OnThreadTerminating(const KThread *thread); }; void GetUserContext(ams::svc::ThreadContext *out, const KThread *thread); diff --git a/libmesosphere/include/mesosphere/kern_k_capabilities.hpp b/libmesosphere/include/mesosphere/kern_k_capabilities.hpp index 6557fd5f..8d8492db 100644 --- a/libmesosphere/include/mesosphere/kern_k_capabilities.hpp +++ b/libmesosphere/include/mesosphere/kern_k_capabilities.hpp @@ -328,8 +328,6 @@ namespace ams::kern { constexpr bool CanForceDebug() const { return this->debug_capabilities.Get(); } - - /* TODO: Member functions. */ }; } diff --git a/libmesosphere/include/mesosphere/kern_k_client_port.hpp b/libmesosphere/include/mesosphere/kern_k_client_port.hpp index c647830b..5000f762 100644 --- a/libmesosphere/include/mesosphere/kern_k_client_port.hpp +++ b/libmesosphere/include/mesosphere/kern_k_client_port.hpp @@ -48,7 +48,6 @@ namespace ams::kern { virtual void Destroy() override; virtual bool IsSignaled() const override; - /* TODO: More of KClientPort. */ Result CreateSession(KClientSession **out); Result CreateLightSession(KLightClientSession **out); }; diff --git a/libmesosphere/include/mesosphere/kern_k_debug_base.hpp b/libmesosphere/include/mesosphere/kern_k_debug_base.hpp index 10c234e0..c4483b00 100644 --- a/libmesosphere/include/mesosphere/kern_k_debug_base.hpp +++ b/libmesosphere/include/mesosphere/kern_k_debug_base.hpp @@ -53,8 +53,6 @@ namespace ams::kern { Result GetDebugEventInfo(ams::svc::ilp32::DebugEventInfo *out); KScopedAutoObject GetProcess(); - - /* TODO: This is a placeholder definition. */ private: void PushDebugEvent(ams::svc::DebugEvent event, uintptr_t param0 = 0, uintptr_t param1 = 0, uintptr_t param2 = 0, uintptr_t param3 = 0, uintptr_t param4 = 0); void EnqueueDebugEventInfo(KEventInfo *info); diff --git a/libmesosphere/include/mesosphere/kern_k_interrupt_task_manager.hpp b/libmesosphere/include/mesosphere/kern_k_interrupt_task_manager.hpp index eaeec87d..d3c4d511 100644 --- a/libmesosphere/include/mesosphere/kern_k_interrupt_task_manager.hpp +++ b/libmesosphere/include/mesosphere/kern_k_interrupt_task_manager.hpp @@ -49,8 +49,6 @@ namespace ams::kern { NOINLINE void Initialize(); void EnqueueTask(KInterruptTask *task); - - /* TODO: Actually implement KInterruptTaskManager. This is a placeholder. */ }; } diff --git a/libmesosphere/include/mesosphere/kern_k_process.hpp b/libmesosphere/include/mesosphere/kern_k_process.hpp index 23abf02d..a7c15ca6 100644 --- a/libmesosphere/include/mesosphere/kern_k_process.hpp +++ b/libmesosphere/include/mesosphere/kern_k_process.hpp @@ -281,6 +281,11 @@ namespace ams::kern { return this->dynamic_page_manager.GetUsed() * PageSize; } + void SetRunningThread(s32 core, KThread *thread, u64 idle_count) { + this->running_threads[core] = thread; + this->running_thread_idle_counts[core] = idle_count; + } + void ClearRunningThread(KThread *thread) { for (size_t i = 0; i < util::size(this->running_threads); ++i) { if (this->running_threads[i] == thread) { diff --git a/libmesosphere/include/mesosphere/kern_k_server_port.hpp b/libmesosphere/include/mesosphere/kern_k_server_port.hpp index 339f7381..e5862aa5 100644 --- a/libmesosphere/include/mesosphere/kern_k_server_port.hpp +++ b/libmesosphere/include/mesosphere/kern_k_server_port.hpp @@ -51,11 +51,8 @@ namespace ams::kern { /* Overridden virtual functions. */ virtual void Destroy() override; virtual bool IsSignaled() const override; - - /* TODO: More of KServerPort. */ private: void CleanupSessions(); - /* TODO: This is a placeholder definition. */ }; } diff --git a/libmesosphere/include/mesosphere/kern_k_server_session.hpp b/libmesosphere/include/mesosphere/kern_k_server_session.hpp index dbda6889..136a5dc6 100644 --- a/libmesosphere/include/mesosphere/kern_k_server_session.hpp +++ b/libmesosphere/include/mesosphere/kern_k_server_session.hpp @@ -44,7 +44,6 @@ namespace ams::kern { virtual bool IsSignaled() const override; - /* TODO: More of KServerSession. */ Result OnRequest(KSessionRequest *request); Result ReceiveRequest(uintptr_t message, uintptr_t buffer_size, KPhysicalAddress message_paddr); diff --git a/libmesosphere/include/mesosphere/kern_k_thread.hpp b/libmesosphere/include/mesosphere/kern_k_thread.hpp index 1a2ec749..9cce690b 100644 --- a/libmesosphere/include/mesosphere/kern_k_thread.hpp +++ b/libmesosphere/include/mesosphere/kern_k_thread.hpp @@ -203,7 +203,6 @@ namespace ams::kern { constexpr KThread() : wait_result(svc::ResultNoSynchronizationObject()), debug_exception_result(ResultSuccess()) { /* ... */ } virtual ~KThread() { /* ... */ } - /* TODO: Is a constexpr KThread() possible? */ Result Initialize(KThreadFunction func, uintptr_t arg, void *kern_stack_top, KProcessAddress user_stack_top, s32 prio, s32 core, KProcess *owner, ThreadType type); @@ -497,8 +496,6 @@ namespace ams::kern { ALWAYS_INLINE void *GetStackTop() const { return reinterpret_cast(this->kernel_stack_top) - 1; } ALWAYS_INLINE void *GetKernelStackTop() const { return this->kernel_stack_top; } - /* TODO: This is kind of a placeholder definition. */ - ALWAYS_INLINE bool IsTerminationRequested() const { return this->termination_requested || this->GetRawState() == ThreadState_Terminated; } diff --git a/libmesosphere/include/mesosphere/kern_k_typed_address.hpp b/libmesosphere/include/mesosphere/kern_k_typed_address.hpp index d078ff48..bc291e0b 100644 --- a/libmesosphere/include/mesosphere/kern_k_typed_address.hpp +++ b/libmesosphere/include/mesosphere/kern_k_typed_address.hpp @@ -124,8 +124,6 @@ namespace ams::kern { return this->address != rhs; } - /* TODO: <, <=, >, >= against uintptr_t? would need to be declared outside of class. Maybe worth it. */ - /* Allow getting the address explicitly, for use in accessors. */ constexpr ALWAYS_INLINE uintptr_t GetValue() const { return this->address; @@ -244,6 +242,5 @@ namespace ams::kern { /* Accessors. */ static_assert(15 == GetInteger(KPhysicalAddress(15))); static_assert(0 == GetInteger(Null)); - /* TODO: reinterpret_cast<> not valid in a constant expression, can't test get pointers. */ } diff --git a/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp b/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp index cb648894..3164fba9 100644 --- a/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp +++ b/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp @@ -26,7 +26,7 @@ namespace ams::kern::arch::arm64 { /* Send KDebug event for this thread's creation. */ { KScopedInterruptEnable ei; - /* TODO */ + KDebug::OnDebugEvent(ams::svc::DebugEvent_CreateThread, GetCurrentThread().GetId(), GetInteger(GetCurrentThread().GetThreadLocalRegionAddress()), GetCurrentThread().GetEntrypoint()); } /* Handle any pending dpc. */ @@ -263,4 +263,8 @@ namespace ams::kern::arch::arm64 { out->fpsr = t_ctx->GetFpsr(); } + void KThreadContext::OnThreadTerminating(const KThread *thread) { + /* ... */ + } + } diff --git a/libmesosphere/source/init/kern_init_slab_setup.cpp b/libmesosphere/source/init/kern_init_slab_setup.cpp index 65451a9b..01a580c2 100644 --- a/libmesosphere/source/init/kern_init_slab_setup.cpp +++ b/libmesosphere/source/init/kern_init_slab_setup.cpp @@ -129,8 +129,7 @@ namespace ams::kern::init { /* NOTE: This can't be used right now because we don't have all these types implemented. */ /* Once we do, uncomment the following and stop using the hardcoded size. */ - /* TODO: FOREACH_SLAB_TYPE(ADD_SLAB_SIZE) */ - size = 0x647000; + FOREACH_SLAB_TYPE(ADD_SLAB_SIZE) return size; } diff --git a/libmesosphere/source/kern_k_client_port.cpp b/libmesosphere/source/kern_k_client_port.cpp index 44fd08e4..97c023ce 100644 --- a/libmesosphere/source/kern_k_client_port.cpp +++ b/libmesosphere/source/kern_k_client_port.cpp @@ -51,7 +51,6 @@ namespace ams::kern { } bool KClientPort::IsSignaled() const { - /* TODO: Check preconditions later. */ MESOSPHERE_ASSERT_THIS(); return this->num_sessions < this->max_sessions; } diff --git a/libmesosphere/source/kern_k_debug_base.cpp b/libmesosphere/source/kern_k_debug_base.cpp index 5b83b0b7..720ec4f6 100644 --- a/libmesosphere/source/kern_k_debug_base.cpp +++ b/libmesosphere/source/kern_k_debug_base.cpp @@ -305,7 +305,7 @@ namespace ams::kern { this->old_process_state = this->process->SetDebugObject(this); /* Send an event for our attaching to the process. */ - this->PushDebugEvent(ams::svc::DebugEvent_AttachProcess); + this->PushDebugEvent(ams::svc::DebugEvent_CreateProcess); /* Send events for attaching to each thread in the process. */ { @@ -320,7 +320,7 @@ namespace ams::kern { it->SetDebugAttached(); /* Send the event. */ - this->PushDebugEvent(ams::svc::DebugEvent_AttachThread, it->GetId(), GetInteger(it->GetThreadLocalRegionAddress()), it->GetEntrypoint()); + this->PushDebugEvent(ams::svc::DebugEvent_CreateThread, it->GetId(), GetInteger(it->GetThreadLocalRegionAddress()), it->GetEntrypoint()); } } } @@ -561,12 +561,12 @@ namespace ams::kern { /* Set event specific fields. */ switch (event) { - case ams::svc::DebugEvent_AttachProcess: + case ams::svc::DebugEvent_CreateProcess: { /* ... */ } break; - case ams::svc::DebugEvent_AttachThread: + case ams::svc::DebugEvent_CreateThread: { /* Set the thread id. */ info->thread_id = param0; @@ -584,7 +584,7 @@ namespace ams::kern { /* Clear the thread id and flags. */ info->thread_id = 0; - info->flags = 0 /* TODO: enum this in ams::svc */; + info->flags = 0; } break; case ams::svc::DebugEvent_ExitThread: @@ -720,21 +720,21 @@ namespace ams::kern { /* Set event specific fields. */ switch (info->event) { - case ams::svc::DebugEvent_AttachProcess: + case ams::svc::DebugEvent_CreateProcess: { - out->info.attach_process.program_id = process->GetProgramId(); - out->info.attach_process.process_id = process->GetId(); - out->info.attach_process.flags = process->GetCreateProcessFlags(); - out->info.attach_process.user_exception_context_address = GetInteger(process->GetProcessLocalRegionAddress()); + out->info.create_process.program_id = process->GetProgramId(); + out->info.create_process.process_id = process->GetId(); + out->info.create_process.flags = process->GetCreateProcessFlags(); + out->info.create_process.user_exception_context_address = GetInteger(process->GetProcessLocalRegionAddress()); - std::memcpy(out->info.attach_process.name, process->GetName(), sizeof(out->info.attach_process.name)); + std::memcpy(out->info.create_process.name, process->GetName(), sizeof(out->info.create_process.name)); } break; - case ams::svc::DebugEvent_AttachThread: + case ams::svc::DebugEvent_CreateThread: { - out->info.attach_thread.thread_id = info->info.create_thread.thread_id; - out->info.attach_thread.tls_address = info->info.create_thread.tls_address; - out->info.attach_thread.entrypoint = info->info.create_thread.entrypoint; + out->info.create_thread.thread_id = info->info.create_thread.thread_id; + out->info.create_thread.tls_address = info->info.create_thread.tls_address; + out->info.create_thread.entrypoint = info->info.create_thread.entrypoint; } break; case ams::svc::DebugEvent_ExitProcess: @@ -882,8 +882,8 @@ namespace ams::kern { /* Get the current process. */ KProcess *process = GetCurrentProcessPointer(); - /* If the event is AttachThread and we've already attached, there's nothing to do. */ - if (event == ams::svc::DebugEvent_AttachThread) { + /* If the event is CreateThread and we've already attached, there's nothing to do. */ + if (event == ams::svc::DebugEvent_CreateThread) { R_SUCCEED_IF(GetCurrentThread().IsAttachedToDebugger()); } diff --git a/libmesosphere/source/kern_k_memory_layout.cpp b/libmesosphere/source/kern_k_memory_layout.cpp index 588c7cb7..e768f6af 100644 --- a/libmesosphere/source/kern_k_memory_layout.cpp +++ b/libmesosphere/source/kern_k_memory_layout.cpp @@ -144,7 +144,7 @@ namespace ams::kern { constexpr size_t CoreLocalRegionSize = PageSize * (1 + cpu::NumCores); constexpr size_t CoreLocalRegionSizeWithGuards = CoreLocalRegionSize + 2 * PageSize; constexpr size_t CoreLocalRegionBoundsAlign = 1_GB; - /* TODO: static_assert(CoreLocalRegionSize == sizeof(KCoreLocalRegion)); */ + static_assert(CoreLocalRegionSize == sizeof(KCoreLocalRegion)); KVirtualAddress GetCoreLocalRegionVirtualAddress() { while (true) { diff --git a/libmesosphere/source/kern_k_page_table_base.cpp b/libmesosphere/source/kern_k_page_table_base.cpp index 58780fb1..c489c0cc 100644 --- a/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libmesosphere/source/kern_k_page_table_base.cpp @@ -999,8 +999,8 @@ namespace ams::kern { if (address == Null) { /* NOTE: Nintendo does not account for guard pages here. */ /* This may theoretically cause an offset to be chosen that cannot be mapped. */ - /* TODO: Should we account for guard pages? */ - const size_t offset_pages = KSystemControl::GenerateRandomRange(0, region_num_pages - num_pages); + /* We will account for guard pages. */ + const size_t offset_pages = KSystemControl::GenerateRandomRange(0, region_num_pages - num_pages - guard_pages); address = this->memory_block_manager.FindFreeArea(region_start + offset_pages * PageSize, region_num_pages - offset_pages, num_pages, alignment, offset, guard_pages); } } diff --git a/libmesosphere/source/kern_k_scheduler.cpp b/libmesosphere/source/kern_k_scheduler.cpp index 2e99b20f..ee186955 100644 --- a/libmesosphere/source/kern_k_scheduler.cpp +++ b/libmesosphere/source/kern_k_scheduler.cpp @@ -90,7 +90,9 @@ namespace ams::kern { } if (this->state.should_count_idle) { if (AMS_LIKELY(highest_thread != nullptr)) { - /* TODO: Set parent process's idle count if it exists. */ + if (KProcess *process = highest_thread->GetOwnerProcess(); process != nullptr) { + process->SetRunningThread(this->core_id, highest_thread, this->state.idle_count); + } } else { this->state.idle_count++; } diff --git a/libmesosphere/source/kern_k_server_port.cpp b/libmesosphere/source/kern_k_server_port.cpp index 9aff70a9..965f7972 100644 --- a/libmesosphere/source/kern_k_server_port.cpp +++ b/libmesosphere/source/kern_k_server_port.cpp @@ -84,7 +84,6 @@ namespace ams::kern { } bool KServerPort::IsSignaled() const { - /* TODO: Check preconditions later. */ MESOSPHERE_ASSERT_THIS(); if (this->IsLight()) { return !this->light_session_list.empty(); diff --git a/libmesosphere/source/kern_k_synchronization_object.cpp b/libmesosphere/source/kern_k_synchronization_object.cpp index adfd71de..ce94f95e 100644 --- a/libmesosphere/source/kern_k_synchronization_object.cpp +++ b/libmesosphere/source/kern_k_synchronization_object.cpp @@ -32,6 +32,19 @@ namespace ams::kern { void KSynchronizationObject::Finalize() { MESOSPHERE_ASSERT_THIS(); + /* If auditing, ensure that the object has no waiters. */ + #if defined(MESOSPHERE_BUILD_FOR_AUDITING) + { + KScopedSchedulerLock sl; + + auto end = this->end(); + for (auto it = this->begin(); it != end; ++it) { + KThread *thread = std::addressof(*it); + MESOSPHERE_LOG("KSynchronizationObject::Finalize(%p) with %p (id=%ld) waiting.\n", this, thread, thread->GetId()); + } + } + #endif + this->OnFinalizeSynchronizationObject(); KAutoObject::Finalize(); } @@ -39,7 +52,33 @@ namespace ams::kern { void KSynchronizationObject::DebugWaiters() { MESOSPHERE_ASSERT_THIS(); - MESOSPHERE_TODO("Do useful debug operation here."); + /* If debugging, dump the list of waiters. */ + #if defined(MESOSPHERE_BUILD_FOR_DEBUGGING) + { + KScopedSchedulerLock sl; + + MESOSPHERE_RELEASE_LOG("Threads waiting on %p:\n", this); + + bool has_waiters = false; + auto end = this->end(); + for (auto it = this->begin(); it != end; ++it) { + KThread *thread = std::addressof(*it); + + if (KProcess *process = thread->GetOwnerProcess(); process != nullptr) { + MESOSPHERE_RELEASE_LOG(" %p tid=%ld pid=%ld (%s)\n", thread, thread->GetId(), process->GetId(), process->GetName()); + } else { + MESOSPHERE_RELEASE_LOG(" %p tid=%ld (Kernel)\n", thread, thread->GetId()); + } + + has_waiters = true; + } + + /* If we didn't have any waiters, print so. */ + if (!has_waiters) { + MESOSPHERE_RELEASE_LOG(" None\n"); + } + } + #endif } KSynchronizationObject::iterator KSynchronizationObject::RegisterWaitingThread(KThread *thread) { diff --git a/libmesosphere/source/kern_k_thread.cpp b/libmesosphere/source/kern_k_thread.cpp index 2198779d..7d6be53b 100644 --- a/libmesosphere/source/kern_k_thread.cpp +++ b/libmesosphere/source/kern_k_thread.cpp @@ -344,7 +344,8 @@ namespace ams::kern { this->signaled = true; this->NotifyAvailable(); - /* TODO: On Thread Termination handler */ + /* Call the on thread termination handler. */ + KThreadContext::OnThreadTerminating(this); /* Clear previous thread in KScheduler. */ KScheduler::ClearPreviousThread(this); diff --git a/libvapours/include/vapours/svc/svc_types_common.hpp b/libvapours/include/vapours/svc/svc_types_common.hpp index 45e62daf..13e5d80a 100644 --- a/libvapours/include/vapours/svc/svc_types_common.hpp +++ b/libvapours/include/vapours/svc/svc_types_common.hpp @@ -396,8 +396,8 @@ namespace ams::svc { /* Debug types. */ enum DebugEvent : u32 { - DebugEvent_AttachProcess = 0, - DebugEvent_AttachThread = 1, + DebugEvent_CreateProcess = 0, + DebugEvent_CreateThread = 1, DebugEvent_ExitProcess = 2, DebugEvent_ExitThread = 3, DebugEvent_Exception = 4, diff --git a/libvapours/include/vapours/svc/svc_types_dmnt.hpp b/libvapours/include/vapours/svc/svc_types_dmnt.hpp index da614539..e65ab27c 100644 --- a/libvapours/include/vapours/svc/svc_types_dmnt.hpp +++ b/libvapours/include/vapours/svc/svc_types_dmnt.hpp @@ -20,7 +20,7 @@ namespace ams::svc { namespace lp64 { - struct DebugInfoAttachProcess { + struct DebugInfoCreateProcess { u64 program_id; u64 process_id; char name[0xC]; @@ -28,7 +28,7 @@ namespace ams::svc { u64 user_exception_context_address; /* 5.0.0+ */ }; - struct DebugInfoAttachThread { + struct DebugInfoCreateThread { u64 thread_id; u64 tls_address; u64 entrypoint; @@ -91,8 +91,8 @@ namespace ams::svc { }; union DebugInfo { - DebugInfoAttachProcess attach_process; - DebugInfoAttachThread attach_thread; + DebugInfoCreateProcess create_process; + DebugInfoCreateThread create_thread; DebugInfoExitProcess exit_process; DebugInfoExitThread exit_thread; DebugInfoException exception; @@ -110,7 +110,7 @@ namespace ams::svc { namespace ilp32 { - struct DebugInfoAttachProcess { + struct DebugInfoCreateProcess { u64 program_id; u64 process_id; char name[0xC]; @@ -118,7 +118,7 @@ namespace ams::svc { u32 user_exception_context_address; /* 5.0.0+ */ }; - struct DebugInfoAttachThread { + struct DebugInfoCreateThread { u64 thread_id; u32 tls_address; u32 entrypoint; @@ -181,8 +181,8 @@ namespace ams::svc { }; union DebugInfo { - DebugInfoAttachProcess attach_process; - DebugInfoAttachThread attach_thread; + DebugInfoCreateProcess create_process; + DebugInfoCreateThread create_thread; DebugInfoExitProcess exit_process; DebugInfoExitThread exit_thread; DebugInfoException exception;