From 8ba3894c3a934e0bc311e40e76bb2fd949423289 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 18 Apr 2018 12:53:04 -0600 Subject: [PATCH] Stratosphere: Skeleton actual IPC dispatch in ServiceSession --- stratosphere/loader/source/iserviceobject.hpp | 2 +- stratosphere/loader/source/iwaitable.hpp | 2 +- .../loader/source/ldr_debug_monitor.cpp | 2 +- .../loader/source/ldr_debug_monitor.hpp | 2 +- stratosphere/loader/source/ldr_shell.cpp | 2 +- stratosphere/loader/source/ldr_shell.hpp | 2 +- stratosphere/loader/source/serviceserver.hpp | 2 +- stratosphere/loader/source/servicesession.hpp | 45 +++++++++++++++++-- .../loader/source/waitablemanager.cpp | 14 +++--- 9 files changed, 57 insertions(+), 16 deletions(-) diff --git a/stratosphere/loader/source/iserviceobject.hpp b/stratosphere/loader/source/iserviceobject.hpp index 3b6148cb3..79156d533 100644 --- a/stratosphere/loader/source/iserviceobject.hpp +++ b/stratosphere/loader/source/iserviceobject.hpp @@ -4,5 +4,5 @@ class IServiceObject { public: virtual ~IServiceObject() { } - virtual Result dispatch(IpcParsedCommand *r, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) = 0; + virtual Result dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) = 0; }; \ No newline at end of file diff --git a/stratosphere/loader/source/iwaitable.hpp b/stratosphere/loader/source/iwaitable.hpp index bd574f09e..b14d62b91 100644 --- a/stratosphere/loader/source/iwaitable.hpp +++ b/stratosphere/loader/source/iwaitable.hpp @@ -12,7 +12,7 @@ class IWaitable { virtual void get_waitables(IWaitable **dst) = 0; virtual void delete_child(IWaitable *child) = 0; virtual Handle get_handle() = 0; - virtual Result handle_signaled() = 0; + virtual Result handle_signaled(u64 timeout) = 0; bool has_parent() { return this->parent_waitable != NULL; diff --git a/stratosphere/loader/source/ldr_debug_monitor.cpp b/stratosphere/loader/source/ldr_debug_monitor.cpp index f4d492967..a19006c30 100644 --- a/stratosphere/loader/source/ldr_debug_monitor.cpp +++ b/stratosphere/loader/source/ldr_debug_monitor.cpp @@ -2,7 +2,7 @@ #include "ldr_debug_monitor.hpp" #include "ldr_launch_queue.hpp" -Result DebugMonitorService::dispatch(IpcParsedCommand *r, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) { +Result DebugMonitorService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) { Result rc = 0xF601; diff --git a/stratosphere/loader/source/ldr_debug_monitor.hpp b/stratosphere/loader/source/ldr_debug_monitor.hpp index 223aee111..c28615c13 100644 --- a/stratosphere/loader/source/ldr_debug_monitor.hpp +++ b/stratosphere/loader/source/ldr_debug_monitor.hpp @@ -11,7 +11,7 @@ enum DebugMonitorServiceCmd { class DebugMonitorService : IServiceObject { public: - Result dispatch(IpcParsedCommand *r, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count); + Result dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count); private: /* Actual commands. */ diff --git a/stratosphere/loader/source/ldr_shell.cpp b/stratosphere/loader/source/ldr_shell.cpp index 4ff84acb5..f89977c0d 100644 --- a/stratosphere/loader/source/ldr_shell.cpp +++ b/stratosphere/loader/source/ldr_shell.cpp @@ -2,7 +2,7 @@ #include "ldr_shell.hpp" #include "ldr_launch_queue.hpp" -Result ShellService::dispatch(IpcParsedCommand *r, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) { +Result ShellService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) { Result rc = 0xF601; diff --git a/stratosphere/loader/source/ldr_shell.hpp b/stratosphere/loader/source/ldr_shell.hpp index 295517912..5b8da6e84 100644 --- a/stratosphere/loader/source/ldr_shell.hpp +++ b/stratosphere/loader/source/ldr_shell.hpp @@ -10,7 +10,7 @@ enum ShellServiceCmd { class ShellService : IServiceObject { public: - Result dispatch(IpcParsedCommand *r, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count); + Result dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count); private: /* Actual commands. */ diff --git a/stratosphere/loader/source/serviceserver.hpp b/stratosphere/loader/source/serviceserver.hpp index a48decf86..151023cbc 100644 --- a/stratosphere/loader/source/serviceserver.hpp +++ b/stratosphere/loader/source/serviceserver.hpp @@ -87,7 +87,7 @@ class ServiceServer : public IWaitable { return this->port_handle; } - virtual Result handle_signaled() { + virtual Result handle_signaled(u64 timeout) { /* If this server's port was signaled, accept a new session. */ Handle session_h; svcAcceptSession(&session_h, this->port_handle); diff --git a/stratosphere/loader/source/servicesession.hpp b/stratosphere/loader/source/servicesession.hpp index 6d06d9398..c6b0bcd4e 100644 --- a/stratosphere/loader/source/servicesession.hpp +++ b/stratosphere/loader/source/servicesession.hpp @@ -53,8 +53,47 @@ class ServiceSession : public IWaitable { return this->server_handle; } - virtual Result handle_signaled() { - /* TODO */ - return 0; + virtual Result handle_signaled(u64 timeout) { + Result rc; + int handle_index; + if (R_SUCCEEDED(rc = svcReplyAndReceive(&handle_index, &this->server_handle, 1, 0, timeout))) { + if (handle_index != 0) { + /* TODO: Panic? */ + } + u32 *cmdbuf = (u32 *)armGetTls(); + u32 out_words = 4; + u32 extra_rawdata_count = 0; + u32 wordcount = 0; + Result retval = 0; + u32 *rawdata_start = cmdbuf; + + IpcParsedCommand r; + IpcCommand c; + + ipcInitialize(&c); + + retval = ipcParse(&r); + + if (R_SUCCEEDED(retval)) { + rawdata_start = (u32 *)r.Raw; + wordcount = r.RawSize; + retval = this->service_object->dispatch(&r, &c, cmdbuf, rawdata_start[2], &rawdata_start[4], wordcount - 6, &cmdbuf[8], &extra_rawdata_count); + out_words += extra_rawdata_count; + } + + struct { + u64 magic; + u64 retval; + } *raw; + + raw = (decltype(raw))ipcPrepareHeader(&c, out_words); + + raw->magic = SFCO_MAGIC; + raw->retval = retval; + + rc = svcReplyAndReceive(&handle_index, &this->server_handle, 1, this->server_handle, 0); + } + + return rc; } }; \ No newline at end of file diff --git a/stratosphere/loader/source/waitablemanager.cpp b/stratosphere/loader/source/waitablemanager.cpp index 702cadb3b..de9479b13 100644 --- a/stratosphere/loader/source/waitablemanager.cpp +++ b/stratosphere/loader/source/waitablemanager.cpp @@ -43,8 +43,8 @@ void WaitableManager::process() { rc = svcWaitSynchronization(&handle_index, handles.data(), handles.size(), this->timeout); if (R_SUCCEEDED(rc)) { /* Handle a signaled waitable. */ - /* TODO: What should be done with the result here? */ - signalables[handle_index]->handle_signaled(); + /* TODO: What timeout should be passed here? */ + rc = signalables[handle_index]->handle_signaled(0); for (int i = 0; i < handle_index; i++) { signalables[i]->update_priority(); @@ -54,7 +54,11 @@ void WaitableManager::process() { for (auto & waitable : signalables) { waitable->update_priority(); } - } else if (rc == 0xF601) { + } else if (rc != 0xF601) { + /* TODO: Panic. When can this happen? */ + } + + if (rc == 0xF601) { /* handles[handle_index] was closed! */ /* Close the handle. */ @@ -73,8 +77,6 @@ void WaitableManager::process() { for (int i = 0; i < handle_index; i++) { signalables[i]->update_priority(); } - } else { - /* TODO: Panic. When can this happen? */ - } + } } } \ No newline at end of file