mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-10-30 23:49:01 -05:00 
			
		
		
		
	Use std::move where appropriate.
This commit is contained in:
		| @@ -179,6 +179,7 @@ set(HEADERS | |||||||
|             hle/config_mem.h |             hle/config_mem.h | ||||||
|             hle/function_wrappers.h |             hle/function_wrappers.h | ||||||
|             hle/hle.h |             hle/hle.h | ||||||
|  |             hle/ipc.h | ||||||
|             hle/applets/applet.h |             hle/applets/applet.h | ||||||
|             hle/applets/erreula.h |             hle/applets/erreula.h | ||||||
|             hle/applets/mii_selector.h |             hle/applets/mii_selector.h | ||||||
|   | |||||||
							
								
								
									
										162
									
								
								src/core/hle/ipc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								src/core/hle/ipc.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,162 @@ | |||||||
|  | // Copyright 2016 Citra Emulator Project | ||||||
|  | // Licensed under GPLv2 or any later version | ||||||
|  | // Refer to the license.txt file included. | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "common/common_types.h" | ||||||
|  | #include "core/hle/kernel/thread.h" | ||||||
|  | #include "core/memory.h" | ||||||
|  |  | ||||||
|  | namespace Kernel { | ||||||
|  | class ServerSession; | ||||||
|  |  | ||||||
|  | // TODO(Subv): Move these declarations out of here | ||||||
|  | static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of header | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Returns a pointer to the command buffer in the current thread's TLS | ||||||
|  |  * TODO(Subv): This is not entirely correct, the command buffer should be copied from | ||||||
|  |  * the thread's TLS to an intermediate buffer in kernel memory, and then copied again to | ||||||
|  |  * the service handler process' memory. | ||||||
|  |  * @param offset Optional offset into command buffer | ||||||
|  |  * @return Pointer to command buffer | ||||||
|  |  */ | ||||||
|  | inline u32* GetCommandBuffer(const int offset = 0) { | ||||||
|  |     return (u32*)Memory::GetPointer(GetCurrentThread()->GetTLSAddress() + kCommandHeaderOffset + | ||||||
|  |                                     offset); | ||||||
|  | } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | namespace IPC { | ||||||
|  |  | ||||||
|  | enum DescriptorType : u32 { | ||||||
|  |     // Buffer related desciptors types (mask : 0x0F) | ||||||
|  |     StaticBuffer = 0x02, | ||||||
|  |     PXIBuffer = 0x04, | ||||||
|  |     MappedBuffer = 0x08, | ||||||
|  |     // Handle related descriptors types (mask : 0x30, but need to check for buffer related | ||||||
|  |     // descriptors first ) | ||||||
|  |     CopyHandle = 0x00, | ||||||
|  |     MoveHandle = 0x10, | ||||||
|  |     CallingPid = 0x20, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Creates a command header to be used for IPC | ||||||
|  |  * @param command_id            ID of the command to create a header for. | ||||||
|  |  * @param normal_params         Size of the normal parameters in words. Up to 63. | ||||||
|  |  * @param translate_params_size Size of the translate parameters in words. Up to 63. | ||||||
|  |  * @return The created IPC header. | ||||||
|  |  * | ||||||
|  |  * Normal parameters are sent directly to the process while the translate parameters might go | ||||||
|  |  * through modifications and checks by the kernel. | ||||||
|  |  * The translate parameters are described by headers generated with the IPC::*Desc functions. | ||||||
|  |  * | ||||||
|  |  * @note While #normal_params is equivalent to the number of normal parameters, | ||||||
|  |  * #translate_params_size includes the size occupied by the translate parameters headers. | ||||||
|  |  */ | ||||||
|  | constexpr u32 MakeHeader(u16 command_id, unsigned int normal_params, | ||||||
|  |                          unsigned int translate_params_size) { | ||||||
|  |     return (u32(command_id) << 16) | ((u32(normal_params) & 0x3F) << 6) | | ||||||
|  |            (u32(translate_params_size) & 0x3F); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | union Header { | ||||||
|  |     u32 raw; | ||||||
|  |     BitField<0, 6, u32> translate_params_size; | ||||||
|  |     BitField<6, 6, u32> normal_params; | ||||||
|  |     BitField<16, 16, u32> command_id; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | inline Header ParseHeader(u32 header) { | ||||||
|  |     return {header}; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | constexpr u32 MoveHandleDesc(u32 num_handles = 1) { | ||||||
|  |     return MoveHandle | ((num_handles - 1) << 26); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | constexpr u32 CopyHandleDesc(u32 num_handles = 1) { | ||||||
|  |     return CopyHandle | ((num_handles - 1) << 26); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | constexpr u32 CallingPidDesc() { | ||||||
|  |     return CallingPid; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | constexpr bool isHandleDescriptor(u32 descriptor) { | ||||||
|  |     return (descriptor & 0xF) == 0x0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | constexpr u32 HandleNumberFromDesc(u32 handle_descriptor) { | ||||||
|  |     return (handle_descriptor >> 26) + 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | constexpr u32 StaticBufferDesc(u32 size, u8 buffer_id) { | ||||||
|  |     return StaticBuffer | (size << 14) | ((buffer_id & 0xF) << 10); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | union StaticBufferDescInfo { | ||||||
|  |     u32 raw; | ||||||
|  |     BitField<10, 4, u32> buffer_id; | ||||||
|  |     BitField<14, 18, u32> size; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | inline StaticBufferDescInfo ParseStaticBufferDesc(const u32 desc) { | ||||||
|  |     return {desc}; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Creates a header describing a buffer to be sent over PXI. | ||||||
|  |  * @param size         Size of the buffer. Max 0x00FFFFFF. | ||||||
|  |  * @param buffer_id    The Id of the buffer. Max 0xF. | ||||||
|  |  * @param is_read_only true if the buffer is read-only. If false, the buffer is considered to have | ||||||
|  |  * read-write access. | ||||||
|  |  * @return The created PXI buffer header. | ||||||
|  |  * | ||||||
|  |  * The next value is a phys-address of a table located in the BASE memregion. | ||||||
|  |  */ | ||||||
|  | inline u32 PXIBufferDesc(u32 size, unsigned buffer_id, bool is_read_only) { | ||||||
|  |     u32 type = PXIBuffer; | ||||||
|  |     if (is_read_only) | ||||||
|  |         type |= 0x2; | ||||||
|  |     return type | (size << 8) | ((buffer_id & 0xF) << 4); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | enum MappedBufferPermissions { | ||||||
|  |     R = 1, | ||||||
|  |     W = 2, | ||||||
|  |     RW = R | W, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | constexpr u32 MappedBufferDesc(u32 size, MappedBufferPermissions perms) { | ||||||
|  |     return MappedBuffer | (size << 4) | (u32(perms) << 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | union MappedBufferDescInfo { | ||||||
|  |     u32 raw; | ||||||
|  |     BitField<4, 28, u32> size; | ||||||
|  |     BitField<1, 2, MappedBufferPermissions> perms; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | inline MappedBufferDescInfo ParseMappedBufferDesc(const u32 desc) { | ||||||
|  |     return{ desc }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | inline DescriptorType GetDescriptorType(u32 descriptor) { | ||||||
|  |     // Note: Those checks must be done in this order | ||||||
|  |     if (isHandleDescriptor(descriptor)) | ||||||
|  |         return (DescriptorType)(descriptor & 0x30); | ||||||
|  |  | ||||||
|  |     // handle the fact that the following descriptors can have rights | ||||||
|  |     if (descriptor & MappedBuffer) | ||||||
|  |         return MappedBuffer; | ||||||
|  |  | ||||||
|  |     if (descriptor & PXIBuffer) | ||||||
|  |         return PXIBuffer; | ||||||
|  |  | ||||||
|  |     return StaticBuffer; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } // namespace IPC | ||||||
| @@ -15,6 +15,9 @@ ClientPort::ClientPort() {} | |||||||
| ClientPort::~ClientPort() {} | ClientPort::~ClientPort() {} | ||||||
|  |  | ||||||
| ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { | ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { | ||||||
|  |     // Note: Threads do not wait for the server endpoint to call | ||||||
|  |     // AcceptSession before returning from this call. | ||||||
|  |  | ||||||
|     if (active_sessions >= max_sessions) { |     if (active_sessions >= max_sessions) { | ||||||
|         return ResultCode(ErrorDescription::MaxConnectionsReached, |         return ResultCode(ErrorDescription::MaxConnectionsReached, | ||||||
|                           ErrorModule::OS, ErrorSummary::WouldBlock, |                           ErrorModule::OS, ErrorSummary::WouldBlock, | ||||||
| @@ -27,7 +30,7 @@ ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { | |||||||
|     auto client_session = std::get<SharedPtr<ClientSession>>(sessions); |     auto client_session = std::get<SharedPtr<ClientSession>>(sessions); | ||||||
|     auto server_session = std::get<SharedPtr<ServerSession>>(sessions); |     auto server_session = std::get<SharedPtr<ServerSession>>(sessions); | ||||||
|  |  | ||||||
|     server_port->pending_sessions.push_back(server_session); |     server_port->pending_sessions.push_back(std::move(server_session)); | ||||||
|  |  | ||||||
|     // Wake the threads waiting on the ServerPort |     // Wake the threads waiting on the ServerPort | ||||||
|     server_port->WakeupAllWaitingThreads(); |     server_port->WakeupAllWaitingThreads(); | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ ResultVal<SharedPtr<ClientSession>> ClientSession::Create(SharedPtr<ServerSessio | |||||||
|     SharedPtr<ClientSession> client_session(new ClientSession); |     SharedPtr<ClientSession> client_session(new ClientSession); | ||||||
|  |  | ||||||
|     client_session->name = std::move(name); |     client_session->name = std::move(name); | ||||||
|     client_session->server_session = server_session; |     client_session->server_session = std::move(server_session); | ||||||
|     return MakeResult<SharedPtr<ClientSession>>(std::move(client_session)); |     return MakeResult<SharedPtr<ClientSession>>(std::move(client_session)); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> ServerPort::CreatePortP | |||||||
|     SharedPtr<ClientPort> client_port(new ClientPort); |     SharedPtr<ClientPort> client_port(new ClientPort); | ||||||
|  |  | ||||||
|     server_port->name = name + "_Server"; |     server_port->name = name + "_Server"; | ||||||
|     server_port->hle_handler = hle_handler; |     server_port->hle_handler = std::move(hle_handler); | ||||||
|     client_port->name = name + "_Client"; |     client_port->name = name + "_Client"; | ||||||
|     client_port->server_port = server_port; |     client_port->server_port = server_port; | ||||||
|     client_port->max_sessions = max_sessions; |     client_port->max_sessions = max_sessions; | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ ResultVal<SharedPtr<ServerSession>> ServerSession::Create(std::string name, std: | |||||||
|  |  | ||||||
|     server_session->name = std::move(name); |     server_session->name = std::move(name); | ||||||
|     server_session->signaled = false; |     server_session->signaled = false; | ||||||
|     server_session->hle_handler = hle_handler; |     server_session->hle_handler = std::move(hle_handler); | ||||||
|  |  | ||||||
|     return MakeResult<SharedPtr<ServerSession>>(std::move(server_session)); |     return MakeResult<SharedPtr<ServerSession>>(std::move(server_session)); | ||||||
| } | } | ||||||
| @@ -46,8 +46,9 @@ ResultCode ServerSession::HandleSyncRequest() { | |||||||
|     return RESULT_SUCCESS; |     return RESULT_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
| std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>> ServerSession::CreateSessionPair(const std::string& name, std::shared_ptr<Service::SessionRequestHandler> hle_handler) { | ServerSession::SessionPair ServerSession::CreateSessionPair(const std::string& name, | ||||||
|     auto server_session = ServerSession::Create(name + "_Server", hle_handler).MoveFrom(); |                                                             std::shared_ptr<Service::SessionRequestHandler> hle_handler) { | ||||||
|  |     auto server_session = ServerSession::Create(name + "_Server", std::move(hle_handler)).MoveFrom(); | ||||||
|     auto client_session = ClientSession::Create(server_session, name + "_Client").MoveFrom(); |     auto client_session = ClientSession::Create(server_session, name + "_Client").MoveFrom(); | ||||||
|  |  | ||||||
|     return std::make_tuple(std::move(server_session), std::move(client_session)); |     return std::make_tuple(std::move(server_session), std::move(client_session)); | ||||||
|   | |||||||
| @@ -40,12 +40,14 @@ public: | |||||||
|         return HANDLE_TYPE; |         return HANDLE_TYPE; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     using SessionPair = std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>>; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Creates a pair of ServerSession and an associated ClientSession. |      * Creates a pair of ServerSession and an associated ClientSession. | ||||||
|      * @param name Optional name of the ports |      * @param name Optional name of the ports | ||||||
|      * @return The created session tuple |      * @return The created session tuple | ||||||
|      */ |      */ | ||||||
|     static std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>> CreateSessionPair(const std::string& name = "Unknown", std::shared_ptr<Service::SessionRequestHandler> hle_handler = nullptr); |     static SessionPair CreateSessionPair(const std::string& name = "Unknown", std::shared_ptr<Service::SessionRequestHandler> hle_handler = nullptr); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Handle a sync request from the emulated application. |      * Handle a sync request from the emulated application. | ||||||
|   | |||||||
| @@ -41,7 +41,7 @@ enum class MediaType : u32 { NAND = 0, SDMC = 1 }; | |||||||
|  |  | ||||||
| typedef u64 ArchiveHandle; | typedef u64 ArchiveHandle; | ||||||
|  |  | ||||||
| class File : public SessionRequestHandler, public std::enable_shared_from_this<File> { | class File final : public SessionRequestHandler, public std::enable_shared_from_this<File> { | ||||||
| public: | public: | ||||||
|     File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path); |     File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path); | ||||||
|     ~File(); |     ~File(); | ||||||
| @@ -58,7 +58,7 @@ protected: | |||||||
|     void HandleSyncRequestImpl(Kernel::SharedPtr<Kernel::ServerSession> server_session) override; |     void HandleSyncRequestImpl(Kernel::SharedPtr<Kernel::ServerSession> server_session) override; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| class Directory : public SessionRequestHandler { | class Directory final : public SessionRequestHandler { | ||||||
| public: | public: | ||||||
|     Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path); |     Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path); | ||||||
|     ~Directory(); |     ~Directory(); | ||||||
|   | |||||||
| @@ -84,6 +84,9 @@ ResultCode SessionRequestHandler::TranslateRequest(Kernel::SharedPtr<Kernel::Ser | |||||||
|     return RESULT_SUCCESS; |     return RESULT_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | Interface::~Interface() = default; | ||||||
|  | Interface::Interface(u32 max_sessions) : max_sessions(max_sessions) { } | ||||||
|  |  | ||||||
| void Interface::HandleSyncRequestImpl(Kernel::SharedPtr<Kernel::ServerSession> server_session) { | void Interface::HandleSyncRequestImpl(Kernel::SharedPtr<Kernel::ServerSession> server_session) { | ||||||
|     // TODO(Subv): Make use of the server_session in the HLE service handlers to distinguish which session triggered each command. |     // TODO(Subv): Make use of the server_session in the HLE service handlers to distinguish which session triggered each command. | ||||||
|  |  | ||||||
| @@ -123,14 +126,14 @@ static void AddNamedPort(Interface* interface_) { | |||||||
|     auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName(), |     auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName(), | ||||||
|                                                     std::shared_ptr<Interface>(interface_)); |                                                     std::shared_ptr<Interface>(interface_)); | ||||||
|     auto client_port = std::get<Kernel::SharedPtr<Kernel::ClientPort>>(ports); |     auto client_port = std::get<Kernel::SharedPtr<Kernel::ClientPort>>(ports); | ||||||
|     g_kernel_named_ports.emplace(interface_->GetPortName(), client_port); |     g_kernel_named_ports.emplace(interface_->GetPortName(), std::move(client_port)); | ||||||
| } | } | ||||||
|  |  | ||||||
| void AddService(Interface* interface_) { | void AddService(Interface* interface_) { | ||||||
|     auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName(), |     auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName(), | ||||||
|                                                     std::shared_ptr<Interface>(interface_)); |                                                     std::shared_ptr<Interface>(interface_)); | ||||||
|     auto client_port = std::get<Kernel::SharedPtr<Kernel::ClientPort>>(ports); |     auto client_port = std::get<Kernel::SharedPtr<Kernel::ClientPort>>(ports); | ||||||
|     g_srv_services.emplace(interface_->GetPortName(), client_port); |     g_srv_services.emplace(interface_->GetPortName(), std::move(client_port)); | ||||||
| } | } | ||||||
|  |  | ||||||
| /// Initialize ServiceManager | /// Initialize ServiceManager | ||||||
|   | |||||||
| @@ -9,165 +9,12 @@ | |||||||
| #include <unordered_map> | #include <unordered_map> | ||||||
| #include <boost/container/flat_map.hpp> | #include <boost/container/flat_map.hpp> | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
|  | #include "core/hle/ipc.h" | ||||||
| #include "core/hle/kernel/client_port.h" | #include "core/hle/kernel/client_port.h" | ||||||
| #include "core/hle/kernel/thread.h" | #include "core/hle/kernel/thread.h" | ||||||
| #include "core/hle/result.h" | #include "core/hle/result.h" | ||||||
| #include "core/memory.h" | #include "core/memory.h" | ||||||
|  |  | ||||||
| namespace Kernel { |  | ||||||
| class ServerSession; |  | ||||||
|  |  | ||||||
| // TODO(Subv): Move these declarations out of here |  | ||||||
| static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of header |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Returns a pointer to the command buffer in the current thread's TLS |  | ||||||
|  * TODO(Subv): This is not entirely correct, the command buffer should be copied from |  | ||||||
|  * the thread's TLS to an intermediate buffer in kernel memory, and then copied again to |  | ||||||
|  * the service handler process' memory. |  | ||||||
|  * @param offset Optional offset into command buffer |  | ||||||
|  * @return Pointer to command buffer |  | ||||||
|  */ |  | ||||||
| inline u32* GetCommandBuffer(const int offset = 0) { |  | ||||||
|     return (u32*)Memory::GetPointer(GetCurrentThread()->GetTLSAddress() + kCommandHeaderOffset + |  | ||||||
|                                     offset); |  | ||||||
| } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // TODO(Subv): Move this namespace out of here |  | ||||||
| namespace IPC { |  | ||||||
|  |  | ||||||
| enum DescriptorType : u32 { |  | ||||||
|     // Buffer related desciptors types (mask : 0x0F) |  | ||||||
|     StaticBuffer = 0x02, |  | ||||||
|     PXIBuffer = 0x04, |  | ||||||
|     MappedBuffer = 0x08, |  | ||||||
|     // Handle related descriptors types (mask : 0x30, but need to check for buffer related |  | ||||||
|     // descriptors first ) |  | ||||||
|     CopyHandle = 0x00, |  | ||||||
|     MoveHandle = 0x10, |  | ||||||
|     CallingPid = 0x20, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * @brief Creates a command header to be used for IPC |  | ||||||
|  * @param command_id            ID of the command to create a header for. |  | ||||||
|  * @param normal_params         Size of the normal parameters in words. Up to 63. |  | ||||||
|  * @param translate_params_size Size of the translate parameters in words. Up to 63. |  | ||||||
|  * @return The created IPC header. |  | ||||||
|  * |  | ||||||
|  * Normal parameters are sent directly to the process while the translate parameters might go |  | ||||||
|  * through modifications and checks by the kernel. |  | ||||||
|  * The translate parameters are described by headers generated with the IPC::*Desc functions. |  | ||||||
|  * |  | ||||||
|  * @note While #normal_params is equivalent to the number of normal parameters, |  | ||||||
|  * #translate_params_size includes the size occupied by the translate parameters headers. |  | ||||||
|  */ |  | ||||||
| constexpr u32 MakeHeader(u16 command_id, unsigned int normal_params, |  | ||||||
|                          unsigned int translate_params_size) { |  | ||||||
|     return (u32(command_id) << 16) | ((u32(normal_params) & 0x3F) << 6) | |  | ||||||
|            (u32(translate_params_size) & 0x3F); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| union Header { |  | ||||||
|     u32 raw; |  | ||||||
|     BitField<0, 6, u32> translate_params_size; |  | ||||||
|     BitField<6, 6, u32> normal_params; |  | ||||||
|     BitField<16, 16, u32> command_id; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| inline Header ParseHeader(u32 header) { |  | ||||||
|     return {header}; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| constexpr u32 MoveHandleDesc(u32 num_handles = 1) { |  | ||||||
|     return MoveHandle | ((num_handles - 1) << 26); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| constexpr u32 CopyHandleDesc(u32 num_handles = 1) { |  | ||||||
|     return CopyHandle | ((num_handles - 1) << 26); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| constexpr u32 CallingPidDesc() { |  | ||||||
|     return CallingPid; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| constexpr bool isHandleDescriptor(u32 descriptor) { |  | ||||||
|     return (descriptor & 0xF) == 0x0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| constexpr u32 HandleNumberFromDesc(u32 handle_descriptor) { |  | ||||||
|     return (handle_descriptor >> 26) + 1; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| constexpr u32 StaticBufferDesc(u32 size, u8 buffer_id) { |  | ||||||
|     return StaticBuffer | (size << 14) | ((buffer_id & 0xF) << 10); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| union StaticBufferDescInfo { |  | ||||||
|     u32 raw; |  | ||||||
|     BitField<10, 4, u32> buffer_id; |  | ||||||
|     BitField<14, 18, u32> size; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| inline StaticBufferDescInfo ParseStaticBufferDesc(const u32 desc) { |  | ||||||
|     return {desc}; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * @brief Creates a header describing a buffer to be sent over PXI. |  | ||||||
|  * @param size         Size of the buffer. Max 0x00FFFFFF. |  | ||||||
|  * @param buffer_id    The Id of the buffer. Max 0xF. |  | ||||||
|  * @param is_read_only true if the buffer is read-only. If false, the buffer is considered to have |  | ||||||
|  * read-write access. |  | ||||||
|  * @return The created PXI buffer header. |  | ||||||
|  * |  | ||||||
|  * The next value is a phys-address of a table located in the BASE memregion. |  | ||||||
|  */ |  | ||||||
| inline u32 PXIBufferDesc(u32 size, unsigned buffer_id, bool is_read_only) { |  | ||||||
|     u32 type = PXIBuffer; |  | ||||||
|     if (is_read_only) |  | ||||||
|         type |= 0x2; |  | ||||||
|     return type | (size << 8) | ((buffer_id & 0xF) << 4); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| enum MappedBufferPermissions { |  | ||||||
|     R = 1, |  | ||||||
|     W = 2, |  | ||||||
|     RW = R | W, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| constexpr u32 MappedBufferDesc(u32 size, MappedBufferPermissions perms) { |  | ||||||
|     return MappedBuffer | (size << 4) | (u32(perms) << 1); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| union MappedBufferDescInfo { |  | ||||||
|     u32 raw; |  | ||||||
|     BitField<4, 28, u32> size; |  | ||||||
|     BitField<1, 2, MappedBufferPermissions> perms; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| inline MappedBufferDescInfo ParseMappedBufferDesc(const u32 desc) { |  | ||||||
|     return{ desc }; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| inline DescriptorType GetDescriptorType(u32 descriptor) { |  | ||||||
|     // Note: Those checks must be done in this order |  | ||||||
|     if (isHandleDescriptor(descriptor)) |  | ||||||
|         return (DescriptorType)(descriptor & 0x30); |  | ||||||
|  |  | ||||||
|     // handle the fact that the following descriptors can have rights |  | ||||||
|     if (descriptor & MappedBuffer) |  | ||||||
|         return MappedBuffer; |  | ||||||
|  |  | ||||||
|     if (descriptor & PXIBuffer) |  | ||||||
|         return PXIBuffer; |  | ||||||
|  |  | ||||||
|     return StaticBuffer; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| } // namespace IPC |  | ||||||
|  |  | ||||||
| //////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
| // Namespace Service | // Namespace Service | ||||||
|  |  | ||||||
| @@ -220,9 +67,9 @@ public: | |||||||
|      * @param max_sessions Maximum number of sessions that can be |      * @param max_sessions Maximum number of sessions that can be | ||||||
|      * connected to this service at the same time. |      * connected to this service at the same time. | ||||||
|      */ |      */ | ||||||
|     Interface(u32 max_sessions = DefaultMaxSessions) : max_sessions(max_sessions) { } |     Interface(u32 max_sessions = DefaultMaxSessions); | ||||||
|  |  | ||||||
|     virtual ~Interface() = default; |     virtual ~Interface(); | ||||||
|  |  | ||||||
|     std::string GetName() const { |     std::string GetName() const { | ||||||
|         return GetPortName(); |         return GetPortName(); | ||||||
|   | |||||||
| @@ -87,12 +87,7 @@ static void GetServiceHandle(Service::Interface* self) { | |||||||
|     if (it != Service::g_srv_services.end()) { |     if (it != Service::g_srv_services.end()) { | ||||||
|         auto client_port = it->second; |         auto client_port = it->second; | ||||||
|  |  | ||||||
|         // Note: Threads do not wait for the server endpoint to call |  | ||||||
|         // AcceptSession before returning from this call. |  | ||||||
|  |  | ||||||
|         // Connect to the port and retrieve the client endpoint of the connection Session. |  | ||||||
|         auto client_session = client_port->Connect(); |         auto client_session = client_port->Connect(); | ||||||
|  |  | ||||||
|         res = client_session.Code(); |         res = client_session.Code(); | ||||||
|  |  | ||||||
|         if (client_session.Succeeded()) { |         if (client_session.Succeeded()) { | ||||||
|   | |||||||
| @@ -226,19 +226,15 @@ static ResultCode ConnectToPort(Handle* out_handle, const char* port_name) { | |||||||
|  |  | ||||||
|     auto client_port = it->second; |     auto client_port = it->second; | ||||||
|  |  | ||||||
|     // Connect to the port and retrieve the client endpoint of the connection Session. |  | ||||||
|     SharedPtr<Kernel::ClientSession> client_session; |     SharedPtr<Kernel::ClientSession> client_session; | ||||||
|     CASCADE_RESULT(client_session, client_port->Connect()); |     CASCADE_RESULT(client_session, client_port->Connect()); | ||||||
|  |  | ||||||
|     // Note: Threads do not wait for the server endpoint to call |  | ||||||
|     // AcceptSession before returning from this call. |  | ||||||
|  |  | ||||||
|     // Return the client session |     // Return the client session | ||||||
|     CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(client_session)); |     CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(client_session)); | ||||||
|     return RESULT_SUCCESS; |     return RESULT_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
| /// Synchronize to an OS service | /// Makes a blocking IPC call to an OS service. | ||||||
| static ResultCode SendSyncRequest(Handle handle) { | static ResultCode SendSyncRequest(Handle handle) { | ||||||
|     SharedPtr<Kernel::ClientSession> session = Kernel::g_handle_table.Get<Kernel::ClientSession>(handle); |     SharedPtr<Kernel::ClientSession> session = Kernel::g_handle_table.Get<Kernel::ClientSession>(handle); | ||||||
|     if (session == nullptr) { |     if (session == nullptr) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Subv
					Subv