diff options
| author | 2016-06-28 18:53:10 -0400 | |
|---|---|---|
| committer | 2016-06-28 18:53:10 -0400 | |
| commit | 87c07643ff14f2a5ea61fc92c2a83529a166781a (patch) | |
| tree | 3a83c873ee6971aada11376cf604159c8ab1fb8c /src | |
| parent | Merge pull request #1930 from scurest/superfluous-moves (diff) | |
| parent | Fix parameter name in EnableNotification (diff) | |
| download | yuzu-87c07643ff14f2a5ea61fc92c2a83529a166781a.tar.gz yuzu-87c07643ff14f2a5ea61fc92c2a83529a166781a.tar.xz yuzu-87c07643ff14f2a5ea61fc92c2a83529a166781a.zip | |
Merge pull request #1867 from mailwl/srv-update
srv: Update according 3dbrew
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/session.h | 4 | ||||
| -rw-r--r-- | src/core/hle/service/srv.cpp | 136 |
2 files changed, 125 insertions, 15 deletions
diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h index 6ddaf970e..26b086f87 100644 --- a/src/core/hle/kernel/session.h +++ b/src/core/hle/kernel/session.h | |||
| @@ -32,6 +32,10 @@ constexpr u32 CallingPidDesc() { | |||
| 32 | return 0x20; | 32 | return 0x20; |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | constexpr u32 TransferHandleDesc() { | ||
| 36 | return 0x20; | ||
| 37 | } | ||
| 38 | |||
| 35 | constexpr u32 StaticBufferDesc(u32 size, unsigned int buffer_id) { | 39 | constexpr u32 StaticBufferDesc(u32 size, unsigned int buffer_id) { |
| 36 | return 0x2 | (size << 14) | ((buffer_id & 0xF) << 10); | 40 | return 0x2 | (size << 14) | ((buffer_id & 0xF) << 10); |
| 37 | } | 41 | } |
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index aae955bf8..8bd36d5ea 100644 --- a/src/core/hle/service/srv.cpp +++ b/src/core/hle/service/srv.cpp | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | 1 | // Copyright 2016 Citra Emulator Project |
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| @@ -15,23 +15,64 @@ namespace SRV { | |||
| 15 | 15 | ||
| 16 | static Kernel::SharedPtr<Kernel::Event> event_handle; | 16 | static Kernel::SharedPtr<Kernel::Event> event_handle; |
| 17 | 17 | ||
| 18 | static void Initialize(Service::Interface* self) { | 18 | /** |
| 19 | * SRV::RegisterClient service function | ||
| 20 | * Inputs: | ||
| 21 | * 0: 0x00010002 | ||
| 22 | * 1: ProcessId Header (must be 0x20) | ||
| 23 | * Outputs: | ||
| 24 | * 0: 0x00010040 | ||
| 25 | * 1: ResultCode | ||
| 26 | */ | ||
| 27 | static void RegisterClient(Service::Interface* self) { | ||
| 19 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 28 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 20 | 29 | ||
| 21 | cmd_buff[1] = 0; // No error | 30 | if (cmd_buff[1] != IPC::CallingPidDesc()) { |
| 31 | cmd_buff[0] = IPC::MakeHeader(0x0, 0x1, 0); //0x40 | ||
| 32 | cmd_buff[1] = ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS, | ||
| 33 | ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw; | ||
| 34 | return; | ||
| 35 | } | ||
| 36 | cmd_buff[0] = IPC::MakeHeader(0x1, 0x1, 0); //0x10040 | ||
| 37 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | ||
| 38 | LOG_WARNING(Service_SRV, "(STUBBED) called"); | ||
| 22 | } | 39 | } |
| 23 | 40 | ||
| 24 | static void GetProcSemaphore(Service::Interface* self) { | 41 | /** |
| 42 | * SRV::EnableNotification service function | ||
| 43 | * Inputs: | ||
| 44 | * 0: 0x00020000 | ||
| 45 | * Outputs: | ||
| 46 | * 0: 0x00020042 | ||
| 47 | * 1: ResultCode | ||
| 48 | * 2: Translation descriptor: 0x20 | ||
| 49 | * 3: Handle to semaphore signaled on process notification | ||
| 50 | */ | ||
| 51 | static void EnableNotification(Service::Interface* self) { | ||
| 25 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 52 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 26 | 53 | ||
| 27 | // TODO(bunnei): Change to a semaphore once these have been implemented | 54 | // TODO(bunnei): Change to a semaphore once these have been implemented |
| 28 | event_handle = Kernel::Event::Create(Kernel::ResetType::OneShot, "SRV:Event"); | 55 | event_handle = Kernel::Event::Create(Kernel::ResetType::OneShot, "SRV:Event"); |
| 29 | event_handle->Clear(); | 56 | event_handle->Clear(); |
| 30 | 57 | ||
| 31 | cmd_buff[1] = 0; // No error | 58 | cmd_buff[0] = IPC::MakeHeader(0x2, 0x1, 0x2); // 0x20042 |
| 59 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | ||
| 60 | cmd_buff[2] = IPC::TransferHandleDesc(); | ||
| 32 | cmd_buff[3] = Kernel::g_handle_table.Create(event_handle).MoveFrom(); | 61 | cmd_buff[3] = Kernel::g_handle_table.Create(event_handle).MoveFrom(); |
| 62 | LOG_WARNING(Service_SRV, "(STUBBED) called"); | ||
| 33 | } | 63 | } |
| 34 | 64 | ||
| 65 | /** | ||
| 66 | * SRV::GetServiceHandle service function | ||
| 67 | * Inputs: | ||
| 68 | * 0: 0x00050100 | ||
| 69 | * 1-2: 8-byte UTF-8 service name | ||
| 70 | * 3: Name length | ||
| 71 | * 4: Flags (bit0: if not set, return port-handle if session-handle unavailable) | ||
| 72 | * Outputs: | ||
| 73 | * 1: ResultCode | ||
| 74 | * 3: Service handle | ||
| 75 | */ | ||
| 35 | static void GetServiceHandle(Service::Interface* self) { | 76 | static void GetServiceHandle(Service::Interface* self) { |
| 36 | ResultCode res = RESULT_SUCCESS; | 77 | ResultCode res = RESULT_SUCCESS; |
| 37 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 78 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| @@ -49,16 +90,80 @@ static void GetServiceHandle(Service::Interface* self) { | |||
| 49 | cmd_buff[1] = res.raw; | 90 | cmd_buff[1] = res.raw; |
| 50 | } | 91 | } |
| 51 | 92 | ||
| 93 | /** | ||
| 94 | * SRV::Subscribe service function | ||
| 95 | * Inputs: | ||
| 96 | * 0: 0x00090040 | ||
| 97 | * 1: Notification ID | ||
| 98 | * Outputs: | ||
| 99 | * 0: 0x00090040 | ||
| 100 | * 1: ResultCode | ||
| 101 | */ | ||
| 102 | static void Subscribe(Service::Interface* self) { | ||
| 103 | u32* cmd_buff = Kernel::GetCommandBuffer(); | ||
| 104 | |||
| 105 | u32 notification_id = cmd_buff[1]; | ||
| 106 | |||
| 107 | cmd_buff[0] = IPC::MakeHeader(0x9, 0x1, 0); // 0x90040 | ||
| 108 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | ||
| 109 | LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x%X", notification_id); | ||
| 110 | } | ||
| 111 | |||
| 112 | /** | ||
| 113 | * SRV::Unsubscribe service function | ||
| 114 | * Inputs: | ||
| 115 | * 0: 0x000A0040 | ||
| 116 | * 1: Notification ID | ||
| 117 | * Outputs: | ||
| 118 | * 0: 0x000A0040 | ||
| 119 | * 1: ResultCode | ||
| 120 | */ | ||
| 121 | static void Unsubscribe(Service::Interface* self) { | ||
| 122 | u32* cmd_buff = Kernel::GetCommandBuffer(); | ||
| 123 | |||
| 124 | u32 notification_id = cmd_buff[1]; | ||
| 125 | |||
| 126 | cmd_buff[0] = IPC::MakeHeader(0xA, 0x1, 0); // 0xA0040 | ||
| 127 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | ||
| 128 | LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x%X", notification_id); | ||
| 129 | } | ||
| 130 | |||
| 131 | /** | ||
| 132 | * SRV::PublishToSubscriber service function | ||
| 133 | * Inputs: | ||
| 134 | * 0: 0x000C0080 | ||
| 135 | * 1: Notification ID | ||
| 136 | * 2: Flags (bit0: only fire if not fired, bit1: report errors) | ||
| 137 | * Outputs: | ||
| 138 | * 0: 0x000C0040 | ||
| 139 | * 1: ResultCode | ||
| 140 | */ | ||
| 141 | static void PublishToSubscriber(Service::Interface* self) { | ||
| 142 | u32* cmd_buff = Kernel::GetCommandBuffer(); | ||
| 143 | |||
| 144 | u32 notification_id = cmd_buff[1]; | ||
| 145 | u8 flags = cmd_buff[2] & 0xFF; | ||
| 146 | |||
| 147 | cmd_buff[0] = IPC::MakeHeader(0xC, 0x1, 0); // 0xC0040 | ||
| 148 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | ||
| 149 | LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x%X, flags=%u", notification_id, flags); | ||
| 150 | } | ||
| 151 | |||
| 52 | const Interface::FunctionInfo FunctionTable[] = { | 152 | const Interface::FunctionInfo FunctionTable[] = { |
| 53 | {0x00010002, Initialize, "Initialize"}, | 153 | {0x00010002, RegisterClient, "RegisterClient"}, |
| 54 | {0x00020000, GetProcSemaphore, "GetProcSemaphore"}, | 154 | {0x00020000, EnableNotification, "EnableNotification"}, |
| 55 | {0x00030100, nullptr, "RegisterService"}, | 155 | {0x00030100, nullptr, "RegisterService"}, |
| 56 | {0x000400C0, nullptr, "UnregisterService"}, | 156 | {0x000400C0, nullptr, "UnregisterService"}, |
| 57 | {0x00050100, GetServiceHandle, "GetServiceHandle"}, | 157 | {0x00050100, GetServiceHandle, "GetServiceHandle"}, |
| 58 | {0x000600C2, nullptr, "RegisterHandle"}, | 158 | {0x000600C2, nullptr, "RegisterPort"}, |
| 59 | {0x00090040, nullptr, "Subscribe"}, | 159 | {0x000700C0, nullptr, "UnregisterPort"}, |
| 60 | {0x000B0000, nullptr, "ReceiveNotification"}, | 160 | {0x00080100, nullptr, "GetPort"}, |
| 61 | {0x000C0080, nullptr, "PublishToSubscriber"}, | 161 | {0x00090040, Subscribe, "Subscribe"}, |
| 162 | {0x000A0040, Unsubscribe, "Unsubscribe"}, | ||
| 163 | {0x000B0000, nullptr, "ReceiveNotification"}, | ||
| 164 | {0x000C0080, PublishToSubscriber, "PublishToSubscriber"}, | ||
| 165 | {0x000D0040, nullptr, "PublishAndGetSubscriber"}, | ||
| 166 | {0x000E00C0, nullptr, "IsServiceRegistered"}, | ||
| 62 | }; | 167 | }; |
| 63 | 168 | ||
| 64 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 169 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| @@ -66,10 +171,11 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 66 | 171 | ||
| 67 | Interface::Interface() { | 172 | Interface::Interface() { |
| 68 | Register(FunctionTable); | 173 | Register(FunctionTable); |
| 174 | event_handle = nullptr; | ||
| 69 | } | 175 | } |
| 70 | 176 | ||
| 71 | Interface::~Interface() { | 177 | Interface::~Interface() { |
| 72 | event_handle = nullptr; | 178 | event_handle = nullptr; |
| 73 | } | 179 | } |
| 74 | 180 | ||
| 75 | } // namespace | 181 | } // namespace SRV |