diff --git a/src/core/core.cpp b/src/core/core.cpp index 4f7a5e908..4d4379299 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -191,13 +191,13 @@ System::ResultStatus System::Init(EmuWindow& emu_window, u32 system_mode) { rpc_server = std::make_unique(); #endif - service_manager = std::make_shared(); + service_manager = std::make_shared(*this); shared_page_handler = std::make_shared(); - archive_manager = std::make_unique(); + archive_manager = std::make_unique(*this); HW::Init(); - Kernel::Init(system_mode); - Service::Init(*this, service_manager); + kernel = std::make_unique(system_mode); + Service::Init(*this); GDBStub::Init(); ResultStatus result = VideoCore::Init(emu_window); @@ -230,6 +230,14 @@ const Service::FS::ArchiveManager& System::ArchiveManager() const { return *archive_manager; } +Kernel::KernelSystem& System::Kernel() { + return *kernel; +} + +const Kernel::KernelSystem& System::Kernel() const { + return *kernel; +} + void System::RegisterSoftwareKeyboard(std::shared_ptr swkbd) { registered_swkbd = std::move(swkbd); } @@ -248,7 +256,7 @@ void System::Shutdown() { GDBStub::Shutdown(); VideoCore::Shutdown(); Service::Shutdown(); - Kernel::Shutdown(); + kernel.reset(); HW::Shutdown(); telemetry_session.reset(); #ifdef ENABLE_SCRIPTING diff --git a/src/core/core.h b/src/core/core.h index cecd29896..9341f79a4 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -36,6 +36,10 @@ class ArchiveManager; } } // namespace Service +namespace Kernel { +class KernelSystem; +} + namespace Core { class System { @@ -167,6 +171,12 @@ public: /// Gets a const reference to the archive manager const Service::FS::ArchiveManager& ArchiveManager() const; + /// Gets a reference to the kernel + Kernel::KernelSystem& Kernel(); + + /// Gets a const reference to the kernel + const Kernel::KernelSystem& Kernel() const; + PerfStats perf_stats; FrameLimiter frame_limiter; @@ -241,6 +251,8 @@ private: std::unique_ptr archive_manager; + std::unique_ptr kernel; + static System s_instance; ResultStatus status = ResultStatus::Success; diff --git a/src/core/hle/applets/erreula.cpp b/src/core/hle/applets/erreula.cpp index a8135a2ae..7b8cf1d02 100644 --- a/src/core/hle/applets/erreula.cpp +++ b/src/core/hle/applets/erreula.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "common/string_util.h" +#include "core/core.h" #include "core/hle/applets/erreula.h" #include "core/hle/service/apt/apt.h" @@ -30,7 +31,7 @@ ResultCode ErrEula::ReceiveParameter(const Service::APT::MessageParameter& param // Allocate a heap block of the required size for this applet. heap_memory = std::make_shared>(capture_info.size); // Create a SharedMemory that directly points to this heap block. - framebuffer_memory = Kernel::SharedMemory::CreateForApplet( + framebuffer_memory = Core::System::GetInstance().Kernel().CreateSharedMemoryForApplet( heap_memory, 0, capture_info.size, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, "ErrEula Memory"); diff --git a/src/core/hle/applets/mii_selector.cpp b/src/core/hle/applets/mii_selector.cpp index cfe25b11d..dd57f0efd 100644 --- a/src/core/hle/applets/mii_selector.cpp +++ b/src/core/hle/applets/mii_selector.cpp @@ -7,6 +7,7 @@ #include "common/assert.h" #include "common/logging/log.h" #include "common/string_util.h" +#include "core/core.h" #include "core/hle/applets/mii_selector.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/shared_memory.h" @@ -37,7 +38,7 @@ ResultCode MiiSelector::ReceiveParameter(const Service::APT::MessageParameter& p // Allocate a heap block of the required size for this applet. heap_memory = std::make_shared>(capture_info.size); // Create a SharedMemory that directly points to this heap block. - framebuffer_memory = Kernel::SharedMemory::CreateForApplet( + framebuffer_memory = Core::System::GetInstance().Kernel().CreateSharedMemoryForApplet( heap_memory, 0, capture_info.size, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, "MiiSelector Memory"); diff --git a/src/core/hle/applets/mint.cpp b/src/core/hle/applets/mint.cpp index d71cd7001..ee70ba615 100644 --- a/src/core/hle/applets/mint.cpp +++ b/src/core/hle/applets/mint.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "common/string_util.h" +#include "core/core.h" #include "core/hle/applets/mint.h" #include "core/hle/service/apt/apt.h" @@ -30,7 +31,7 @@ ResultCode Mint::ReceiveParameter(const Service::APT::MessageParameter& paramete // Allocate a heap block of the required size for this applet. heap_memory = std::make_shared>(capture_info.size); // Create a SharedMemory that directly points to this heap block. - framebuffer_memory = Kernel::SharedMemory::CreateForApplet( + framebuffer_memory = Core::System::GetInstance().Kernel().CreateSharedMemoryForApplet( heap_memory, 0, capture_info.size, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, "Mint Memory"); diff --git a/src/core/hle/applets/swkbd.cpp b/src/core/hle/applets/swkbd.cpp index d13050002..cd8a9f57a 100644 --- a/src/core/hle/applets/swkbd.cpp +++ b/src/core/hle/applets/swkbd.cpp @@ -8,6 +8,7 @@ #include "common/assert.h" #include "common/logging/log.h" #include "common/string_util.h" +#include "core/core.h" #include "core/hle/applets/swkbd.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/shared_memory.h" @@ -41,7 +42,7 @@ ResultCode SoftwareKeyboard::ReceiveParameter(Service::APT::MessageParameter con // Allocate a heap block of the required size for this applet. heap_memory = std::make_shared>(capture_info.size); // Create a SharedMemory that directly points to this heap block. - framebuffer_memory = Kernel::SharedMemory::CreateForApplet( + framebuffer_memory = Core::System::GetInstance().Kernel().CreateSharedMemoryForApplet( heap_memory, 0, capture_info.size, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, "SoftwareKeyboard Memory"); diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 1dc005554..d391da208 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -7,6 +7,7 @@ #include "common/logging/log.h" #include "core/hle/kernel/address_arbiter.h" #include "core/hle/kernel/errors.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/thread.h" #include "core/memory.h" @@ -64,11 +65,11 @@ SharedPtr AddressArbiter::ResumeHighestPriorityThread(VAddr address) { return thread; } -AddressArbiter::AddressArbiter() {} +AddressArbiter::AddressArbiter(KernelSystem& kernel) : Object(kernel) {} AddressArbiter::~AddressArbiter() {} -SharedPtr AddressArbiter::Create(std::string name) { - SharedPtr address_arbiter(new AddressArbiter); +SharedPtr KernelSystem::CreateAddressArbiter(std::string name) { + SharedPtr address_arbiter(new AddressArbiter(*this)); address_arbiter->name = std::move(name); diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index cf2761819..cdfa64ec2 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -31,14 +31,6 @@ enum class ArbitrationType : u32 { class AddressArbiter final : public Object { public: - /** - * Creates an address arbiter. - * - * @param name Optional name used for debugging. - * @returns The created AddressArbiter. - */ - static SharedPtr Create(std::string name = "Unknown"); - std::string GetTypeName() const override { return "Arbiter"; } @@ -57,7 +49,7 @@ public: s32 value, u64 nanoseconds); private: - AddressArbiter(); + explicit AddressArbiter(KernelSystem& kernel); ~AddressArbiter() override; /// Puts the thread to wait on the specified arbitration address under this address arbiter. @@ -72,6 +64,8 @@ private: /// Threads waiting for the address arbiter to be signaled. std::vector> waiting_threads; + + friend class KernelSystem; }; } // namespace Kernel diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index e45494db2..02c5d08fd 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -13,7 +13,7 @@ namespace Kernel { -ClientPort::ClientPort() = default; +ClientPort::ClientPort(KernelSystem& kernel) : kernel(kernel), Object(kernel) {} ClientPort::~ClientPort() = default; ResultVal> ClientPort::Connect() { @@ -26,7 +26,7 @@ ResultVal> ClientPort::Connect() { active_sessions++; // Create a new session pair, let the created sessions inherit the parent port's HLE handler. - auto sessions = ServerSession::CreateSessionPair(server_port->GetName(), this); + auto sessions = kernel.CreateSessionPair(server_port->GetName(), this); if (server_port->hle_handler) server_port->hle_handler->ClientConnected(std::get>(sessions)); diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h index 46227347e..149ca77a1 100644 --- a/src/core/hle/kernel/client_port.h +++ b/src/core/hle/kernel/client_port.h @@ -48,13 +48,16 @@ public: void ConnectionClosed(); private: - ClientPort(); + explicit ClientPort(KernelSystem& kernel); ~ClientPort() override; + KernelSystem& kernel; SharedPtr server_port; ///< ServerPort associated with this client port. u32 max_sessions = 0; ///< Maximum number of simultaneous sessions the port can have u32 active_sessions = 0; ///< Number of currently open sessions to this port std::string name; ///< Name of client port (optional) + + friend class KernelSystem; }; } // namespace Kernel diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp index 17f4c12d3..ef1b90195 100644 --- a/src/core/hle/kernel/client_session.cpp +++ b/src/core/hle/kernel/client_session.cpp @@ -13,7 +13,7 @@ namespace Kernel { -ClientSession::ClientSession() = default; +ClientSession::ClientSession(KernelSystem& kernel) : Object(kernel) {} ClientSession::~ClientSession() { // This destructor will be called automatically when the last ClientSession handle is closed by // the emulated application. diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h index 9c6b47927..5d5a2d9cd 100644 --- a/src/core/hle/kernel/client_session.h +++ b/src/core/hle/kernel/client_session.h @@ -12,13 +12,12 @@ namespace Kernel { -class ServerSession; class Session; class Thread; class ClientSession final : public Object { public: - friend class ServerSession; + friend class KernelSystem; std::string GetTypeName() const override { return "ClientSession"; @@ -46,7 +45,7 @@ public: std::shared_ptr parent; private: - ClientSession(); + explicit ClientSession(KernelSystem& kernel); ~ClientSession() override; }; diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 6c93719e3..ce5f3d6ec 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -7,16 +7,16 @@ #include #include "common/assert.h" #include "core/hle/kernel/event.h" -#include "core/hle/kernel/object.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/thread.h" namespace Kernel { -Event::Event() {} +Event::Event(KernelSystem& kernel) : WaitObject(kernel) {} Event::~Event() {} -SharedPtr Event::Create(ResetType reset_type, std::string name) { - SharedPtr evt(new Event); +SharedPtr KernelSystem::CreateEvent(ResetType reset_type, std::string name) { + SharedPtr evt(new Event(*this)); evt->signaled = false; evt->reset_type = reset_type; diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index 53679810e..09c21587d 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h @@ -12,13 +12,6 @@ namespace Kernel { class Event final : public WaitObject { public: - /** - * Creates an event - * @param reset_type ResetType describing how to create event - * @param name Optional name of event - */ - static SharedPtr Create(ResetType reset_type, std::string name = "Unknown"); - std::string GetTypeName() const override { return "Event"; } @@ -47,13 +40,15 @@ public: void Clear(); private: - Event(); + explicit Event(KernelSystem& kernel); ~Event() override; ResetType reset_type; ///< Current ResetType bool signaled; ///< Whether the event has already been signaled std::string name; ///< Name of event (optional) + + friend class KernelSystem; }; } // namespace Kernel diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index cb63fe5e3..1da7c8a81 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -6,6 +6,7 @@ #include #include "common/assert.h" #include "common/common_types.h" +#include "core/core.h" #include "core/hle/kernel/event.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/hle_ipc.h" @@ -55,7 +56,8 @@ SharedPtr HLERequestContext::SleepClientThread(SharedPtr thread, cmd_buff.size() * sizeof(u32)); }; - auto event = Kernel::Event::Create(Kernel::ResetType::OneShot, "HLE Pause Event: " + reason); + auto event = Core::System::GetInstance().Kernel().CreateEvent(Kernel::ResetType::OneShot, + "HLE Pause Event: " + reason); thread->status = ThreadStatus::WaitHleEvent; thread->wait_objects = {event}; event->AddWaitingThread(thread); diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index d494914e3..ba7223db4 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -14,34 +14,41 @@ namespace Kernel { -std::atomic Object::next_object_id{0}; - /// Initialize the kernel -void Init(u32 system_mode) { +KernelSystem::KernelSystem(u32 system_mode) { ConfigMem::Init(); Kernel::MemoryInit(system_mode); - Kernel::ResourceLimitsInit(); + resource_limits = std::make_unique(*this); Kernel::ThreadingInit(); Kernel::TimersInit(); - - Object::next_object_id = 0; // TODO(Subv): Start the process ids from 10 for now, as lower PIDs are // reserved for low-level services Process::next_process_id = 10; } /// Shutdown the kernel -void Shutdown() { +KernelSystem::~KernelSystem() { g_handle_table.Clear(); // Free all kernel objects Kernel::ThreadingShutdown(); g_current_process = nullptr; Kernel::TimersShutdown(); - Kernel::ResourceLimitsShutdown(); Kernel::MemoryShutdown(); } +ResourceLimitList& KernelSystem::ResourceLimit() { + return *resource_limits; +} + +const ResourceLimitList& KernelSystem::ResourceLimit() const { + return *resource_limits; +} + +u32 KernelSystem::GenerateObjectID() { + return next_object_id++; +} + } // namespace Kernel diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 2bc45d7db..98a5d14a2 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -4,14 +4,185 @@ #pragma once +#include +#include +#include +#include #include "common/common_types.h" +#include "core/hle/result.h" namespace Kernel { -/// Initialize the kernel with the specified system mode. -void Init(u32 system_mode); +class AddressArbiter; +class Event; +class Mutex; +class CodeSet; +class Process; +class Thread; +class Semaphore; +class Timer; +class ClientPort; +class ServerPort; +class ClientSession; +class ServerSession; +class ResourceLimitList; +class SharedMemory; -/// Shutdown the kernel -void Shutdown(); +enum class ResetType { + OneShot, + Sticky, + Pulse, +}; + +/// Permissions for mapped shared memory blocks +enum class MemoryPermission : u32 { + None = 0, + Read = (1u << 0), + Write = (1u << 1), + ReadWrite = (Read | Write), + Execute = (1u << 2), + ReadExecute = (Read | Execute), + WriteExecute = (Write | Execute), + ReadWriteExecute = (Read | Write | Execute), + DontCare = (1u << 28) +}; + +enum class MemoryRegion : u16 { + APPLICATION = 1, + SYSTEM = 2, + BASE = 3, +}; + +template +using SharedPtr = boost::intrusive_ptr; + +class KernelSystem { +public: + explicit KernelSystem(u32 system_mode); + ~KernelSystem(); + + /** + * Creates an address arbiter. + * + * @param name Optional name used for debugging. + * @returns The created AddressArbiter. + */ + SharedPtr CreateAddressArbiter(std::string name = "Unknown"); + + /** + * Creates an event + * @param reset_type ResetType describing how to create event + * @param name Optional name of event + */ + SharedPtr CreateEvent(ResetType reset_type, std::string name = "Unknown"); + + /** + * Creates a mutex. + * @param initial_locked Specifies if the mutex should be locked initially + * @param name Optional name of mutex + * @return Pointer to new Mutex object + */ + SharedPtr CreateMutex(bool initial_locked, std::string name = "Unknown"); + + SharedPtr CreateCodeSet(std::string name, u64 program_id); + + SharedPtr CreateProcess(SharedPtr code_set); + + /** + * Creates and returns a new thread. The new thread is immediately scheduled + * @param name The friendly name desired for the thread + * @param entry_point The address at which the thread should start execution + * @param priority The thread's priority + * @param arg User data to pass to the thread + * @param processor_id The ID(s) of the processors on which the thread is desired to be run + * @param stack_top The address of the thread's stack top + * @param owner_process The parent process for the thread + * @return A shared pointer to the newly created thread + */ + ResultVal> CreateThread(std::string name, VAddr entry_point, u32 priority, + u32 arg, s32 processor_id, VAddr stack_top, + SharedPtr owner_process); + + /** + * Creates a semaphore. + * @param initial_count Number of slots reserved for other threads + * @param max_count Maximum number of slots the semaphore can have + * @param name Optional name of semaphore + * @return The created semaphore + */ + ResultVal> CreateSemaphore(s32 initial_count, s32 max_count, + std::string name = "Unknown"); + + /** + * Creates a timer + * @param reset_type ResetType describing how to create the timer + * @param name Optional name of timer + * @return The created Timer + */ + SharedPtr CreateTimer(ResetType reset_type, std::string name = "Unknown"); + + /** + * Creates a pair of ServerPort and an associated ClientPort. + * + * @param max_sessions Maximum number of sessions to the port + * @param name Optional name of the ports + * @return The created port tuple + */ + std::tuple, SharedPtr> CreatePortPair( + u32 max_sessions, std::string name = "UnknownPort"); + + /** + * Creates a pair of ServerSession and an associated ClientSession. + * @param name Optional name of the ports. + * @param client_port Optional The ClientPort that spawned this session. + * @return The created session tuple + */ + std::tuple, SharedPtr> CreateSessionPair( + const std::string& name = "Unknown", SharedPtr client_port = nullptr); + + ResourceLimitList& ResourceLimit(); + const ResourceLimitList& ResourceLimit() const; + + /** + * Creates a shared memory object. + * @param owner_process Process that created this shared memory object. + * @param size Size of the memory block. Must be page-aligned. + * @param permissions Permission restrictions applied to the process which created the block. + * @param other_permissions Permission restrictions applied to other processes mapping the + * block. + * @param address The address from which to map the Shared Memory. + * @param region If the address is 0, the shared memory will be allocated in this region of the + * linear heap. + * @param name Optional object name, used for debugging purposes. + */ + SharedPtr CreateSharedMemory(SharedPtr owner_process, u32 size, + MemoryPermission permissions, + MemoryPermission other_permissions, + VAddr address = 0, + MemoryRegion region = MemoryRegion::BASE, + std::string name = "Unknown"); + + /** + * Creates a shared memory object from a block of memory managed by an HLE applet. + * @param heap_block Heap block of the HLE applet. + * @param offset The offset into the heap block that the SharedMemory will map. + * @param size Size of the memory block. Must be page-aligned. + * @param permissions Permission restrictions applied to the process which created the block. + * @param other_permissions Permission restrictions applied to other processes mapping the + * block. + * @param name Optional object name, used for debugging purposes. + */ + SharedPtr CreateSharedMemoryForApplet(std::shared_ptr> heap_block, + u32 offset, u32 size, + MemoryPermission permissions, + MemoryPermission other_permissions, + std::string name = "Unknown Applet"); + + u32 GenerateObjectID(); + +private: + std::unique_ptr resource_limits; + std::atomic next_object_id{0}; +}; } // namespace Kernel diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 02cbf613c..f31a2a5d7 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -24,11 +24,11 @@ void ReleaseThreadMutexes(Thread* thread) { thread->held_mutexes.clear(); } -Mutex::Mutex() {} +Mutex::Mutex(KernelSystem& kernel) : WaitObject(kernel) {} Mutex::~Mutex() {} -SharedPtr Mutex::Create(bool initial_locked, std::string name) { - SharedPtr mutex(new Mutex); +SharedPtr KernelSystem::CreateMutex(bool initial_locked, std::string name) { + SharedPtr mutex(new Mutex(*this)); mutex->lock_count = 0; mutex->name = std::move(name); diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 3afb99c59..ec0e3f794 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -16,14 +16,6 @@ class Thread; class Mutex final : public WaitObject { public: - /** - * Creates a mutex. - * @param initial_locked Specifies if the mutex should be locked initially - * @param name Optional name of mutex - * @return Pointer to new Mutex object - */ - static SharedPtr Create(bool initial_locked, std::string name = "Unknown"); - std::string GetTypeName() const override { return "Mutex"; } @@ -61,8 +53,10 @@ public: ResultCode Release(Thread* thread); private: - Mutex(); + explicit Mutex(KernelSystem& kernel); ~Mutex() override; + + friend class KernelSystem; }; /** diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp index 48bc80fb2..f9ca68218 100644 --- a/src/core/hle/kernel/object.cpp +++ b/src/core/hle/kernel/object.cpp @@ -3,10 +3,13 @@ // Refer to the license.txt file included. #include "common/assert.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/object.h" namespace Kernel { +Object::Object(KernelSystem& kernel) : object_id{kernel.GenerateObjectID()} {} + Object::~Object() = default; bool Object::IsWaitable() const { diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index fbacf9359..f1fd03295 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h @@ -6,13 +6,13 @@ #include #include - -#include - #include "common/common_types.h" +#include "core/hle/kernel/kernel.h" namespace Kernel { +class KernelSystem; + using Handle = u32; enum class HandleType : u32 { @@ -37,14 +37,9 @@ enum { DEFAULT_STACK_SIZE = 0x4000, }; -enum class ResetType { - OneShot, - Sticky, - Pulse, -}; - class Object : NonCopyable { public: + explicit Object(KernelSystem& kernel); virtual ~Object(); /// Returns a unique identifier for the object. For debugging purposes only. @@ -66,15 +61,12 @@ public: */ bool IsWaitable() const; -public: - static std::atomic next_object_id; - private: friend void intrusive_ptr_add_ref(Object*); friend void intrusive_ptr_release(Object*); std::atomic ref_count{0}; - std::atomic object_id{next_object_id++}; + std::atomic object_id; }; // Special functions used by boost::instrusive_ptr to do automatic ref-counting @@ -88,9 +80,6 @@ inline void intrusive_ptr_release(Object* object) { } } -template -using SharedPtr = boost::intrusive_ptr; - /** * Attempts to downcast the given Object pointer to a pointer to T. * @return Derived pointer to the object, or `nullptr` if `object` isn't of type T. diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 8f3efe5d9..ae799d15f 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -20,8 +20,8 @@ namespace Kernel { // Lists all processes that exist in the current session. static std::vector> process_list; -SharedPtr CodeSet::Create(std::string name, u64 program_id) { - SharedPtr codeset(new CodeSet); +SharedPtr KernelSystem::CreateCodeSet(std::string name, u64 program_id) { + SharedPtr codeset(new CodeSet(*this)); codeset->name = std::move(name); codeset->program_id = program_id; @@ -29,13 +29,13 @@ SharedPtr CodeSet::Create(std::string name, u64 program_id) { return codeset; } -CodeSet::CodeSet() {} +CodeSet::CodeSet(KernelSystem& kernel) : Object(kernel) {} CodeSet::~CodeSet() {} u32 Process::next_process_id; -SharedPtr Process::Create(SharedPtr code_set) { - SharedPtr process(new Process); +SharedPtr KernelSystem::CreateProcess(SharedPtr code_set) { + SharedPtr process(new Process(*this)); process->codeset = std::move(code_set); process->flags.raw = 0; @@ -155,7 +155,7 @@ void Process::Run(s32 main_thread_priority, u32 stack_size) { status = ProcessStatus::Running; vm_manager.LogLayout(Log::Level::Debug); - Kernel::SetupMainThread(codeset->entrypoint, main_thread_priority, this); + Kernel::SetupMainThread(kernel, codeset->entrypoint, main_thread_priority, this); } VAddr Process::GetLinearHeapAreaAddress() const { @@ -304,7 +304,7 @@ ResultCode Process::LinearFree(VAddr target, u32 size) { return RESULT_SUCCESS; } -Kernel::Process::Process() {} +Kernel::Process::Process(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} Kernel::Process::~Process() {} void ClearProcessList() { diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 1081be063..a141dff4c 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -26,12 +26,6 @@ struct AddressMapping { bool unk_flag; }; -enum class MemoryRegion : u16 { - APPLICATION = 1, - SYSTEM = 2, - BASE = 3, -}; - union ProcessFlags { u16 raw; @@ -62,8 +56,6 @@ struct CodeSet final : public Object { u32 size = 0; }; - static SharedPtr Create(std::string name, u64 program_id); - std::string GetTypeName() const override { return "CodeSet"; } @@ -111,14 +103,14 @@ struct CodeSet final : public Object { u64 program_id; private: - CodeSet(); + explicit CodeSet(KernelSystem& kernel); ~CodeSet() override; + + friend class KernelSystem; }; class Process final : public Object { public: - static SharedPtr Create(SharedPtr code_set); - std::string GetTypeName() const override { return "Process"; } @@ -201,8 +193,11 @@ public: ResultCode LinearFree(VAddr target, u32 size); private: - Process(); + explicit Process(Kernel::KernelSystem& kernel); ~Process() override; + + friend class KernelSystem; + KernelSystem& kernel; }; void ClearProcessList(); diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp index ffe9f5108..3498acb23 100644 --- a/src/core/hle/kernel/resource_limit.cpp +++ b/src/core/hle/kernel/resource_limit.cpp @@ -9,19 +9,17 @@ namespace Kernel { -static SharedPtr resource_limits[4]; - -ResourceLimit::ResourceLimit() {} +ResourceLimit::ResourceLimit(KernelSystem& kernel) : Object(kernel) {} ResourceLimit::~ResourceLimit() {} -SharedPtr ResourceLimit::Create(std::string name) { - SharedPtr resource_limit(new ResourceLimit); +SharedPtr ResourceLimit::Create(KernelSystem& kernel, std::string name) { + SharedPtr resource_limit(new ResourceLimit(kernel)); resource_limit->name = std::move(name); return resource_limit; } -SharedPtr ResourceLimit::GetForCategory(ResourceLimitCategory category) { +SharedPtr ResourceLimitList::GetForCategory(ResourceLimitCategory category) { switch (category) { case ResourceLimitCategory::APPLICATION: case ResourceLimitCategory::SYS_APPLET: @@ -90,10 +88,10 @@ u32 ResourceLimit::GetMaxResourceValue(u32 resource) const { } } -void ResourceLimitsInit() { +ResourceLimitList::ResourceLimitList(KernelSystem& kernel) { // Create the four resource limits that the system uses // Create the APPLICATION resource limit - SharedPtr resource_limit = ResourceLimit::Create("Applications"); + SharedPtr resource_limit = ResourceLimit::Create(kernel, "Applications"); resource_limit->max_priority = 0x18; resource_limit->max_commit = 0x4000000; resource_limit->max_threads = 0x20; @@ -107,7 +105,7 @@ void ResourceLimitsInit() { resource_limits[static_cast(ResourceLimitCategory::APPLICATION)] = resource_limit; // Create the SYS_APPLET resource limit - resource_limit = ResourceLimit::Create("System Applets"); + resource_limit = ResourceLimit::Create(kernel, "System Applets"); resource_limit->max_priority = 0x4; resource_limit->max_commit = 0x5E00000; resource_limit->max_threads = 0x1D; @@ -121,7 +119,7 @@ void ResourceLimitsInit() { resource_limits[static_cast(ResourceLimitCategory::SYS_APPLET)] = resource_limit; // Create the LIB_APPLET resource limit - resource_limit = ResourceLimit::Create("Library Applets"); + resource_limit = ResourceLimit::Create(kernel, "Library Applets"); resource_limit->max_priority = 0x4; resource_limit->max_commit = 0x600000; resource_limit->max_threads = 0xE; @@ -135,7 +133,7 @@ void ResourceLimitsInit() { resource_limits[static_cast(ResourceLimitCategory::LIB_APPLET)] = resource_limit; // Create the OTHER resource limit - resource_limit = ResourceLimit::Create("Others"); + resource_limit = ResourceLimit::Create(kernel, "Others"); resource_limit->max_priority = 0x4; resource_limit->max_commit = 0x2180000; resource_limit->max_threads = 0xE1; @@ -149,6 +147,6 @@ void ResourceLimitsInit() { resource_limits[static_cast(ResourceLimitCategory::OTHER)] = resource_limit; } -void ResourceLimitsShutdown() {} +ResourceLimitList::~ResourceLimitList() = default; } // namespace Kernel diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h index 7d6e8611d..3b8b79d0c 100644 --- a/src/core/hle/kernel/resource_limit.h +++ b/src/core/hle/kernel/resource_limit.h @@ -4,6 +4,7 @@ #pragma once +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" @@ -34,14 +35,7 @@ public: /** * Creates a resource limit object. */ - static SharedPtr Create(std::string name = "Unknown"); - - /** - * Retrieves the resource limit associated with the specified resource limit category. - * @param category The resource limit category - * @returns The resource limit associated with the category - */ - static SharedPtr GetForCategory(ResourceLimitCategory category); + static SharedPtr Create(KernelSystem& kernel, std::string name = "Unknown"); std::string GetTypeName() const override { return "ResourceLimit"; @@ -113,14 +107,24 @@ public: s32 current_cpu_time = 0; private: - ResourceLimit(); + explicit ResourceLimit(KernelSystem& kernel); ~ResourceLimit() override; }; -/// Initializes the resource limits -void ResourceLimitsInit(); +class ResourceLimitList { +public: + explicit ResourceLimitList(KernelSystem& kernel); + ~ResourceLimitList(); -// Destroys the resource limits -void ResourceLimitsShutdown(); + /** + * Retrieves the resource limit associated with the specified resource limit category. + * @param category The resource limit category + * @returns The resource limit associated with the category + */ + SharedPtr GetForCategory(ResourceLimitCategory category); + +private: + std::array, 4> resource_limits; +}; } // namespace Kernel diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp index 4ec1669ba..8193f848d 100644 --- a/src/core/hle/kernel/semaphore.cpp +++ b/src/core/hle/kernel/semaphore.cpp @@ -10,16 +10,16 @@ namespace Kernel { -Semaphore::Semaphore() {} +Semaphore::Semaphore(KernelSystem& kernel) : WaitObject(kernel) {} Semaphore::~Semaphore() {} -ResultVal> Semaphore::Create(s32 initial_count, s32 max_count, - std::string name) { +ResultVal> KernelSystem::CreateSemaphore(s32 initial_count, s32 max_count, + std::string name) { if (initial_count > max_count) return ERR_INVALID_COMBINATION_KERNEL; - SharedPtr semaphore(new Semaphore); + SharedPtr semaphore(new Semaphore(*this)); // When the semaphore is created, some slots are reserved for other threads, // and the rest is reserved for the caller thread diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h index 6019b09a2..7303ee7d1 100644 --- a/src/core/hle/kernel/semaphore.h +++ b/src/core/hle/kernel/semaphore.h @@ -15,16 +15,6 @@ namespace Kernel { class Semaphore final : public WaitObject { public: - /** - * Creates a semaphore. - * @param initial_count Number of slots reserved for other threads - * @param max_count Maximum number of slots the semaphore can have - * @param name Optional name of semaphore - * @return The created semaphore - */ - static ResultVal> Create(s32 initial_count, s32 max_count, - std::string name = "Unknown"); - std::string GetTypeName() const override { return "Semaphore"; } @@ -52,8 +42,10 @@ public: ResultVal Release(s32 release_count); private: - Semaphore(); + explicit Semaphore(KernelSystem& kernel); ~Semaphore() override; + + friend class KernelSystem; }; } // namespace Kernel diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index 7b6211fd8..e17e699a4 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -13,7 +13,7 @@ namespace Kernel { -ServerPort::ServerPort() {} +ServerPort::ServerPort(KernelSystem& kernel) : WaitObject(kernel) {} ServerPort::~ServerPort() {} ResultVal> ServerPort::Accept() { @@ -35,11 +35,11 @@ void ServerPort::Acquire(Thread* thread) { ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); } -std::tuple, SharedPtr> ServerPort::CreatePortPair( +std::tuple, SharedPtr> KernelSystem::CreatePortPair( u32 max_sessions, std::string name) { - SharedPtr server_port(new ServerPort); - SharedPtr client_port(new ClientPort); + SharedPtr server_port(new ServerPort(*this)); + SharedPtr client_port(new ClientPort(*this)); server_port->name = name + "_Server"; client_port->name = name + "_Client"; diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h index 6d458b188..ee09efba1 100644 --- a/src/core/hle/kernel/server_port.h +++ b/src/core/hle/kernel/server_port.h @@ -20,16 +20,6 @@ class SessionRequestHandler; class ServerPort final : public WaitObject { public: - /** - * Creates a pair of ServerPort and an associated ClientPort. - * - * @param max_sessions Maximum number of sessions to the port - * @param name Optional name of the ports - * @return The created port tuple - */ - static std::tuple, SharedPtr> CreatePortPair( - u32 max_sessions, std::string name = "UnknownPort"); - std::string GetTypeName() const override { return "ServerPort"; } @@ -69,8 +59,10 @@ public: void Acquire(Thread* thread) override; private: - ServerPort(); + explicit ServerPort(KernelSystem& kernel); ~ServerPort() override; + + friend class KernelSystem; }; } // namespace Kernel diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 71f702b9e..83e2ec4fa 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -13,7 +13,7 @@ namespace Kernel { -ServerSession::ServerSession() = default; +ServerSession::ServerSession(KernelSystem& kernel) : WaitObject(kernel) {} ServerSession::~ServerSession() { // This destructor will be called automatically when the last ServerSession handle is closed by // the emulated application. @@ -28,8 +28,8 @@ ServerSession::~ServerSession() { parent->server = nullptr; } -ResultVal> ServerSession::Create(std::string name) { - SharedPtr server_session(new ServerSession); +ResultVal> ServerSession::Create(KernelSystem& kernel, std::string name) { + SharedPtr server_session(new ServerSession(kernel)); server_session->name = std::move(name); server_session->parent = nullptr; @@ -100,10 +100,10 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr thread) { return RESULT_SUCCESS; } -ServerSession::SessionPair ServerSession::CreateSessionPair(const std::string& name, - SharedPtr port) { - auto server_session = ServerSession::Create(name + "_Server").Unwrap(); - SharedPtr client_session(new ClientSession); +std::tuple, SharedPtr> KernelSystem::CreateSessionPair( + const std::string& name, SharedPtr port) { + auto server_session = ServerSession::Create(*this, name + "_Server").Unwrap(); + SharedPtr client_session(new ClientSession(*this)); client_session->name = name + "_Client"; std::shared_ptr parent(new Session); diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index c739bae5e..18411e417 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -48,17 +48,6 @@ public: return HANDLE_TYPE; } - using SessionPair = std::tuple, SharedPtr>; - - /** - * Creates a pair of ServerSession and an associated ClientSession. - * @param name Optional name of the ports. - * @param client_port Optional The ClientPort that spawned this session. - * @return The created session tuple - */ - static SessionPair CreateSessionPair(const std::string& name = "Unknown", - SharedPtr client_port = nullptr); - /** * Sets the HLE handler for the session. This handler will be called to service IPC requests * instead of the regular IPC machinery. (The regular IPC machinery is currently not @@ -95,16 +84,20 @@ public: SharedPtr currently_handling; private: - ServerSession(); + explicit ServerSession(KernelSystem& kernel); ~ServerSession() override; /** * Creates a server session. The server session can have an optional HLE handler, * which will be invoked to handle the IPC requests that this session receives. + * @param kernel The kernel instance to create the server session on * @param name Optional name of the server session. * @return The created server session */ - static ResultVal> Create(std::string name = "Unknown"); + static ResultVal> Create(KernelSystem& kernel, + std::string name = "Unknown"); + + friend class KernelSystem; }; } // namespace Kernel diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index f5b9dad2c..35bd53003 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -11,14 +11,15 @@ namespace Kernel { -SharedMemory::SharedMemory() {} +SharedMemory::SharedMemory(KernelSystem& kernel) : Object(kernel) {} SharedMemory::~SharedMemory() {} -SharedPtr SharedMemory::Create(SharedPtr owner_process, u32 size, - MemoryPermission permissions, - MemoryPermission other_permissions, VAddr address, - MemoryRegion region, std::string name) { - SharedPtr shared_memory(new SharedMemory); +SharedPtr KernelSystem::CreateSharedMemory(SharedPtr owner_process, u32 size, + MemoryPermission permissions, + MemoryPermission other_permissions, + VAddr address, MemoryRegion region, + std::string name) { + SharedPtr shared_memory(new SharedMemory(*this)); shared_memory->owner_process = owner_process; shared_memory->name = std::move(name); @@ -74,12 +75,10 @@ SharedPtr SharedMemory::Create(SharedPtr owner_process, u return shared_memory; } -SharedPtr SharedMemory::CreateForApplet(std::shared_ptr> heap_block, - u32 offset, u32 size, - MemoryPermission permissions, - MemoryPermission other_permissions, - std::string name) { - SharedPtr shared_memory(new SharedMemory); +SharedPtr KernelSystem::CreateSharedMemoryForApplet( + std::shared_ptr> heap_block, u32 offset, u32 size, MemoryPermission permissions, + MemoryPermission other_permissions, std::string name) { + SharedPtr shared_memory(new SharedMemory(*this)); shared_memory->owner_process = nullptr; shared_memory->name = std::move(name); diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 5ccd81572..d5d862927 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -12,55 +12,8 @@ namespace Kernel { -/// Permissions for mapped shared memory blocks -enum class MemoryPermission : u32 { - None = 0, - Read = (1u << 0), - Write = (1u << 1), - ReadWrite = (Read | Write), - Execute = (1u << 2), - ReadExecute = (Read | Execute), - WriteExecute = (Write | Execute), - ReadWriteExecute = (Read | Write | Execute), - DontCare = (1u << 28) -}; - class SharedMemory final : public Object { public: - /** - * Creates a shared memory object. - * @param owner_process Process that created this shared memory object. - * @param size Size of the memory block. Must be page-aligned. - * @param permissions Permission restrictions applied to the process which created the block. - * @param other_permissions Permission restrictions applied to other processes mapping the - * block. - * @param address The address from which to map the Shared Memory. - * @param region If the address is 0, the shared memory will be allocated in this region of the - * linear heap. - * @param name Optional object name, used for debugging purposes. - */ - static SharedPtr Create(SharedPtr owner_process, u32 size, - MemoryPermission permissions, - MemoryPermission other_permissions, VAddr address = 0, - MemoryRegion region = MemoryRegion::BASE, - std::string name = "Unknown"); - - /** - * Creates a shared memory object from a block of memory managed by an HLE applet. - * @param heap_block Heap block of the HLE applet. - * @param offset The offset into the heap block that the SharedMemory will map. - * @param size Size of the memory block. Must be page-aligned. - * @param permissions Permission restrictions applied to the process which created the block. - * @param other_permissions Permission restrictions applied to other processes mapping the - * block. - * @param name Optional object name, used for debugging purposes. - */ - static SharedPtr CreateForApplet(std::shared_ptr> heap_block, - u32 offset, u32 size, - MemoryPermission permissions, - MemoryPermission other_permissions, - std::string name = "Unknown Applet"); - std::string GetTypeName() const override { return "SharedMemory"; } @@ -125,8 +78,10 @@ public: std::string name; private: - SharedMemory(); + explicit SharedMemory(KernelSystem& kernel); ~SharedMemory() override; + + friend class KernelSystem; }; } // namespace Kernel diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index a5889d6c8..3e292bd3b 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -615,7 +615,7 @@ static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_ /// Create an address arbiter (to allocate access to shared resources) static ResultCode CreateAddressArbiter(Handle* out_handle) { - SharedPtr arbiter = AddressArbiter::Create(); + SharedPtr arbiter = Core::System::GetInstance().Kernel().CreateAddressArbiter(); CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(arbiter))); LOG_TRACE(Kernel_SVC, "returned handle=0x{:08X}", *out_handle); return RESULT_SUCCESS; @@ -761,9 +761,9 @@ static ResultCode CreateThread(Handle* out_handle, u32 priority, u32 entry_point break; } - CASCADE_RESULT(SharedPtr thread, - Thread::Create(name, entry_point, priority, arg, processor_id, stack_top, - g_current_process)); + CASCADE_RESULT(SharedPtr thread, Core::System::GetInstance().Kernel().CreateThread( + name, entry_point, priority, arg, processor_id, + stack_top, g_current_process)); thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO); // 0x03C00000 @@ -828,7 +828,7 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) { /// Create a mutex static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) { - SharedPtr mutex = Mutex::Create(initial_locked != 0); + SharedPtr mutex = Core::System::GetInstance().Kernel().CreateMutex(initial_locked != 0); mutex->name = fmt::format("mutex-{:08x}", Core::CPU().GetReg(14)); CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(mutex))); @@ -891,7 +891,8 @@ static ResultCode GetThreadId(u32* thread_id, Handle handle) { /// Creates a semaphore static ResultCode CreateSemaphore(Handle* out_handle, s32 initial_count, s32 max_count) { - CASCADE_RESULT(SharedPtr semaphore, Semaphore::Create(initial_count, max_count)); + CASCADE_RESULT(SharedPtr semaphore, + Core::System::GetInstance().Kernel().CreateSemaphore(initial_count, max_count)); semaphore->name = fmt::format("semaphore-{:08x}", Core::CPU().GetReg(14)); CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(semaphore))); @@ -942,8 +943,8 @@ static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, u32 /// Create an event static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) { - SharedPtr evt = Event::Create(static_cast(reset_type), - fmt::format("event-{:08x}", Core::CPU().GetReg(14))); + SharedPtr evt = Core::System::GetInstance().Kernel().CreateEvent( + static_cast(reset_type), fmt::format("event-{:08x}", Core::CPU().GetReg(14))); CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(evt))); LOG_TRACE(Kernel_SVC, "called reset_type=0x{:08X} : created handle=0x{:08X}", reset_type, @@ -985,8 +986,8 @@ static ResultCode ClearEvent(Handle handle) { /// Creates a timer static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) { - SharedPtr timer = Timer::Create(static_cast(reset_type), - fmt ::format("timer-{:08x}", Core::CPU().GetReg(14))); + SharedPtr timer = Core::System::GetInstance().Kernel().CreateTimer( + static_cast(reset_type), fmt ::format("timer-{:08x}", Core::CPU().GetReg(14))); CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(timer))); LOG_TRACE(Kernel_SVC, "called reset_type=0x{:08X} : created handle=0x{:08X}", reset_type, @@ -1104,9 +1105,9 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 if (addr == 0 && g_current_process->flags.shared_device_mem) region = g_current_process->flags.memory_region; - shared_memory = - SharedMemory::Create(g_current_process, size, static_cast(my_permission), - static_cast(other_permission), addr, region); + shared_memory = Core::System::GetInstance().Kernel().CreateSharedMemory( + g_current_process, size, static_cast(my_permission), + static_cast(other_permission), addr, region); CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(shared_memory))); LOG_WARNING(Kernel_SVC, "called addr=0x{:08X}", addr); @@ -1118,7 +1119,7 @@ static ResultCode CreatePort(Handle* server_port, Handle* client_port, VAddr nam // TODO(Subv): Implement named ports. ASSERT_MSG(name_address == 0, "Named ports are currently unimplemented"); - auto ports = ServerPort::CreatePortPair(max_sessions); + auto ports = Core::System::GetInstance().Kernel().CreatePortPair(max_sessions); CASCADE_RESULT(*client_port, g_handle_table.Create(std::move(std::get>(ports)))); // Note: The 3DS kernel also leaks the client port handle if the server port handle fails to be @@ -1141,7 +1142,7 @@ static ResultCode CreateSessionToPort(Handle* out_client_session, Handle client_ } static ResultCode CreateSession(Handle* server_session, Handle* client_session) { - auto sessions = ServerSession::CreateSessionPair(); + auto sessions = Core::System::GetInstance().Kernel().CreateSessionPair(); auto& server = std::get>(sessions); CASCADE_RESULT(*server_session, g_handle_table.Create(std::move(server))); diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 50fa061c4..6844e76d5 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -60,7 +60,7 @@ inline static u32 const NewThreadId() { return next_thread_id++; } -Thread::Thread() : context(Core::CPU().NewContext()) {} +Thread::Thread(KernelSystem& kernel) : WaitObject(kernel), context(Core::CPU().NewContext()) {} Thread::~Thread() {} Thread* GetCurrentThread() { @@ -320,9 +320,10 @@ static void ResetThreadContext(const std::unique_ptrSetCpsr(USER32MODE | ((entry_point & 1) << 5)); // Usermode and THUMB mode } -ResultVal> Thread::Create(std::string name, VAddr entry_point, u32 priority, - u32 arg, s32 processor_id, VAddr stack_top, - SharedPtr owner_process) { +ResultVal> KernelSystem::CreateThread(std::string name, VAddr entry_point, + u32 priority, u32 arg, s32 processor_id, + VAddr stack_top, + SharedPtr owner_process) { // Check if priority is in ranged. Lowest priority -> highest priority id. if (priority > ThreadPrioLowest) { LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority); @@ -343,7 +344,7 @@ ResultVal> Thread::Create(std::string name, VAddr entry_point, ErrorSummary::InvalidArgument, ErrorLevel::Permanent); } - SharedPtr thread(new Thread); + SharedPtr thread(new Thread(*this)); thread_list.push_back(thread); ready_queue.prepare(priority); @@ -443,11 +444,12 @@ void Thread::BoostPriority(u32 priority) { current_priority = priority; } -SharedPtr SetupMainThread(u32 entry_point, u32 priority, SharedPtr owner_process) { +SharedPtr SetupMainThread(KernelSystem& kernel, u32 entry_point, u32 priority, + SharedPtr owner_process) { // Initialize new "main" thread auto thread_res = - Thread::Create("main", entry_point, priority, 0, owner_process->ideal_processor, - Memory::HEAP_VADDR_END, owner_process); + kernel.CreateThread("main", entry_point, priority, 0, owner_process->ideal_processor, + Memory::HEAP_VADDR_END, owner_process); SharedPtr thread = std::move(thread_res).Unwrap(); diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 3fd72563f..9e6a22759 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -55,21 +55,6 @@ enum class ThreadWakeupReason { class Thread final : public WaitObject { public: - /** - * Creates and returns a new thread. The new thread is immediately scheduled - * @param name The friendly name desired for the thread - * @param entry_point The address at which the thread should start execution - * @param priority The thread's priority - * @param arg User data to pass to the thread - * @param processor_id The ID(s) of the processors on which the thread is desired to be run - * @param stack_top The address of the thread's stack top - * @param owner_process The parent process for the thread - * @return A shared pointer to the newly created thread - */ - static ResultVal> Create(std::string name, VAddr entry_point, u32 priority, - u32 arg, s32 processor_id, VAddr stack_top, - SharedPtr owner_process); - std::string GetName() const override { return name; } @@ -225,18 +210,22 @@ public: std::function wakeup_callback; private: - Thread(); + explicit Thread(KernelSystem&); ~Thread() override; + + friend class KernelSystem; }; /** * Sets up the primary application thread + * @param kernel The kernel instance on which the thread is created * @param entry_point The address at which the thread should start execution * @param priority The priority to give the main thread * @param owner_process The parent process for the main thread * @return A shared pointer to the main thread */ -SharedPtr SetupMainThread(u32 entry_point, u32 priority, SharedPtr owner_process); +SharedPtr SetupMainThread(KernelSystem& kernel, u32 entry_point, u32 priority, + SharedPtr owner_process); /** * Returns whether there are any threads that are ready to run. diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index f1965365c..8ef96e058 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -19,11 +19,11 @@ static CoreTiming::EventType* timer_callback_event_type = nullptr; // us to simply use a pool index or similar. static Kernel::HandleTable timer_callback_handle_table; -Timer::Timer() {} +Timer::Timer(KernelSystem& kernel) : WaitObject(kernel) {} Timer::~Timer() {} -SharedPtr Timer::Create(ResetType reset_type, std::string name) { - SharedPtr timer(new Timer); +SharedPtr KernelSystem::CreateTimer(ResetType reset_type, std::string name) { + SharedPtr timer(new Timer(*this)); timer->reset_type = reset_type; timer->signaled = false; diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index 6607f6058..c039bb4f1 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h @@ -12,14 +12,6 @@ namespace Kernel { class Timer final : public WaitObject { public: - /** - * Creates a timer - * @param reset_type ResetType describing how to create the timer - * @param name Optional name of timer - * @return The created Timer - */ - static SharedPtr Create(ResetType reset_type, std::string name = "Unknown"); - std::string GetTypeName() const override { return "Timer"; } @@ -68,7 +60,7 @@ public: void Signal(s64 cycles_late); private: - Timer(); + explicit Timer(KernelSystem& kernel); ~Timer() override; ResetType reset_type; ///< The ResetType of this timer @@ -81,6 +73,8 @@ private: /// Handle used as userdata to reference this object when inserting into the CoreTiming queue. Handle callback_handle; + + friend class KernelSystem; }; /// Initializes the required variables for timers diff --git a/src/core/hle/kernel/wait_object.h b/src/core/hle/kernel/wait_object.h index 2b9a9393b..01fc40a0d 100644 --- a/src/core/hle/kernel/wait_object.h +++ b/src/core/hle/kernel/wait_object.h @@ -16,6 +16,8 @@ class Thread; /// Class that represents a Kernel object that a thread can be waiting on class WaitObject : public Object { public: + using Object::Object; + /** * Check if the specified thread should wait until the object is available * @param thread The thread about which we're deciding. diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 35e3c0ad9..972c826a9 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -1026,8 +1026,8 @@ void Module::Interface::BeginImportProgram(Kernel::HLERequestContext& ctx) { // Create our CIAFile handle for the app to write to, and while the app writes // Citra will store contents out to sdmc/nand const FileSys::Path cia_path = {}; - auto file = - std::make_shared(std::make_unique(media_type), cia_path); + auto file = std::make_shared( + am->system, std::make_unique(media_type), cia_path); am->cia_installing = true; @@ -1053,8 +1053,8 @@ void Module::Interface::BeginImportProgramTemporarily(Kernel::HLERequestContext& // Create our CIAFile handle for the app to write to, and while the app writes Citra will store // contents out to sdmc/nand const FileSys::Path cia_path = {}; - auto file = std::make_shared(std::make_unique(FS::MediaType::NAND), - cia_path); + auto file = std::make_shared( + am->system, std::make_unique(FS::MediaType::NAND), cia_path); am->cia_installing = true; @@ -1455,16 +1455,16 @@ void Module::Interface::GetMetaDataFromCia(Kernel::HLERequestContext& ctx) { rb.PushMappedBuffer(output_buffer); } -Module::Module() { +Module::Module(Core::System& system) : system(system) { ScanForAllTitles(); - system_updater_mutex = Kernel::Mutex::Create(false, "AM::SystemUpdaterMutex"); + system_updater_mutex = system.Kernel().CreateMutex(false, "AM::SystemUpdaterMutex"); } Module::~Module() = default; void InstallInterfaces(Core::System& system) { auto& service_manager = system.ServiceManager(); - auto am = std::make_shared(); + auto am = std::make_shared(system); std::make_shared(am)->InstallAsService(service_manager); std::make_shared(am)->InstallAsService(service_manager); std::make_shared(am)->InstallAsService(service_manager); diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 543dbd8fe..e00e16abd 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -149,7 +149,7 @@ std::string GetMediaTitlePath(Service::FS::MediaType media_type); class Module final { public: - Module(); + explicit Module(Core::System& system); ~Module(); class Interface : public ServiceFramework { @@ -573,6 +573,7 @@ private: */ void ScanForAllTitles(); + Core::System& system; bool cia_installing = false; std::array, 3> am_title_list; Kernel::SharedPtr system_updater_mutex; diff --git a/src/core/hle/service/apt/applet_manager.cpp b/src/core/hle/service/apt/applet_manager.cpp index 1abf1e521..bc02c5eb6 100644 --- a/src/core/hle/service/apt/applet_manager.cpp +++ b/src/core/hle/service/apt/applet_manager.cpp @@ -572,9 +572,9 @@ AppletManager::AppletManager(Core::System& system) : system(system) { slot_data.registered = false; slot_data.loaded = false; slot_data.notification_event = - Kernel::Event::Create(Kernel::ResetType::OneShot, "APT:Notification"); + system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "APT:Notification"); slot_data.parameter_event = - Kernel::Event::Create(Kernel::ResetType::OneShot, "APT:Parameter"); + system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "APT:Parameter"); } HLE::Applets::Init(); } diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index a673fe97e..13c278158 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -855,11 +855,11 @@ Module::Module(Core::System& system) : system(system) { using Kernel::MemoryPermission; shared_font_mem = - Kernel::SharedMemory::Create(nullptr, 0x332000, // 3272 KB - MemoryPermission::ReadWrite, MemoryPermission::Read, 0, - Kernel::MemoryRegion::SYSTEM, "APT:SharedFont"); + system.Kernel().CreateSharedMemory(nullptr, 0x332000, // 3272 KB + MemoryPermission::ReadWrite, MemoryPermission::Read, 0, + Kernel::MemoryRegion::SYSTEM, "APT:SharedFont"); - lock = Kernel::Mutex::Create(false, "APT_U:Lock"); + lock = system.Kernel().CreateMutex(false, "APT_U:Lock"); } Module::~Module() {} diff --git a/src/core/hle/service/boss/boss.cpp b/src/core/hle/service/boss/boss.cpp index 8dd21ab3b..63df57427 100644 --- a/src/core/hle/service/boss/boss.cpp +++ b/src/core/hle/service/boss/boss.cpp @@ -903,15 +903,16 @@ void Module::Interface::GetNsDataNewFlagPrivileged(Kernel::HLERequestContext& ct Module::Interface::Interface(std::shared_ptr boss, const char* name, u32 max_session) : ServiceFramework(name, max_session), boss(std::move(boss)) {} -Module::Module() { +Module::Module(Core::System& system) { using namespace Kernel; // TODO: verify ResetType - task_finish_event = Event::Create(Kernel::ResetType::OneShot, "BOSS::task_finish_event"); + task_finish_event = + system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "BOSS::task_finish_event"); } void InstallInterfaces(Core::System& system) { auto& service_manager = system.ServiceManager(); - auto boss = std::make_shared(); + auto boss = std::make_shared(system); std::make_shared(boss)->InstallAsService(service_manager); std::make_shared(boss)->InstallAsService(service_manager); } diff --git a/src/core/hle/service/boss/boss.h b/src/core/hle/service/boss/boss.h index 222f88066..15a41746e 100644 --- a/src/core/hle/service/boss/boss.h +++ b/src/core/hle/service/boss/boss.h @@ -15,7 +15,7 @@ namespace Service::BOSS { class Module final { public: - Module(); + explicit Module(Core::System& system); ~Module() = default; class Interface : public ServiceFramework { diff --git a/src/core/hle/service/cam/cam.cpp b/src/core/hle/service/cam/cam.cpp index 99dad6980..21ae00f49 100644 --- a/src/core/hle/service/cam/cam.cpp +++ b/src/core/hle/service/cam/cam.cpp @@ -1019,14 +1019,15 @@ void Module::Interface::DriverFinalize(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_CAM, "called"); } -Module::Module() { +Module::Module(Core::System& system) { using namespace Kernel; for (PortConfig& port : ports) { - port.completion_event = Event::Create(ResetType::Sticky, "CAM::completion_event"); + port.completion_event = + system.Kernel().CreateEvent(ResetType::Sticky, "CAM::completion_event"); port.buffer_error_interrupt_event = - Event::Create(ResetType::OneShot, "CAM::buffer_error_interrupt_event"); + system.Kernel().CreateEvent(ResetType::OneShot, "CAM::buffer_error_interrupt_event"); port.vsync_interrupt_event = - Event::Create(ResetType::OneShot, "CAM::vsync_interrupt_event"); + system.Kernel().CreateEvent(ResetType::OneShot, "CAM::vsync_interrupt_event"); } completion_event_callback = CoreTiming::RegisterEvent( "CAM::CompletionEventCallBack", @@ -1061,7 +1062,7 @@ std::shared_ptr GetModule(Core::System& system) { void InstallInterfaces(Core::System& system) { auto& service_manager = system.ServiceManager(); - auto cam = std::make_shared(); + auto cam = std::make_shared(system); std::make_shared(cam)->InstallAsService(service_manager); std::make_shared(cam)->InstallAsService(service_manager); diff --git a/src/core/hle/service/cam/cam.h b/src/core/hle/service/cam/cam.h index 401a2a203..4f608fc8e 100644 --- a/src/core/hle/service/cam/cam.h +++ b/src/core/hle/service/cam/cam.h @@ -241,7 +241,7 @@ static_assert(sizeof(PackageParameterWithContextDetail) == 28, class Module final { public: - Module(); + explicit Module(Core::System& system); ~Module(); void ReloadCameraDevices(); diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index 451a5ce84..f2759e7fc 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -1351,10 +1351,11 @@ Module::SessionData::~SessionData() { Module::Interface::Interface(std::shared_ptr cecd, const char* name, u32 max_session) : ServiceFramework(name, max_session), cecd(std::move(cecd)) {} -Module::Module() { +Module::Module(Core::System& system) { using namespace Kernel; - cecinfo_event = Event::Create(Kernel::ResetType::OneShot, "CECD::cecinfo_event"); - change_state_event = Event::Create(Kernel::ResetType::OneShot, "CECD::change_state_event"); + cecinfo_event = system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "CECD::cecinfo_event"); + change_state_event = + system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "CECD::change_state_event"); std::string nand_directory = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir); FileSys::ArchiveFactory_SystemSaveData systemsavedata_factory(nand_directory); @@ -1433,7 +1434,7 @@ Module::~Module() = default; void InstallInterfaces(Core::System& system) { auto& service_manager = system.ServiceManager(); - auto cecd = std::make_shared(); + auto cecd = std::make_shared(system); std::make_shared(cecd)->InstallAsService(service_manager); std::make_shared(cecd)->InstallAsService(service_manager); std::make_shared(cecd)->InstallAsService(service_manager); diff --git a/src/core/hle/service/cecd/cecd.h b/src/core/hle/service/cecd/cecd.h index 929f0f397..3102bc318 100644 --- a/src/core/hle/service/cecd/cecd.h +++ b/src/core/hle/service/cecd/cecd.h @@ -23,7 +23,7 @@ namespace Service::CECD { class Module final { public: - Module(); + explicit Module(Core::System& system); ~Module(); enum class CecCommand : u32 { diff --git a/src/core/hle/service/csnd/csnd_snd.cpp b/src/core/hle/service/csnd/csnd_snd.cpp index 6e0488b3a..ec4f55c0d 100644 --- a/src/core/hle/service/csnd/csnd_snd.cpp +++ b/src/core/hle/service/csnd/csnd_snd.cpp @@ -19,10 +19,10 @@ void CSND_SND::Initialize(Kernel::HLERequestContext& ctx) { const u32 offset3 = rp.Pop(); using Kernel::MemoryPermission; - mutex = Kernel::Mutex::Create(false, "CSND:mutex"); - shared_memory = Kernel::SharedMemory::Create(nullptr, size, MemoryPermission::ReadWrite, - MemoryPermission::ReadWrite, 0, - Kernel::MemoryRegion::BASE, "CSND:SharedMemory"); + mutex = system.Kernel().CreateMutex(false, "CSND:mutex"); + shared_memory = system.Kernel().CreateSharedMemory( + nullptr, size, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, 0, + Kernel::MemoryRegion::BASE, "CSND:SharedMemory"); IPC::RequestBuilder rb = rp.MakeBuilder(1, 3); rb.Push(RESULT_SUCCESS); @@ -173,7 +173,7 @@ void CSND_SND::Reset(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_CSND, "(STUBBED) called"); } -CSND_SND::CSND_SND() : ServiceFramework("csnd:SND", 4) { +CSND_SND::CSND_SND(Core::System& system) : ServiceFramework("csnd:SND", 4), system(system) { static const FunctionInfo functions[] = { // clang-format off {0x00010140, &CSND_SND::Initialize, "Initialize"}, @@ -196,7 +196,7 @@ CSND_SND::CSND_SND() : ServiceFramework("csnd:SND", 4) { void InstallInterfaces(Core::System& system) { auto& service_manager = system.ServiceManager(); - std::make_shared()->InstallAsService(service_manager); + std::make_shared(system)->InstallAsService(service_manager); } } // namespace Service::CSND diff --git a/src/core/hle/service/csnd/csnd_snd.h b/src/core/hle/service/csnd/csnd_snd.h index 909034e6d..94b1bf3bb 100644 --- a/src/core/hle/service/csnd/csnd_snd.h +++ b/src/core/hle/service/csnd/csnd_snd.h @@ -16,7 +16,7 @@ namespace Service::CSND { class CSND_SND final : public ServiceFramework { public: - CSND_SND(); + explicit CSND_SND(Core::System& system); ~CSND_SND() = default; private: @@ -174,6 +174,8 @@ private: }; static_assert(sizeof(Type0Command) == 0x20, "Type0Command structure size is wrong"); + Core::System& system; + Kernel::SharedPtr mutex = nullptr; Kernel::SharedPtr shared_memory = nullptr; diff --git a/src/core/hle/service/dsp/dsp_dsp.cpp b/src/core/hle/service/dsp/dsp_dsp.cpp index fa1ddd4c9..b15e670d3 100644 --- a/src/core/hle/service/dsp/dsp_dsp.cpp +++ b/src/core/hle/service/dsp/dsp_dsp.cpp @@ -350,7 +350,7 @@ bool DSP_DSP::HasTooManyEventsRegistered() const { return number >= max_number_of_interrupt_events; } -DSP_DSP::DSP_DSP() : ServiceFramework("dsp::DSP", DefaultMaxSessions) { +DSP_DSP::DSP_DSP(Core::System& system) : ServiceFramework("dsp::DSP", DefaultMaxSessions) { static const FunctionInfo functions[] = { // clang-format off {0x00010040, &DSP_DSP::RecvData, "RecvData"}, @@ -391,7 +391,8 @@ DSP_DSP::DSP_DSP() : ServiceFramework("dsp::DSP", DefaultMaxSessions) { RegisterHandlers(functions); - semaphore_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "DSP_DSP::semaphore_event"); + semaphore_event = + system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "DSP_DSP::semaphore_event"); } DSP_DSP::~DSP_DSP() { @@ -401,7 +402,7 @@ DSP_DSP::~DSP_DSP() { void InstallInterfaces(Core::System& system) { auto& service_manager = system.ServiceManager(); - auto dsp = std::make_shared(); + auto dsp = std::make_shared(system); dsp->InstallAsService(service_manager); Core::DSP().SetServiceToInterrupt(std::move(dsp)); } diff --git a/src/core/hle/service/dsp/dsp_dsp.h b/src/core/hle/service/dsp/dsp_dsp.h index 506a1f9f4..7226aeeac 100644 --- a/src/core/hle/service/dsp/dsp_dsp.h +++ b/src/core/hle/service/dsp/dsp_dsp.h @@ -17,7 +17,7 @@ namespace Service::DSP { class DSP_DSP final : public ServiceFramework { public: - DSP_DSP(); + explicit DSP_DSP(Core::System& system); ~DSP_DSP(); /// There are three types of interrupts diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp index 9a914ee7b..13b2c7e46 100644 --- a/src/core/hle/service/err_f.cpp +++ b/src/core/hle/service/err_f.cpp @@ -244,7 +244,7 @@ ERR_F::~ERR_F() = default; void InstallInterfaces(Core::System& system) { auto errf = std::make_shared(system); - errf->InstallAsNamedPort(); + errf->InstallAsNamedPort(system.Kernel()); } } // namespace Service::ERR diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 0f2375124..4322f6653 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -87,7 +87,7 @@ ResultVal> ArchiveManager::OpenFileFromArchive(ArchiveHand if (backend.Failed()) return backend.Code(); - auto file = std::shared_ptr(new File(std::move(backend).Unwrap(), path)); + auto file = std::shared_ptr(new File(system, std::move(backend).Unwrap(), path)); return MakeResult>(std::move(file)); } @@ -348,7 +348,7 @@ void ArchiveManager::RegisterSelfNCCH(Loader::AppLoader& app_loader) { factory->Register(app_loader); } -ArchiveManager::ArchiveManager() { +ArchiveManager::ArchiveManager(Core::System& system) : system(system) { RegisterArchiveTypes(); } diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index ef9b9efc2..f335f650d 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -24,6 +24,10 @@ namespace Loader { class AppLoader; } +namespace Core { +class System; +} + namespace Service::FS { /// Supported archive types @@ -50,7 +54,8 @@ using FileSys::ArchiveFactory; class ArchiveManager { public: - ArchiveManager(); + explicit ArchiveManager(Core::System& system); + /** * Opens an archive * @param id_code IdCode of the archive to open @@ -224,6 +229,8 @@ public: void RegisterSelfNCCH(Loader::AppLoader& app_loader); private: + Core::System& system; + /** * Registers an Archive type, instances of which can later be opened using its IdCode. * @param factory File system backend interface to the archive diff --git a/src/core/hle/service/fs/file.cpp b/src/core/hle/service/fs/file.cpp index d2f1f2a85..59635cab8 100644 --- a/src/core/hle/service/fs/file.cpp +++ b/src/core/hle/service/fs/file.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "common/logging/log.h" +#include "core/core.h" #include "core/file_sys/errors.h" #include "core/file_sys/file_backend.h" #include "core/hle/ipc_helpers.h" @@ -14,8 +15,9 @@ namespace Service::FS { -File::File(std::unique_ptr&& backend, const FileSys::Path& path) - : ServiceFramework("", 1), path(path), backend(std::move(backend)) { +File::File(Core::System& system, std::unique_ptr&& backend, + const FileSys::Path& path) + : ServiceFramework("", 1), path(path), backend(std::move(backend)), system(system) { static const FunctionInfo functions[] = { {0x08010100, &File::OpenSubFile, "OpenSubFile"}, {0x080200C2, &File::Read, "Read"}, @@ -195,7 +197,7 @@ void File::OpenLinkFile(Kernel::HLERequestContext& ctx) { using Kernel::SharedPtr; IPC::RequestParser rp(ctx, 0x080C, 0, 0); IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); - auto sessions = ServerSession::CreateSessionPair(GetName()); + auto sessions = system.Kernel().CreateSessionPair(GetName()); auto server = std::get>(sessions); ClientConnected(server); @@ -243,7 +245,7 @@ void File::OpenSubFile(Kernel::HLERequestContext& ctx) { using Kernel::ClientSession; using Kernel::ServerSession; using Kernel::SharedPtr; - auto sessions = ServerSession::CreateSessionPair(GetName()); + auto sessions = system.Kernel().CreateSessionPair(GetName()); auto server = std::get>(sessions); ClientConnected(server); @@ -258,7 +260,7 @@ void File::OpenSubFile(Kernel::HLERequestContext& ctx) { } Kernel::SharedPtr File::Connect() { - auto sessions = Kernel::ServerSession::CreateSessionPair(GetName()); + auto sessions = system.Kernel().CreateSessionPair(GetName()); auto server = std::get>(sessions); ClientConnected(server); diff --git a/src/core/hle/service/fs/file.h b/src/core/hle/service/fs/file.h index 2de9add98..b946491b8 100644 --- a/src/core/hle/service/fs/file.h +++ b/src/core/hle/service/fs/file.h @@ -8,6 +8,10 @@ #include "core/hle/kernel/kernel.h" #include "core/hle/service/service.h" +namespace Core { +class System; +} + namespace Service::FS { struct FileSessionSlot : public Kernel::SessionRequestHandler::SessionDataBase { @@ -21,7 +25,8 @@ struct FileSessionSlot : public Kernel::SessionRequestHandler::SessionDataBase { // Consider splitting ServiceFramework interface. class File final : public ServiceFramework { public: - File(std::unique_ptr&& backend, const FileSys::Path& path); + File(Core::System& system, std::unique_ptr&& backend, + const FileSys::Path& path); ~File() = default; std::string GetName() const { @@ -53,6 +58,8 @@ private: void GetPriority(Kernel::HLERequestContext& ctx); void OpenLinkFile(Kernel::HLERequestContext& ctx); void OpenSubFile(Kernel::HLERequestContext& ctx); + + Core::System& system; }; } // namespace Service::FS diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index e4a7c251d..7b1316e48 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -286,7 +286,7 @@ void FS_USER::OpenDirectory(Kernel::HLERequestContext& ctx) { rb.Push(dir_res.Code()); if (dir_res.Succeeded()) { std::shared_ptr directory = *dir_res; - auto sessions = ServerSession::CreateSessionPair(directory->GetName()); + auto sessions = system.Kernel().CreateSessionPair(directory->GetName()); directory->ClientConnected(std::get>(sessions)); rb.PushMoveObjects(std::get>(sessions)); } else { @@ -741,7 +741,8 @@ void FS_USER::GetSaveDataSecureValue(Kernel::HLERequestContext& ctx) { rb.Push(0); // the secure value } -FS_USER::FS_USER(ArchiveManager& archives) : ServiceFramework("fs:USER", 30), archives(archives) { +FS_USER::FS_USER(Core::System& system) + : ServiceFramework("fs:USER", 30), system(system), archives(system.ArchiveManager()) { static const FunctionInfo functions[] = { {0x000100C6, nullptr, "Dummy1"}, {0x040100C4, nullptr, "Control"}, @@ -860,6 +861,6 @@ FS_USER::FS_USER(ArchiveManager& archives) : ServiceFramework("fs:USER", 30), ar void InstallInterfaces(Core::System& system) { auto& service_manager = system.ServiceManager(); - std::make_shared(system.ArchiveManager())->InstallAsService(service_manager); + std::make_shared(system)->InstallAsService(service_manager); } } // namespace Service::FS diff --git a/src/core/hle/service/fs/fs_user.h b/src/core/hle/service/fs/fs_user.h index eb1b5af36..90c0ed7ec 100644 --- a/src/core/hle/service/fs/fs_user.h +++ b/src/core/hle/service/fs/fs_user.h @@ -17,7 +17,7 @@ class ArchiveManager; class FS_USER final : public ServiceFramework { public: - explicit FS_USER(ArchiveManager& archives); + explicit FS_USER(Core::System& system); private: void Initialize(Kernel::HLERequestContext& ctx); @@ -534,6 +534,7 @@ private: u32 priority = -1; ///< For SetPriority and GetPriority service functions + Core::System& system; ArchiveManager& archives; }; diff --git a/src/core/hle/service/gsp/gsp_gpu.cpp b/src/core/hle/service/gsp/gsp_gpu.cpp index be2a7ca64..a6b4826e2 100644 --- a/src/core/hle/service/gsp/gsp_gpu.cpp +++ b/src/core/hle/service/gsp/gsp_gpu.cpp @@ -786,9 +786,9 @@ GSP_GPU::GSP_GPU(Core::System& system) : ServiceFramework("gsp::Gpu", 2), system RegisterHandlers(functions); using Kernel::MemoryPermission; - shared_memory = Kernel::SharedMemory::Create(nullptr, 0x1000, MemoryPermission::ReadWrite, - MemoryPermission::ReadWrite, 0, - Kernel::MemoryRegion::BASE, "GSP:SharedMemory"); + shared_memory = system.Kernel().CreateSharedMemory( + nullptr, 0x1000, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, 0, + Kernel::MemoryRegion::BASE, "GSP:SharedMemory"); first_initialization = true; }; diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index b9876012e..205d7860e 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -359,16 +359,16 @@ std::shared_ptr Module::Interface::GetModule() const { Module::Module(Core::System& system) : system(system) { using namespace Kernel; - shared_mem = - SharedMemory::Create(nullptr, 0x1000, MemoryPermission::ReadWrite, MemoryPermission::Read, - 0, MemoryRegion::BASE, "HID:SharedMemory"); + shared_mem = system.Kernel().CreateSharedMemory(nullptr, 0x1000, MemoryPermission::ReadWrite, + MemoryPermission::Read, 0, MemoryRegion::BASE, + "HID:SharedMemory"); // Create event handles - event_pad_or_touch_1 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch1"); - event_pad_or_touch_2 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch2"); - event_accelerometer = Event::Create(ResetType::OneShot, "HID:EventAccelerometer"); - event_gyroscope = Event::Create(ResetType::OneShot, "HID:EventGyroscope"); - event_debug_pad = Event::Create(ResetType::OneShot, "HID:EventDebugPad"); + event_pad_or_touch_1 = system.Kernel().CreateEvent(ResetType::OneShot, "HID:EventPadOrTouch1"); + event_pad_or_touch_2 = system.Kernel().CreateEvent(ResetType::OneShot, "HID:EventPadOrTouch2"); + event_accelerometer = system.Kernel().CreateEvent(ResetType::OneShot, "HID:EventAccelerometer"); + event_gyroscope = system.Kernel().CreateEvent(ResetType::OneShot, "HID:EventGyroscope"); + event_debug_pad = system.Kernel().CreateEvent(ResetType::OneShot, "HID:EventDebugPad"); // Register update callbacks pad_update_event = diff --git a/src/core/hle/service/ir/ir.cpp b/src/core/hle/service/ir/ir.cpp index 0869941f2..5d99908cc 100644 --- a/src/core/hle/service/ir/ir.cpp +++ b/src/core/hle/service/ir/ir.cpp @@ -16,10 +16,10 @@ void InstallInterfaces(Core::System& system) { auto& service_manager = system.ServiceManager(); std::make_shared()->InstallAsService(service_manager); - auto ir_user = std::make_shared(); + auto ir_user = std::make_shared(system); ir_user->InstallAsService(service_manager); - auto ir_rst = std::make_shared(); + auto ir_rst = std::make_shared(system); ir_rst->InstallAsService(service_manager); } diff --git a/src/core/hle/service/ir/ir_rst.cpp b/src/core/hle/service/ir/ir_rst.cpp index 3dbf04722..147c91861 100644 --- a/src/core/hle/service/ir/ir_rst.cpp +++ b/src/core/hle/service/ir/ir_rst.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "core/core.h" #include "core/core_timing.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/event.h" @@ -144,14 +145,14 @@ void IR_RST::Shutdown(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_IR, "called"); } -IR_RST::IR_RST() : ServiceFramework("ir:rst", 1) { +IR_RST::IR_RST(Core::System& system) : ServiceFramework("ir:rst", 1) { using namespace Kernel; // Note: these two kernel objects are even available before Initialize service function is // called. - shared_memory = - SharedMemory::Create(nullptr, 0x1000, MemoryPermission::ReadWrite, MemoryPermission::Read, - 0, MemoryRegion::BASE, "IRRST:SharedMemory"); - update_event = Event::Create(ResetType::OneShot, "IRRST:UpdateEvent"); + shared_memory = system.Kernel().CreateSharedMemory(nullptr, 0x1000, MemoryPermission::ReadWrite, + MemoryPermission::Read, 0, + MemoryRegion::BASE, "IRRST:SharedMemory"); + update_event = system.Kernel().CreateEvent(ResetType::OneShot, "IRRST:UpdateEvent"); update_callback_id = CoreTiming::RegisterEvent("IRRST:UpdateCallBack", [this](u64 userdata, s64 cycles_late) { diff --git a/src/core/hle/service/ir/ir_rst.h b/src/core/hle/service/ir/ir_rst.h index 0ba5ea8f7..821fb0b2f 100644 --- a/src/core/hle/service/ir/ir_rst.h +++ b/src/core/hle/service/ir/ir_rst.h @@ -39,7 +39,7 @@ union PadState { /// Interface to "ir:rst" service class IR_RST final : public ServiceFramework { public: - IR_RST(); + explicit IR_RST(Core::System& system); ~IR_RST(); void ReloadInputDevices(); diff --git a/src/core/hle/service/ir/ir_user.cpp b/src/core/hle/service/ir/ir_user.cpp index 2edf11c48..e0158f67e 100644 --- a/src/core/hle/service/ir/ir_user.cpp +++ b/src/core/hle/service/ir/ir_user.cpp @@ -6,6 +6,7 @@ #include #include "common/string_util.h" #include "common/swap.h" +#include "core/core.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/event.h" #include "core/hle/kernel/shared_memory.h" @@ -380,7 +381,7 @@ void IR_USER::ReleaseReceivedData(Kernel::HLERequestContext& ctx) { LOG_TRACE(Service_IR, "called, count={}", count); } -IR_USER::IR_USER() : ServiceFramework("ir:USER", 1) { +IR_USER::IR_USER(Core::System& system) : ServiceFramework("ir:USER", 1) { const FunctionInfo functions[] = { {0x00010182, nullptr, "InitializeIrNop"}, {0x00020000, &IR_USER::FinalizeIrNop, "FinalizeIrNop"}, @@ -413,9 +414,9 @@ IR_USER::IR_USER() : ServiceFramework("ir:USER", 1) { using namespace Kernel; - conn_status_event = Event::Create(ResetType::OneShot, "IR:ConnectionStatusEvent"); - send_event = Event::Create(ResetType::OneShot, "IR:SendEvent"); - receive_event = Event::Create(ResetType::OneShot, "IR:ReceiveEvent"); + conn_status_event = system.Kernel().CreateEvent(ResetType::OneShot, "IR:ConnectionStatusEvent"); + send_event = system.Kernel().CreateEvent(ResetType::OneShot, "IR:SendEvent"); + receive_event = system.Kernel().CreateEvent(ResetType::OneShot, "IR:ReceiveEvent"); extra_hid = std::make_unique([this](const std::vector& data) { PutToReceive(data); }); diff --git a/src/core/hle/service/ir/ir_user.h b/src/core/hle/service/ir/ir_user.h index 207a54058..fea0794bc 100644 --- a/src/core/hle/service/ir/ir_user.h +++ b/src/core/hle/service/ir/ir_user.h @@ -55,7 +55,7 @@ private: /// Interface to "ir:USER" service class IR_USER final : public ServiceFramework { public: - IR_USER(); + explicit IR_USER(Core::System& system); ~IR_USER(); void ReloadInputDevices(); diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index 34e68099f..b2c24bd17 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp @@ -29,6 +29,11 @@ enum class SampleRate : u8 { }; struct MIC_U::Impl { + explicit Impl(Core::System& system) { + buffer_full_event = + system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "MIC_U::buffer_full_event"); + } + void MapSharedMem(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx, 0x01, 1, 2}; const u32 size = rp.Pop(); @@ -187,8 +192,7 @@ struct MIC_U::Impl { } u32 client_version = 0; - Kernel::SharedPtr buffer_full_event = - Kernel::Event::Create(Kernel::ResetType::OneShot, "MIC_U::buffer_full_event"); + Kernel::SharedPtr buffer_full_event; Kernel::SharedPtr shared_memory; u8 mic_gain = 0; bool mic_power = false; @@ -266,7 +270,8 @@ void MIC_U::SetClientVersion(Kernel::HLERequestContext& ctx) { impl->SetClientVersion(ctx); } -MIC_U::MIC_U() : ServiceFramework{"mic:u", 1}, impl{std::make_unique()} { +MIC_U::MIC_U(Core::System& system) + : ServiceFramework{"mic:u", 1}, impl{std::make_unique(system)} { static const FunctionInfo functions[] = { {0x00010042, &MIC_U::MapSharedMem, "MapSharedMem"}, {0x00020000, &MIC_U::UnmapSharedMem, "UnmapSharedMem"}, @@ -293,7 +298,7 @@ MIC_U::~MIC_U() = default; void InstallInterfaces(Core::System& system) { auto& service_manager = system.ServiceManager(); - std::make_shared()->InstallAsService(service_manager); + std::make_shared(system)->InstallAsService(service_manager); } } // namespace Service::MIC diff --git a/src/core/hle/service/mic_u.h b/src/core/hle/service/mic_u.h index 8fd835f0a..bc4933229 100644 --- a/src/core/hle/service/mic_u.h +++ b/src/core/hle/service/mic_u.h @@ -16,7 +16,7 @@ namespace Service::MIC { class MIC_U final : public ServiceFramework { public: - MIC_U(); + explicit MIC_U(Core::System& system); ~MIC_U(); private: diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp index 80bd6aa72..e76c7b3ee 100644 --- a/src/core/hle/service/nfc/nfc.cpp +++ b/src/core/hle/service/nfc/nfc.cpp @@ -140,18 +140,18 @@ Module::Interface::Interface(std::shared_ptr nfc, const char* name, u32 Module::Interface::~Interface() = default; -Module::Module() { +Module::Module(Core::System& system) { tag_in_range_event = - Kernel::Event::Create(Kernel::ResetType::OneShot, "NFC::tag_in_range_event"); + system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "NFC::tag_in_range_event"); tag_out_of_range_event = - Kernel::Event::Create(Kernel::ResetType::OneShot, "NFC::tag_out_range_event"); + system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "NFC::tag_out_range_event"); } Module::~Module() = default; void InstallInterfaces(Core::System& system) { auto& service_manager = system.ServiceManager(); - auto nfc = std::make_shared(); + auto nfc = std::make_shared(system); std::make_shared(nfc)->InstallAsService(service_manager); std::make_shared(nfc)->InstallAsService(service_manager); } diff --git a/src/core/hle/service/nfc/nfc.h b/src/core/hle/service/nfc/nfc.h index d942e4b63..bafdcf0fa 100644 --- a/src/core/hle/service/nfc/nfc.h +++ b/src/core/hle/service/nfc/nfc.h @@ -41,7 +41,7 @@ enum class CommunicationStatus : u8 { class Module final { public: - Module(); + explicit Module(Core::System& system); ~Module(); class Interface : public ServiceFramework { diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp index 25dafaa6e..a0b84bd03 100644 --- a/src/core/hle/service/nim/nim.cpp +++ b/src/core/hle/service/nim/nim.cpp @@ -14,7 +14,7 @@ void InstallInterfaces(Core::System& system) { auto& service_manager = system.ServiceManager(); std::make_shared()->InstallAsService(service_manager); std::make_shared()->InstallAsService(service_manager); - std::make_shared()->InstallAsService(service_manager); + std::make_shared(system)->InstallAsService(service_manager); } } // namespace Service::NIM diff --git a/src/core/hle/service/nim/nim_u.cpp b/src/core/hle/service/nim/nim_u.cpp index acf29cfe0..dd0e4d31c 100644 --- a/src/core/hle/service/nim/nim_u.cpp +++ b/src/core/hle/service/nim/nim_u.cpp @@ -2,13 +2,14 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "core/core.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/event.h" #include "core/hle/service/nim/nim_u.h" namespace Service::NIM { -NIM_U::NIM_U() : ServiceFramework("nim:u", 2) { +NIM_U::NIM_U(Core::System& system) : ServiceFramework("nim:u", 2) { const FunctionInfo functions[] = { {0x00010000, nullptr, "StartSysUpdate"}, {0x00020000, nullptr, "GetUpdateDownloadProgress"}, @@ -20,7 +21,7 @@ NIM_U::NIM_U() : ServiceFramework("nim:u", 2) { }; RegisterHandlers(functions); nim_system_update_event = - Kernel::Event::Create(Kernel::ResetType::OneShot, "NIM System Update Event"); + system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "NIM System Update Event"); } NIM_U::~NIM_U() = default; diff --git a/src/core/hle/service/nim/nim_u.h b/src/core/hle/service/nim/nim_u.h index 610688fc2..0f4338f16 100644 --- a/src/core/hle/service/nim/nim_u.h +++ b/src/core/hle/service/nim/nim_u.h @@ -6,11 +6,15 @@ #include "core/hle/service/service.h" +namespace Core { +class System; +} + namespace Service::NIM { class NIM_U final : public ServiceFramework { public: - NIM_U(); + explicit NIM_U(Core::System& system); ~NIM_U(); private: diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index fe9d09b98..4072aac09 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -839,8 +839,8 @@ void NWM_UDS::Bind(Kernel::HLERequestContext& ctx) { } // Create a new event for this bind node. - auto event = Kernel::Event::Create(Kernel::ResetType::OneShot, - "NWM::BindNodeEvent" + std::to_string(bind_node_id)); + auto event = system.Kernel().CreateEvent(Kernel::ResetType::OneShot, + "NWM::BindNodeEvent" + std::to_string(bind_node_id)); std::lock_guard lock(connection_status_mutex); ASSERT(channel_data.find(data_channel) == channel_data.end()); @@ -1355,7 +1355,7 @@ static void BeaconBroadcastCallback(u64 userdata, s64 cycles_late) { beacon_broadcast_event, 0); } -NWM_UDS::NWM_UDS(Core::System& system) : ServiceFramework("nwm::UDS") { +NWM_UDS::NWM_UDS(Core::System& system) : ServiceFramework("nwm::UDS"), system(system) { static const FunctionInfo functions[] = { {0x000102C2, nullptr, "Initialize (deprecated)"}, {0x00020000, nullptr, "Scrap"}, @@ -1388,7 +1388,7 @@ NWM_UDS::NWM_UDS(Core::System& system) : ServiceFramework("nwm::UDS") { {0x00220402, nullptr, "ScanOnConnection"}, }; connection_status_event = - Kernel::Event::Create(Kernel::ResetType::OneShot, "NWM::connection_status_event"); + system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "NWM::connection_status_event"); RegisterHandlers(functions); diff --git a/src/core/hle/service/nwm/nwm_uds.h b/src/core/hle/service/nwm/nwm_uds.h index 2c79aa674..b6cac1ee0 100644 --- a/src/core/hle/service/nwm/nwm_uds.h +++ b/src/core/hle/service/nwm/nwm_uds.h @@ -112,6 +112,8 @@ public: ~NWM_UDS(); private: + Core::System& system; + void UpdateNetworkAttribute(Kernel::HLERequestContext& ctx); /** diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 5755d0335..6bdafd0e8 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -143,11 +143,11 @@ void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager) port->SetHleHandler(shared_from_this()); } -void ServiceFrameworkBase::InstallAsNamedPort() { +void ServiceFrameworkBase::InstallAsNamedPort(Kernel::KernelSystem& kernel) { ASSERT(port == nullptr); SharedPtr server_port; SharedPtr client_port; - std::tie(server_port, client_port) = ServerPort::CreatePortPair(max_sessions, service_name); + std::tie(server_port, client_port) = kernel.CreatePortPair(max_sessions, service_name); server_port->SetHleHandler(shared_from_this()); AddNamedPort(service_name, std::move(client_port)); } @@ -235,8 +235,8 @@ static bool AttemptLLE(const ServiceModuleInfo& service_module) { } /// Initialize ServiceManager -void Init(Core::System& core, std::shared_ptr& sm) { - SM::ServiceManager::InstallInterfaces(sm); +void Init(Core::System& core) { + SM::ServiceManager::InstallInterfaces(core); for (const auto& service_module : service_module_map) { if (!AttemptLLE(service_module) && service_module.init_function != nullptr) diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 3a8634251..5cb4fbf23 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -20,6 +20,7 @@ class System; } namespace Kernel { +class KernelSystem; class ClientPort; class ServerPort; class ServerSession; @@ -59,7 +60,7 @@ public: /// Creates a port pair and registers this service with the given ServiceManager. void InstallAsService(SM::ServiceManager& service_manager); /// Creates a port pair and registers it on the kernel's global port registry. - void InstallAsNamedPort(); + void InstallAsNamedPort(Kernel::KernelSystem& kernel); void HandleSyncRequest(Kernel::SharedPtr server_session) override; @@ -184,7 +185,7 @@ private: }; /// Initialize ServiceManager -void Init(Core::System& system, std::shared_ptr& sm); +void Init(Core::System& system); /// Shutdown ServiceManager void Shutdown(); diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 588de7daa..81819c9bd 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -4,6 +4,7 @@ #include #include "common/assert.h" +#include "core/core.h" #include "core/hle/kernel/client_session.h" #include "core/hle/result.h" #include "core/hle/service/sm/sm.h" @@ -21,12 +22,14 @@ static ResultCode ValidateServiceName(const std::string& name) { return RESULT_SUCCESS; } -void ServiceManager::InstallInterfaces(std::shared_ptr self) { - ASSERT(self->srv_interface.expired()); +ServiceManager::ServiceManager(Core::System& system) : system(system) {} - auto srv = std::make_shared(self); - srv->InstallAsNamedPort(); - self->srv_interface = srv; +void ServiceManager::InstallInterfaces(Core::System& system) { + ASSERT(system.ServiceManager().srv_interface.expired()); + + auto srv = std::make_shared(system); + srv->InstallAsNamedPort(system.Kernel()); + system.ServiceManager().srv_interface = srv; } ResultVal> ServiceManager::RegisterService( @@ -39,7 +42,7 @@ ResultVal> ServiceManager::RegisterService Kernel::SharedPtr server_port; Kernel::SharedPtr client_port; - std::tie(server_port, client_port) = Kernel::ServerPort::CreatePortPair(max_sessions, name); + std::tie(server_port, client_port) = system.Kernel().CreatePortPair(max_sessions, name); registered_services.emplace(std::move(name), std::move(client_port)); return MakeResult>(std::move(server_port)); diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index 9e9164a66..f3cf40756 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -14,6 +14,10 @@ #include "core/hle/result.h" #include "core/hle/service/service.h" +namespace Core { +class System; +} + namespace Kernel { class ClientSession; class SessionRequestHandler; @@ -39,7 +43,9 @@ constexpr ResultCode ERR_ALREADY_REGISTERED(ErrorDescription::AlreadyExists, Err class ServiceManager { public: - static void InstallInterfaces(std::shared_ptr self); + static void InstallInterfaces(Core::System& system); + + explicit ServiceManager(Core::System& system); ResultVal> RegisterService(std::string name, unsigned int max_sessions); @@ -63,6 +69,7 @@ public: } private: + Core::System& system; std::weak_ptr srv_interface; /// Map of registered services, retrieved using GetServicePort or ConnectToService. diff --git a/src/core/hle/service/sm/srv.cpp b/src/core/hle/service/sm/srv.cpp index ca723745f..07b47ea9b 100644 --- a/src/core/hle/service/sm/srv.cpp +++ b/src/core/hle/service/sm/srv.cpp @@ -5,6 +5,7 @@ #include #include "common/common_types.h" #include "common/logging/log.h" +#include "core/core.h" #include "core/hle/ipc.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/client_port.h" @@ -62,7 +63,7 @@ void SRV::EnableNotification(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x2, 0, 0); notification_semaphore = - Kernel::Semaphore::Create(0, MAX_PENDING_NOTIFICATIONS, "SRV:Notification").Unwrap(); + system.Kernel().CreateSemaphore(0, MAX_PENDING_NOTIFICATIONS, "SRV:Notification").Unwrap(); IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); rb.Push(RESULT_SUCCESS); @@ -103,7 +104,7 @@ void SRV::GetServiceHandle(Kernel::HLERequestContext& ctx) { Kernel::HLERequestContext& ctx, Kernel::ThreadWakeupReason reason) { LOG_ERROR(Service_SRV, "called service={} wakeup", name); - auto client_port = service_manager->GetServicePort(name); + auto client_port = system.ServiceManager().GetServicePort(name); auto session = client_port.Unwrap()->Connect(); if (session.Succeeded()) { @@ -122,7 +123,7 @@ void SRV::GetServiceHandle(Kernel::HLERequestContext& ctx) { } }; - auto client_port = service_manager->GetServicePort(name); + auto client_port = system.ServiceManager().GetServicePort(name); if (client_port.Failed()) { if (wait_until_available && client_port.Code() == ERR_SERVICE_NOT_REGISTERED) { LOG_INFO(Service_SRV, "called service={} delayed", name); @@ -223,7 +224,7 @@ void SRV::RegisterService(Kernel::HLERequestContext& ctx) { std::string name(name_buf.data(), std::min(name_len, name_buf.size())); - auto port = service_manager->RegisterService(name, max_sessions); + auto port = system.ServiceManager().RegisterService(name, max_sessions); if (port.Failed()) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); @@ -243,8 +244,7 @@ void SRV::RegisterService(Kernel::HLERequestContext& ctx) { rb.PushMoveObjects(port.Unwrap()); } -SRV::SRV(std::shared_ptr service_manager) - : ServiceFramework("srv:", 4), service_manager(std::move(service_manager)) { +SRV::SRV(Core::System& system) : ServiceFramework("srv:", 4), system(system) { static const FunctionInfo functions[] = { {0x00010002, &SRV::RegisterClient, "RegisterClient"}, {0x00020000, &SRV::EnableNotification, "EnableNotification"}, diff --git a/src/core/hle/service/sm/srv.h b/src/core/hle/service/sm/srv.h index 066d00eac..02d72ec49 100644 --- a/src/core/hle/service/sm/srv.h +++ b/src/core/hle/service/sm/srv.h @@ -8,6 +8,10 @@ #include "core/hle/kernel/kernel.h" #include "core/hle/service/service.h" +namespace Core { +class System; +} + namespace Kernel { class HLERequestContext; class Semaphore; @@ -18,7 +22,7 @@ namespace Service::SM { /// Interface to "srv:" service class SRV final : public ServiceFramework { public: - explicit SRV(std::shared_ptr service_manager); + explicit SRV(Core::System& system); ~SRV(); private: @@ -30,7 +34,7 @@ private: void PublishToSubscriber(Kernel::HLERequestContext& ctx); void RegisterService(Kernel::HLERequestContext& ctx); - std::shared_ptr service_manager; + Core::System& system; Kernel::SharedPtr notification_semaphore; std::unordered_map> get_service_handle_delayed_map; diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index cd20b57bd..0de5cf8d5 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp @@ -632,7 +632,7 @@ void Y2R_U::GetPackageParameter(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Y2R, "called"); } -Y2R_U::Y2R_U() : ServiceFramework("y2r:u", 1) { +Y2R_U::Y2R_U(Core::System& system) : ServiceFramework("y2r:u", 1) { static const FunctionInfo functions[] = { {0x00010040, &Y2R_U::SetInputFormat, "SetInputFormat"}, {0x00020000, &Y2R_U::GetInputFormat, "GetInputFormat"}, @@ -682,14 +682,14 @@ Y2R_U::Y2R_U() : ServiceFramework("y2r:u", 1) { }; RegisterHandlers(functions); - completion_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "Y2R:Completed"); + completion_event = system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "Y2R:Completed"); } Y2R_U::~Y2R_U() = default; void InstallInterfaces(Core::System& system) { auto& service_manager = system.ServiceManager(); - std::make_shared()->InstallAsService(service_manager); + std::make_shared(system)->InstallAsService(service_manager); } } // namespace Service::Y2R diff --git a/src/core/hle/service/y2r_u.h b/src/core/hle/service/y2r_u.h index e32763925..007782dd5 100644 --- a/src/core/hle/service/y2r_u.h +++ b/src/core/hle/service/y2r_u.h @@ -149,7 +149,7 @@ static_assert(sizeof(ConversionParameters) == 12, "ConversionParameters struct h class Y2R_U final : public ServiceFramework { public: - Y2R_U(); + explicit Y2R_U(Core::System& system); ~Y2R_U() override; private: diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index d791c085c..1b3905b02 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp @@ -217,7 +217,7 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, } // Create the CodeSet - SharedPtr code_set = CodeSet::Create("", 0); + SharedPtr code_set = Core::System::GetInstance().Kernel().CreateCodeSet("", 0); code_set->CodeSegment().offset = loadinfo.seg_ptrs[0] - program_image.data(); code_set->CodeSegment().addr = loadinfo.seg_addrs[0]; @@ -267,13 +267,13 @@ ResultStatus AppLoader_THREEDSX::Load(Kernel::SharedPtr& proces return ResultStatus::Error; codeset->name = filename; - process = Kernel::Process::Create(std::move(codeset)); + process = Core::System::GetInstance().Kernel().CreateProcess(std::move(codeset)); process->svc_access_mask.set(); process->address_mappings = default_address_mappings; // Attach the default resource limit (APPLICATION) to the process - process->resource_limit = - Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); + process->resource_limit = Core::System::GetInstance().Kernel().ResourceLimit().GetForCategory( + Kernel::ResourceLimitCategory::APPLICATION); process->Run(48, Kernel::DEFAULT_STACK_SIZE); diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index fd2bb23b3..26470ff9d 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -8,6 +8,7 @@ #include "common/common_types.h" #include "common/file_util.h" #include "common/logging/log.h" +#include "core/core.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/resource_limit.h" #include "core/loader/elf.h" @@ -299,7 +300,7 @@ SharedPtr ElfReader::LoadInto(u32 vaddr) { std::vector program_image(total_image_size); std::size_t current_image_position = 0; - SharedPtr codeset = CodeSet::Create("", 0); + SharedPtr codeset = Core::System::GetInstance().Kernel().CreateCodeSet("", 0); for (unsigned int i = 0; i < header->e_phnum; ++i) { Elf32_Phdr* p = &segments[i]; @@ -395,13 +396,13 @@ ResultStatus AppLoader_ELF::Load(Kernel::SharedPtr& process) { SharedPtr codeset = elf_reader.LoadInto(Memory::PROCESS_IMAGE_VADDR); codeset->name = filename; - process = Kernel::Process::Create(std::move(codeset)); + process = Core::System::GetInstance().Kernel().CreateProcess(std::move(codeset)); process->svc_access_mask.set(); process->address_mappings = default_address_mappings; // Attach the default resource limit (APPLICATION) to the process - process->resource_limit = - Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); + process->resource_limit = Core::System::GetInstance().Kernel().ResourceLimit().GetForCategory( + Kernel::ResourceLimitCategory::APPLICATION); process->Run(48, Kernel::DEFAULT_STACK_SIZE); diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index 9fa1d05f1..34f49663a 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp @@ -75,7 +75,8 @@ ResultStatus AppLoader_NCCH::LoadExec(Kernel::SharedPtr& proces std::string process_name = Common::StringFromFixedZeroTerminatedBuffer( (const char*)overlay_ncch->exheader_header.codeset_info.name, 8); - SharedPtr codeset = CodeSet::Create(process_name, program_id); + SharedPtr codeset = + Core::System::GetInstance().Kernel().CreateCodeSet(process_name, program_id); codeset->CodeSegment().offset = 0; codeset->CodeSegment().addr = overlay_ncch->exheader_header.codeset_info.text.address; @@ -103,12 +104,13 @@ ResultStatus AppLoader_NCCH::LoadExec(Kernel::SharedPtr& proces codeset->entrypoint = codeset->CodeSegment().addr; codeset->memory = std::make_shared>(std::move(code)); - process = Kernel::Process::Create(std::move(codeset)); + process = Core::System::GetInstance().Kernel().CreateProcess(std::move(codeset)); // Attach a resource limit to the process based on the resource limit category process->resource_limit = - Kernel::ResourceLimit::GetForCategory(static_cast( - overlay_ncch->exheader_header.arm11_system_local_caps.resource_limit_category)); + Core::System::GetInstance().Kernel().ResourceLimit().GetForCategory( + static_cast( + overlay_ncch->exheader_header.arm11_system_local_caps.resource_limit_category)); // Set the default CPU core for this process process->ideal_processor = diff --git a/src/tests/core/arm/arm_test_common.cpp b/src/tests/core/arm/arm_test_common.cpp index 23c0411e7..4706c2512 100644 --- a/src/tests/core/arm/arm_test_common.cpp +++ b/src/tests/core/arm/arm_test_common.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/core.h" +#include "core/core_timing.h" #include "core/hle/kernel/process.h" #include "core/memory.h" #include "core/memory_setup.h" @@ -15,7 +16,10 @@ static Memory::PageTable* page_table = nullptr; TestEnvironment::TestEnvironment(bool mutable_memory_) : mutable_memory(mutable_memory_), test_memory(std::make_shared(this)) { - Kernel::g_current_process = Kernel::Process::Create(Kernel::CodeSet::Create("", 0)); + CoreTiming::Init(); + kernel = std::make_unique(0); + + Kernel::g_current_process = kernel->CreateProcess(kernel->CreateCodeSet("", 0)); page_table = &Kernel::g_current_process->vm_manager.page_table; page_table->pointers.fill(nullptr); @@ -30,6 +34,8 @@ TestEnvironment::TestEnvironment(bool mutable_memory_) TestEnvironment::~TestEnvironment() { Memory::UnmapRegion(*page_table, 0x80000000, 0x80000000); Memory::UnmapRegion(*page_table, 0x00000000, 0x80000000); + + CoreTiming::Shutdown(); } void TestEnvironment::SetMemory64(VAddr vaddr, u64 value) { diff --git a/src/tests/core/arm/arm_test_common.h b/src/tests/core/arm/arm_test_common.h index 44c63818a..4f396416f 100644 --- a/src/tests/core/arm/arm_test_common.h +++ b/src/tests/core/arm/arm_test_common.h @@ -5,8 +5,8 @@ #include #include #include - #include "common/common_types.h" +#include "core/hle/kernel/kernel.h" #include "core/mmio.h" namespace ArmTests { @@ -79,6 +79,8 @@ private: bool mutable_memory; std::shared_ptr test_memory; std::vector write_records; + + std::unique_ptr kernel; }; } // namespace ArmTests diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index d0bf44a58..9e093f4e4 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "core/core_timing.h" #include "core/hle/ipc.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" @@ -14,15 +15,17 @@ namespace Kernel { -static SharedPtr MakeObject() { - return Event::Create(ResetType::OneShot); +static SharedPtr MakeObject(Kernel::KernelSystem& kernel) { + return kernel.CreateEvent(ResetType::OneShot); } TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") { - auto session = std::get>(ServerSession::CreateSessionPair()); + CoreTiming::Init(); + Kernel::KernelSystem kernel(0); + auto session = std::get>(kernel.CreateSessionPair()); HLERequestContext context(std::move(session)); - auto process = Process::Create(CodeSet::Create("", 0)); + auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); HandleTable handle_table; SECTION("works with empty cmdbuf") { @@ -52,7 +55,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel } SECTION("translates move handles") { - auto a = MakeObject(); + auto a = MakeObject(kernel); Handle a_handle = handle_table.Create(a).Unwrap(); const u32_le input[]{ IPC::MakeHeader(0, 0, 2), @@ -68,7 +71,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel } SECTION("translates copy handles") { - auto a = MakeObject(); + auto a = MakeObject(kernel); Handle a_handle = handle_table.Create(a).Unwrap(); const u32_le input[]{ IPC::MakeHeader(0, 0, 2), @@ -84,9 +87,9 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel } SECTION("translates multi-handle descriptors") { - auto a = MakeObject(); - auto b = MakeObject(); - auto c = MakeObject(); + auto a = MakeObject(kernel); + auto b = MakeObject(kernel); + auto c = MakeObject(kernel); const u32_le input[]{ IPC::MakeHeader(0, 0, 5), IPC::MoveHandleDesc(2), handle_table.Create(a).Unwrap(), handle_table.Create(b).Unwrap(), @@ -190,7 +193,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel buffer_mapped->size(), MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); - auto a = MakeObject(); + auto a = MakeObject(kernel); const u32_le input[]{ IPC::MakeHeader(0, 2, 8), 0x12345678, @@ -222,13 +225,17 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel REQUIRE(process->vm_manager.UnmapRange(target_address_mapped, buffer_mapped->size()) == RESULT_SUCCESS); } + + CoreTiming::Shutdown(); } TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { - auto session = std::get>(ServerSession::CreateSessionPair()); + CoreTiming::Init(); + Kernel::KernelSystem kernel(0); + auto session = std::get>(kernel.CreateSessionPair()); HLERequestContext context(std::move(session)); - auto process = Process::Create(CodeSet::Create("", 0)); + auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); HandleTable handle_table; auto* input = context.CommandBuffer(); u32_le output[IPC::COMMAND_BUFFER_LENGTH]; @@ -255,8 +262,8 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { } SECTION("translates move/copy handles") { - auto a = MakeObject(); - auto b = MakeObject(); + auto a = MakeObject(kernel); + auto b = MakeObject(kernel); input[0] = IPC::MakeHeader(0, 0, 4); input[1] = IPC::MoveHandleDesc(1); input[2] = context.AddOutgoingHandle(a); @@ -281,9 +288,9 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { } SECTION("translates multi-handle descriptors") { - auto a = MakeObject(); - auto b = MakeObject(); - auto c = MakeObject(); + auto a = MakeObject(kernel); + auto b = MakeObject(kernel); + auto c = MakeObject(kernel); input[0] = IPC::MakeHeader(0, 0, 5); input[1] = IPC::MoveHandleDesc(2); input[2] = context.AddOutgoingHandle(a); @@ -361,6 +368,8 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer->size()) == RESULT_SUCCESS); } + + CoreTiming::Shutdown(); } } // namespace Kernel diff --git a/src/tests/core/memory/memory.cpp b/src/tests/core/memory/memory.cpp index c69340865..d5f96e1f2 100644 --- a/src/tests/core/memory/memory.cpp +++ b/src/tests/core/memory/memory.cpp @@ -3,14 +3,17 @@ // Refer to the license.txt file included. #include +#include "core/core_timing.h" #include "core/hle/kernel/memory.h" #include "core/hle/kernel/process.h" #include "core/hle/shared_page.h" #include "core/memory.h" TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory]") { + CoreTiming::Init(); + Kernel::KernelSystem kernel(0); SECTION("these regions should not be mapped on an empty process") { - auto process = Kernel::Process::Create(Kernel::CodeSet::Create("", 0)); + auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); CHECK(Memory::IsValidVirtualAddress(*process, Memory::PROCESS_IMAGE_VADDR) == false); CHECK(Memory::IsValidVirtualAddress(*process, Memory::HEAP_VADDR) == false); CHECK(Memory::IsValidVirtualAddress(*process, Memory::LINEAR_HEAP_VADDR) == false); @@ -21,14 +24,14 @@ TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory]") { } SECTION("CONFIG_MEMORY_VADDR and SHARED_PAGE_VADDR should be valid after mapping them") { - auto process = Kernel::Process::Create(Kernel::CodeSet::Create("", 0)); + auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); Kernel::MapSharedPages(process->vm_manager); CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == true); CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == true); } SECTION("special regions should be valid after mapping them") { - auto process = Kernel::Process::Create(Kernel::CodeSet::Create("", 0)); + auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); SECTION("VRAM") { Kernel::HandleSpecialMapping(process->vm_manager, {Memory::VRAM_VADDR, Memory::VRAM_SIZE, false, false}); @@ -43,9 +46,11 @@ TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory]") { } SECTION("Unmapping a VAddr should make it invalid") { - auto process = Kernel::Process::Create(Kernel::CodeSet::Create("", 0)); + auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); Kernel::MapSharedPages(process->vm_manager); process->vm_manager.UnmapRange(Memory::CONFIG_MEMORY_VADDR, Memory::CONFIG_MEMORY_SIZE); CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false); } + + CoreTiming::Shutdown(); }