From ddd3f4873627a37c1e5c17bb406e86773cf7f5bc Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 29 Oct 2022 12:13:17 -0700 Subject: core: hle: kernel: Add KDebug. --- src/core/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core/CMakeLists.txt') diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 113e663b5..d3831f4a9 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -190,6 +190,7 @@ add_library(core STATIC hle/kernel/k_code_memory.h hle/kernel/k_condition_variable.cpp hle/kernel/k_condition_variable.h + hle/kernel/k_debug.h hle/kernel/k_dynamic_page_manager.h hle/kernel/k_dynamic_resource_manager.h hle/kernel/k_dynamic_slab_heap.h -- cgit v1.2.3 From 37b17252d175478dea7e1eeaf7332da1558f0373 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 29 Oct 2022 13:19:33 -0700 Subject: core: hle: kernel: Add KEventInfo. --- src/core/CMakeLists.txt | 1 + src/core/hle/kernel/k_event_info.h | 64 ++++++++++++++++++++++++++++++++++++++ src/core/hle/kernel/svc.cpp | 2 +- src/core/hle/kernel/svc_types.h | 36 +++++++++++++++++++++ 4 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 src/core/hle/kernel/k_event_info.h (limited to 'src/core/CMakeLists.txt') diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index d3831f4a9..457a0bfd2 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -196,6 +196,7 @@ add_library(core STATIC hle/kernel/k_dynamic_slab_heap.h hle/kernel/k_event.cpp hle/kernel/k_event.h + hle/kernel/k_event_info.h hle/kernel/k_handle_table.cpp hle/kernel/k_handle_table.h hle/kernel/k_interrupt_manager.cpp diff --git a/src/core/hle/kernel/k_event_info.h b/src/core/hle/kernel/k_event_info.h new file mode 100644 index 000000000..25b3ff594 --- /dev/null +++ b/src/core/hle/kernel/k_event_info.h @@ -0,0 +1,64 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include + +#include "core/hle/kernel/slab_helpers.h" +#include "core/hle/kernel/svc_types.h" + +namespace Kernel { + +class KEventInfo : public KSlabAllocated, public boost::intrusive::list_base_hook<> { +public: + struct InfoCreateThread { + u32 thread_id{}; + uintptr_t tls_address{}; + }; + + struct InfoExitProcess { + Svc::ProcessExitReason reason{}; + }; + + struct InfoExitThread { + Svc::ThreadExitReason reason{}; + }; + + struct InfoException { + Svc::DebugException exception_type{}; + s32 exception_data_count{}; + uintptr_t exception_address{}; + std::array exception_data{}; + }; + + struct InfoSystemCall { + s64 tick{}; + s32 id{}; + }; + +public: + KEventInfo() = default; + ~KEventInfo() = default; + +public: + Svc::DebugEvent event{}; + u32 thread_id{}; + u32 flags{}; + bool is_attached{}; + bool continue_flag{}; + bool ignore_continue{}; + bool close_once{}; + union { + InfoCreateThread create_thread; + InfoExitProcess exit_process; + InfoExitThread exit_thread; + InfoException exception; + InfoSystemCall system_call; + } info{}; + KThread* debug_thread{}; +}; + +} // namespace Kernel diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 4aca5b27d..319c9f572 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -2246,7 +2246,7 @@ static u64 GetSystemTick(Core::System& system) { auto& core_timing = system.CoreTiming(); // Returns the value of cntpct_el0 (https://switchbrew.org/wiki/SVC#svcGetSystemTick) - const u64 result{system.CoreTiming().GetClockTicks()}; + const u64 result{core_timing.GetClockTicks()}; if (!system.Kernel().IsMulticore()) { core_timing.AddTicks(400U); diff --git a/src/core/hle/kernel/svc_types.h b/src/core/hle/kernel/svc_types.h index abb9847fe..11bb0fe0f 100644 --- a/src/core/hle/kernel/svc_types.h +++ b/src/core/hle/kernel/svc_types.h @@ -32,6 +32,7 @@ enum class MemoryState : u32 { GeneratedCode = 0x14, CodeOut = 0x15, Coverage = 0x16, + Insecure = 0x17, }; DECLARE_ENUM_FLAG_OPERATORS(MemoryState); @@ -83,6 +84,13 @@ enum class YieldType : s64 { ToAnyThread = -2, }; +enum class ThreadExitReason : u32 { + ExitThread = 0, + TerminateThread = 1, + ExitProcess = 2, + TerminateProcess = 3, +}; + enum class ThreadActivity : u32 { Runnable = 0, Paused = 1, @@ -108,6 +116,34 @@ enum class ProcessState : u32 { DebugBreak = 7, }; +enum class ProcessExitReason : u32 { + ExitProcess = 0, + TerminateProcess = 1, + Exception = 2, +}; + constexpr inline size_t ThreadLocalRegionSize = 0x200; +// Debug types. +enum class DebugEvent : u32 { + CreateProcess = 0, + CreateThread = 1, + ExitProcess = 2, + ExitThread = 3, + Exception = 4, +}; + +enum class DebugException : u32 { + UndefinedInstruction = 0, + InstructionAbort = 1, + DataAbort = 2, + AlignmentFault = 3, + DebuggerAttached = 4, + BreakPoint = 5, + UserBreak = 6, + DebuggerBreak = 7, + UndefinedSystemCall = 8, + MemorySystemError = 9, +}; + } // namespace Kernel::Svc -- cgit v1.2.3 From 6d4f411c08146696caf45a29db2a4aa25a55c639 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 29 Oct 2022 13:35:50 -0700 Subject: core: hle: kernel: Add KPageTableSlabHeap. --- src/core/CMakeLists.txt | 1 + src/core/hle/kernel/k_page_table_slab_heap.h | 93 ++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 src/core/hle/kernel/k_page_table_slab_heap.h (limited to 'src/core/CMakeLists.txt') diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 457a0bfd2..199e0e69f 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -224,6 +224,7 @@ add_library(core STATIC hle/kernel/k_page_group.h hle/kernel/k_page_table.cpp hle/kernel/k_page_table.h + hle/kernel/k_page_table_slab_heap.h hle/kernel/k_port.cpp hle/kernel/k_port.h hle/kernel/k_priority_queue.h diff --git a/src/core/hle/kernel/k_page_table_slab_heap.h b/src/core/hle/kernel/k_page_table_slab_heap.h new file mode 100644 index 000000000..a9543cbd0 --- /dev/null +++ b/src/core/hle/kernel/k_page_table_slab_heap.h @@ -0,0 +1,93 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include "common/common_types.h" +#include "core/hle/kernel/k_dynamic_slab_heap.h" +#include "core/hle/kernel/slab_helpers.h" + +namespace Kernel { + +namespace impl { + +class PageTablePage { +public: + // Do not initialize anything. + PageTablePage() = default; + +private: + std::array m_buffer{}; +}; +static_assert(sizeof(PageTablePage) == PageSize); + +} // namespace impl + +class KPageTableSlabHeap : public KDynamicSlabHeap { +public: + using RefCount = u16; + static constexpr size_t PageTableSize = sizeof(impl::PageTablePage); + static_assert(PageTableSize == PageSize); + +public: + KPageTableSlabHeap() = default; + + static constexpr size_t CalculateReferenceCountSize(size_t size) { + return (size / PageSize) * sizeof(RefCount); + } + + void Initialize(KDynamicPageManager* page_allocator, size_t object_count, RefCount* rc) { + BaseHeap::Initialize(page_allocator, object_count); + this->Initialize(rc); + } + + RefCount GetRefCount(VAddr addr) { + ASSERT(this->IsInRange(addr)); + return *this->GetRefCountPointer(addr); + } + + void Open(VAddr addr, int count) { + ASSERT(this->IsInRange(addr)); + + *this->GetRefCountPointer(addr) += static_cast(count); + + ASSERT(this->GetRefCount(addr) > 0); + } + + bool Close(VAddr addr, int count) { + ASSERT(this->IsInRange(addr)); + ASSERT(this->GetRefCount(addr) >= count); + + *this->GetRefCountPointer(addr) -= static_cast(count); + return this->GetRefCount(addr) == 0; + } + + bool IsInPageTableHeap(VAddr addr) const { + return this->IsInRange(addr); + } + +private: + void Initialize([[maybe_unused]] RefCount* rc) { + // TODO(bunnei): Use rc once we support kernel virtual memory allocations. + const auto count = this->GetSize() / PageSize; + m_ref_counts.resize(count); + + for (size_t i = 0; i < count; i++) { + m_ref_counts[i] = 0; + } + } + + RefCount* GetRefCountPointer(VAddr addr) { + return m_ref_counts.data() + ((addr - this->GetAddress()) / PageSize); + } + +private: + using BaseHeap = KDynamicSlabHeap; + + std::vector m_ref_counts; +}; + +} // namespace Kernel -- cgit v1.2.3 From 0897f4f96c2d463976e7a28ac0b69c449bcd9624 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 29 Oct 2022 13:38:45 -0700 Subject: core: hle: kernel: Add KPageTableManager. --- src/core/CMakeLists.txt | 1 + src/core/hle/kernel/k_page_table_manager.h | 55 ++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/core/hle/kernel/k_page_table_manager.h (limited to 'src/core/CMakeLists.txt') diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 199e0e69f..f0d5b0887 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -224,6 +224,7 @@ add_library(core STATIC hle/kernel/k_page_group.h hle/kernel/k_page_table.cpp hle/kernel/k_page_table.h + hle/kernel/k_page_table_manager.h hle/kernel/k_page_table_slab_heap.h hle/kernel/k_port.cpp hle/kernel/k_port.h diff --git a/src/core/hle/kernel/k_page_table_manager.h b/src/core/hle/kernel/k_page_table_manager.h new file mode 100644 index 000000000..91a45cde3 --- /dev/null +++ b/src/core/hle/kernel/k_page_table_manager.h @@ -0,0 +1,55 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include "common/common_types.h" +#include "core/hle/kernel/k_dynamic_resource_manager.h" +#include "core/hle/kernel/k_page_table_slab_heap.h" + +namespace Kernel { + +class KPageTableManager : public KDynamicResourceManager { +public: + using RefCount = KPageTableSlabHeap::RefCount; + static constexpr size_t PageTableSize = KPageTableSlabHeap::PageTableSize; + +public: + KPageTableManager() = default; + + void Initialize(KDynamicPageManager* page_allocator, KPageTableSlabHeap* pt_heap) { + m_pt_heap = pt_heap; + + static_assert(std::derived_from); + BaseHeap::Initialize(page_allocator, pt_heap); + } + + VAddr Allocate() { + return VAddr(BaseHeap::Allocate()); + } + + RefCount GetRefCount(VAddr addr) const { + return m_pt_heap->GetRefCount(addr); + } + + void Open(VAddr addr, int count) { + return m_pt_heap->Open(addr, count); + } + + bool Close(VAddr addr, int count) { + return m_pt_heap->Close(addr, count); + } + + bool IsInPageTableHeap(VAddr addr) const { + return m_pt_heap->IsInRange(addr); + } + +private: + using BaseHeap = KDynamicResourceManager; + + KPageTableSlabHeap* m_pt_heap{}; +}; + +} // namespace Kernel -- cgit v1.2.3 From 6f941121e6c66664d183eb1a07d781a7bcb998f9 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 29 Oct 2022 14:33:33 -0700 Subject: core: hle: kernel: Add KSystemResource. --- src/core/CMakeLists.txt | 2 + src/core/hle/kernel/k_class_token.cpp | 3 + src/core/hle/kernel/k_class_token.h | 6 +- src/core/hle/kernel/k_system_resource.cpp | 26 ++++++ src/core/hle/kernel/k_system_resource.h | 137 ++++++++++++++++++++++++++++++ 5 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 src/core/hle/kernel/k_system_resource.cpp create mode 100644 src/core/hle/kernel/k_system_resource.h (limited to 'src/core/CMakeLists.txt') diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index f0d5b0887..f6e082c36 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -258,6 +258,8 @@ add_library(core STATIC hle/kernel/k_synchronization_object.cpp hle/kernel/k_synchronization_object.h hle/kernel/k_system_control.h + hle/kernel/k_system_resource.cpp + hle/kernel/k_system_resource.h hle/kernel/k_thread.cpp hle/kernel/k_thread.h hle/kernel/k_thread_local_page.cpp diff --git a/src/core/hle/kernel/k_class_token.cpp b/src/core/hle/kernel/k_class_token.cpp index 10265c23c..6eb44d6a6 100644 --- a/src/core/hle/kernel/k_class_token.cpp +++ b/src/core/hle/kernel/k_class_token.cpp @@ -16,6 +16,7 @@ #include "core/hle/kernel/k_session.h" #include "core/hle/kernel/k_shared_memory.h" #include "core/hle/kernel/k_synchronization_object.h" +#include "core/hle/kernel/k_system_resource.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_transfer_memory.h" @@ -119,4 +120,6 @@ static_assert(std::is_final_v && std::is_base_of_v && // std::is_base_of_v); +static_assert(std::is_base_of::value); + } // namespace Kernel diff --git a/src/core/hle/kernel/k_class_token.h b/src/core/hle/kernel/k_class_token.h index ab20e00ff..e75b1c035 100644 --- a/src/core/hle/kernel/k_class_token.h +++ b/src/core/hle/kernel/k_class_token.h @@ -10,6 +10,8 @@ namespace Kernel { class KAutoObject; +class KSystemResource; + class KClassTokenGenerator { public: using TokenBaseType = u16; @@ -58,7 +60,7 @@ private: if constexpr (std::is_same::value) { static_assert(T::ObjectType == ObjectType::KAutoObject); return 0; - } else if constexpr (!std::is_final::value) { + } else if constexpr (!std::is_final::value && !std::same_as) { static_assert(ObjectType::BaseClassesStart <= T::ObjectType && T::ObjectType < ObjectType::BaseClassesEnd); constexpr auto ClassIndex = static_cast(T::ObjectType) - @@ -108,6 +110,8 @@ public: KSessionRequest, KCodeMemory, + KSystemResource, + // NOTE: True order for these has not been determined yet. KAlpha, KBeta, diff --git a/src/core/hle/kernel/k_system_resource.cpp b/src/core/hle/kernel/k_system_resource.cpp new file mode 100644 index 000000000..4cc377a6c --- /dev/null +++ b/src/core/hle/kernel/k_system_resource.cpp @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/kernel/k_system_resource.h" + +namespace Kernel { + +Result KSecureSystemResource::Initialize([[maybe_unused]] size_t size, + [[maybe_unused]] KResourceLimit* resource_limit, + [[maybe_unused]] KMemoryManager::Pool pool) { + // Unimplemented + UNREACHABLE(); +} + +void KSecureSystemResource::Finalize() { + // Unimplemented + UNREACHABLE(); +} + +size_t KSecureSystemResource::CalculateRequiredSecureMemorySize( + [[maybe_unused]] size_t size, [[maybe_unused]] KMemoryManager::Pool pool) { + // Unimplemented + UNREACHABLE(); +} + +} // namespace Kernel diff --git a/src/core/hle/kernel/k_system_resource.h b/src/core/hle/kernel/k_system_resource.h new file mode 100644 index 000000000..9a991f725 --- /dev/null +++ b/src/core/hle/kernel/k_system_resource.h @@ -0,0 +1,137 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/assert.h" +#include "common/common_types.h" +#include "core/hle/kernel/k_auto_object.h" +#include "core/hle/kernel/k_dynamic_resource_manager.h" +#include "core/hle/kernel/k_memory_manager.h" +#include "core/hle/kernel/k_page_table_manager.h" +#include "core/hle/kernel/k_resource_limit.h" +#include "core/hle/kernel/slab_helpers.h" + +namespace Kernel { + +// NOTE: Nintendo's implementation does not have the "is_secure_resource" field, and instead uses +// virtual IsSecureResource(). + +class KSystemResource : public KAutoObject { + KERNEL_AUTOOBJECT_TRAITS(KSystemResource, KAutoObject); + +public: + explicit KSystemResource(KernelCore& kernel_) : KAutoObject(kernel_) {} + +protected: + void SetSecureResource() { + m_is_secure_resource = true; + } + +public: + virtual void Destroy() override { + UNREACHABLE_MSG("KSystemResource::Destroy() was called"); + } + + bool IsSecureResource() const { + return m_is_secure_resource; + } + + void SetManagers(KMemoryBlockSlabManager& mb, KBlockInfoManager& bi, KPageTableManager& pt) { + ASSERT(m_p_memory_block_slab_manager == nullptr); + ASSERT(m_p_block_info_manager == nullptr); + ASSERT(m_p_page_table_manager == nullptr); + + m_p_memory_block_slab_manager = std::addressof(mb); + m_p_block_info_manager = std::addressof(bi); + m_p_page_table_manager = std::addressof(pt); + } + + const KMemoryBlockSlabManager& GetMemoryBlockSlabManager() const { + return *m_p_memory_block_slab_manager; + } + const KBlockInfoManager& GetBlockInfoManager() const { + return *m_p_block_info_manager; + } + const KPageTableManager& GetPageTableManager() const { + return *m_p_page_table_manager; + } + + KMemoryBlockSlabManager& GetMemoryBlockSlabManager() { + return *m_p_memory_block_slab_manager; + } + KBlockInfoManager& GetBlockInfoManager() { + return *m_p_block_info_manager; + } + KPageTableManager& GetPageTableManager() { + return *m_p_page_table_manager; + } + + KMemoryBlockSlabManager* GetMemoryBlockSlabManagerPointer() { + return m_p_memory_block_slab_manager; + } + KBlockInfoManager* GetBlockInfoManagerPointer() { + return m_p_block_info_manager; + } + KPageTableManager* GetPageTableManagerPointer() { + return m_p_page_table_manager; + } + +private: + KMemoryBlockSlabManager* m_p_memory_block_slab_manager{}; + KBlockInfoManager* m_p_block_info_manager{}; + KPageTableManager* m_p_page_table_manager{}; + bool m_is_secure_resource{false}; +}; + +class KSecureSystemResource final + : public KAutoObjectWithSlabHeap { +public: + explicit KSecureSystemResource(KernelCore& kernel_) + : KAutoObjectWithSlabHeap(kernel_) { + // Mark ourselves as being a secure resource. + this->SetSecureResource(); + } + + Result Initialize(size_t size, KResourceLimit* resource_limit, KMemoryManager::Pool pool); + void Finalize(); + + bool IsInitialized() const { + return m_is_initialized; + } + static void PostDestroy([[maybe_unused]] uintptr_t arg) {} + + size_t CalculateRequiredSecureMemorySize() const { + return CalculateRequiredSecureMemorySize(m_resource_size, m_resource_pool); + } + + size_t GetSize() const { + return m_resource_size; + } + size_t GetUsedSize() const { + return m_dynamic_page_manager.GetUsed() * PageSize; + } + + const KDynamicPageManager& GetDynamicPageManager() const { + return m_dynamic_page_manager; + } + +public: + static size_t CalculateRequiredSecureMemorySize(size_t size, KMemoryManager::Pool pool); + +private: + bool m_is_initialized{}; + KMemoryManager::Pool m_resource_pool{}; + KDynamicPageManager m_dynamic_page_manager; + KMemoryBlockSlabManager m_memory_block_slab_manager; + KBlockInfoManager m_block_info_manager; + KPageTableManager m_page_table_manager; + KMemoryBlockSlabHeap m_memory_block_heap; + KBlockInfoSlabHeap m_block_info_heap; + KPageTableSlabHeap m_page_table_heap; + KResourceLimit* m_resource_limit{}; + VAddr m_resource_address{}; + size_t m_resource_size{}; +}; + +} // namespace Kernel -- cgit v1.2.3