kern: clean up majority of TODOs

This commit is contained in:
Michael Scire 2020-07-31 01:27:09 -07:00
parent d50efee2c7
commit bb044b1934
24 changed files with 88 additions and 60 deletions

View File

@ -222,8 +222,6 @@ namespace ams::kern::arch::arm64 {
const s32 num_interrupts = std::min(32 + 32 * (this->gicd->typer & 0x1F), static_cast<u32>(NumInterrupts)); const s32 num_interrupts = std::min(32 + 32 * (this->gicd->typer & 0x1F), static_cast<u32>(NumInterrupts));
return (0 <= irq && irq < num_interrupts); return (0 <= irq && irq < num_interrupts);
} }
/* TODO: Implement more KInterruptController functionality. */
public: public:
static constexpr ALWAYS_INLINE bool IsSoftware(s32 id) { static constexpr ALWAYS_INLINE bool IsSoftware(s32 id) {
MESOSPHERE_ASSERT(0 <= id && id < NumInterrupts); MESOSPHERE_ASSERT(0 <= id && id < NumInterrupts);

View File

@ -266,7 +266,6 @@ namespace ams::kern::arch::arm64 {
u32 GetAllocateOption() const { return this->page_table.GetAllocateOption(); } u32 GetAllocateOption() const { return this->page_table.GetAllocateOption(); }
KPhysicalAddress GetHeapPhysicalAddress(KVirtualAddress address) const { KPhysicalAddress GetHeapPhysicalAddress(KVirtualAddress address) const {
/* TODO: Better way to convert address type? */
return this->page_table.GetHeapPhysicalAddress(address); return this->page_table.GetHeapPhysicalAddress(address);
} }

View File

@ -75,8 +75,8 @@ namespace ams::kern::arch::arm64 {
void CloneFpuStatus(); void CloneFpuStatus();
const u128 *GetFpuRegisters() const { return this->fpu_registers; } const u128 *GetFpuRegisters() const { return this->fpu_registers; }
public:
/* TODO: More methods (especially FPU management) */ static void OnThreadTerminating(const KThread *thread);
}; };
void GetUserContext(ams::svc::ThreadContext *out, const KThread *thread); void GetUserContext(ams::svc::ThreadContext *out, const KThread *thread);

View File

@ -328,8 +328,6 @@ namespace ams::kern {
constexpr bool CanForceDebug() const { constexpr bool CanForceDebug() const {
return this->debug_capabilities.Get<DebugFlags::ForceDebug>(); return this->debug_capabilities.Get<DebugFlags::ForceDebug>();
} }
/* TODO: Member functions. */
}; };
} }

View File

@ -48,7 +48,6 @@ namespace ams::kern {
virtual void Destroy() override; virtual void Destroy() override;
virtual bool IsSignaled() const override; virtual bool IsSignaled() const override;
/* TODO: More of KClientPort. */
Result CreateSession(KClientSession **out); Result CreateSession(KClientSession **out);
Result CreateLightSession(KLightClientSession **out); Result CreateLightSession(KLightClientSession **out);
}; };

View File

@ -53,8 +53,6 @@ namespace ams::kern {
Result GetDebugEventInfo(ams::svc::ilp32::DebugEventInfo *out); Result GetDebugEventInfo(ams::svc::ilp32::DebugEventInfo *out);
KScopedAutoObject<KProcess> GetProcess(); KScopedAutoObject<KProcess> GetProcess();
/* TODO: This is a placeholder definition. */
private: 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 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); void EnqueueDebugEventInfo(KEventInfo *info);

View File

@ -49,8 +49,6 @@ namespace ams::kern {
NOINLINE void Initialize(); NOINLINE void Initialize();
void EnqueueTask(KInterruptTask *task); void EnqueueTask(KInterruptTask *task);
/* TODO: Actually implement KInterruptTaskManager. This is a placeholder. */
}; };
} }

View File

@ -281,6 +281,11 @@ namespace ams::kern {
return this->dynamic_page_manager.GetUsed() * PageSize; 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) { void ClearRunningThread(KThread *thread) {
for (size_t i = 0; i < util::size(this->running_threads); ++i) { for (size_t i = 0; i < util::size(this->running_threads); ++i) {
if (this->running_threads[i] == thread) { if (this->running_threads[i] == thread) {

View File

@ -51,11 +51,8 @@ namespace ams::kern {
/* Overridden virtual functions. */ /* Overridden virtual functions. */
virtual void Destroy() override; virtual void Destroy() override;
virtual bool IsSignaled() const override; virtual bool IsSignaled() const override;
/* TODO: More of KServerPort. */
private: private:
void CleanupSessions(); void CleanupSessions();
/* TODO: This is a placeholder definition. */
}; };
} }

View File

@ -44,7 +44,6 @@ namespace ams::kern {
virtual bool IsSignaled() const override; virtual bool IsSignaled() const override;
/* TODO: More of KServerSession. */
Result OnRequest(KSessionRequest *request); Result OnRequest(KSessionRequest *request);
Result ReceiveRequest(uintptr_t message, uintptr_t buffer_size, KPhysicalAddress message_paddr); Result ReceiveRequest(uintptr_t message, uintptr_t buffer_size, KPhysicalAddress message_paddr);

View File

@ -203,7 +203,6 @@ namespace ams::kern {
constexpr KThread() : wait_result(svc::ResultNoSynchronizationObject()), debug_exception_result(ResultSuccess()) { /* ... */ } constexpr KThread() : wait_result(svc::ResultNoSynchronizationObject()), debug_exception_result(ResultSuccess()) { /* ... */ }
virtual ~KThread() { /* ... */ } 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); 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<StackParameters *>(this->kernel_stack_top) - 1; } ALWAYS_INLINE void *GetStackTop() const { return reinterpret_cast<StackParameters *>(this->kernel_stack_top) - 1; }
ALWAYS_INLINE void *GetKernelStackTop() const { return this->kernel_stack_top; } ALWAYS_INLINE void *GetKernelStackTop() const { return this->kernel_stack_top; }
/* TODO: This is kind of a placeholder definition. */
ALWAYS_INLINE bool IsTerminationRequested() const { ALWAYS_INLINE bool IsTerminationRequested() const {
return this->termination_requested || this->GetRawState() == ThreadState_Terminated; return this->termination_requested || this->GetRawState() == ThreadState_Terminated;
} }

View File

@ -124,8 +124,6 @@ namespace ams::kern {
return this->address != rhs; 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. */ /* Allow getting the address explicitly, for use in accessors. */
constexpr ALWAYS_INLINE uintptr_t GetValue() const { constexpr ALWAYS_INLINE uintptr_t GetValue() const {
return this->address; return this->address;
@ -244,6 +242,5 @@ namespace ams::kern {
/* Accessors. */ /* Accessors. */
static_assert(15 == GetInteger(KPhysicalAddress(15))); static_assert(15 == GetInteger(KPhysicalAddress(15)));
static_assert(0 == GetInteger(Null<KPhysicalAddress>)); static_assert(0 == GetInteger(Null<KPhysicalAddress>));
/* TODO: reinterpret_cast<> not valid in a constant expression, can't test get pointers. */
} }

View File

@ -26,7 +26,7 @@ namespace ams::kern::arch::arm64 {
/* Send KDebug event for this thread's creation. */ /* Send KDebug event for this thread's creation. */
{ {
KScopedInterruptEnable ei; KScopedInterruptEnable ei;
/* TODO */ KDebug::OnDebugEvent(ams::svc::DebugEvent_CreateThread, GetCurrentThread().GetId(), GetInteger(GetCurrentThread().GetThreadLocalRegionAddress()), GetCurrentThread().GetEntrypoint());
} }
/* Handle any pending dpc. */ /* Handle any pending dpc. */
@ -263,4 +263,8 @@ namespace ams::kern::arch::arm64 {
out->fpsr = t_ctx->GetFpsr(); out->fpsr = t_ctx->GetFpsr();
} }
void KThreadContext::OnThreadTerminating(const KThread *thread) {
/* ... */
}
} }

View File

@ -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. */ /* 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. */ /* Once we do, uncomment the following and stop using the hardcoded size. */
/* TODO: FOREACH_SLAB_TYPE(ADD_SLAB_SIZE) */ FOREACH_SLAB_TYPE(ADD_SLAB_SIZE)
size = 0x647000;
return size; return size;
} }

View File

@ -51,7 +51,6 @@ namespace ams::kern {
} }
bool KClientPort::IsSignaled() const { bool KClientPort::IsSignaled() const {
/* TODO: Check preconditions later. */
MESOSPHERE_ASSERT_THIS(); MESOSPHERE_ASSERT_THIS();
return this->num_sessions < this->max_sessions; return this->num_sessions < this->max_sessions;
} }

View File

@ -305,7 +305,7 @@ namespace ams::kern {
this->old_process_state = this->process->SetDebugObject(this); this->old_process_state = this->process->SetDebugObject(this);
/* Send an event for our attaching to the process. */ /* 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. */ /* Send events for attaching to each thread in the process. */
{ {
@ -320,7 +320,7 @@ namespace ams::kern {
it->SetDebugAttached(); it->SetDebugAttached();
/* Send the event. */ /* 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. */ /* Set event specific fields. */
switch (event) { switch (event) {
case ams::svc::DebugEvent_AttachProcess: case ams::svc::DebugEvent_CreateProcess:
{ {
/* ... */ /* ... */
} }
break; break;
case ams::svc::DebugEvent_AttachThread: case ams::svc::DebugEvent_CreateThread:
{ {
/* Set the thread id. */ /* Set the thread id. */
info->thread_id = param0; info->thread_id = param0;
@ -584,7 +584,7 @@ namespace ams::kern {
/* Clear the thread id and flags. */ /* Clear the thread id and flags. */
info->thread_id = 0; info->thread_id = 0;
info->flags = 0 /* TODO: enum this in ams::svc */; info->flags = 0;
} }
break; break;
case ams::svc::DebugEvent_ExitThread: case ams::svc::DebugEvent_ExitThread:
@ -720,21 +720,21 @@ namespace ams::kern {
/* Set event specific fields. */ /* Set event specific fields. */
switch (info->event) { switch (info->event) {
case ams::svc::DebugEvent_AttachProcess: case ams::svc::DebugEvent_CreateProcess:
{ {
out->info.attach_process.program_id = process->GetProgramId(); out->info.create_process.program_id = process->GetProgramId();
out->info.attach_process.process_id = process->GetId(); out->info.create_process.process_id = process->GetId();
out->info.attach_process.flags = process->GetCreateProcessFlags(); out->info.create_process.flags = process->GetCreateProcessFlags();
out->info.attach_process.user_exception_context_address = GetInteger(process->GetProcessLocalRegionAddress()); 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; 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.create_thread.thread_id = info->info.create_thread.thread_id;
out->info.attach_thread.tls_address = info->info.create_thread.tls_address; out->info.create_thread.tls_address = info->info.create_thread.tls_address;
out->info.attach_thread.entrypoint = info->info.create_thread.entrypoint; out->info.create_thread.entrypoint = info->info.create_thread.entrypoint;
} }
break; break;
case ams::svc::DebugEvent_ExitProcess: case ams::svc::DebugEvent_ExitProcess:
@ -882,8 +882,8 @@ namespace ams::kern {
/* Get the current process. */ /* Get the current process. */
KProcess *process = GetCurrentProcessPointer(); KProcess *process = GetCurrentProcessPointer();
/* If the event is AttachThread and we've already attached, there's nothing to do. */ /* If the event is CreateThread and we've already attached, there's nothing to do. */
if (event == ams::svc::DebugEvent_AttachThread) { if (event == ams::svc::DebugEvent_CreateThread) {
R_SUCCEED_IF(GetCurrentThread().IsAttachedToDebugger()); R_SUCCEED_IF(GetCurrentThread().IsAttachedToDebugger());
} }

View File

@ -144,7 +144,7 @@ namespace ams::kern {
constexpr size_t CoreLocalRegionSize = PageSize * (1 + cpu::NumCores); constexpr size_t CoreLocalRegionSize = PageSize * (1 + cpu::NumCores);
constexpr size_t CoreLocalRegionSizeWithGuards = CoreLocalRegionSize + 2 * PageSize; constexpr size_t CoreLocalRegionSizeWithGuards = CoreLocalRegionSize + 2 * PageSize;
constexpr size_t CoreLocalRegionBoundsAlign = 1_GB; constexpr size_t CoreLocalRegionBoundsAlign = 1_GB;
/* TODO: static_assert(CoreLocalRegionSize == sizeof(KCoreLocalRegion)); */ static_assert(CoreLocalRegionSize == sizeof(KCoreLocalRegion));
KVirtualAddress GetCoreLocalRegionVirtualAddress() { KVirtualAddress GetCoreLocalRegionVirtualAddress() {
while (true) { while (true) {

View File

@ -999,8 +999,8 @@ namespace ams::kern {
if (address == Null<KProcessAddress>) { if (address == Null<KProcessAddress>) {
/* NOTE: Nintendo does not account for guard pages here. */ /* NOTE: Nintendo does not account for guard pages here. */
/* This may theoretically cause an offset to be chosen that cannot be mapped. */ /* This may theoretically cause an offset to be chosen that cannot be mapped. */
/* TODO: Should we account for guard pages? */ /* We will account for guard pages. */
const size_t offset_pages = KSystemControl::GenerateRandomRange(0, region_num_pages - num_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); address = this->memory_block_manager.FindFreeArea(region_start + offset_pages * PageSize, region_num_pages - offset_pages, num_pages, alignment, offset, guard_pages);
} }
} }

View File

@ -90,7 +90,9 @@ namespace ams::kern {
} }
if (this->state.should_count_idle) { if (this->state.should_count_idle) {
if (AMS_LIKELY(highest_thread != nullptr)) { 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 { } else {
this->state.idle_count++; this->state.idle_count++;
} }

View File

@ -84,7 +84,6 @@ namespace ams::kern {
} }
bool KServerPort::IsSignaled() const { bool KServerPort::IsSignaled() const {
/* TODO: Check preconditions later. */
MESOSPHERE_ASSERT_THIS(); MESOSPHERE_ASSERT_THIS();
if (this->IsLight()) { if (this->IsLight()) {
return !this->light_session_list.empty(); return !this->light_session_list.empty();

View File

@ -32,6 +32,19 @@ namespace ams::kern {
void KSynchronizationObject::Finalize() { void KSynchronizationObject::Finalize() {
MESOSPHERE_ASSERT_THIS(); 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(); this->OnFinalizeSynchronizationObject();
KAutoObject::Finalize(); KAutoObject::Finalize();
} }
@ -39,7 +52,33 @@ namespace ams::kern {
void KSynchronizationObject::DebugWaiters() { void KSynchronizationObject::DebugWaiters() {
MESOSPHERE_ASSERT_THIS(); 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) { KSynchronizationObject::iterator KSynchronizationObject::RegisterWaitingThread(KThread *thread) {

View File

@ -344,7 +344,8 @@ namespace ams::kern {
this->signaled = true; this->signaled = true;
this->NotifyAvailable(); this->NotifyAvailable();
/* TODO: On Thread Termination handler */ /* Call the on thread termination handler. */
KThreadContext::OnThreadTerminating(this);
/* Clear previous thread in KScheduler. */ /* Clear previous thread in KScheduler. */
KScheduler::ClearPreviousThread(this); KScheduler::ClearPreviousThread(this);

View File

@ -396,8 +396,8 @@ namespace ams::svc {
/* Debug types. */ /* Debug types. */
enum DebugEvent : u32 { enum DebugEvent : u32 {
DebugEvent_AttachProcess = 0, DebugEvent_CreateProcess = 0,
DebugEvent_AttachThread = 1, DebugEvent_CreateThread = 1,
DebugEvent_ExitProcess = 2, DebugEvent_ExitProcess = 2,
DebugEvent_ExitThread = 3, DebugEvent_ExitThread = 3,
DebugEvent_Exception = 4, DebugEvent_Exception = 4,

View File

@ -20,7 +20,7 @@ namespace ams::svc {
namespace lp64 { namespace lp64 {
struct DebugInfoAttachProcess { struct DebugInfoCreateProcess {
u64 program_id; u64 program_id;
u64 process_id; u64 process_id;
char name[0xC]; char name[0xC];
@ -28,7 +28,7 @@ namespace ams::svc {
u64 user_exception_context_address; /* 5.0.0+ */ u64 user_exception_context_address; /* 5.0.0+ */
}; };
struct DebugInfoAttachThread { struct DebugInfoCreateThread {
u64 thread_id; u64 thread_id;
u64 tls_address; u64 tls_address;
u64 entrypoint; u64 entrypoint;
@ -91,8 +91,8 @@ namespace ams::svc {
}; };
union DebugInfo { union DebugInfo {
DebugInfoAttachProcess attach_process; DebugInfoCreateProcess create_process;
DebugInfoAttachThread attach_thread; DebugInfoCreateThread create_thread;
DebugInfoExitProcess exit_process; DebugInfoExitProcess exit_process;
DebugInfoExitThread exit_thread; DebugInfoExitThread exit_thread;
DebugInfoException exception; DebugInfoException exception;
@ -110,7 +110,7 @@ namespace ams::svc {
namespace ilp32 { namespace ilp32 {
struct DebugInfoAttachProcess { struct DebugInfoCreateProcess {
u64 program_id; u64 program_id;
u64 process_id; u64 process_id;
char name[0xC]; char name[0xC];
@ -118,7 +118,7 @@ namespace ams::svc {
u32 user_exception_context_address; /* 5.0.0+ */ u32 user_exception_context_address; /* 5.0.0+ */
}; };
struct DebugInfoAttachThread { struct DebugInfoCreateThread {
u64 thread_id; u64 thread_id;
u32 tls_address; u32 tls_address;
u32 entrypoint; u32 entrypoint;
@ -181,8 +181,8 @@ namespace ams::svc {
}; };
union DebugInfo { union DebugInfo {
DebugInfoAttachProcess attach_process; DebugInfoCreateProcess create_process;
DebugInfoAttachThread attach_thread; DebugInfoCreateThread create_thread;
DebugInfoExitProcess exit_process; DebugInfoExitProcess exit_process;
DebugInfoExitThread exit_thread; DebugInfoExitThread exit_thread;
DebugInfoException exception; DebugInfoException exception;