From fba8fb539d20653ea800a414b0d114bfe27216eb Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 18 Feb 2020 05:04:49 -0800 Subject: [PATCH] kern: add KProcess members --- .../arch/arm64/kern_k_process_page_table.hpp | 5 +- .../mesosphere/kern_k_address_arbiter.hpp | 61 ++++++++ .../mesosphere/kern_k_capabilities.hpp | 45 ++++++ .../mesosphere/kern_k_condition_variable.hpp | 69 +++++++++ .../include/mesosphere/kern_k_process.hpp | 125 +++++++++++++++- .../include/mesosphere/kern_k_thread.hpp | 134 +++++++++--------- .../include/mesosphere/kern_k_wait_object.hpp | 37 +++++ .../source/kern_initial_process.cpp | 3 +- .../libmesosphere/source/kern_k_process.cpp | 8 ++ .../libmesosphere/source/kern_k_thread.cpp | 6 +- .../source/kern_k_wait_object.cpp | 24 ++++ .../include/stratosphere/ncm/ncm_types.hpp | 4 +- .../include/vapours/svc/svc_types_common.hpp | 13 +- .../arch/arm64/kern_k_thread_context_asm.s | 16 +-- mesosphere/kernel/source/libc/kern_env.cpp | 6 +- 15 files changed, 460 insertions(+), 96 deletions(-) create mode 100644 libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp create mode 100644 libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp create mode 100644 libraries/libmesosphere/include/mesosphere/kern_k_condition_variable.hpp create mode 100644 libraries/libmesosphere/include/mesosphere/kern_k_wait_object.hpp create mode 100644 libraries/libmesosphere/source/kern_k_wait_object.cpp diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp index 54a2164a6..5d71ff8ea 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp @@ -20,7 +20,10 @@ namespace ams::kern::arch::arm64 { class KProcessPageTable { - + private: + KPageTable page_table; + public: + constexpr KProcessPageTable() : page_table() { /* ... */ } }; } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp new file mode 100644 index 000000000..14f23b4e4 --- /dev/null +++ b/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include + +namespace ams::kern { + + class KAddressArbiter { + public: + using ThreadTree = KConditionVariable::ThreadTree; + private: + ThreadTree tree; + public: + constexpr KAddressArbiter() : tree() { /* ... */ } + + Result SignalToAddress(uintptr_t addr, ams::svc::SignalType type, s32 value, s32 count) { + switch (type) { + case ams::svc::SignalType_Signal: + return this->Signal(addr, count); + case ams::svc::SignalType_SignalAndIncrementIfEqual: + return this->SignalAndIncrementIfEqual(addr, value, count); + case ams::svc::SignalType_SignalAndModifyByWaitingCountIfEqual: + return this->SignalAndModifyByWaitingCountIfEqual(addr, value, count); + MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); + } + } + + Result WaitForAddress(uintptr_t addr, ams::svc::ArbitrationType type, s32 value, s64 timeout) { + switch (type) { + case ams::svc::ArbitrationType_WaitIfLessThan: + return this->WaitIfLessThan(addr, value, false, timeout); + case ams::svc::ArbitrationType_DecrementAndWaitIfLessThan: + return this->WaitIfLessThan(addr, value, true, timeout); + case ams::svc::ArbitrationType_WaitIfEqual: + return this->WaitIfEqual(addr, value, timeout); + MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); + } + } + private: + Result Signal(uintptr_t addr, s32 count); + Result SignalAndIncrementIfEqual(uintptr_t addr, s32 value, s32 count); + Result SignalAndModifyByWaitingCountIfEqual(uintptr_t addr, s32 value, s32 count); + Result WaitIfLessThan(uintptr_t addr, s32 value, bool decrement, s64 timeout); + Result WaitIfEqual(uintptr_t addr, s32 value, s64 timeout); + }; + +} diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp new file mode 100644 index 000000000..54b6796c0 --- /dev/null +++ b/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include + +namespace ams::kern { + + class KCapabilities { + private: + static constexpr size_t SvcFlagCount = svc::NumSupervisorCalls / BITSIZEOF(u8); + static constexpr size_t IrqFlagCount = /* TODO */0x80; + private: + u8 svc_access_flags[SvcFlagCount]{}; + u8 irq_access_flags[IrqFlagCount]{}; + u64 core_mask{}; + u64 priority_mask{}; + util::BitPack32 debug_capabilities; + s32 handle_table_size{}; + util::BitPack32 intended_kernel_version; + u32 program_type{}; + public: + constexpr KCapabilities() : svc_access_flags(), debug_capabilities(0), intended_kernel_version(0) { /* ... */ } + + constexpr u64 GetCoreMask() const { return this->core_mask; } + constexpr u64 GetPriorityMask() const { return this->priority_mask; } + + /* TODO: Member functions. */ + }; + +} diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_condition_variable.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_condition_variable.hpp new file mode 100644 index 000000000..85462c611 --- /dev/null +++ b/libraries/libmesosphere/include/mesosphere/kern_k_condition_variable.hpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include + +namespace ams::kern { + + struct KConditionVariableComparator { + static constexpr ALWAYS_INLINE int Compare(const KThread &lhs, const KThread &rhs) { + const uintptr_t l_key = lhs.GetConditionVariableKey(); + const uintptr_t r_key = rhs.GetConditionVariableKey(); + + if (l_key < r_key) { + /* Sort first by key */ + return -1; + } else if (l_key == r_key && lhs.GetPriority() < rhs.GetPriority()) { + /* And then by priority. */ + return -1; + } else { + return 1; + } + } + }; + + class KConditionVariable { + public: + using ThreadTree = util::IntrusiveRedBlackTreeMemberTraits<&KThread::condvar_arbiter_tree_node>::TreeType; + private: + ThreadTree tree; + public: + constexpr KConditionVariable() : tree() { /* ... */ } + + /* Arbitration. */ + Result SignalToAddress(KProcessAddress addr); + Result WaitForAddress(ams::svc::Handle handle, KProcessAddress addr, u32 value); + + /* Condition variable. */ + void Signal(uintptr_t cv_key, s32 count); + Result Wait(KProcessAddress addr, uintptr_t key, u32 value, s64 timeout); + + ALWAYS_INLINE void BeforeUpdatePriority(KThread *thread) { + MESOSPHERE_ASSERT(KScheduler::IsSchedulerLockedByCurrentThread()); + + this->tree.erase(this->tree.iterator_to(*thread)); + } + + ALWAYS_INLINE void AfterUpdatePriority(KThread *thread) { + MESOSPHERE_ASSERT(KScheduler::IsSchedulerLockedByCurrentThread()); + + this->tree.insert(*thread); + } + }; + +} diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp index 33e38bc5b..3b3d4ce55 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp @@ -21,21 +21,134 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace ams::kern { - class KProcess final : public KAutoObjectWithSlabHeapAndContainer { + class KProcess final : public KAutoObjectWithSlabHeapAndContainer, public KWorkerTask { MESOSPHERE_AUTOOBJECT_TRAITS(KProcess, KSynchronizationObject); - /* TODO: This is a placeholder definition. */ public: - u64 GetCoreMask() const { MESOSPHERE_TODO_IMPLEMENT(); } - u64 GetPriorityMask() const { MESOSPHERE_TODO_IMPLEMENT();} + enum State { + State_Created = ams::svc::ProcessState_Created, + State_CreatedAttached = ams::svc::ProcessState_CreatedAttached, + State_Running = ams::svc::ProcessState_Running, + State_Crashed = ams::svc::ProcessState_Crashed, + State_RunningAttached = ams::svc::ProcessState_RunningAttached, + State_Terminating = ams::svc::ProcessState_Terminating, + State_Terminated = ams::svc::ProcessState_Terminated, + State_DebugBreak = ams::svc::ProcessState_DebugBreak, + }; - bool Is64Bit() const { MESOSPHERE_TODO_IMPLEMENT(); } + using ThreadList = util::IntrusiveListMemberTraits<&KThread::process_list_node>::ListType; + private: + using SharedMemoryInfoList = util::IntrusiveListBaseTraits::ListType; + using TLPTree = util::IntrusiveRedBlackTreeBaseTraits::TreeType; + using TLPIterator = TLPTree::iterator; + private: + KProcessPageTable page_table{}; + std::atomic used_kernel_memory_size{}; + TLPTree fully_used_tlp_tree{}; + TLPTree partially_used_tlp_tree{}; + s32 ideal_core_id{}; + void *attached_object{}; + KResourceLimit *resource_limit{}; + KVirtualAddress system_resource_address{}; + size_t system_resource_num_pages{}; + size_t memory_release_hint{}; + State state{}; + KLightLock lock{}; + KLightLock list_lock{}; + KConditionVariable cond_var{}; + KAddressArbiter address_arbiter{}; + u64 entropy[4]{}; + bool is_signaled{}; + bool is_initialized{}; + bool is_application{}; + char name[13]{}; + std::atomic num_threads{}; + u16 peak_num_threads{}; + u32 flags{}; + KMemoryManager::Pool memory_pool{}; + s64 schedule_count{}; + KCapabilities capabilities{}; + ams::svc::ProgramId program_id{}; + u64 process_id{}; + s64 creation_time{}; + KProcessAddress code_address{}; + size_t code_size{}; + size_t main_thread_stack_size{}; + size_t max_process_memory{}; + u32 version{}; + KHandleTable handle_table{}; + KProcessAddress plr_address{}; + KThread *exception_thread{}; + ThreadList thread_list{}; + SharedMemoryInfoList shared_memory_list{}; + bool is_suspended{}; + bool is_jit_debug{}; + ams::svc::DebugEvent jit_debug_event_type{}; + ams::svc::DebugException jit_debug_exception_type{}; + uintptr_t jit_debug_params[4]{}; + u64 jit_debug_thread_id{}; + KWaitObject wait_object{}; + KThread *running_threads[cpu::NumCores]{}; + u64 running_thread_idle_counts[cpu::NumCores]{}; + KThread *pinned_threads[cpu::NumCores]{}; + std::atomic num_created_threads{}; + std::atomic cpu_time{}; + std::atomic num_process_switches{}; + std::atomic num_thread_switches{}; + std::atomic num_fpu_switches{}; + std::atomic num_supervisor_calls{}; + std::atomic num_ipc_messages{}; + std::atomic num_ipc_replies{}; + std::atomic num_ipc_receives{}; + KDynamicPageManager dynamic_page_manager{}; + KMemoryBlockSlabManager memory_block_slab_manager{}; + KBlockInfoManager block_info_manager{}; + KPageTableManager page_table_manager{}; + public: + constexpr KProcess() { /* ... */ } + virtual ~KProcess() { /* ... */ } - KThread *GetPreemptionStatePinnedThread(s32 core_id) { MESOSPHERE_TODO_IMPLEMENT(); } + constexpr u64 GetProcessId() const { return this->process_id; } + + constexpr u64 GetCoreMask() const { return this->capabilities.GetCoreMask(); } + constexpr u64 GetPriorityMask() const { return this->capabilities.GetPriorityMask(); } + + constexpr bool Is64Bit() const { return this->flags & ams::svc::CreateProcessFlag_Is64Bit; } + + KThread *GetPreemptionStatePinnedThread(s32 core_id) const { + MESOSPHERE_ASSERT(0 <= core_id && core_id < static_cast(cpu::NumCores)); + return this->pinned_threads[core_id]; + } void SetPreemptionState(); + public: + /* Overridden parent functions. */ + virtual bool IsInitialized() const override { return this->is_initialized; } + + static void PostDestroy(uintptr_t arg) { /* ... */ } + + virtual void Finalize() override; + + virtual u64 GetId() const override { return this->GetProcessId(); } + + virtual bool IsSignaled() const override { + MESOSPHERE_ASSERT_THIS(); + MESOSPHERE_ASSERT(KScheduler::IsSchedulerLockedByCurrentThread()); + return this->is_signaled; + } + + virtual void DoWorkerTask() override; }; } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp index 5dc1b3c8b..3c5c7cc47 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp @@ -25,11 +25,18 @@ namespace ams::kern { class KThreadQueue; + class KProcess; + class KConditionVariable; + class KAddressArbiter; using KThreadFunction = void (*)(uintptr_t); class KThread final : public KAutoObjectWithSlabHeapAndContainer, public KTimerTask, public KWorkerTask { MESOSPHERE_AUTOOBJECT_TRAITS(KThread, KSynchronizationObject); + private: + friend class KProcess; + friend class KConditionVariable; + friend class KAddressArbiter; public: static constexpr s32 MainThreadPriority = 1; static constexpr s32 IdleThreadPriority = 64; @@ -115,79 +122,66 @@ namespace ams::kern { private: static inline std::atomic s_next_thread_id = 0; private: - alignas(16) KThreadContext thread_context; - KAffinityMask affinity_mask; - u64 thread_id; - std::atomic cpu_time; - KSynchronizationObject *synced_object; - KLightLock *waiting_lock; - uintptr_t condvar_key; - uintptr_t entrypoint; - KProcessAddress arbiter_key; - KProcess *parent; - void *kernel_stack_top; - u32 *light_ipc_data; - KProcessAddress tls_address; - void *tls_heap_address; - KLightLock activity_pause_lock; - SyncObjectBuffer sync_object_buffer; - s64 schedule_count; - s64 last_scheduled_tick; - QueueEntry per_core_priority_queue_entry[cpu::NumCores]; - QueueEntry sleeping_queue_entry; - KThreadQueue *sleeping_queue; - util::IntrusiveListNode waiter_list_node; - util::IntrusiveRedBlackTreeNode condvar_arbiter_tree_node; - util::IntrusiveListNode process_list_node; + alignas(16) KThreadContext thread_context{}; + KAffinityMask affinity_mask{}; + u64 thread_id{}; + std::atomic cpu_time{}; + KSynchronizationObject *synced_object{}; + KLightLock *waiting_lock{}; + uintptr_t condvar_key{}; + uintptr_t entrypoint{}; + KProcessAddress arbiter_key{}; + KProcess *parent{}; + void *kernel_stack_top{}; + u32 *light_ipc_data{}; + KProcessAddress tls_address{}; + void *tls_heap_address{}; + KLightLock activity_pause_lock{}; + SyncObjectBuffer sync_object_buffer{}; + s64 schedule_count{}; + s64 last_scheduled_tick{}; + QueueEntry per_core_priority_queue_entry[cpu::NumCores]{}; + QueueEntry sleeping_queue_entry{}; + KThreadQueue *sleeping_queue{}; + util::IntrusiveListNode waiter_list_node{}; + util::IntrusiveRedBlackTreeNode condvar_arbiter_tree_node{}; + util::IntrusiveListNode process_list_node{}; using WaiterListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&KThread::waiter_list_node>; using WaiterList = WaiterListTraits::ListType; - WaiterList waiter_list; - WaiterList paused_waiter_list; - KThread *lock_owner; - void /* TODO KCondVar*/ *cond_var_tree; - uintptr_t debug_params[3]; - u32 arbiter_value; - u32 suspend_request_flags; - u32 suspend_allowed_flags; + WaiterList waiter_list{}; + WaiterList paused_waiter_list{}; + KThread *lock_owner{}; + KConditionVariable *cond_var{}; + uintptr_t debug_params[3]{}; + u32 arbiter_value{}; + u32 suspend_request_flags{}; + u32 suspend_allowed_flags{}; Result wait_result; Result debug_exception_result; - s32 priority; - s32 core_id; - s32 base_priority; - s32 ideal_core_id; - s32 num_kernel_waiters; - KAffinityMask original_affinity_mask; - s32 original_ideal_core_id; - s32 num_core_migration_disables; - ThreadState thread_state; - std::atomic termination_requested; - bool ipc_cancelled; - bool wait_cancelled; - bool cancellable; - bool registered; - bool signaled; - bool initialized; - bool debug_attached; - s8 priority_inheritance_count; - bool resource_limit_release_hint; + s32 priority{}; + s32 core_id{}; + s32 base_priority{}; + s32 ideal_core_id{}; + s32 num_kernel_waiters{}; + KAffinityMask original_affinity_mask{}; + s32 original_ideal_core_id{}; + s32 num_core_migration_disables{}; + ThreadState thread_state{}; + std::atomic termination_requested{}; + bool ipc_cancelled{}; + bool wait_cancelled{}; + bool cancellable{}; + bool registered{}; + bool signaled{}; + bool initialized{}; + bool debug_attached{}; + s8 priority_inheritance_count{}; + bool resource_limit_release_hint{}; public: - constexpr KThread() : - thread_context(), affinity_mask(), thread_id(), cpu_time(), synced_object(), waiting_lock(), - condvar_key(), entrypoint(), arbiter_key(), parent(), kernel_stack_top(), light_ipc_data(), - tls_address(), tls_heap_address(), activity_pause_lock(), sync_object_buffer(), schedule_count(), - last_scheduled_tick(), per_core_priority_queue_entry(), sleeping_queue_entry(), sleeping_queue(), waiter_list_node(), - condvar_arbiter_tree_node(), process_list_node(), waiter_list(), paused_waiter_list(), lock_owner(), - cond_var_tree(), debug_params(), arbiter_value(), suspend_request_flags(), suspend_allowed_flags(), - wait_result(ResultSuccess()), debug_exception_result(ResultSuccess()), priority(), core_id(), base_priority(), - ideal_core_id(), num_kernel_waiters(), original_affinity_mask(), original_ideal_core_id(), num_core_migration_disables(), - thread_state(), termination_requested(), ipc_cancelled(), wait_cancelled(), cancellable(), - registered(), signaled(), initialized(), debug_attached(), priority_inheritance_count(), - resource_limit_release_hint() - { - /* ... */ - } + constexpr KThread() : wait_result(svc::ResultNoSynchronizationObject()), debug_exception_result(ResultSuccess()) { /* ... */ } + virtual ~KThread() { /* ... */ } /* TODO: Is a constexpr KThread() possible? */ @@ -271,7 +265,7 @@ namespace ams::kern { ALWAYS_INLINE void RemoveWaiterImpl(KThread *thread); ALWAYS_INLINE static void RestorePriority(KThread *thread); public: - constexpr u64 GetId() const { return this->thread_id; } + constexpr u64 GetThreadId() const { return this->thread_id; } constexpr KThreadContext *GetContext() { return std::addressof(this->thread_context); } constexpr const KThreadContext *GetContext() const { return std::addressof(this->thread_context); } @@ -282,6 +276,8 @@ namespace ams::kern { NOINLINE KThreadContext *GetContextForSchedulerLoop(); + constexpr uintptr_t GetConditionVariableKey() const { return this->condvar_key; } + constexpr s32 GetActiveCore() const { return this->core_id; } constexpr void SetActiveCore(s32 core) { this->core_id = core; } constexpr s32 GetPriority() const { return this->priority; } @@ -295,7 +291,7 @@ namespace ams::kern { constexpr const QueueEntry &GetSleepingQueueEntry() const { return this->sleeping_queue_entry; } constexpr void SetSleepingQueue(KThreadQueue *q) { this->sleeping_queue = q; } - constexpr void /* TODO */ *GetConditionVariable() const { return this->cond_var_tree; } + constexpr KConditionVariable *GetConditionVariable() const { return this->cond_var; } constexpr s32 GetNumKernelWaiters() const { return this->num_kernel_waiters; } @@ -354,6 +350,8 @@ namespace ams::kern { public: /* Overridden parent functions. */ + virtual u64 GetId() const override { return this->GetThreadId(); } + virtual bool IsInitialized() const override { return this->initialized; } virtual uintptr_t GetPostDestroyArgument() const override { return reinterpret_cast(this->parent) | (this->resource_limit_release_hint ? 1 : 0); } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_wait_object.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_wait_object.hpp new file mode 100644 index 000000000..ac287c126 --- /dev/null +++ b/libraries/libmesosphere/include/mesosphere/kern_k_wait_object.hpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include + +namespace ams::kern { + + class KWaitObject : public KTimerTask { + private: + using Entry = KThread::QueueEntry; + private: + Entry root; + bool uses_timer; + public: + constexpr KWaitObject() : root(), uses_timer() { /* ... */ } + + virtual void OnTimer() override; + + /* TODO: Member functions */ + }; + +} diff --git a/libraries/libmesosphere/source/kern_initial_process.cpp b/libraries/libmesosphere/source/kern_initial_process.cpp index 780fadb9d..7d18a96d7 100644 --- a/libraries/libmesosphere/source/kern_initial_process.cpp +++ b/libraries/libmesosphere/source/kern_initial_process.cpp @@ -81,7 +81,8 @@ namespace ams::kern { MESOSPHERE_R_ABORT_UNLESS(Kernel::GetKernelPageTable().UnmapPageGroup(temp_address, pg, KMemoryState_Kernel)); /* Create a KProcess object. */ - MESOSPHERE_TODO("Create a KProcess"); + new_process = KProcess::Create(); + MESOSPHERE_ABORT_UNLESS(new_process != nullptr); /* Initialize the process. */ MESOSPHERE_TODO("Initialize the process"); diff --git a/libraries/libmesosphere/source/kern_k_process.cpp b/libraries/libmesosphere/source/kern_k_process.cpp index 703904b30..637c58d32 100644 --- a/libraries/libmesosphere/source/kern_k_process.cpp +++ b/libraries/libmesosphere/source/kern_k_process.cpp @@ -17,6 +17,14 @@ namespace ams::kern { + void KProcess::Finalize() { + MESOSPHERE_TODO_IMPLEMENT(); + } + + void KProcess::DoWorkerTask() { + MESOSPHERE_TODO_IMPLEMENT(); + } + void KProcess::SetPreemptionState() { MESOSPHERE_TODO_IMPLEMENT(); } diff --git a/libraries/libmesosphere/source/kern_k_thread.cpp b/libraries/libmesosphere/source/kern_k_thread.cpp index e9f3f5ef9..78495d6c4 100644 --- a/libraries/libmesosphere/source/kern_k_thread.cpp +++ b/libraries/libmesosphere/source/kern_k_thread.cpp @@ -96,7 +96,7 @@ namespace ams::kern { /* Set parent and condvar tree. */ this->parent = nullptr; - this->cond_var_tree = nullptr; + this->cond_var = nullptr; /* Set sync booleans. */ this->signaled = false; @@ -423,7 +423,7 @@ namespace ams::kern { /* Ensure we don't violate condition variable red black tree invariants. */ if (auto *cond_var = thread->GetConditionVariable(); cond_var != nullptr) { - MESOSPHERE_TODO("Remove from condvar tree"); + cond_var->BeforeUpdatePriority(thread); } /* Change the priority. */ @@ -432,7 +432,7 @@ namespace ams::kern { /* Restore the condition variable, if relevant. */ if (auto *cond_var = thread->GetConditionVariable(); cond_var != nullptr) { - MESOSPHERE_TODO("Re-insert into condvar tree"); + cond_var->AfterUpdatePriority(thread); } /* Update the scheduler. */ diff --git a/libraries/libmesosphere/source/kern_k_wait_object.cpp b/libraries/libmesosphere/source/kern_k_wait_object.cpp new file mode 100644 index 000000000..87d374b96 --- /dev/null +++ b/libraries/libmesosphere/source/kern_k_wait_object.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +namespace ams::kern { + + void KWaitObject::OnTimer() { + MESOSPHERE_TODO_IMPLEMENT(); + } + +} diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_types.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_types.hpp index 5c1b9dd06..10992f9e6 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_types.hpp @@ -34,9 +34,9 @@ namespace ams::ncm { /* Program IDs (Formerly: Title IDs). */ struct ProgramId { - u64 value; + svc::ProgramId value; - inline explicit operator u64() const { + inline explicit operator svc::ProgramId() const { return this->value; } diff --git a/libraries/libvapours/include/vapours/svc/svc_types_common.hpp b/libraries/libvapours/include/vapours/svc/svc_types_common.hpp index d46f3ae8f..e10c313de 100644 --- a/libraries/libvapours/include/vapours/svc/svc_types_common.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_types_common.hpp @@ -64,6 +64,7 @@ namespace ams::svc { template static constexpr inline bool IsUserPointer = std::is_base_of::value; + using ProgramId = u64; using PhysicalAddress = u64; /* Memory types. */ @@ -196,9 +197,9 @@ namespace ams::svc { /* Synchronization types. */ enum SignalType : u32 { - SignalType_Signal = 0, - SignalType_SignalAndIfEqual = 1, - SignalType_SignalAndModifyBasedOnWaitingThreadCountIfEqual = 2, + SignalType_Signal = 0, + SignalType_SignalAndIncrementIfEqual = 1, + SignalType_SignalAndModifyByWaitingCountIfEqual = 2, }; enum ArbitrationType : u32 { @@ -291,9 +292,9 @@ namespace ams::svc { ProcessState_Running = 2, ProcessState_Crashed = 3, ProcessState_RunningAttached = 4, - ProcessState_Exiting = 5, - ProcessState_Exited = 6, - ProcessState_DebugSuspended = 7, + ProcessState_Terminating = 5, + ProcessState_Terminated = 6, + ProcessState_DebugBreak = 7, }; enum ProcessExitReason : u32 { diff --git a/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s b/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s index 2d34cf704..7582e622d 100644 --- a/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s +++ b/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s @@ -89,10 +89,10 @@ _ZN3ams4kern4arch5arm6427SupervisorModeThreadStarterEv: /* ams::kern::arch::arm64::KThreadContext::RestoreFpuRegisters64(const KThreadContext &) */ -.section .text._ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters64ERKS2_, "ax", %progbits -.global _ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters64ERKS2_ -.type _ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters64ERKS2_, %function -_ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters64ERKS2_: +.section .text._ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters64ERKS3_, "ax", %progbits +.global _ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters64ERKS3_ +.type _ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters64ERKS3_, %function +_ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters64ERKS3_: /* Load and restore FPCR and FPSR from the context. */ ldr x1, [x0, #0x70] msr fpcr, x1 @@ -120,10 +120,10 @@ _ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters64ERKS2_: ret /* ams::kern::arch::arm64::KThreadContext::RestoreFpuRegisters32(const KThreadContext &) */ -.section .text._ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters32ERKS2_, "ax", %progbits -.global _ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters32ERKS2_ -.type _ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters32ERKS2_, %function -_ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters32ERKS2_: +.section .text._ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters32ERKS3_, "ax", %progbits +.global _ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters32ERKS3_ +.type _ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters32ERKS3_, %function +_ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters32ERKS3_: /* Load and restore FPCR and FPSR from the context. */ ldr x1, [x0, #0x70] msr fpcr, x1 diff --git a/mesosphere/kernel/source/libc/kern_env.cpp b/mesosphere/kernel/source/libc/kern_env.cpp index c17ea9bdc..442977145 100644 --- a/mesosphere/kernel/source/libc/kern_env.cpp +++ b/mesosphere/kernel/source/libc/kern_env.cpp @@ -23,6 +23,10 @@ void operator delete (void *deleted, size_t size) throw() { MESOSPHERE_PANIC("operator delete(void *, size_t) was called: %p %zu", deleted, size); } -void abort() { +void operator delete (void *deleted, size_t size, std::align_val_t align) throw() { + MESOSPHERE_PANIC("operator delete(void *, size_t, std::align_val_t) was called: %p %zu, %zu", deleted, size, static_cast(align)); +} + +extern "C" void abort() { MESOSPHERE_PANIC("abort() was called"); }