diff options
| author | 2018-01-17 01:16:55 -0500 | |
|---|---|---|
| committer | 2018-01-17 01:20:10 -0500 | |
| commit | 30cb98f874d0df9e818976f2140135ac8fe1501b (patch) | |
| tree | 53bba56a04da35b8c262038db928bc0158458389 | |
| parent | loggin: Add IPC logging category. (diff) | |
| download | yuzu-30cb98f874d0df9e818976f2140135ac8fe1501b.tar.gz yuzu-30cb98f874d0df9e818976f2140135ac8fe1501b.tar.xz yuzu-30cb98f874d0df9e818976f2140135ac8fe1501b.zip | |
ipc: Implement domain command CloseVirtualHandle.
| -rw-r--r-- | src/core/hle/ipc.h | 7 | ||||
| -rw-r--r-- | src/core/hle/kernel/domain.cpp | 21 | ||||
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.cpp | 9 |
3 files changed, 34 insertions, 3 deletions
diff --git a/src/core/hle/ipc.h b/src/core/hle/ipc.h index 88ba105e5..1840fac12 100644 --- a/src/core/hle/ipc.h +++ b/src/core/hle/ipc.h | |||
| @@ -143,6 +143,11 @@ struct DataPayloadHeader { | |||
| 143 | static_assert(sizeof(DataPayloadHeader) == 8, "DataPayloadRequest size is incorrect"); | 143 | static_assert(sizeof(DataPayloadHeader) == 8, "DataPayloadRequest size is incorrect"); |
| 144 | 144 | ||
| 145 | struct DomainMessageHeader { | 145 | struct DomainMessageHeader { |
| 146 | enum class CommandType : u32_le { | ||
| 147 | SendMessage = 1, | ||
| 148 | CloseVirtualHandle = 2, | ||
| 149 | }; | ||
| 150 | |||
| 146 | union { | 151 | union { |
| 147 | // Used when responding to an IPC request, Server -> Client. | 152 | // Used when responding to an IPC request, Server -> Client. |
| 148 | struct { | 153 | struct { |
| @@ -153,7 +158,7 @@ struct DomainMessageHeader { | |||
| 153 | // Used when performing an IPC request, Client -> Server. | 158 | // Used when performing an IPC request, Client -> Server. |
| 154 | struct { | 159 | struct { |
| 155 | union { | 160 | union { |
| 156 | BitField<0, 8, u32_le> command; | 161 | BitField<0, 8, CommandType> command; |
| 157 | BitField<16, 16, u32_le> size; | 162 | BitField<16, 16, u32_le> size; |
| 158 | }; | 163 | }; |
| 159 | u32_le object_id; | 164 | u32_le object_id; |
diff --git a/src/core/hle/kernel/domain.cpp b/src/core/hle/kernel/domain.cpp index 7ebb4b9c7..5035e9c08 100644 --- a/src/core/hle/kernel/domain.cpp +++ b/src/core/hle/kernel/domain.cpp | |||
| @@ -2,6 +2,8 @@ | |||
| 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 | ||
| 5 | #include "common/logging/log.h" | ||
| 6 | #include "core/hle/ipc_helpers.h" | ||
| 5 | #include "core/hle/kernel/client_port.h" | 7 | #include "core/hle/kernel/client_port.h" |
| 6 | #include "core/hle/kernel/domain.h" | 8 | #include "core/hle/kernel/domain.h" |
| 7 | #include "core/hle/kernel/handle_table.h" | 9 | #include "core/hle/kernel/handle_table.h" |
| @@ -36,7 +38,24 @@ ResultCode Domain::SendSyncRequest(SharedPtr<Thread> thread) { | |||
| 36 | if (domain_message_header) { | 38 | if (domain_message_header) { |
| 37 | // If there is a DomainMessageHeader, then this is CommandType "Request" | 39 | // If there is a DomainMessageHeader, then this is CommandType "Request" |
| 38 | const u32 object_id{context.GetDomainMessageHeader()->object_id}; | 40 | const u32 object_id{context.GetDomainMessageHeader()->object_id}; |
| 39 | return request_handlers[object_id - 1]->HandleSyncRequest(context); | 41 | switch (domain_message_header->command) { |
| 42 | case IPC::DomainMessageHeader::CommandType::SendMessage: | ||
| 43 | return request_handlers[object_id - 1]->HandleSyncRequest(context); | ||
| 44 | |||
| 45 | case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: { | ||
| 46 | LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x%08X", object_id); | ||
| 47 | |||
| 48 | request_handlers[object_id - 1] = nullptr; | ||
| 49 | |||
| 50 | IPC::RequestBuilder rb{context, 2}; | ||
| 51 | rb.Push(RESULT_SUCCESS); | ||
| 52 | |||
| 53 | return RESULT_SUCCESS; | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | LOG_CRITICAL(IPC, "Unknown domain command=%d", domain_message_header->command.Value()); | ||
| 58 | UNIMPLEMENTED(); | ||
| 40 | } | 59 | } |
| 41 | return request_handlers.front()->HandleSyncRequest(context); | 60 | return request_handlers.front()->HandleSyncRequest(context); |
| 42 | } | 61 | } |
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index afa09b404..2ccc242f6 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp | |||
| @@ -102,13 +102,20 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) { | |||
| 102 | data_payload_header = | 102 | data_payload_header = |
| 103 | std::make_unique<IPC::DataPayloadHeader>(rp.PopRaw<IPC::DataPayloadHeader>()); | 103 | std::make_unique<IPC::DataPayloadHeader>(rp.PopRaw<IPC::DataPayloadHeader>()); |
| 104 | 104 | ||
| 105 | data_payload_offset = rp.GetCurrentOffset(); | ||
| 106 | |||
| 107 | if (domain_message_header && domain_message_header->command == | ||
| 108 | IPC::DomainMessageHeader::CommandType::CloseVirtualHandle) { | ||
| 109 | // CloseVirtualHandle command does not have SFC* or any data | ||
| 110 | return; | ||
| 111 | } | ||
| 112 | |||
| 105 | if (incoming) { | 113 | if (incoming) { |
| 106 | ASSERT(data_payload_header->magic == Common::MakeMagic('S', 'F', 'C', 'I')); | 114 | ASSERT(data_payload_header->magic == Common::MakeMagic('S', 'F', 'C', 'I')); |
| 107 | } else { | 115 | } else { |
| 108 | ASSERT(data_payload_header->magic == Common::MakeMagic('S', 'F', 'C', 'O')); | 116 | ASSERT(data_payload_header->magic == Common::MakeMagic('S', 'F', 'C', 'O')); |
| 109 | } | 117 | } |
| 110 | 118 | ||
| 111 | data_payload_offset = rp.GetCurrentOffset(); | ||
| 112 | command = rp.Pop<u32_le>(); | 119 | command = rp.Pop<u32_le>(); |
| 113 | rp.Skip(1, false); // The command is actually an u64, but we don't use the high part. | 120 | rp.Skip(1, false); // The command is actually an u64, but we don't use the high part. |
| 114 | } | 121 | } |