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");
}