diff options
| author | 2016-12-08 11:06:19 -0500 | |
|---|---|---|
| committer | 2016-12-08 11:06:19 -0500 | |
| commit | f9bcf895103e5a6d99f5fe755bcac92b7781fd38 (patch) | |
| tree | aebba4794da82175756a09e7d4d1de8d835bf412 /src | |
| parent | Return an error code when connecting to a saturated port. (diff) | |
| download | yuzu-f9bcf895103e5a6d99f5fe755bcac92b7781fd38.tar.gz yuzu-f9bcf895103e5a6d99f5fe755bcac92b7781fd38.tar.xz yuzu-f9bcf895103e5a6d99f5fe755bcac92b7781fd38.zip | |
Use std::move where appropriate.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/core/hle/ipc.h | 162 | ||||
| -rw-r--r-- | src/core/hle/kernel/client_port.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/kernel/client_session.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/server_port.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/server_session.cpp | 7 | ||||
| -rw-r--r-- | src/core/hle/kernel/server_session.h | 4 | ||||
| -rw-r--r-- | src/core/hle/service/fs/archive.h | 4 | ||||
| -rw-r--r-- | src/core/hle/service/service.cpp | 7 | ||||
| -rw-r--r-- | src/core/hle/service/service.h | 159 | ||||
| -rw-r--r-- | src/core/hle/service/srv.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/svc.cpp | 6 |
12 files changed, 187 insertions, 177 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 59260d2e8..5d2537202 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -179,6 +179,7 @@ set(HEADERS | |||
| 179 | hle/config_mem.h | 179 | hle/config_mem.h |
| 180 | hle/function_wrappers.h | 180 | hle/function_wrappers.h |
| 181 | hle/hle.h | 181 | hle/hle.h |
| 182 | hle/ipc.h | ||
| 182 | hle/applets/applet.h | 183 | hle/applets/applet.h |
| 183 | hle/applets/erreula.h | 184 | hle/applets/erreula.h |
| 184 | hle/applets/mii_selector.h | 185 | hle/applets/mii_selector.h |
diff --git a/src/core/hle/ipc.h b/src/core/hle/ipc.h new file mode 100644 index 000000000..90ea4d191 --- /dev/null +++ b/src/core/hle/ipc.h | |||
| @@ -0,0 +1,162 @@ | |||
| 1 | // Copyright 2016 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/common_types.h" | ||
| 8 | #include "core/hle/kernel/thread.h" | ||
| 9 | #include "core/memory.h" | ||
| 10 | |||
| 11 | namespace Kernel { | ||
| 12 | class ServerSession; | ||
| 13 | |||
| 14 | // TODO(Subv): Move these declarations out of here | ||
| 15 | static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of header | ||
| 16 | |||
| 17 | /** | ||
| 18 | * Returns a pointer to the command buffer in the current thread's TLS | ||
| 19 | * TODO(Subv): This is not entirely correct, the command buffer should be copied from | ||
| 20 | * the thread's TLS to an intermediate buffer in kernel memory, and then copied again to | ||
| 21 | * the service handler process' memory. | ||
| 22 | * @param offset Optional offset into command buffer | ||
| 23 | * @return Pointer to command buffer | ||
| 24 | */ | ||
| 25 | inline u32* GetCommandBuffer(const int offset = 0) { | ||
| 26 | return (u32*)Memory::GetPointer(GetCurrentThread()->GetTLSAddress() + kCommandHeaderOffset + | ||
| 27 | offset); | ||
| 28 | } | ||
| 29 | } | ||
| 30 | |||
| 31 | namespace IPC { | ||
| 32 | |||
| 33 | enum DescriptorType : u32 { | ||
| 34 | // Buffer related desciptors types (mask : 0x0F) | ||
| 35 | StaticBuffer = 0x02, | ||
| 36 | PXIBuffer = 0x04, | ||
| 37 | MappedBuffer = 0x08, | ||
| 38 | // Handle related descriptors types (mask : 0x30, but need to check for buffer related | ||
| 39 | // descriptors first ) | ||
| 40 | CopyHandle = 0x00, | ||
| 41 | MoveHandle = 0x10, | ||
| 42 | CallingPid = 0x20, | ||
| 43 | }; | ||
| 44 | |||
| 45 | /** | ||
| 46 | * @brief Creates a command header to be used for IPC | ||
| 47 | * @param command_id ID of the command to create a header for. | ||
| 48 | * @param normal_params Size of the normal parameters in words. Up to 63. | ||
| 49 | * @param translate_params_size Size of the translate parameters in words. Up to 63. | ||
| 50 | * @return The created IPC header. | ||
| 51 | * | ||
| 52 | * Normal parameters are sent directly to the process while the translate parameters might go | ||
| 53 | * through modifications and checks by the kernel. | ||
| 54 | * The translate parameters are described by headers generated with the IPC::*Desc functions. | ||
| 55 | * | ||
| 56 | * @note While #normal_params is equivalent to the number of normal parameters, | ||
| 57 | * #translate_params_size includes the size occupied by the translate parameters headers. | ||
| 58 | */ | ||
| 59 | constexpr u32 MakeHeader(u16 command_id, unsigned int normal_params, | ||
| 60 | unsigned int translate_params_size) { | ||
| 61 | return (u32(command_id) << 16) | ((u32(normal_params) & 0x3F) << 6) | | ||
| 62 | (u32(translate_params_size) & 0x3F); | ||
| 63 | } | ||
| 64 | |||
| 65 | union Header { | ||
| 66 | u32 raw; | ||
| 67 | BitField<0, 6, u32> translate_params_size; | ||
| 68 | BitField<6, 6, u32> normal_params; | ||
| 69 | BitField<16, 16, u32> command_id; | ||
| 70 | }; | ||
| 71 | |||
| 72 | inline Header ParseHeader(u32 header) { | ||
| 73 | return {header}; | ||
| 74 | } | ||
| 75 | |||
| 76 | constexpr u32 MoveHandleDesc(u32 num_handles = 1) { | ||
| 77 | return MoveHandle | ((num_handles - 1) << 26); | ||
| 78 | } | ||
| 79 | |||
| 80 | constexpr u32 CopyHandleDesc(u32 num_handles = 1) { | ||
| 81 | return CopyHandle | ((num_handles - 1) << 26); | ||
| 82 | } | ||
| 83 | |||
| 84 | constexpr u32 CallingPidDesc() { | ||
| 85 | return CallingPid; | ||
| 86 | } | ||
| 87 | |||
| 88 | constexpr bool isHandleDescriptor(u32 descriptor) { | ||
| 89 | return (descriptor & 0xF) == 0x0; | ||
| 90 | } | ||
| 91 | |||
| 92 | constexpr u32 HandleNumberFromDesc(u32 handle_descriptor) { | ||
| 93 | return (handle_descriptor >> 26) + 1; | ||
| 94 | } | ||
| 95 | |||
| 96 | constexpr u32 StaticBufferDesc(u32 size, u8 buffer_id) { | ||
| 97 | return StaticBuffer | (size << 14) | ((buffer_id & 0xF) << 10); | ||
| 98 | } | ||
| 99 | |||
| 100 | union StaticBufferDescInfo { | ||
| 101 | u32 raw; | ||
| 102 | BitField<10, 4, u32> buffer_id; | ||
| 103 | BitField<14, 18, u32> size; | ||
| 104 | }; | ||
| 105 | |||
| 106 | inline StaticBufferDescInfo ParseStaticBufferDesc(const u32 desc) { | ||
| 107 | return {desc}; | ||
| 108 | } | ||
| 109 | |||
| 110 | /** | ||
| 111 | * @brief Creates a header describing a buffer to be sent over PXI. | ||
| 112 | * @param size Size of the buffer. Max 0x00FFFFFF. | ||
| 113 | * @param buffer_id The Id of the buffer. Max 0xF. | ||
| 114 | * @param is_read_only true if the buffer is read-only. If false, the buffer is considered to have | ||
| 115 | * read-write access. | ||
| 116 | * @return The created PXI buffer header. | ||
| 117 | * | ||
| 118 | * The next value is a phys-address of a table located in the BASE memregion. | ||
| 119 | */ | ||
| 120 | inline u32 PXIBufferDesc(u32 size, unsigned buffer_id, bool is_read_only) { | ||
| 121 | u32 type = PXIBuffer; | ||
| 122 | if (is_read_only) | ||
| 123 | type |= 0x2; | ||
| 124 | return type | (size << 8) | ((buffer_id & 0xF) << 4); | ||
| 125 | } | ||
| 126 | |||
| 127 | enum MappedBufferPermissions { | ||
| 128 | R = 1, | ||
| 129 | W = 2, | ||
| 130 | RW = R | W, | ||
| 131 | }; | ||
| 132 | |||
| 133 | constexpr u32 MappedBufferDesc(u32 size, MappedBufferPermissions perms) { | ||
| 134 | return MappedBuffer | (size << 4) | (u32(perms) << 1); | ||
| 135 | } | ||
| 136 | |||
| 137 | union MappedBufferDescInfo { | ||
| 138 | u32 raw; | ||
| 139 | BitField<4, 28, u32> size; | ||
| 140 | BitField<1, 2, MappedBufferPermissions> perms; | ||
| 141 | }; | ||
| 142 | |||
| 143 | inline MappedBufferDescInfo ParseMappedBufferDesc(const u32 desc) { | ||
| 144 | return{ desc }; | ||
| 145 | } | ||
| 146 | |||
| 147 | inline DescriptorType GetDescriptorType(u32 descriptor) { | ||
| 148 | // Note: Those checks must be done in this order | ||
| 149 | if (isHandleDescriptor(descriptor)) | ||
| 150 | return (DescriptorType)(descriptor & 0x30); | ||
| 151 | |||
| 152 | // handle the fact that the following descriptors can have rights | ||
| 153 | if (descriptor & MappedBuffer) | ||
| 154 | return MappedBuffer; | ||
| 155 | |||
| 156 | if (descriptor & PXIBuffer) | ||
| 157 | return PXIBuffer; | ||
| 158 | |||
| 159 | return StaticBuffer; | ||
| 160 | } | ||
| 161 | |||
| 162 | } // namespace IPC | ||
diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index 120ce554d..20179e546 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp | |||
| @@ -15,6 +15,9 @@ ClientPort::ClientPort() {} | |||
| 15 | ClientPort::~ClientPort() {} | 15 | ClientPort::~ClientPort() {} |
| 16 | 16 | ||
| 17 | ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { | 17 | ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { |
| 18 | // Note: Threads do not wait for the server endpoint to call | ||
| 19 | // AcceptSession before returning from this call. | ||
| 20 | |||
| 18 | if (active_sessions >= max_sessions) { | 21 | if (active_sessions >= max_sessions) { |
| 19 | return ResultCode(ErrorDescription::MaxConnectionsReached, | 22 | return ResultCode(ErrorDescription::MaxConnectionsReached, |
| 20 | ErrorModule::OS, ErrorSummary::WouldBlock, | 23 | ErrorModule::OS, ErrorSummary::WouldBlock, |
| @@ -27,7 +30,7 @@ ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { | |||
| 27 | auto client_session = std::get<SharedPtr<ClientSession>>(sessions); | 30 | auto client_session = std::get<SharedPtr<ClientSession>>(sessions); |
| 28 | auto server_session = std::get<SharedPtr<ServerSession>>(sessions); | 31 | auto server_session = std::get<SharedPtr<ServerSession>>(sessions); |
| 29 | 32 | ||
| 30 | server_port->pending_sessions.push_back(server_session); | 33 | server_port->pending_sessions.push_back(std::move(server_session)); |
| 31 | 34 | ||
| 32 | // Wake the threads waiting on the ServerPort | 35 | // Wake the threads waiting on the ServerPort |
| 33 | server_port->WakeupAllWaitingThreads(); | 36 | server_port->WakeupAllWaitingThreads(); |
diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp index 6c577610d..30ef10764 100644 --- a/src/core/hle/kernel/client_session.cpp +++ b/src/core/hle/kernel/client_session.cpp | |||
| @@ -16,7 +16,7 @@ ResultVal<SharedPtr<ClientSession>> ClientSession::Create(SharedPtr<ServerSessio | |||
| 16 | SharedPtr<ClientSession> client_session(new ClientSession); | 16 | SharedPtr<ClientSession> client_session(new ClientSession); |
| 17 | 17 | ||
| 18 | client_session->name = std::move(name); | 18 | client_session->name = std::move(name); |
| 19 | client_session->server_session = server_session; | 19 | client_session->server_session = std::move(server_session); |
| 20 | return MakeResult<SharedPtr<ClientSession>>(std::move(client_session)); | 20 | return MakeResult<SharedPtr<ClientSession>>(std::move(client_session)); |
| 21 | } | 21 | } |
| 22 | 22 | ||
diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index f90fe76d5..f7699f023 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp | |||
| @@ -30,7 +30,7 @@ std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> ServerPort::CreatePortP | |||
| 30 | SharedPtr<ClientPort> client_port(new ClientPort); | 30 | SharedPtr<ClientPort> client_port(new ClientPort); |
| 31 | 31 | ||
| 32 | server_port->name = name + "_Server"; | 32 | server_port->name = name + "_Server"; |
| 33 | server_port->hle_handler = hle_handler; | 33 | server_port->hle_handler = std::move(hle_handler); |
| 34 | client_port->name = name + "_Client"; | 34 | client_port->name = name + "_Client"; |
| 35 | client_port->server_port = server_port; | 35 | client_port->server_port = server_port; |
| 36 | client_port->max_sessions = max_sessions; | 36 | client_port->max_sessions = max_sessions; |
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 3782cb493..f8bccadfd 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp | |||
| @@ -18,7 +18,7 @@ ResultVal<SharedPtr<ServerSession>> ServerSession::Create(std::string name, std: | |||
| 18 | 18 | ||
| 19 | server_session->name = std::move(name); | 19 | server_session->name = std::move(name); |
| 20 | server_session->signaled = false; | 20 | server_session->signaled = false; |
| 21 | server_session->hle_handler = hle_handler; | 21 | server_session->hle_handler = std::move(hle_handler); |
| 22 | 22 | ||
| 23 | return MakeResult<SharedPtr<ServerSession>>(std::move(server_session)); | 23 | return MakeResult<SharedPtr<ServerSession>>(std::move(server_session)); |
| 24 | } | 24 | } |
| @@ -46,8 +46,9 @@ ResultCode ServerSession::HandleSyncRequest() { | |||
| 46 | return RESULT_SUCCESS; | 46 | return RESULT_SUCCESS; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>> ServerSession::CreateSessionPair(const std::string& name, std::shared_ptr<Service::SessionRequestHandler> hle_handler) { | 49 | ServerSession::SessionPair ServerSession::CreateSessionPair(const std::string& name, |
| 50 | auto server_session = ServerSession::Create(name + "_Server", hle_handler).MoveFrom(); | 50 | std::shared_ptr<Service::SessionRequestHandler> hle_handler) { |
| 51 | auto server_session = ServerSession::Create(name + "_Server", std::move(hle_handler)).MoveFrom(); | ||
| 51 | auto client_session = ClientSession::Create(server_session, name + "_Client").MoveFrom(); | 52 | auto client_session = ClientSession::Create(server_session, name + "_Client").MoveFrom(); |
| 52 | 53 | ||
| 53 | return std::make_tuple(std::move(server_session), std::move(client_session)); | 54 | return std::make_tuple(std::move(server_session), std::move(client_session)); |
diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index c73ccee73..7f00db07b 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h | |||
| @@ -40,12 +40,14 @@ public: | |||
| 40 | return HANDLE_TYPE; | 40 | return HANDLE_TYPE; |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | using SessionPair = std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>>; | ||
| 44 | |||
| 43 | /** | 45 | /** |
| 44 | * Creates a pair of ServerSession and an associated ClientSession. | 46 | * Creates a pair of ServerSession and an associated ClientSession. |
| 45 | * @param name Optional name of the ports | 47 | * @param name Optional name of the ports |
| 46 | * @return The created session tuple | 48 | * @return The created session tuple |
| 47 | */ | 49 | */ |
| 48 | static std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>> CreateSessionPair(const std::string& name = "Unknown", std::shared_ptr<Service::SessionRequestHandler> hle_handler = nullptr); | 50 | static SessionPair CreateSessionPair(const std::string& name = "Unknown", std::shared_ptr<Service::SessionRequestHandler> hle_handler = nullptr); |
| 49 | 51 | ||
| 50 | /** | 52 | /** |
| 51 | * Handle a sync request from the emulated application. | 53 | * Handle a sync request from the emulated application. |
diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index cb014b5d7..09a922fb5 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h | |||
| @@ -41,7 +41,7 @@ enum class MediaType : u32 { NAND = 0, SDMC = 1 }; | |||
| 41 | 41 | ||
| 42 | typedef u64 ArchiveHandle; | 42 | typedef u64 ArchiveHandle; |
| 43 | 43 | ||
| 44 | class File : public SessionRequestHandler, public std::enable_shared_from_this<File> { | 44 | class File final : public SessionRequestHandler, public std::enable_shared_from_this<File> { |
| 45 | public: | 45 | public: |
| 46 | File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path); | 46 | File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path); |
| 47 | ~File(); | 47 | ~File(); |
| @@ -58,7 +58,7 @@ protected: | |||
| 58 | void HandleSyncRequestImpl(Kernel::SharedPtr<Kernel::ServerSession> server_session) override; | 58 | void HandleSyncRequestImpl(Kernel::SharedPtr<Kernel::ServerSession> server_session) override; |
| 59 | }; | 59 | }; |
| 60 | 60 | ||
| 61 | class Directory : public SessionRequestHandler { | 61 | class Directory final : public SessionRequestHandler { |
| 62 | public: | 62 | public: |
| 63 | Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path); | 63 | Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path); |
| 64 | ~Directory(); | 64 | ~Directory(); |
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 3d5e3058c..6ea5cf745 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -84,6 +84,9 @@ ResultCode SessionRequestHandler::TranslateRequest(Kernel::SharedPtr<Kernel::Ser | |||
| 84 | return RESULT_SUCCESS; | 84 | return RESULT_SUCCESS; |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | Interface::~Interface() = default; | ||
| 88 | Interface::Interface(u32 max_sessions) : max_sessions(max_sessions) { } | ||
| 89 | |||
| 87 | void Interface::HandleSyncRequestImpl(Kernel::SharedPtr<Kernel::ServerSession> server_session) { | 90 | void Interface::HandleSyncRequestImpl(Kernel::SharedPtr<Kernel::ServerSession> server_session) { |
| 88 | // TODO(Subv): Make use of the server_session in the HLE service handlers to distinguish which session triggered each command. | 91 | // TODO(Subv): Make use of the server_session in the HLE service handlers to distinguish which session triggered each command. |
| 89 | 92 | ||
| @@ -123,14 +126,14 @@ static void AddNamedPort(Interface* interface_) { | |||
| 123 | auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName(), | 126 | auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName(), |
| 124 | std::shared_ptr<Interface>(interface_)); | 127 | std::shared_ptr<Interface>(interface_)); |
| 125 | auto client_port = std::get<Kernel::SharedPtr<Kernel::ClientPort>>(ports); | 128 | auto client_port = std::get<Kernel::SharedPtr<Kernel::ClientPort>>(ports); |
| 126 | g_kernel_named_ports.emplace(interface_->GetPortName(), client_port); | 129 | g_kernel_named_ports.emplace(interface_->GetPortName(), std::move(client_port)); |
| 127 | } | 130 | } |
| 128 | 131 | ||
| 129 | void AddService(Interface* interface_) { | 132 | void AddService(Interface* interface_) { |
| 130 | auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName(), | 133 | auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName(), |
| 131 | std::shared_ptr<Interface>(interface_)); | 134 | std::shared_ptr<Interface>(interface_)); |
| 132 | auto client_port = std::get<Kernel::SharedPtr<Kernel::ClientPort>>(ports); | 135 | auto client_port = std::get<Kernel::SharedPtr<Kernel::ClientPort>>(ports); |
| 133 | g_srv_services.emplace(interface_->GetPortName(), client_port); | 136 | g_srv_services.emplace(interface_->GetPortName(), std::move(client_port)); |
| 134 | } | 137 | } |
| 135 | 138 | ||
| 136 | /// Initialize ServiceManager | 139 | /// Initialize ServiceManager |
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 2274e50ca..ba5ba062e 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h | |||
| @@ -9,165 +9,12 @@ | |||
| 9 | #include <unordered_map> | 9 | #include <unordered_map> |
| 10 | #include <boost/container/flat_map.hpp> | 10 | #include <boost/container/flat_map.hpp> |
| 11 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 12 | #include "core/hle/ipc.h" | ||
| 12 | #include "core/hle/kernel/client_port.h" | 13 | #include "core/hle/kernel/client_port.h" |
| 13 | #include "core/hle/kernel/thread.h" | 14 | #include "core/hle/kernel/thread.h" |
| 14 | #include "core/hle/result.h" | 15 | #include "core/hle/result.h" |
| 15 | #include "core/memory.h" | 16 | #include "core/memory.h" |
| 16 | 17 | ||
| 17 | namespace Kernel { | ||
| 18 | class ServerSession; | ||
| 19 | |||
| 20 | // TODO(Subv): Move these declarations out of here | ||
| 21 | static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of header | ||
| 22 | |||
| 23 | /** | ||
| 24 | * Returns a pointer to the command buffer in the current thread's TLS | ||
| 25 | * TODO(Subv): This is not entirely correct, the command buffer should be copied from | ||
| 26 | * the thread's TLS to an intermediate buffer in kernel memory, and then copied again to | ||
| 27 | * the service handler process' memory. | ||
| 28 | * @param offset Optional offset into command buffer | ||
| 29 | * @return Pointer to command buffer | ||
| 30 | */ | ||
| 31 | inline u32* GetCommandBuffer(const int offset = 0) { | ||
| 32 | return (u32*)Memory::GetPointer(GetCurrentThread()->GetTLSAddress() + kCommandHeaderOffset + | ||
| 33 | offset); | ||
| 34 | } | ||
| 35 | } | ||
| 36 | |||
| 37 | // TODO(Subv): Move this namespace out of here | ||
| 38 | namespace IPC { | ||
| 39 | |||
| 40 | enum DescriptorType : u32 { | ||
| 41 | // Buffer related desciptors types (mask : 0x0F) | ||
| 42 | StaticBuffer = 0x02, | ||
| 43 | PXIBuffer = 0x04, | ||
| 44 | MappedBuffer = 0x08, | ||
| 45 | // Handle related descriptors types (mask : 0x30, but need to check for buffer related | ||
| 46 | // descriptors first ) | ||
| 47 | CopyHandle = 0x00, | ||
| 48 | MoveHandle = 0x10, | ||
| 49 | CallingPid = 0x20, | ||
| 50 | }; | ||
| 51 | |||
| 52 | /** | ||
| 53 | * @brief Creates a command header to be used for IPC | ||
| 54 | * @param command_id ID of the command to create a header for. | ||
| 55 | * @param normal_params Size of the normal parameters in words. Up to 63. | ||
| 56 | * @param translate_params_size Size of the translate parameters in words. Up to 63. | ||
| 57 | * @return The created IPC header. | ||
| 58 | * | ||
| 59 | * Normal parameters are sent directly to the process while the translate parameters might go | ||
| 60 | * through modifications and checks by the kernel. | ||
| 61 | * The translate parameters are described by headers generated with the IPC::*Desc functions. | ||
| 62 | * | ||
| 63 | * @note While #normal_params is equivalent to the number of normal parameters, | ||
| 64 | * #translate_params_size includes the size occupied by the translate parameters headers. | ||
| 65 | */ | ||
| 66 | constexpr u32 MakeHeader(u16 command_id, unsigned int normal_params, | ||
| 67 | unsigned int translate_params_size) { | ||
| 68 | return (u32(command_id) << 16) | ((u32(normal_params) & 0x3F) << 6) | | ||
| 69 | (u32(translate_params_size) & 0x3F); | ||
| 70 | } | ||
| 71 | |||
| 72 | union Header { | ||
| 73 | u32 raw; | ||
| 74 | BitField<0, 6, u32> translate_params_size; | ||
| 75 | BitField<6, 6, u32> normal_params; | ||
| 76 | BitField<16, 16, u32> command_id; | ||
| 77 | }; | ||
| 78 | |||
| 79 | inline Header ParseHeader(u32 header) { | ||
| 80 | return {header}; | ||
| 81 | } | ||
| 82 | |||
| 83 | constexpr u32 MoveHandleDesc(u32 num_handles = 1) { | ||
| 84 | return MoveHandle | ((num_handles - 1) << 26); | ||
| 85 | } | ||
| 86 | |||
| 87 | constexpr u32 CopyHandleDesc(u32 num_handles = 1) { | ||
| 88 | return CopyHandle | ((num_handles - 1) << 26); | ||
| 89 | } | ||
| 90 | |||
| 91 | constexpr u32 CallingPidDesc() { | ||
| 92 | return CallingPid; | ||
| 93 | } | ||
| 94 | |||
| 95 | constexpr bool isHandleDescriptor(u32 descriptor) { | ||
| 96 | return (descriptor & 0xF) == 0x0; | ||
| 97 | } | ||
| 98 | |||
| 99 | constexpr u32 HandleNumberFromDesc(u32 handle_descriptor) { | ||
| 100 | return (handle_descriptor >> 26) + 1; | ||
| 101 | } | ||
| 102 | |||
| 103 | constexpr u32 StaticBufferDesc(u32 size, u8 buffer_id) { | ||
| 104 | return StaticBuffer | (size << 14) | ((buffer_id & 0xF) << 10); | ||
| 105 | } | ||
| 106 | |||
| 107 | union StaticBufferDescInfo { | ||
| 108 | u32 raw; | ||
| 109 | BitField<10, 4, u32> buffer_id; | ||
| 110 | BitField<14, 18, u32> size; | ||
| 111 | }; | ||
| 112 | |||
| 113 | inline StaticBufferDescInfo ParseStaticBufferDesc(const u32 desc) { | ||
| 114 | return {desc}; | ||
| 115 | } | ||
| 116 | |||
| 117 | /** | ||
| 118 | * @brief Creates a header describing a buffer to be sent over PXI. | ||
| 119 | * @param size Size of the buffer. Max 0x00FFFFFF. | ||
| 120 | * @param buffer_id The Id of the buffer. Max 0xF. | ||
| 121 | * @param is_read_only true if the buffer is read-only. If false, the buffer is considered to have | ||
| 122 | * read-write access. | ||
| 123 | * @return The created PXI buffer header. | ||
| 124 | * | ||
| 125 | * The next value is a phys-address of a table located in the BASE memregion. | ||
| 126 | */ | ||
| 127 | inline u32 PXIBufferDesc(u32 size, unsigned buffer_id, bool is_read_only) { | ||
| 128 | u32 type = PXIBuffer; | ||
| 129 | if (is_read_only) | ||
| 130 | type |= 0x2; | ||
| 131 | return type | (size << 8) | ((buffer_id & 0xF) << 4); | ||
| 132 | } | ||
| 133 | |||
| 134 | enum MappedBufferPermissions { | ||
| 135 | R = 1, | ||
| 136 | W = 2, | ||
| 137 | RW = R | W, | ||
| 138 | }; | ||
| 139 | |||
| 140 | constexpr u32 MappedBufferDesc(u32 size, MappedBufferPermissions perms) { | ||
| 141 | return MappedBuffer | (size << 4) | (u32(perms) << 1); | ||
| 142 | } | ||
| 143 | |||
| 144 | union MappedBufferDescInfo { | ||
| 145 | u32 raw; | ||
| 146 | BitField<4, 28, u32> size; | ||
| 147 | BitField<1, 2, MappedBufferPermissions> perms; | ||
| 148 | }; | ||
| 149 | |||
| 150 | inline MappedBufferDescInfo ParseMappedBufferDesc(const u32 desc) { | ||
| 151 | return{ desc }; | ||
| 152 | } | ||
| 153 | |||
| 154 | inline DescriptorType GetDescriptorType(u32 descriptor) { | ||
| 155 | // Note: Those checks must be done in this order | ||
| 156 | if (isHandleDescriptor(descriptor)) | ||
| 157 | return (DescriptorType)(descriptor & 0x30); | ||
| 158 | |||
| 159 | // handle the fact that the following descriptors can have rights | ||
| 160 | if (descriptor & MappedBuffer) | ||
| 161 | return MappedBuffer; | ||
| 162 | |||
| 163 | if (descriptor & PXIBuffer) | ||
| 164 | return PXIBuffer; | ||
| 165 | |||
| 166 | return StaticBuffer; | ||
| 167 | } | ||
| 168 | |||
| 169 | } // namespace IPC | ||
| 170 | |||
| 171 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 18 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 172 | // Namespace Service | 19 | // Namespace Service |
| 173 | 20 | ||
| @@ -220,9 +67,9 @@ public: | |||
| 220 | * @param max_sessions Maximum number of sessions that can be | 67 | * @param max_sessions Maximum number of sessions that can be |
| 221 | * connected to this service at the same time. | 68 | * connected to this service at the same time. |
| 222 | */ | 69 | */ |
| 223 | Interface(u32 max_sessions = DefaultMaxSessions) : max_sessions(max_sessions) { } | 70 | Interface(u32 max_sessions = DefaultMaxSessions); |
| 224 | 71 | ||
| 225 | virtual ~Interface() = default; | 72 | virtual ~Interface(); |
| 226 | 73 | ||
| 227 | std::string GetName() const { | 74 | std::string GetName() const { |
| 228 | return GetPortName(); | 75 | return GetPortName(); |
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index ff7a84347..37420201b 100644 --- a/src/core/hle/service/srv.cpp +++ b/src/core/hle/service/srv.cpp | |||
| @@ -87,12 +87,7 @@ static void GetServiceHandle(Service::Interface* self) { | |||
| 87 | if (it != Service::g_srv_services.end()) { | 87 | if (it != Service::g_srv_services.end()) { |
| 88 | auto client_port = it->second; | 88 | auto client_port = it->second; |
| 89 | 89 | ||
| 90 | // Note: Threads do not wait for the server endpoint to call | ||
| 91 | // AcceptSession before returning from this call. | ||
| 92 | |||
| 93 | // Connect to the port and retrieve the client endpoint of the connection Session. | ||
| 94 | auto client_session = client_port->Connect(); | 90 | auto client_session = client_port->Connect(); |
| 95 | |||
| 96 | res = client_session.Code(); | 91 | res = client_session.Code(); |
| 97 | 92 | ||
| 98 | if (client_session.Succeeded()) { | 93 | if (client_session.Succeeded()) { |
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 0a2b474ee..f24b5c91a 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp | |||
| @@ -226,19 +226,15 @@ static ResultCode ConnectToPort(Handle* out_handle, const char* port_name) { | |||
| 226 | 226 | ||
| 227 | auto client_port = it->second; | 227 | auto client_port = it->second; |
| 228 | 228 | ||
| 229 | // Connect to the port and retrieve the client endpoint of the connection Session. | ||
| 230 | SharedPtr<Kernel::ClientSession> client_session; | 229 | SharedPtr<Kernel::ClientSession> client_session; |
| 231 | CASCADE_RESULT(client_session, client_port->Connect()); | 230 | CASCADE_RESULT(client_session, client_port->Connect()); |
| 232 | 231 | ||
| 233 | // Note: Threads do not wait for the server endpoint to call | ||
| 234 | // AcceptSession before returning from this call. | ||
| 235 | |||
| 236 | // Return the client session | 232 | // Return the client session |
| 237 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(client_session)); | 233 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(client_session)); |
| 238 | return RESULT_SUCCESS; | 234 | return RESULT_SUCCESS; |
| 239 | } | 235 | } |
| 240 | 236 | ||
| 241 | /// Synchronize to an OS service | 237 | /// Makes a blocking IPC call to an OS service. |
| 242 | static ResultCode SendSyncRequest(Handle handle) { | 238 | static ResultCode SendSyncRequest(Handle handle) { |
| 243 | SharedPtr<Kernel::ClientSession> session = Kernel::g_handle_table.Get<Kernel::ClientSession>(handle); | 239 | SharedPtr<Kernel::ClientSession> session = Kernel::g_handle_table.Get<Kernel::ClientSession>(handle); |
| 244 | if (session == nullptr) { | 240 | if (session == nullptr) { |