summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/logging/backend.cpp3
-rw-r--r--src/common/logging/log.h1
-rw-r--r--src/core/hle/ipc.h7
-rw-r--r--src/core/hle/kernel/domain.cpp21
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp10
5 files changed, 38 insertions, 4 deletions
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 13f915a01..ba0acfb72 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -43,6 +43,7 @@ namespace Log {
SUB(HW, LCD) \
SUB(HW, GPU) \
SUB(HW, AES) \
+ CLS(IPC) \
CLS(Frontend) \
CLS(Render) \
SUB(Render, Software) \
@@ -91,8 +92,8 @@ const char* GetLevelName(Level log_level) {
Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
const char* function, const char* format, va_list args) {
- using std::chrono::steady_clock;
using std::chrono::duration_cast;
+ using std::chrono::steady_clock;
static steady_clock::time_point time_origin = steady_clock::now();
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index 35b5af3cb..57021037a 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -60,6 +60,7 @@ enum class Class : ClassType {
HW_LCD, ///< LCD register emulation
HW_GPU, ///< GPU control emulation
HW_AES, ///< AES engine emulation
+ IPC, ///< IPC interface
Frontend, ///< Emulator UI
Render, ///< Emulator video output and hardware acceleration
Render_Software, ///< Software renderer backend
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 {
static_assert(sizeof(DataPayloadHeader) == 8, "DataPayloadRequest size is incorrect");
struct DomainMessageHeader {
+ enum class CommandType : u32_le {
+ SendMessage = 1,
+ CloseVirtualHandle = 2,
+ };
+
union {
// Used when responding to an IPC request, Server -> Client.
struct {
@@ -153,7 +158,7 @@ struct DomainMessageHeader {
// Used when performing an IPC request, Client -> Server.
struct {
union {
- BitField<0, 8, u32_le> command;
+ BitField<0, 8, CommandType> command;
BitField<16, 16, u32_le> size;
};
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 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/logging/log.h"
+#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/domain.h"
#include "core/hle/kernel/handle_table.h"
@@ -36,7 +38,24 @@ ResultCode Domain::SendSyncRequest(SharedPtr<Thread> thread) {
if (domain_message_header) {
// If there is a DomainMessageHeader, then this is CommandType "Request"
const u32 object_id{context.GetDomainMessageHeader()->object_id};
- return request_handlers[object_id - 1]->HandleSyncRequest(context);
+ switch (domain_message_header->command) {
+ case IPC::DomainMessageHeader::CommandType::SendMessage:
+ return request_handlers[object_id - 1]->HandleSyncRequest(context);
+
+ case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: {
+ LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x%08X", object_id);
+
+ request_handlers[object_id - 1] = nullptr;
+
+ IPC::RequestBuilder rb{context, 2};
+ rb.Push(RESULT_SUCCESS);
+
+ return RESULT_SUCCESS;
+ }
+ }
+
+ LOG_CRITICAL(IPC, "Unknown domain command=%d", domain_message_header->command.Value());
+ UNIMPLEMENTED();
}
return request_handlers.front()->HandleSyncRequest(context);
}
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index afa09b404..ac62a0d5a 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -102,13 +102,21 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
data_payload_header =
std::make_unique<IPC::DataPayloadHeader>(rp.PopRaw<IPC::DataPayloadHeader>());
+ data_payload_offset = rp.GetCurrentOffset();
+
+ if (domain_message_header &&
+ domain_message_header->command ==
+ IPC::DomainMessageHeader::CommandType::CloseVirtualHandle) {
+ // CloseVirtualHandle command does not have SFC* or any data
+ return;
+ }
+
if (incoming) {
ASSERT(data_payload_header->magic == Common::MakeMagic('S', 'F', 'C', 'I'));
} else {
ASSERT(data_payload_header->magic == Common::MakeMagic('S', 'F', 'C', 'O'));
}
- data_payload_offset = rp.GetCurrentOffset();
command = rp.Pop<u32_le>();
rp.Skip(1, false); // The command is actually an u64, but we don't use the high part.
}