mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Merge pull request #4341 from wwylele/kernel-global
Kernel: make a kernel instance and remove object ID counter from global state
This commit is contained in:
		
						commit
						6f1759c5bd
					
				
					 91 changed files with 620 additions and 443 deletions
				
			
		|  | @ -191,13 +191,13 @@ System::ResultStatus System::Init(EmuWindow& emu_window, u32 system_mode) { | |||
|     rpc_server = std::make_unique<RPC::RPCServer>(); | ||||
| #endif | ||||
| 
 | ||||
|     service_manager = std::make_shared<Service::SM::ServiceManager>(); | ||||
|     service_manager = std::make_shared<Service::SM::ServiceManager>(*this); | ||||
|     shared_page_handler = std::make_shared<SharedPage::Handler>(); | ||||
|     archive_manager = std::make_unique<Service::FS::ArchiveManager>(); | ||||
|     archive_manager = std::make_unique<Service::FS::ArchiveManager>(*this); | ||||
| 
 | ||||
|     HW::Init(); | ||||
|     Kernel::Init(system_mode); | ||||
|     Service::Init(*this, service_manager); | ||||
|     kernel = std::make_unique<Kernel::KernelSystem>(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<Frontend::SoftwareKeyboard> 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 | ||||
|  |  | |||
|  | @ -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<Service::FS::ArchiveManager> archive_manager; | ||||
| 
 | ||||
|     std::unique_ptr<Kernel::KernelSystem> kernel; | ||||
| 
 | ||||
|     static System s_instance; | ||||
| 
 | ||||
|     ResultStatus status = ResultStatus::Success; | ||||
|  |  | |||
|  | @ -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<std::vector<u8>>(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"); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<std::vector<u8>>(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"); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<std::vector<u8>>(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"); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<std::vector<u8>>(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"); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<Thread> AddressArbiter::ResumeHighestPriorityThread(VAddr address) { | |||
|     return thread; | ||||
| } | ||||
| 
 | ||||
| AddressArbiter::AddressArbiter() {} | ||||
| AddressArbiter::AddressArbiter(KernelSystem& kernel) : Object(kernel) {} | ||||
| AddressArbiter::~AddressArbiter() {} | ||||
| 
 | ||||
| SharedPtr<AddressArbiter> AddressArbiter::Create(std::string name) { | ||||
|     SharedPtr<AddressArbiter> address_arbiter(new AddressArbiter); | ||||
| SharedPtr<AddressArbiter> KernelSystem::CreateAddressArbiter(std::string name) { | ||||
|     SharedPtr<AddressArbiter> address_arbiter(new AddressArbiter(*this)); | ||||
| 
 | ||||
|     address_arbiter->name = std::move(name); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<AddressArbiter> 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<SharedPtr<Thread>> waiting_threads; | ||||
| 
 | ||||
|     friend class KernelSystem; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Kernel
 | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ | |||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| ClientPort::ClientPort() = default; | ||||
| ClientPort::ClientPort(KernelSystem& kernel) : kernel(kernel), Object(kernel) {} | ||||
| ClientPort::~ClientPort() = default; | ||||
| 
 | ||||
| ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { | ||||
|  | @ -26,7 +26,7 @@ ResultVal<SharedPtr<ClientSession>> 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<SharedPtr<ServerSession>>(sessions)); | ||||
|  |  | |||
|  | @ -48,13 +48,16 @@ public: | |||
|     void ConnectionClosed(); | ||||
| 
 | ||||
| private: | ||||
|     ClientPort(); | ||||
|     explicit ClientPort(KernelSystem& kernel); | ||||
|     ~ClientPort() override; | ||||
| 
 | ||||
|     KernelSystem& kernel; | ||||
|     SharedPtr<ServerPort> 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
 | ||||
|  |  | |||
|  | @ -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.
 | ||||
|  |  | |||
|  | @ -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<Session> parent; | ||||
| 
 | ||||
| private: | ||||
|     ClientSession(); | ||||
|     explicit ClientSession(KernelSystem& kernel); | ||||
|     ~ClientSession() override; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,16 +7,16 @@ | |||
| #include <vector> | ||||
| #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> Event::Create(ResetType reset_type, std::string name) { | ||||
|     SharedPtr<Event> evt(new Event); | ||||
| SharedPtr<Event> KernelSystem::CreateEvent(ResetType reset_type, std::string name) { | ||||
|     SharedPtr<Event> evt(new Event(*this)); | ||||
| 
 | ||||
|     evt->signaled = false; | ||||
|     evt->reset_type = reset_type; | ||||
|  |  | |||
|  | @ -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<Event> 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
 | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
| #include <vector> | ||||
| #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<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> 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); | ||||
|  |  | |||
|  | @ -14,34 +14,41 @@ | |||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| std::atomic<u32> 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<ResourceLimitList>(*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
 | ||||
|  |  | |||
|  | @ -4,14 +4,185 @@ | |||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <atomic> | ||||
| #include <memory> | ||||
| #include <string> | ||||
| #include <boost/smart_ptr/intrusive_ptr.hpp> | ||||
| #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 <typename T> | ||||
| using SharedPtr = boost::intrusive_ptr<T>; | ||||
| 
 | ||||
| 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<AddressArbiter> CreateAddressArbiter(std::string name = "Unknown"); | ||||
| 
 | ||||
|     /**
 | ||||
|      * Creates an event | ||||
|      * @param reset_type ResetType describing how to create event | ||||
|      * @param name Optional name of event | ||||
|      */ | ||||
|     SharedPtr<Event> 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<Mutex> CreateMutex(bool initial_locked, std::string name = "Unknown"); | ||||
| 
 | ||||
|     SharedPtr<CodeSet> CreateCodeSet(std::string name, u64 program_id); | ||||
| 
 | ||||
|     SharedPtr<Process> CreateProcess(SharedPtr<CodeSet> 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<SharedPtr<Thread>> CreateThread(std::string name, VAddr entry_point, u32 priority, | ||||
|                                               u32 arg, s32 processor_id, VAddr stack_top, | ||||
|                                               SharedPtr<Process> 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<SharedPtr<Semaphore>> 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<Timer> 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<ServerPort>, SharedPtr<ClientPort>> 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<ServerSession>, SharedPtr<ClientSession>> CreateSessionPair( | ||||
|         const std::string& name = "Unknown", SharedPtr<ClientPort> 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<SharedMemory> CreateSharedMemory(SharedPtr<Process> 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<SharedMemory> CreateSharedMemoryForApplet(std::shared_ptr<std::vector<u8>> heap_block, | ||||
|                                                         u32 offset, u32 size, | ||||
|                                                         MemoryPermission permissions, | ||||
|                                                         MemoryPermission other_permissions, | ||||
|                                                         std::string name = "Unknown Applet"); | ||||
| 
 | ||||
|     u32 GenerateObjectID(); | ||||
| 
 | ||||
| private: | ||||
|     std::unique_ptr<ResourceLimitList> resource_limits; | ||||
|     std::atomic<u32> next_object_id{0}; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Kernel
 | ||||
|  |  | |||
|  | @ -24,11 +24,11 @@ void ReleaseThreadMutexes(Thread* thread) { | |||
|     thread->held_mutexes.clear(); | ||||
| } | ||||
| 
 | ||||
| Mutex::Mutex() {} | ||||
| Mutex::Mutex(KernelSystem& kernel) : WaitObject(kernel) {} | ||||
| Mutex::~Mutex() {} | ||||
| 
 | ||||
| SharedPtr<Mutex> Mutex::Create(bool initial_locked, std::string name) { | ||||
|     SharedPtr<Mutex> mutex(new Mutex); | ||||
| SharedPtr<Mutex> KernelSystem::CreateMutex(bool initial_locked, std::string name) { | ||||
|     SharedPtr<Mutex> mutex(new Mutex(*this)); | ||||
| 
 | ||||
|     mutex->lock_count = 0; | ||||
|     mutex->name = std::move(name); | ||||
|  |  | |||
|  | @ -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<Mutex> 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; | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -6,13 +6,13 @@ | |||
| 
 | ||||
| #include <atomic> | ||||
| #include <string> | ||||
| 
 | ||||
| #include <boost/smart_ptr/intrusive_ptr.hpp> | ||||
| 
 | ||||
| #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<u32> next_object_id; | ||||
| 
 | ||||
| private: | ||||
|     friend void intrusive_ptr_add_ref(Object*); | ||||
|     friend void intrusive_ptr_release(Object*); | ||||
| 
 | ||||
|     std::atomic<u32> ref_count{0}; | ||||
|     std::atomic<u32> object_id{next_object_id++}; | ||||
|     std::atomic<u32> 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 <typename T> | ||||
| using SharedPtr = boost::intrusive_ptr<T>; | ||||
| 
 | ||||
| /**
 | ||||
|  * 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. | ||||
|  |  | |||
|  | @ -20,8 +20,8 @@ namespace Kernel { | |||
| // Lists all processes that exist in the current session.
 | ||||
| static std::vector<SharedPtr<Process>> process_list; | ||||
| 
 | ||||
| SharedPtr<CodeSet> CodeSet::Create(std::string name, u64 program_id) { | ||||
|     SharedPtr<CodeSet> codeset(new CodeSet); | ||||
| SharedPtr<CodeSet> KernelSystem::CreateCodeSet(std::string name, u64 program_id) { | ||||
|     SharedPtr<CodeSet> codeset(new CodeSet(*this)); | ||||
| 
 | ||||
|     codeset->name = std::move(name); | ||||
|     codeset->program_id = program_id; | ||||
|  | @ -29,13 +29,13 @@ SharedPtr<CodeSet> 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> Process::Create(SharedPtr<CodeSet> code_set) { | ||||
|     SharedPtr<Process> process(new Process); | ||||
| SharedPtr<Process> KernelSystem::CreateProcess(SharedPtr<CodeSet> code_set) { | ||||
|     SharedPtr<Process> 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() { | ||||
|  |  | |||
|  | @ -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<CodeSet> 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<Process> Create(SharedPtr<CodeSet> 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(); | ||||
|  |  | |||
|  | @ -9,19 +9,17 @@ | |||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| static SharedPtr<ResourceLimit> resource_limits[4]; | ||||
| 
 | ||||
| ResourceLimit::ResourceLimit() {} | ||||
| ResourceLimit::ResourceLimit(KernelSystem& kernel) : Object(kernel) {} | ||||
| ResourceLimit::~ResourceLimit() {} | ||||
| 
 | ||||
| SharedPtr<ResourceLimit> ResourceLimit::Create(std::string name) { | ||||
|     SharedPtr<ResourceLimit> resource_limit(new ResourceLimit); | ||||
| SharedPtr<ResourceLimit> ResourceLimit::Create(KernelSystem& kernel, std::string name) { | ||||
|     SharedPtr<ResourceLimit> resource_limit(new ResourceLimit(kernel)); | ||||
| 
 | ||||
|     resource_limit->name = std::move(name); | ||||
|     return resource_limit; | ||||
| } | ||||
| 
 | ||||
| SharedPtr<ResourceLimit> ResourceLimit::GetForCategory(ResourceLimitCategory category) { | ||||
| SharedPtr<ResourceLimit> 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<ResourceLimit> resource_limit = ResourceLimit::Create("Applications"); | ||||
|     SharedPtr<ResourceLimit> 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<u8>(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<u8>(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<u8>(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<u8>(ResourceLimitCategory::OTHER)] = resource_limit; | ||||
| } | ||||
| 
 | ||||
| void ResourceLimitsShutdown() {} | ||||
| ResourceLimitList::~ResourceLimitList() = default; | ||||
| 
 | ||||
| } // namespace Kernel
 | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <array> | ||||
| #include "common/common_types.h" | ||||
| #include "core/hle/kernel/object.h" | ||||
| 
 | ||||
|  | @ -34,14 +35,7 @@ public: | |||
|     /**
 | ||||
|      * Creates a resource limit object. | ||||
|      */ | ||||
|     static SharedPtr<ResourceLimit> 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<ResourceLimit> GetForCategory(ResourceLimitCategory category); | ||||
|     static SharedPtr<ResourceLimit> 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<ResourceLimit> GetForCategory(ResourceLimitCategory category); | ||||
| 
 | ||||
| private: | ||||
|     std::array<SharedPtr<ResourceLimit>, 4> resource_limits; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Kernel
 | ||||
|  |  | |||
|  | @ -10,16 +10,16 @@ | |||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| Semaphore::Semaphore() {} | ||||
| Semaphore::Semaphore(KernelSystem& kernel) : WaitObject(kernel) {} | ||||
| Semaphore::~Semaphore() {} | ||||
| 
 | ||||
| ResultVal<SharedPtr<Semaphore>> Semaphore::Create(s32 initial_count, s32 max_count, | ||||
|                                                   std::string name) { | ||||
| ResultVal<SharedPtr<Semaphore>> KernelSystem::CreateSemaphore(s32 initial_count, s32 max_count, | ||||
|                                                               std::string name) { | ||||
| 
 | ||||
|     if (initial_count > max_count) | ||||
|         return ERR_INVALID_COMBINATION_KERNEL; | ||||
| 
 | ||||
|     SharedPtr<Semaphore> semaphore(new Semaphore); | ||||
|     SharedPtr<Semaphore> 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
 | ||||
|  |  | |||
|  | @ -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<SharedPtr<Semaphore>> Create(s32 initial_count, s32 max_count, | ||||
|                                                   std::string name = "Unknown"); | ||||
| 
 | ||||
|     std::string GetTypeName() const override { | ||||
|         return "Semaphore"; | ||||
|     } | ||||
|  | @ -52,8 +42,10 @@ public: | |||
|     ResultVal<s32> Release(s32 release_count); | ||||
| 
 | ||||
| private: | ||||
|     Semaphore(); | ||||
|     explicit Semaphore(KernelSystem& kernel); | ||||
|     ~Semaphore() override; | ||||
| 
 | ||||
|     friend class KernelSystem; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Kernel
 | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ | |||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| ServerPort::ServerPort() {} | ||||
| ServerPort::ServerPort(KernelSystem& kernel) : WaitObject(kernel) {} | ||||
| ServerPort::~ServerPort() {} | ||||
| 
 | ||||
| ResultVal<SharedPtr<ServerSession>> ServerPort::Accept() { | ||||
|  | @ -35,11 +35,11 @@ void ServerPort::Acquire(Thread* thread) { | |||
|     ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); | ||||
| } | ||||
| 
 | ||||
| std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> ServerPort::CreatePortPair( | ||||
| std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> KernelSystem::CreatePortPair( | ||||
|     u32 max_sessions, std::string name) { | ||||
| 
 | ||||
|     SharedPtr<ServerPort> server_port(new ServerPort); | ||||
|     SharedPtr<ClientPort> client_port(new ClientPort); | ||||
|     SharedPtr<ServerPort> server_port(new ServerPort(*this)); | ||||
|     SharedPtr<ClientPort> client_port(new ClientPort(*this)); | ||||
| 
 | ||||
|     server_port->name = name + "_Server"; | ||||
|     client_port->name = name + "_Client"; | ||||
|  |  | |||
|  | @ -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<ServerPort>, SharedPtr<ClientPort>> 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
 | ||||
|  |  | |||
|  | @ -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<SharedPtr<ServerSession>> ServerSession::Create(std::string name) { | ||||
|     SharedPtr<ServerSession> server_session(new ServerSession); | ||||
| ResultVal<SharedPtr<ServerSession>> ServerSession::Create(KernelSystem& kernel, std::string name) { | ||||
|     SharedPtr<ServerSession> server_session(new ServerSession(kernel)); | ||||
| 
 | ||||
|     server_session->name = std::move(name); | ||||
|     server_session->parent = nullptr; | ||||
|  | @ -100,10 +100,10 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) { | |||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| ServerSession::SessionPair ServerSession::CreateSessionPair(const std::string& name, | ||||
|                                                             SharedPtr<ClientPort> port) { | ||||
|     auto server_session = ServerSession::Create(name + "_Server").Unwrap(); | ||||
|     SharedPtr<ClientSession> client_session(new ClientSession); | ||||
| std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>> KernelSystem::CreateSessionPair( | ||||
|     const std::string& name, SharedPtr<ClientPort> port) { | ||||
|     auto server_session = ServerSession::Create(*this, name + "_Server").Unwrap(); | ||||
|     SharedPtr<ClientSession> client_session(new ClientSession(*this)); | ||||
|     client_session->name = name + "_Client"; | ||||
| 
 | ||||
|     std::shared_ptr<Session> parent(new Session); | ||||
|  |  | |||
|  | @ -48,17 +48,6 @@ public: | |||
|         return HANDLE_TYPE; | ||||
|     } | ||||
| 
 | ||||
|     using SessionPair = std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>>; | ||||
| 
 | ||||
|     /**
 | ||||
|      * 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<ClientPort> 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<Thread> 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<SharedPtr<ServerSession>> Create(std::string name = "Unknown"); | ||||
|     static ResultVal<SharedPtr<ServerSession>> Create(KernelSystem& kernel, | ||||
|                                                       std::string name = "Unknown"); | ||||
| 
 | ||||
|     friend class KernelSystem; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Kernel
 | ||||
|  |  | |||
|  | @ -11,14 +11,15 @@ | |||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| SharedMemory::SharedMemory() {} | ||||
| SharedMemory::SharedMemory(KernelSystem& kernel) : Object(kernel) {} | ||||
| SharedMemory::~SharedMemory() {} | ||||
| 
 | ||||
| SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u32 size, | ||||
|                                              MemoryPermission permissions, | ||||
|                                              MemoryPermission other_permissions, VAddr address, | ||||
|                                              MemoryRegion region, std::string name) { | ||||
|     SharedPtr<SharedMemory> shared_memory(new SharedMemory); | ||||
| SharedPtr<SharedMemory> KernelSystem::CreateSharedMemory(SharedPtr<Process> owner_process, u32 size, | ||||
|                                                          MemoryPermission permissions, | ||||
|                                                          MemoryPermission other_permissions, | ||||
|                                                          VAddr address, MemoryRegion region, | ||||
|                                                          std::string name) { | ||||
|     SharedPtr<SharedMemory> shared_memory(new SharedMemory(*this)); | ||||
| 
 | ||||
|     shared_memory->owner_process = owner_process; | ||||
|     shared_memory->name = std::move(name); | ||||
|  | @ -74,12 +75,10 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u | |||
|     return shared_memory; | ||||
| } | ||||
| 
 | ||||
| SharedPtr<SharedMemory> SharedMemory::CreateForApplet(std::shared_ptr<std::vector<u8>> heap_block, | ||||
|                                                       u32 offset, u32 size, | ||||
|                                                       MemoryPermission permissions, | ||||
|                                                       MemoryPermission other_permissions, | ||||
|                                                       std::string name) { | ||||
|     SharedPtr<SharedMemory> shared_memory(new SharedMemory); | ||||
| SharedPtr<SharedMemory> KernelSystem::CreateSharedMemoryForApplet( | ||||
|     std::shared_ptr<std::vector<u8>> heap_block, u32 offset, u32 size, MemoryPermission permissions, | ||||
|     MemoryPermission other_permissions, std::string name) { | ||||
|     SharedPtr<SharedMemory> shared_memory(new SharedMemory(*this)); | ||||
| 
 | ||||
|     shared_memory->owner_process = nullptr; | ||||
|     shared_memory->name = std::move(name); | ||||
|  |  | |||
|  | @ -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<SharedMemory> Create(SharedPtr<Process> 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<SharedMemory> CreateForApplet(std::shared_ptr<std::vector<u8>> 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
 | ||||
|  |  | |||
|  | @ -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<AddressArbiter> arbiter = AddressArbiter::Create(); | ||||
|     SharedPtr<AddressArbiter> 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, | ||||
|                    Thread::Create(name, entry_point, priority, arg, processor_id, stack_top, | ||||
|                                   g_current_process)); | ||||
|     CASCADE_RESULT(SharedPtr<Thread> 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 = Mutex::Create(initial_locked != 0); | ||||
|     SharedPtr<Mutex> 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, Semaphore::Create(initial_count, max_count)); | ||||
|     CASCADE_RESULT(SharedPtr<Semaphore> 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<Event> evt = Event::Create(static_cast<ResetType>(reset_type), | ||||
|                                          fmt::format("event-{:08x}", Core::CPU().GetReg(14))); | ||||
|     SharedPtr<Event> evt = Core::System::GetInstance().Kernel().CreateEvent( | ||||
|         static_cast<ResetType>(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 = Timer::Create(static_cast<ResetType>(reset_type), | ||||
|                                            fmt ::format("timer-{:08x}", Core::CPU().GetReg(14))); | ||||
|     SharedPtr<Timer> timer = Core::System::GetInstance().Kernel().CreateTimer( | ||||
|         static_cast<ResetType>(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<MemoryPermission>(my_permission), | ||||
|                              static_cast<MemoryPermission>(other_permission), addr, region); | ||||
|     shared_memory = Core::System::GetInstance().Kernel().CreateSharedMemory( | ||||
|         g_current_process, size, static_cast<MemoryPermission>(my_permission), | ||||
|         static_cast<MemoryPermission>(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<SharedPtr<ClientPort>>(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<SharedPtr<ServerSession>>(sessions); | ||||
|     CASCADE_RESULT(*server_session, g_handle_table.Create(std::move(server))); | ||||
|  |  | |||
|  | @ -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_ptr<ARM_Interface::ThreadContex | |||
|     context->SetCpsr(USER32MODE | ((entry_point & 1) << 5)); // Usermode and THUMB mode
 | ||||
| } | ||||
| 
 | ||||
| ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, u32 priority, | ||||
|                                             u32 arg, s32 processor_id, VAddr stack_top, | ||||
|                                             SharedPtr<Process> owner_process) { | ||||
| ResultVal<SharedPtr<Thread>> KernelSystem::CreateThread(std::string name, VAddr entry_point, | ||||
|                                                         u32 priority, u32 arg, s32 processor_id, | ||||
|                                                         VAddr stack_top, | ||||
|                                                         SharedPtr<Process> 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<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
|                           ErrorSummary::InvalidArgument, ErrorLevel::Permanent); | ||||
|     } | ||||
| 
 | ||||
|     SharedPtr<Thread> thread(new Thread); | ||||
|     SharedPtr<Thread> 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<Thread> SetupMainThread(u32 entry_point, u32 priority, SharedPtr<Process> owner_process) { | ||||
| SharedPtr<Thread> SetupMainThread(KernelSystem& kernel, u32 entry_point, u32 priority, | ||||
|                                   SharedPtr<Process> 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> thread = std::move(thread_res).Unwrap(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<SharedPtr<Thread>> Create(std::string name, VAddr entry_point, u32 priority, | ||||
|                                                u32 arg, s32 processor_id, VAddr stack_top, | ||||
|                                                SharedPtr<Process> owner_process); | ||||
| 
 | ||||
|     std::string GetName() const override { | ||||
|         return name; | ||||
|     } | ||||
|  | @ -225,18 +210,22 @@ public: | |||
|     std::function<WakeupCallback> 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<Thread> SetupMainThread(u32 entry_point, u32 priority, SharedPtr<Process> owner_process); | ||||
| SharedPtr<Thread> SetupMainThread(KernelSystem& kernel, u32 entry_point, u32 priority, | ||||
|                                   SharedPtr<Process> owner_process); | ||||
| 
 | ||||
| /**
 | ||||
|  * Returns whether there are any threads that are ready to run. | ||||
|  |  | |||
|  | @ -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> Timer::Create(ResetType reset_type, std::string name) { | ||||
|     SharedPtr<Timer> timer(new Timer); | ||||
| SharedPtr<Timer> KernelSystem::CreateTimer(ResetType reset_type, std::string name) { | ||||
|     SharedPtr<Timer> timer(new Timer(*this)); | ||||
| 
 | ||||
|     timer->reset_type = reset_type; | ||||
|     timer->signaled = false; | ||||
|  |  | |||
|  | @ -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<Timer> 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
 | ||||
|  |  | |||
|  | @ -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. | ||||
|  |  | |||
|  | @ -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<Service::FS::File>(std::make_unique<CIAFile>(media_type), cia_path); | ||||
|     auto file = std::make_shared<Service::FS::File>( | ||||
|         am->system, std::make_unique<CIAFile>(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<Service::FS::File>(std::make_unique<CIAFile>(FS::MediaType::NAND), | ||||
|                                                     cia_path); | ||||
|     auto file = std::make_shared<Service::FS::File>( | ||||
|         am->system, std::make_unique<CIAFile>(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<Module>(); | ||||
|     auto am = std::make_shared<Module>(system); | ||||
|     std::make_shared<AM_APP>(am)->InstallAsService(service_manager); | ||||
|     std::make_shared<AM_NET>(am)->InstallAsService(service_manager); | ||||
|     std::make_shared<AM_SYS>(am)->InstallAsService(service_manager); | ||||
|  |  | |||
|  | @ -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<Interface> { | ||||
|  | @ -573,6 +573,7 @@ private: | |||
|      */ | ||||
|     void ScanForAllTitles(); | ||||
| 
 | ||||
|     Core::System& system; | ||||
|     bool cia_installing = false; | ||||
|     std::array<std::vector<u64_le>, 3> am_title_list; | ||||
|     Kernel::SharedPtr<Kernel::Mutex> system_updater_mutex; | ||||
|  |  | |||
|  | @ -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(); | ||||
| } | ||||
|  |  | |||
|  | @ -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() {} | ||||
|  |  | |||
|  | @ -903,15 +903,16 @@ void Module::Interface::GetNsDataNewFlagPrivileged(Kernel::HLERequestContext& ct | |||
| Module::Interface::Interface(std::shared_ptr<Module> 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<Module>(); | ||||
|     auto boss = std::make_shared<Module>(system); | ||||
|     std::make_shared<BOSS_P>(boss)->InstallAsService(service_manager); | ||||
|     std::make_shared<BOSS_U>(boss)->InstallAsService(service_manager); | ||||
| } | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ namespace Service::BOSS { | |||
| 
 | ||||
| class Module final { | ||||
| public: | ||||
|     Module(); | ||||
|     explicit Module(Core::System& system); | ||||
|     ~Module() = default; | ||||
| 
 | ||||
|     class Interface : public ServiceFramework<Interface> { | ||||
|  |  | |||
|  | @ -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<Module> GetModule(Core::System& system) { | |||
| 
 | ||||
| void InstallInterfaces(Core::System& system) { | ||||
|     auto& service_manager = system.ServiceManager(); | ||||
|     auto cam = std::make_shared<Module>(); | ||||
|     auto cam = std::make_shared<Module>(system); | ||||
| 
 | ||||
|     std::make_shared<CAM_U>(cam)->InstallAsService(service_manager); | ||||
|     std::make_shared<CAM_S>(cam)->InstallAsService(service_manager); | ||||
|  |  | |||
|  | @ -241,7 +241,7 @@ static_assert(sizeof(PackageParameterWithContextDetail) == 28, | |||
| 
 | ||||
| class Module final { | ||||
| public: | ||||
|     Module(); | ||||
|     explicit Module(Core::System& system); | ||||
|     ~Module(); | ||||
|     void ReloadCameraDevices(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1351,10 +1351,11 @@ Module::SessionData::~SessionData() { | |||
| Module::Interface::Interface(std::shared_ptr<Module> 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<Module>(); | ||||
|     auto cecd = std::make_shared<Module>(system); | ||||
|     std::make_shared<CECD_NDM>(cecd)->InstallAsService(service_manager); | ||||
|     std::make_shared<CECD_S>(cecd)->InstallAsService(service_manager); | ||||
|     std::make_shared<CECD_U>(cecd)->InstallAsService(service_manager); | ||||
|  |  | |||
|  | @ -23,7 +23,7 @@ namespace Service::CECD { | |||
| 
 | ||||
| class Module final { | ||||
| public: | ||||
|     Module(); | ||||
|     explicit Module(Core::System& system); | ||||
|     ~Module(); | ||||
| 
 | ||||
|     enum class CecCommand : u32 { | ||||
|  |  | |||
|  | @ -19,10 +19,10 @@ void CSND_SND::Initialize(Kernel::HLERequestContext& ctx) { | |||
|     const u32 offset3 = rp.Pop<u32>(); | ||||
| 
 | ||||
|     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<CSND_SND>()->InstallAsService(service_manager); | ||||
|     std::make_shared<CSND_SND>(system)->InstallAsService(service_manager); | ||||
| } | ||||
| 
 | ||||
| } // namespace Service::CSND
 | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ namespace Service::CSND { | |||
| 
 | ||||
| class CSND_SND final : public ServiceFramework<CSND_SND> { | ||||
| 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<Kernel::Mutex> mutex = nullptr; | ||||
|     Kernel::SharedPtr<Kernel::SharedMemory> shared_memory = nullptr; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<DSP_DSP>(); | ||||
|     auto dsp = std::make_shared<DSP_DSP>(system); | ||||
|     dsp->InstallAsService(service_manager); | ||||
|     Core::DSP().SetServiceToInterrupt(std::move(dsp)); | ||||
| } | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ namespace Service::DSP { | |||
| 
 | ||||
| class DSP_DSP final : public ServiceFramework<DSP_DSP> { | ||||
| public: | ||||
|     DSP_DSP(); | ||||
|     explicit DSP_DSP(Core::System& system); | ||||
|     ~DSP_DSP(); | ||||
| 
 | ||||
|     /// There are three types of interrupts
 | ||||
|  |  | |||
|  | @ -244,7 +244,7 @@ ERR_F::~ERR_F() = default; | |||
| 
 | ||||
| void InstallInterfaces(Core::System& system) { | ||||
|     auto errf = std::make_shared<ERR_F>(system); | ||||
|     errf->InstallAsNamedPort(); | ||||
|     errf->InstallAsNamedPort(system.Kernel()); | ||||
| } | ||||
| 
 | ||||
| } // namespace Service::ERR
 | ||||
|  |  | |||
|  | @ -87,7 +87,7 @@ ResultVal<std::shared_ptr<File>> ArchiveManager::OpenFileFromArchive(ArchiveHand | |||
|     if (backend.Failed()) | ||||
|         return backend.Code(); | ||||
| 
 | ||||
|     auto file = std::shared_ptr<File>(new File(std::move(backend).Unwrap(), path)); | ||||
|     auto file = std::shared_ptr<File>(new File(system, std::move(backend).Unwrap(), path)); | ||||
|     return MakeResult<std::shared_ptr<File>>(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(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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<FileSys::FileBackend>&& backend, const FileSys::Path& path) | ||||
|     : ServiceFramework("", 1), path(path), backend(std::move(backend)) { | ||||
| File::File(Core::System& system, std::unique_ptr<FileSys::FileBackend>&& 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<SharedPtr<ServerSession>>(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<SharedPtr<ServerSession>>(sessions); | ||||
|     ClientConnected(server); | ||||
| 
 | ||||
|  | @ -258,7 +260,7 @@ void File::OpenSubFile(Kernel::HLERequestContext& ctx) { | |||
| } | ||||
| 
 | ||||
| Kernel::SharedPtr<Kernel::ClientSession> File::Connect() { | ||||
|     auto sessions = Kernel::ServerSession::CreateSessionPair(GetName()); | ||||
|     auto sessions = system.Kernel().CreateSessionPair(GetName()); | ||||
|     auto server = std::get<Kernel::SharedPtr<Kernel::ServerSession>>(sessions); | ||||
|     ClientConnected(server); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<File, FileSessionSlot> { | ||||
| public: | ||||
|     File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path); | ||||
|     File(Core::System& system, std::unique_ptr<FileSys::FileBackend>&& 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
 | ||||
|  |  | |||
|  | @ -286,7 +286,7 @@ void FS_USER::OpenDirectory(Kernel::HLERequestContext& ctx) { | |||
|     rb.Push(dir_res.Code()); | ||||
|     if (dir_res.Succeeded()) { | ||||
|         std::shared_ptr<Directory> directory = *dir_res; | ||||
|         auto sessions = ServerSession::CreateSessionPair(directory->GetName()); | ||||
|         auto sessions = system.Kernel().CreateSessionPair(directory->GetName()); | ||||
|         directory->ClientConnected(std::get<SharedPtr<ServerSession>>(sessions)); | ||||
|         rb.PushMoveObjects(std::get<SharedPtr<ClientSession>>(sessions)); | ||||
|     } else { | ||||
|  | @ -741,7 +741,8 @@ void FS_USER::GetSaveDataSecureValue(Kernel::HLERequestContext& ctx) { | |||
|     rb.Push<u64>(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<FS_USER>(system.ArchiveManager())->InstallAsService(service_manager); | ||||
|     std::make_shared<FS_USER>(system)->InstallAsService(service_manager); | ||||
| } | ||||
| } // namespace Service::FS
 | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ class ArchiveManager; | |||
| 
 | ||||
| class FS_USER final : public ServiceFramework<FS_USER> { | ||||
| 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; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
| }; | ||||
|  |  | |||
|  | @ -359,16 +359,16 @@ std::shared_ptr<Module> 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 = | ||||
|  |  | |||
|  | @ -16,10 +16,10 @@ void InstallInterfaces(Core::System& system) { | |||
|     auto& service_manager = system.ServiceManager(); | ||||
|     std::make_shared<IR_U>()->InstallAsService(service_manager); | ||||
| 
 | ||||
|     auto ir_user = std::make_shared<IR_USER>(); | ||||
|     auto ir_user = std::make_shared<IR_USER>(system); | ||||
|     ir_user->InstallAsService(service_manager); | ||||
| 
 | ||||
|     auto ir_rst = std::make_shared<IR_RST>(); | ||||
|     auto ir_rst = std::make_shared<IR_RST>(system); | ||||
|     ir_rst->InstallAsService(service_manager); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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) { | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ union PadState { | |||
| /// Interface to "ir:rst" service
 | ||||
| class IR_RST final : public ServiceFramework<IR_RST> { | ||||
| public: | ||||
|     IR_RST(); | ||||
|     explicit IR_RST(Core::System& system); | ||||
|     ~IR_RST(); | ||||
|     void ReloadInputDevices(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
| #include <boost/crc.hpp> | ||||
| #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<ExtraHID>([this](const std::vector<u8>& data) { PutToReceive(data); }); | ||||
|  |  | |||
|  | @ -55,7 +55,7 @@ private: | |||
| /// Interface to "ir:USER" service
 | ||||
| class IR_USER final : public ServiceFramework<IR_USER> { | ||||
| public: | ||||
|     IR_USER(); | ||||
|     explicit IR_USER(Core::System& system); | ||||
|     ~IR_USER(); | ||||
| 
 | ||||
|     void ReloadInputDevices(); | ||||
|  |  | |||
|  | @ -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<u32>(); | ||||
|  | @ -187,8 +192,7 @@ struct MIC_U::Impl { | |||
|     } | ||||
| 
 | ||||
|     u32 client_version = 0; | ||||
|     Kernel::SharedPtr<Kernel::Event> buffer_full_event = | ||||
|         Kernel::Event::Create(Kernel::ResetType::OneShot, "MIC_U::buffer_full_event"); | ||||
|     Kernel::SharedPtr<Kernel::Event> buffer_full_event; | ||||
|     Kernel::SharedPtr<Kernel::SharedMemory> 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<Impl>()} { | ||||
| MIC_U::MIC_U(Core::System& system) | ||||
|     : ServiceFramework{"mic:u", 1}, impl{std::make_unique<Impl>(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<MIC_U>()->InstallAsService(service_manager); | ||||
|     std::make_shared<MIC_U>(system)->InstallAsService(service_manager); | ||||
| } | ||||
| 
 | ||||
| } // namespace Service::MIC
 | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ namespace Service::MIC { | |||
| 
 | ||||
| class MIC_U final : public ServiceFramework<MIC_U> { | ||||
| public: | ||||
|     MIC_U(); | ||||
|     explicit MIC_U(Core::System& system); | ||||
|     ~MIC_U(); | ||||
| 
 | ||||
| private: | ||||
|  |  | |||
|  | @ -140,18 +140,18 @@ Module::Interface::Interface(std::shared_ptr<Module> 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<Module>(); | ||||
|     auto nfc = std::make_shared<Module>(system); | ||||
|     std::make_shared<NFC_M>(nfc)->InstallAsService(service_manager); | ||||
|     std::make_shared<NFC_U>(nfc)->InstallAsService(service_manager); | ||||
| } | ||||
|  |  | |||
|  | @ -41,7 +41,7 @@ enum class CommunicationStatus : u8 { | |||
| 
 | ||||
| class Module final { | ||||
| public: | ||||
|     Module(); | ||||
|     explicit Module(Core::System& system); | ||||
|     ~Module(); | ||||
| 
 | ||||
|     class Interface : public ServiceFramework<Interface> { | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ void InstallInterfaces(Core::System& system) { | |||
|     auto& service_manager = system.ServiceManager(); | ||||
|     std::make_shared<NIM_AOC>()->InstallAsService(service_manager); | ||||
|     std::make_shared<NIM_S>()->InstallAsService(service_manager); | ||||
|     std::make_shared<NIM_U>()->InstallAsService(service_manager); | ||||
|     std::make_shared<NIM_U>(system)->InstallAsService(service_manager); | ||||
| } | ||||
| 
 | ||||
| } // namespace Service::NIM
 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -6,11 +6,15 @@ | |||
| 
 | ||||
| #include "core/hle/service/service.h" | ||||
| 
 | ||||
| namespace Core { | ||||
| class System; | ||||
| } | ||||
| 
 | ||||
| namespace Service::NIM { | ||||
| 
 | ||||
| class NIM_U final : public ServiceFramework<NIM_U> { | ||||
| public: | ||||
|     NIM_U(); | ||||
|     explicit NIM_U(Core::System& system); | ||||
|     ~NIM_U(); | ||||
| 
 | ||||
| private: | ||||
|  |  | |||
|  | @ -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<std::mutex> 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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -112,6 +112,8 @@ public: | |||
|     ~NWM_UDS(); | ||||
| 
 | ||||
| private: | ||||
|     Core::System& system; | ||||
| 
 | ||||
|     void UpdateNetworkAttribute(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|     /**
 | ||||
|  |  | |||
|  | @ -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<ServerPort> server_port; | ||||
|     SharedPtr<ClientPort> 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::ServiceManager>& 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) | ||||
|  |  | |||
|  | @ -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<Kernel::ServerSession> server_session) override; | ||||
| 
 | ||||
|  | @ -184,7 +185,7 @@ private: | |||
| }; | ||||
| 
 | ||||
| /// Initialize ServiceManager
 | ||||
| void Init(Core::System& system, std::shared_ptr<SM::ServiceManager>& sm); | ||||
| void Init(Core::System& system); | ||||
| 
 | ||||
| /// Shutdown ServiceManager
 | ||||
| void Shutdown(); | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| 
 | ||||
| #include <tuple> | ||||
| #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<ServiceManager> self) { | ||||
|     ASSERT(self->srv_interface.expired()); | ||||
| ServiceManager::ServiceManager(Core::System& system) : system(system) {} | ||||
| 
 | ||||
|     auto srv = std::make_shared<SRV>(self); | ||||
|     srv->InstallAsNamedPort(); | ||||
|     self->srv_interface = srv; | ||||
| void ServiceManager::InstallInterfaces(Core::System& system) { | ||||
|     ASSERT(system.ServiceManager().srv_interface.expired()); | ||||
| 
 | ||||
|     auto srv = std::make_shared<SRV>(system); | ||||
|     srv->InstallAsNamedPort(system.Kernel()); | ||||
|     system.ServiceManager().srv_interface = srv; | ||||
| } | ||||
| 
 | ||||
| ResultVal<Kernel::SharedPtr<Kernel::ServerPort>> ServiceManager::RegisterService( | ||||
|  | @ -39,7 +42,7 @@ ResultVal<Kernel::SharedPtr<Kernel::ServerPort>> ServiceManager::RegisterService | |||
| 
 | ||||
|     Kernel::SharedPtr<Kernel::ServerPort> server_port; | ||||
|     Kernel::SharedPtr<Kernel::ClientPort> 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<Kernel::SharedPtr<Kernel::ServerPort>>(std::move(server_port)); | ||||
|  |  | |||
|  | @ -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<ServiceManager> self); | ||||
|     static void InstallInterfaces(Core::System& system); | ||||
| 
 | ||||
|     explicit ServiceManager(Core::System& system); | ||||
| 
 | ||||
|     ResultVal<Kernel::SharedPtr<Kernel::ServerPort>> RegisterService(std::string name, | ||||
|                                                                      unsigned int max_sessions); | ||||
|  | @ -63,6 +69,7 @@ public: | |||
|     } | ||||
| 
 | ||||
| private: | ||||
|     Core::System& system; | ||||
|     std::weak_ptr<SRV> srv_interface; | ||||
| 
 | ||||
|     /// Map of registered services, retrieved using GetServicePort or ConnectToService.
 | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ | |||
| #include <tuple> | ||||
| #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<ServiceManager> 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"}, | ||||
|  |  | |||
|  | @ -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<SRV> { | ||||
| public: | ||||
|     explicit SRV(std::shared_ptr<ServiceManager> 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<ServiceManager> service_manager; | ||||
|     Core::System& system; | ||||
|     Kernel::SharedPtr<Kernel::Semaphore> notification_semaphore; | ||||
|     std::unordered_map<std::string, Kernel::SharedPtr<Kernel::Event>> | ||||
|         get_service_handle_delayed_map; | ||||
|  |  | |||
|  | @ -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<Y2R_U>()->InstallAsService(service_manager); | ||||
|     std::make_shared<Y2R_U>(system)->InstallAsService(service_manager); | ||||
| } | ||||
| 
 | ||||
| } // namespace Service::Y2R
 | ||||
|  |  | |||
|  | @ -149,7 +149,7 @@ static_assert(sizeof(ConversionParameters) == 12, "ConversionParameters struct h | |||
| 
 | ||||
| class Y2R_U final : public ServiceFramework<Y2R_U> { | ||||
| public: | ||||
|     Y2R_U(); | ||||
|     explicit Y2R_U(Core::System& system); | ||||
|     ~Y2R_U() override; | ||||
| 
 | ||||
| private: | ||||
|  |  | |||
|  | @ -217,7 +217,7 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, | |||
|     } | ||||
| 
 | ||||
|     // Create the CodeSet
 | ||||
|     SharedPtr<CodeSet> code_set = CodeSet::Create("", 0); | ||||
|     SharedPtr<CodeSet> 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<Kernel::Process>& 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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<CodeSet> ElfReader::LoadInto(u32 vaddr) { | |||
|     std::vector<u8> program_image(total_image_size); | ||||
|     std::size_t current_image_position = 0; | ||||
| 
 | ||||
|     SharedPtr<CodeSet> codeset = CodeSet::Create("", 0); | ||||
|     SharedPtr<CodeSet> 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<Kernel::Process>& process) { | |||
|     SharedPtr<CodeSet> 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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -75,7 +75,8 @@ ResultStatus AppLoader_NCCH::LoadExec(Kernel::SharedPtr<Kernel::Process>& proces | |||
|         std::string process_name = Common::StringFromFixedZeroTerminatedBuffer( | ||||
|             (const char*)overlay_ncch->exheader_header.codeset_info.name, 8); | ||||
| 
 | ||||
|         SharedPtr<CodeSet> codeset = CodeSet::Create(process_name, program_id); | ||||
|         SharedPtr<CodeSet> 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<Kernel::Process>& proces | |||
|         codeset->entrypoint = codeset->CodeSegment().addr; | ||||
|         codeset->memory = std::make_shared<std::vector<u8>>(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<Kernel::ResourceLimitCategory>( | ||||
|                 overlay_ncch->exheader_header.arm11_system_local_caps.resource_limit_category)); | ||||
|             Core::System::GetInstance().Kernel().ResourceLimit().GetForCategory( | ||||
|                 static_cast<Kernel::ResourceLimitCategory>( | ||||
|                     overlay_ncch->exheader_header.arm11_system_local_caps.resource_limit_category)); | ||||
| 
 | ||||
|         // Set the default CPU core for this process
 | ||||
|         process->ideal_processor = | ||||
|  |  | |||
|  | @ -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<TestMemory>(this)) { | ||||
| 
 | ||||
|     Kernel::g_current_process = Kernel::Process::Create(Kernel::CodeSet::Create("", 0)); | ||||
|     CoreTiming::Init(); | ||||
|     kernel = std::make_unique<Kernel::KernelSystem>(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) { | ||||
|  |  | |||
|  | @ -5,8 +5,8 @@ | |||
| #include <tuple> | ||||
| #include <unordered_map> | ||||
| #include <vector> | ||||
| 
 | ||||
| #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<TestMemory> test_memory; | ||||
|     std::vector<WriteRecord> write_records; | ||||
| 
 | ||||
|     std::unique_ptr<Kernel::KernelSystem> kernel; | ||||
| }; | ||||
| 
 | ||||
| } // namespace ArmTests
 | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <catch2/catch.hpp> | ||||
| #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<Object> MakeObject() { | ||||
|     return Event::Create(ResetType::OneShot); | ||||
| static SharedPtr<Object> MakeObject(Kernel::KernelSystem& kernel) { | ||||
|     return kernel.CreateEvent(ResetType::OneShot); | ||||
| } | ||||
| 
 | ||||
| TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") { | ||||
|     auto session = std::get<SharedPtr<ServerSession>>(ServerSession::CreateSessionPair()); | ||||
|     CoreTiming::Init(); | ||||
|     Kernel::KernelSystem kernel(0); | ||||
|     auto session = std::get<SharedPtr<ServerSession>>(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<SharedPtr<ServerSession>>(ServerSession::CreateSessionPair()); | ||||
|     CoreTiming::Init(); | ||||
|     Kernel::KernelSystem kernel(0); | ||||
|     auto session = std::get<SharedPtr<ServerSession>>(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
 | ||||
|  |  | |||
|  | @ -3,14 +3,17 @@ | |||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <catch2/catch.hpp> | ||||
| #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(); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue