From ac0337d8dfcd1a95090b5a8a6982d3bc91218e32 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Tue, 24 Dec 2019 17:49:56 +0000 Subject: [PATCH] Started IPC services serialization --- TODO | 8 +++--- src/common/construct.h | 35 ++++++++++++++++++++++++++ src/core/hle/kernel/hle_ipc.h | 5 ++++ src/core/hle/service/ac/ac.cpp | 3 +++ src/core/hle/service/ac/ac.h | 46 ++++++++++++++++++++++++++++++++++ src/core/hle/service/service.h | 1 + src/core/hle/service/sm/sm.h | 19 +++++++++++--- src/core/memory.cpp | 2 +- 8 files changed, 112 insertions(+), 7 deletions(-) create mode 100644 src/common/construct.h diff --git a/TODO b/TODO index f3e1ea943..bc62720d6 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,11 @@ ☐ Save/load UI ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) + ☐ Page tables + ☐ Skip N3DS RAM if unused ✔ DSP @done(19-08-13 15:41) ✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) - ☐ Fix or ignore inverse map + ✔ Fix or ignore inverse map @done(19-12-23 12:46) ☐ App loader ☐ Archive manager ☐ Custom texture cache @@ -58,8 +60,8 @@ ☐ VM Manager @started(19-08-13 16:46) Just need to figure out backing_mem (a u8*) ✔ Wait object @done(19-08-13 16:46) - ☐ Service - ☐ AC + ☐ Service @started(19-12-23 12:49) + ☐ AC @started(19-12-23 12:48) ☐ ACT ☐ AM ☐ APT diff --git a/src/common/construct.h b/src/common/construct.h new file mode 100644 index 000000000..28f4cc349 --- /dev/null +++ b/src/common/construct.h @@ -0,0 +1,35 @@ +#include + +#define BOOST_SERIALIZATION_FRIENDS \ + friend class boost::serialization::access; \ + friend class construct_access; + +class construct_access { +public: + template + static inline void save_construct(Archive & ar, const T * t, const unsigned int file_version) { + t->save_construct(ar, file_version); + } + template + static inline void load_construct(Archive & ar, T * t, const unsigned int file_version) { + T::load_construct(ar, t, file_version); + } +}; + +#define BOOST_SERIALIZATION_CONSTRUCT(T) \ +namespace boost { namespace serialization { \ +\ + template \ + inline void save_construct_data( \ + Archive & ar, const T * t, const unsigned int file_version \ + ){ \ + construct_access::save_construct(ar, t, file_version); \ + } \ +\ + template \ + inline void load_construct_data( \ + Archive & ar, T * t, const unsigned int file_version \ + ){ \ + construct_access::load_construct(ar, t, file_version); \ + } \ +}} diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index be3a20e79..da89ad39a 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -75,6 +75,10 @@ public: /// in each service must inherit from this. struct SessionDataBase { virtual ~SessionDataBase() = default; + private: + template + void serialize(Archive& ar, const unsigned int file_version) { } + friend class boost::serialization::access; }; protected: @@ -94,6 +98,7 @@ protected: struct SessionInfo { SessionInfo(std::shared_ptr session, std::unique_ptr data); + SessionInfo() = default; std::shared_ptr session; std::unique_ptr data; diff --git a/src/core/hle/service/ac/ac.cpp b/src/core/hle/service/ac/ac.cpp index 9d40b9661..acae47fd5 100644 --- a/src/core/hle/service/ac/ac.cpp +++ b/src/core/hle/service/ac/ac.cpp @@ -5,6 +5,7 @@ #include #include "common/common_types.h" #include "common/logging/log.h" +#include "common/archives.h" #include "core/core.h" #include "core/hle/ipc.h" #include "core/hle/ipc_helpers.h" @@ -16,6 +17,8 @@ #include "core/hle/service/ac/ac_u.h" #include "core/memory.h" +SERIALIZE_EXPORT_IMPL(Service::AC::Module::Interface) + namespace Service::AC { void Module::Interface::CreateDefaultConfig(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x1, 0, 0); diff --git a/src/core/hle/service/ac/ac.h b/src/core/hle/service/ac/ac.h index f3554c876..12e304f59 100644 --- a/src/core/hle/service/ac/ac.h +++ b/src/core/hle/service/ac/ac.h @@ -6,6 +6,9 @@ #include #include +#include +#include +#include "common/construct.h" #include "core/hle/service/service.h" namespace Core { @@ -139,6 +142,34 @@ public: protected: std::shared_ptr ac; + + private: + template + void save_construct(Archive& ar, const unsigned int file_version) const + { + ar << ac; + ar << GetServiceName(); + ar << GetMaxSessions(); + } + + template + static void load_construct(Archive& ar, Interface* t, const unsigned int file_version) + { + std::shared_ptr ac; + std::string name; + u32 max_sessions; + ar >> ac; + ar >> name; + ar >> max_sessions; + ::new(t)Interface(ac, name.c_str(), max_sessions); + } + + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + } + BOOST_SERIALIZATION_FRIENDS }; protected: @@ -153,8 +184,23 @@ protected: std::shared_ptr close_event; std::shared_ptr connect_event; std::shared_ptr disconnect_event; + +private: + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & ac_connected; + ar & close_event; + ar & connect_event; + ar & disconnect_event; + // default_config is never written to + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::AC + +BOOST_SERIALIZATION_CONSTRUCT(Service::AC::Module::Interface) +BOOST_CLASS_EXPORT_KEY(Service::AC::Module::Interface) diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index db6a0ad23..f05c15f23 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -85,6 +85,7 @@ private: using InvokerFn = void(ServiceFrameworkBase* object, HandlerFnP member, Kernel::HLERequestContext& ctx); + // TODO: Replace all these with virtual functions! ServiceFrameworkBase(const char* service_name, u32 max_sessions, InvokerFn* handler_invoker); ~ServiceFrameworkBase() override; diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index 9cdaff72d..d91732da9 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_port.h" @@ -85,11 +86,23 @@ private: std::unordered_map registered_services_inverse; template - void serialize(Archive& ar, const unsigned int file_version) + void save(Archive& ar, const unsigned int file_version) const { - ar & registered_services; - ar & registered_services_inverse; // TODO: Instead, compute this from registered_services + ar << registered_services; } + + template + void load(Archive& ar, const unsigned int file_version) + { + ar >> registered_services; + registered_services_inverse.clear(); + for (const auto& pair : registered_services) { + registered_services_inverse.emplace(pair.second->GetObjectId(), pair.first); + } + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() + friend class boost::serialization::access; }; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index a07cc2e13..7264e1ec4 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -56,7 +56,7 @@ private: std::array linear_heap{}; std::array new_linear_heap{}; - static_assert(sizeof(bool) == 1); // TODO: Maybe this isn't true? + static_assert(sizeof(bool) == 1); friend class boost::serialization::access; template void serialize(Archive & ar, const unsigned int file_version)