From 6940c99ed65c64f462efc082d31f238eac13ae25 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Tue, 6 Aug 2019 15:59:31 +0100 Subject: [PATCH 001/129] Added boost serialization --- .gitmodules | 2 +- CMakeLists.txt | 9 +++++++++ externals/boost | 2 +- src/common/archives.h | 11 +++++++++++ src/core/CMakeLists.txt | 2 +- src/core/hle/kernel/vm_manager.h | 26 ++++++++++++++++++++++++++ src/core/memory.cpp | 31 +++++++++++++++++++++++++++++++ src/core/memory.h | 9 +++++++++ 8 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 src/common/archives.h diff --git a/.gitmodules b/.gitmodules index b247ccdbe0..b0bfcaee88 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "boost"] path = externals/boost - url = https://github.com/citra-emu/ext-boost.git + url = https://github.com/hamish-milne/ext-boost.git [submodule "nihstro"] path = externals/nihstro url = https://github.com/neobrain/nihstro.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 41d55f3753..df8081f059 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,6 +124,8 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) # System imported libraries # ====================== +add_library(boost_libs INTERFACE) + find_package(Boost 1.66.0 QUIET) if (NOT Boost_FOUND) message(STATUS "Boost 1.66.0 or newer not found, falling back to externals") @@ -131,7 +133,14 @@ if (NOT Boost_FOUND) set(BOOST_ROOT "${PROJECT_SOURCE_DIR}/externals/boost") set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost") set(Boost_NO_SYSTEM_PATHS OFF) + add_definitions( -DBOOST_ALL_NO_LIB ) find_package(Boost QUIET REQUIRED) + + # Boost external libraries + file(GLOB boost_serialization_SRC "externals/boost/libs/serialization/src/*.cpp") + add_library(boost_serialization STATIC ${boost_serialization_SRC}) + target_link_libraries(boost_serialization PUBLIC Boost::boost) + target_link_libraries(boost_libs INTERFACE boost_serialization) endif() # Prefer the -pthread flag on Linux. diff --git a/externals/boost b/externals/boost index 502437b2ae..1acb9699ac 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit 502437b2ae3f1da821aa7d5d5174ec356fa89269 +Subproject commit 1acb9699ac8e91654331504cf3524b26463eeee4 diff --git a/src/common/archives.h b/src/common/archives.h new file mode 100644 index 0000000000..76aa710548 --- /dev/null +++ b/src/common/archives.h @@ -0,0 +1,11 @@ +#include "boost/archive/binary_iarchive.hpp" +#include "boost/archive/binary_oarchive.hpp" + +#define SERIALIZE_IMPL(A) template void A::serialize( \ + boost::archive::binary_iarchive & ar, \ + const unsigned int file_version \ +); \ +template void A::serialize( \ + boost::archive::binary_oarchive & ar, \ + const unsigned int file_version \ +); diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 064e44f940..ed26424312 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -465,7 +465,7 @@ endif() create_target_directory_groups(core) target_link_libraries(core PUBLIC common PRIVATE audio_core network video_core) -target_link_libraries(core PUBLIC Boost::boost PRIVATE cryptopp fmt open_source_archives) +target_link_libraries(core PUBLIC Boost::boost PRIVATE cryptopp fmt open_source_archives boost_libs) if (ENABLE_WEB_SERVICE) target_compile_definitions(core PRIVATE -DENABLE_WEB_SERVICE) target_link_libraries(core PRIVATE web_service) diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index fbd9bf09b3..0d3ae1e44d 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -8,6 +8,7 @@ #include #include #include +#include "boost/serialization/split_member.hpp" #include "common/common_types.h" #include "core/hle/result.h" #include "core/memory.h" @@ -193,6 +194,31 @@ public: Memory::PageTable page_table; private: + friend class boost::serialization::access; + template + void save(Archive & ar, const unsigned int file_version) + { + for (int i = 0; i < page_table.pointers.size(); i++) { + ar << memory.GetFCRAMOffset(page_table.pointers[i]); + } + ar & page_table.special_regions; + ar & page_table.attributes; + } + + template + void load(Archive & ar, const unsigned int file_version) + { + for (int i = 0; i < page_table.pointers.size(); i++) { + u32 offset{}; + ar >> offset; + page_table.pointers[i] = memory.GetFCRAMPointer(offset); + } + ar & page_table.special_regions; + ar & page_table.attributes; + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() + using VMAIter = decltype(vma_map)::iterator; /// Converts a VMAHandle to a mutable VMAIter. diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 096f4c6977..e5fb83f5ac 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -4,7 +4,9 @@ #include #include +#include "boost/serialization/split_member.hpp" #include "audio_core/dsp_interface.h" +#include "common/archives.h" #include "common/assert.h" #include "common/common_types.h" #include "common/logging/log.h" @@ -67,8 +69,37 @@ public: std::vector page_table_list; AudioCore::DspInterface* dsp = nullptr; + +private: + friend class boost::serialization::access; + template + void save(Archive & ar, const unsigned int file_version) const + { + // TODO: Skip n3ds ram when not used? + ar.save_binary(fcram.get(), Memory::FCRAM_N3DS_SIZE); + ar.save_binary(vram.get(), Memory::VRAM_SIZE); + ar.save_binary(n3ds_extra_ram.get(), Memory::N3DS_EXTRA_RAM_SIZE); + // ar & cache_marker; + // ar & page_table_list; + // ar & current_page_table; + } + + template + void load(Archive & ar, const unsigned int file_version) + { + ar.load_binary(fcram.get(), Memory::FCRAM_N3DS_SIZE); + ar.load_binary(vram.get(), Memory::VRAM_SIZE); + ar.load_binary(n3ds_extra_ram.get(), Memory::N3DS_EXTRA_RAM_SIZE); + // ar & cache_marker; + // ar & page_table_list; + // ar & current_page_table; + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() }; +SERIALIZE_IMPL(MemorySystem::Impl) + MemorySystem::MemorySystem() : impl(std::make_unique()) {} MemorySystem::~MemorySystem() = default; diff --git a/src/core/memory.h b/src/core/memory.h index 6caca5a2ba..e5582d16d4 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -9,6 +9,7 @@ #include #include #include +#include "boost/serialization/split_member.hpp" #include "common/common_types.h" #include "core/mmio.h" @@ -52,6 +53,14 @@ struct SpecialRegion { VAddr base; u32 size; MMIORegionPointer handler; + + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & base; + ar & size; + ar & handler; + } }; /** From dc04774ece118757007fdf9e14b52585990e2554 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Tue, 6 Aug 2019 17:45:06 +0100 Subject: [PATCH 002/129] Added POD serialization --- externals/boost | 2 +- src/common/CMakeLists.txt | 1 + src/common/pod.h | 20 +++++++++++++++++ src/core/core.h | 9 ++++++++ src/core/hle/result.h | 3 +++ src/core/hw/gpu.h | 3 +++ src/core/hw/lcd.h | 3 +++ src/core/memory.cpp | 47 +++++++++++++++++++++++---------------- 8 files changed, 68 insertions(+), 20 deletions(-) create mode 100644 src/common/pod.h diff --git a/externals/boost b/externals/boost index 1acb9699ac..d2a5baa1ad 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit 1acb9699ac8e91654331504cf3524b26463eeee4 +Subproject commit d2a5baa1ad701671a7ef547ef71cb0f0c80ce2cf diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index af07ac2152..5abf93dbc7 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -84,6 +84,7 @@ add_library(common STATIC misc.cpp param_package.cpp param_package.h + pod.h quaternion.h ring_buffer.h scm_rev.cpp diff --git a/src/common/pod.h b/src/common/pod.h new file mode 100644 index 0000000000..e7224644a3 --- /dev/null +++ b/src/common/pod.h @@ -0,0 +1,20 @@ +#include "boost/serialization/split_member.hpp" + +#define SERIALIZE_AS_POD \ + private: \ + friend class boost::serialization::access; \ + template \ + void save(Archive & ar, const unsigned int file_version) const { \ + ar.save_binary(this, sizeof(*this)); \ + } \ + template \ + void load(Archive & ar, const unsigned int file_version) { \ + ar.load_binary(this, sizeof(*this)); \ + } \ + template \ + void serialize( \ + Archive &ar, \ + const unsigned int file_version \ + ){ \ + boost::serialization::split_member(ar, *this, file_version); \ + } diff --git a/src/core/core.h b/src/core/core.h index 5b79654537..333e4a76c6 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -15,6 +15,7 @@ #include "core/memory.h" #include "core/perf_stats.h" #include "core/telemetry_session.h" +class boost::serialization::access; class ARM_Interface; @@ -338,6 +339,14 @@ private: std::atomic reset_requested; std::atomic shutdown_requested; + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & GPU::g_regs; + ar & LCD::g_regs; + } }; inline ARM_Interface& CPU() { diff --git a/src/core/hle/result.h b/src/core/hle/result.h index 1543d7bd82..4168ce36cf 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h @@ -10,6 +10,7 @@ #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" +#include "common/pod.h" // All the constants in this file come from http://3dbrew.org/wiki/Error_codes @@ -225,6 +226,8 @@ union ResultCode { constexpr bool IsError() const { return is_error.ExtractValue(raw) == 1; } + + SERIALIZE_AS_POD }; constexpr bool operator==(const ResultCode& a, const ResultCode& b) { diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h index 606ab95040..980b48cd77 100644 --- a/src/core/hw/gpu.h +++ b/src/core/hw/gpu.h @@ -10,6 +10,7 @@ #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" +#include "common/pod.h" namespace Memory { class MemorySystem; @@ -296,6 +297,8 @@ private: static inline u32 DecodeAddressRegister(u32 register_value) { return register_value * 8; } + + SERIALIZE_AS_POD }; static_assert(std::is_standard_layout::value, "Structure does not use standard layout"); diff --git a/src/core/hw/lcd.h b/src/core/hw/lcd.h index 5e37121f70..ecc9ecea41 100644 --- a/src/core/hw/lcd.h +++ b/src/core/hw/lcd.h @@ -9,6 +9,7 @@ #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" +#include "common/pod.h" #define LCD_REG_INDEX(field_name) (offsetof(LCD::Regs, field_name) / sizeof(u32)) @@ -50,6 +51,8 @@ struct Regs { u32* content = reinterpret_cast(this); return content[index]; } + + SERIALIZE_AS_POD }; static_assert(std::is_standard_layout::value, "Structure does not use standard layout"); diff --git a/src/core/memory.cpp b/src/core/memory.cpp index e5fb83f5ac..9ee279129d 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -4,7 +4,8 @@ #include #include -#include "boost/serialization/split_member.hpp" +#include "boost/serialization/array.hpp" +#include "boost/serialization/nvp.hpp" #include "audio_core/dsp_interface.h" #include "common/archives.h" #include "common/assert.h" @@ -54,6 +55,16 @@ private: std::array vram{}; std::array linear_heap{}; std::array new_linear_heap{}; + + static_assert(sizeof(bool) == 1); // TODO: Maybe this isn't true? + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & vram; + ar & linear_heap; + ar & new_linear_heap; + } }; class MemorySystem::Impl { @@ -71,31 +82,29 @@ public: AudioCore::DspInterface* dsp = nullptr; private: + + template + void add_blob(Archive & ar, std::unique_ptr & var, const char *name, std::size_t size) + { + ar & boost::serialization::make_nvp( + name, + *static_cast(static_cast(var.get())) + ); + } + friend class boost::serialization::access; template - void save(Archive & ar, const unsigned int file_version) const + void serialize(Archive & ar, const unsigned int file_version) { // TODO: Skip n3ds ram when not used? - ar.save_binary(fcram.get(), Memory::FCRAM_N3DS_SIZE); - ar.save_binary(vram.get(), Memory::VRAM_SIZE); - ar.save_binary(n3ds_extra_ram.get(), Memory::N3DS_EXTRA_RAM_SIZE); - // ar & cache_marker; + add_blob(ar, fcram, "fcram", Memory::FCRAM_N3DS_SIZE); + add_blob(ar, vram, "vram", Memory::VRAM_SIZE); + add_blob(ar, n3ds_extra_ram, "n3ds_extra_ram", Memory::N3DS_EXTRA_RAM_SIZE); + ar & cache_marker; + // TODO: How the hell to do page tables.. // ar & page_table_list; // ar & current_page_table; } - - template - void load(Archive & ar, const unsigned int file_version) - { - ar.load_binary(fcram.get(), Memory::FCRAM_N3DS_SIZE); - ar.load_binary(vram.get(), Memory::VRAM_SIZE); - ar.load_binary(n3ds_extra_ram.get(), Memory::N3DS_EXTRA_RAM_SIZE); - // ar & cache_marker; - // ar & page_table_list; - // ar & current_page_table; - } - - BOOST_SERIALIZATION_SPLIT_MEMBER() }; SERIALIZE_IMPL(MemorySystem::Impl) From ee2cae20931114fb0b6fc7733e70e48930fa80a9 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 7 Aug 2019 02:53:56 +0100 Subject: [PATCH 003/129] Added core serialization --- src/audio_core/dsp_interface.h | 1 + src/core/core.cpp | 26 ++++++++++++++++++++++++++ src/core/core.h | 12 ++++++------ src/core/memory.cpp | 11 +++++++++-- src/core/memory.h | 6 +++++- 5 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/audio_core/dsp_interface.h b/src/audio_core/dsp_interface.h index fc3d7cab2d..29ec13d613 100644 --- a/src/audio_core/dsp_interface.h +++ b/src/audio_core/dsp_interface.h @@ -6,6 +6,7 @@ #include #include +#include "boost/serialization/array.hpp" #include "audio_core/audio_types.h" #include "audio_core/time_stretch.h" #include "common/common_types.h" diff --git a/src/core/core.cpp b/src/core/core.cpp index ebaee4f870..cee6a38666 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -4,9 +4,12 @@ #include #include +#include "boost/serialization/array.hpp" +#include "boost/serialization/unique_ptr.hpp" #include "audio_core/dsp_interface.h" #include "audio_core/hle/hle.h" #include "audio_core/lle/lle.h" +#include "common/archives.h" #include "common/logging/log.h" #include "common/texture.h" #include "core/arm/arm_interface.h" @@ -30,7 +33,9 @@ #include "core/hle/service/fs/archive.h" #include "core/hle/service/service.h" #include "core/hle/service/sm/sm.h" +#include "core/hw/gpu.h" #include "core/hw/hw.h" +#include "core/hw/lcd.h" #include "core/loader/loader.h" #include "core/movie.h" #include "core/rpc/rpc_server.h" @@ -389,4 +394,25 @@ void System::Reset() { Load(*m_emu_window, m_filepath); } +template +void System::serialize(Archive & ar, const unsigned int file_version) +{ + ar & memory; + ar & GPU::g_regs; + ar & LCD::g_regs; + ar & dsp_core->GetDspMemory(); +} + +void System::Save(std::ostream &stream) const +{ + boost::archive::binary_oarchive oa{stream}; + oa & *this; +} + +void System::Load(std::istream &stream) +{ + boost::archive::binary_iarchive ia{stream}; + ia & *this; +} + } // namespace Core diff --git a/src/core/core.h b/src/core/core.h index 333e4a76c6..b811badbaa 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -6,6 +6,7 @@ #include #include +#include "boost/serialization/access.hpp" #include "common/common_types.h" #include "core/custom_tex_cache.h" #include "core/frontend/applets/mii_selector.h" @@ -15,7 +16,6 @@ #include "core/memory.h" #include "core/perf_stats.h" #include "core/telemetry_session.h" -class boost::serialization::access; class ARM_Interface; @@ -272,6 +272,10 @@ public: return registered_image_interface; } + void Save(std::ostream &stream) const; + + void Load(std::istream &stream); + private: /** * Initialize the emulated system. @@ -342,11 +346,7 @@ private: friend class boost::serialization::access; template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & GPU::g_regs; - ar & LCD::g_regs; - } + void serialize(Archive & ar, const unsigned int file_version); }; inline ARM_Interface& CPU() { diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 9ee279129d..fe33cf767d 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -6,6 +6,7 @@ #include #include "boost/serialization/array.hpp" #include "boost/serialization/nvp.hpp" +#include "boost/serialization/unique_ptr.hpp" #include "audio_core/dsp_interface.h" #include "common/archives.h" #include "common/assert.h" @@ -107,11 +108,17 @@ private: } }; -SERIALIZE_IMPL(MemorySystem::Impl) - MemorySystem::MemorySystem() : impl(std::make_unique()) {} MemorySystem::~MemorySystem() = default; +template +void MemorySystem::serialize(Archive & ar, const unsigned int file_version) +{ + ar & impl; +} + +SERIALIZE_IMPL(MemorySystem) + void MemorySystem::SetCurrentPageTable(PageTable* page_table) { impl->current_page_table = page_table; } diff --git a/src/core/memory.h b/src/core/memory.h index e5582d16d4..9c1455a806 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -9,7 +9,7 @@ #include #include #include -#include "boost/serialization/split_member.hpp" +#include "boost/serialization/access.hpp" #include "common/common_types.h" #include "core/mmio.h" @@ -324,6 +324,10 @@ private: class Impl; std::unique_ptr impl; + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version); }; /// Determines if the given VAddr is valid for the specified process. From 6f00976ab59c8e8960c11a43e5d746146aa2884a Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 7 Aug 2019 17:08:52 +0100 Subject: [PATCH 004/129] video_core serialization --- src/common/archives.h | 11 ++-- src/core/core.cpp | 16 +++-- src/core/hw/gpu.cpp | 9 +-- src/video_core/CMakeLists.txt | 2 +- src/video_core/command_processor.cpp | 13 +++- src/video_core/command_processor.h | 2 +- src/video_core/pica_state.h | 90 ++++++++++++++++++++++++++++ src/video_core/video_core.cpp | 16 +++++ src/video_core/video_core.h | 4 ++ 9 files changed, 142 insertions(+), 21 deletions(-) diff --git a/src/common/archives.h b/src/common/archives.h index 76aa710548..490710d3c1 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -1,11 +1,14 @@ #include "boost/archive/binary_iarchive.hpp" #include "boost/archive/binary_oarchive.hpp" -#define SERIALIZE_IMPL(A) template void A::serialize( \ - boost::archive::binary_iarchive & ar, \ +using iarchive = boost::archive::binary_iarchive; +using oarchive = boost::archive::binary_oarchive; + +#define SERIALIZE_IMPL(A) template void A::serialize( \ + iarchive & ar, \ const unsigned int file_version \ ); \ -template void A::serialize( \ - boost::archive::binary_oarchive & ar, \ +template void A::serialize( \ + oarchive & ar, \ const unsigned int file_version \ ); diff --git a/src/core/core.cpp b/src/core/core.cpp index cee6a38666..63730214f0 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -397,22 +397,28 @@ void System::Reset() { template void System::serialize(Archive & ar, const unsigned int file_version) { - ar & memory; ar & GPU::g_regs; ar & LCD::g_regs; ar & dsp_core->GetDspMemory(); + ar & memory; } void System::Save(std::ostream &stream) const { - boost::archive::binary_oarchive oa{stream}; - oa & *this; + { + oarchive oa{stream}; + oa & *this; + } + VideoCore::Save(stream); } void System::Load(std::istream &stream) { - boost::archive::binary_iarchive ia{stream}; - ia & *this; + { + iarchive ia{stream}; + ia & *this; + } + VideoCore::Load(stream); } } // namespace Core diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index fcb60e6fec..b283b7d91b 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp @@ -472,14 +472,7 @@ inline void Write(u32 addr, const T data) { if (config.trigger & 1) { MICROPROFILE_SCOPE(GPU_CmdlistProcessing); - u32* buffer = (u32*)g_memory->GetPhysicalPointer(config.GetPhysicalAddress()); - - if (Pica::g_debug_context && Pica::g_debug_context->recorder) { - Pica::g_debug_context->recorder->MemoryAccessed((u8*)buffer, config.size, - config.GetPhysicalAddress()); - } - - Pica::CommandProcessor::ProcessCommandList(buffer, config.size); + Pica::CommandProcessor::ProcessCommandList(config.GetPhysicalAddress(), config.size); g_regs.command_processor_config.trigger = 0; } diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 4cb9763543..8dbf5d8e09 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -94,7 +94,7 @@ endif() create_target_directory_groups(video_core) target_link_libraries(video_core PUBLIC common core) -target_link_libraries(video_core PRIVATE glad nihstro-headers) +target_link_libraries(video_core PRIVATE glad nihstro-headers boost_libs) if (ARCHITECTURE_x86_64) target_link_libraries(video_core PUBLIC xbyak) diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 72f6f21611..3a5b35236a 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -640,8 +640,17 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { reinterpret_cast(&id)); } -void ProcessCommandList(const u32* list, u32 size) { - g_state.cmd_list.head_ptr = g_state.cmd_list.current_ptr = list; +void ProcessCommandList(PAddr list, u32 size) { + + u32* buffer = (u32*)VideoCore::g_memory->GetPhysicalPointer(list); + + if (Pica::g_debug_context && Pica::g_debug_context->recorder) { + Pica::g_debug_context->recorder->MemoryAccessed((u8*)buffer, size, + list); + } + + g_state.cmd_list.addr = list; + g_state.cmd_list.head_ptr = g_state.cmd_list.current_ptr = buffer; g_state.cmd_list.length = size / sizeof(u32); while (g_state.cmd_list.current_ptr < g_state.cmd_list.head_ptr + g_state.cmd_list.length) { diff --git a/src/video_core/command_processor.h b/src/video_core/command_processor.h index 82b1543274..3b4e055198 100644 --- a/src/video_core/command_processor.h +++ b/src/video_core/command_processor.h @@ -32,6 +32,6 @@ static_assert(std::is_standard_layout::value == true, "CommandHeader does not use standard layout"); static_assert(sizeof(CommandHeader) == sizeof(u32), "CommandHeader has incorrect size!"); -void ProcessCommandList(const u32* list, u32 size); +void ProcessCommandList(PAddr list, u32 size); } // namespace Pica::CommandProcessor diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 5a97ae952c..1e5b1ecd23 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -5,6 +5,7 @@ #pragma once #include +#include "boost/serialization/split_member.hpp" #include "common/bit_field.h" #include "common/common_types.h" #include "common/vector_math.h" @@ -13,6 +14,18 @@ #include "video_core/regs.h" #include "video_core/shader/shader.h" +// NB, by defining this we can't use the built-in std::array serializer in this file +namespace boost::serialization { + +template +void serialize(Archive & ar, std::array &array, const unsigned int version) +{ + static_assert(sizeof(Value) == sizeof(u32)); + ar & *static_cast(static_cast(array.data())); +} + +} + namespace Pica { /// Struct used to describe current Pica state @@ -79,6 +92,18 @@ struct State { std::array alpha_map_table; std::array color_table; std::array color_diff_table; + + private: + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & noise_table; + ar & color_map_table; + ar & alpha_map_table; + ar & color_table; + ar & color_diff_table; + } } proctex; struct Lighting { @@ -101,6 +126,12 @@ struct State { float diff = static_cast(difference) / 2047.f; return neg_difference ? -diff : diff; } + + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & raw; + } }; std::array, 24> luts; @@ -126,8 +157,11 @@ struct State { std::array lut; } fog; +#undef SERIALIZE_RAW + /// Current Pica command list struct { + PAddr addr; // This exists only for serialization const u32* head_ptr; const u32* current_ptr; u32 length; @@ -141,6 +175,17 @@ struct State { u32 current_attribute = 0; // Indicates the immediate mode just started and the geometry pipeline needs to reconfigure bool reset_geometry_pipeline = true; + + private: + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + // ar & input_vertex; + ar & current_attribute; + ar & reset_geometry_pipeline; + } + } immediate; // the geometry shader needs to be kept in the global state because some shaders relie on @@ -161,6 +206,51 @@ struct State { int default_attr_counter = 0; u32 default_attr_write_buffer[3]{}; + +private: + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & regs.reg_array; + // ar & vs; + // ar & gs; + // ar & input_default_attributes; + ar & proctex; + for (auto i = 0; i < lighting.luts.size(); i++) { + ar & lighting.luts[i]; + } + ar & fog.lut; + ar & cmd_list.addr; + ar & cmd_list.length; + ar & immediate; + // ar & gs_unit; + // ar & geometry_pipeline; + // ar & primitive_assembler; + ar & vs_float_regs_counter; + ar & vs_uniform_write_buffer; + ar & gs_float_regs_counter; + ar & gs_uniform_write_buffer; + ar & default_attr_counter; + ar & default_attr_write_buffer; + boost::serialization::split_member(ar, *this, file_version); + } + + template + void save(Archive & ar, const unsigned int file_version) const + { + ar << static_cast(cmd_list.current_ptr - cmd_list.head_ptr); + } + + template + void load(Archive & ar, const unsigned int file_version) + { + u32 offset{}; + ar >> offset; + cmd_list.head_ptr = (u32*)VideoCore::g_memory->GetPhysicalPointer(cmd_list.addr); + cmd_list.current_ptr = cmd_list.head_ptr + offset; + } }; extern State g_state; ///< Current Pica state diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index b7e1d4885b..5bc1e87026 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp @@ -3,9 +3,11 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/logging/log.h" #include "core/settings.h" #include "video_core/pica.h" +#include "video_core/pica_state.h" #include "video_core/renderer_base.h" #include "video_core/renderer_opengl/gl_vars.h" #include "video_core/renderer_opengl/renderer_opengl.h" @@ -85,4 +87,18 @@ u16 GetResolutionScaleFactor() { } } +void Save(std::ostream &stream) +{ + oarchive oa{stream}; + oa & Pica::g_state; +} + +void Load(std::istream &stream) +{ + iarchive ia{stream}; + ia & Pica::g_state; + // TODO: Flush/reset things + +} + } // namespace VideoCore diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h index f11b678399..1ec69f802d 100644 --- a/src/video_core/video_core.h +++ b/src/video_core/video_core.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include #include "core/frontend/emu_window.h" @@ -61,4 +62,7 @@ void RequestScreenshot(void* data, std::function callback, u16 GetResolutionScaleFactor(); +void Save(std::ostream &stream); +void Load(std::istream &stream); + } // namespace VideoCore From 45788b9c825c5361cca5614465fdec64ab7a5cd5 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 8 Aug 2019 05:25:24 +0100 Subject: [PATCH 005/129] Added shader state serialization --- src/common/vector_math.h | 28 ++++++++++++++++++++++++++++ src/video_core/pica_state.h | 30 ++++++++++++++++-------------- src/video_core/pica_types.h | 8 ++++++++ src/video_core/shader/shader.h | 24 ++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 14 deletions(-) diff --git a/src/common/vector_math.h b/src/common/vector_math.h index ba36744fc9..171d4ebfd4 100644 --- a/src/common/vector_math.h +++ b/src/common/vector_math.h @@ -32,6 +32,7 @@ #include #include +#include namespace Common { @@ -44,6 +45,14 @@ class Vec4; template class Vec2 { + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & x; + ar & y; + } + public: T x; T y; @@ -191,6 +200,15 @@ inline float Vec2::Normalize() { template class Vec3 { + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & x; + ar & y; + ar & z; + } + public: T x; T y; @@ -399,6 +417,16 @@ using Vec3f = Vec3; template class Vec4 { + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & x; + ar & y; + ar & z; + ar & w; + } + public: T x; T y; diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 1e5b1ecd23..10d1e637b6 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -14,11 +14,15 @@ #include "video_core/regs.h" #include "video_core/shader/shader.h" -// NB, by defining this we can't use the built-in std::array serializer in this file +// Boost::serialization doesn't like union types for some reason, +// so we need to mark arrays of union values with a special serialization method +template +struct UnionArray : public std::array { }; + namespace boost::serialization { template -void serialize(Archive & ar, std::array &array, const unsigned int version) +void serialize(Archive& ar, UnionArray& array, const unsigned int version) { static_assert(sizeof(Value) == sizeof(u32)); ar & *static_cast(static_cast(array.data())); @@ -87,11 +91,11 @@ struct State { } }; - std::array noise_table; - std::array color_map_table; - std::array alpha_map_table; - std::array color_table; - std::array color_diff_table; + UnionArray noise_table; + UnionArray color_map_table; + UnionArray alpha_map_table; + UnionArray color_table; + UnionArray color_diff_table; private: friend class boost::serialization::access; @@ -134,7 +138,7 @@ struct State { } }; - std::array, 24> luts; + std::array, 24> luts; } lighting; struct { @@ -154,7 +158,7 @@ struct State { } }; - std::array lut; + UnionArray lut; } fog; #undef SERIALIZE_RAW @@ -214,13 +218,11 @@ private: void serialize(Archive & ar, const unsigned int file_version) { ar & regs.reg_array; - // ar & vs; - // ar & gs; + ar & vs; + ar & gs; // ar & input_default_attributes; ar & proctex; - for (auto i = 0; i < lighting.luts.size(); i++) { - ar & lighting.luts[i]; - } + ar & lighting.luts; ar & fog.lut; ar & cmd_list.addr; ar & cmd_list.length; diff --git a/src/video_core/pica_types.h b/src/video_core/pica_types.h index 5aca37b693..bef256e131 100644 --- a/src/video_core/pica_types.h +++ b/src/video_core/pica_types.h @@ -6,6 +6,7 @@ #include #include +#include #include "common/common_types.h" namespace Pica { @@ -140,6 +141,13 @@ private: // Stored as a regular float, merely for convenience // TODO: Perform proper arithmetic on this! float value; + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & value; + } }; using float24 = Float<16, 7>; diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index bb6a5fae73..3f55d30641 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "common/assert.h" #include "common/common_funcs.h" #include "common/common_types.h" @@ -193,6 +194,16 @@ struct Uniforms { static std::size_t GetIntUniformOffset(unsigned index) { return offsetof(Uniforms, i) + index * sizeof(Common::Vec4); } + +private: + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & f; + ar & b; + ar & i; + } }; struct ShaderSetup { @@ -237,6 +248,19 @@ private: bool swizzle_data_hash_dirty = true; u64 program_code_hash = 0xDEADC0DE; u64 swizzle_data_hash = 0xDEADC0DE; + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & uniforms; + ar & program_code; + ar & swizzle_data; + ar & program_code_hash_dirty; + ar & swizzle_data_hash_dirty; + ar & program_code_hash; + ar & swizzle_data_hash; + } }; class ShaderEngine { From f79c9668a3a271a5038bb9d55bf32e701c678a11 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 11 Aug 2019 00:20:09 +0100 Subject: [PATCH 006/129] Added shader state; WIP kernel objects --- externals/boost | 2 +- src/common/CMakeLists.txt | 2 + src/common/serialization/atomic.h | 28 ++++ src/common/serialization/boost_vector.hpp | 189 ++++++++++++++++++++++ src/core/core.cpp | 6 +- src/core/hle/kernel/client_port.cpp | 5 +- src/core/hle/kernel/client_port.h | 16 +- src/core/hle/kernel/event.h | 10 ++ src/core/hle/kernel/handle_table.h | 12 ++ src/core/hle/kernel/kernel.cpp | 23 +++ src/core/hle/kernel/kernel.h | 9 ++ src/core/hle/kernel/memory.h | 11 ++ src/core/hle/kernel/mutex.h | 12 ++ src/core/hle/kernel/object.cpp | 12 +- src/core/hle/kernel/object.h | 11 ++ src/core/hle/kernel/process.cpp | 14 +- src/core/hle/kernel/process.h | 65 +++++++- src/core/hle/kernel/resource_limit.cpp | 6 +- src/core/hle/kernel/resource_limit.h | 40 ++++- src/core/hle/kernel/semaphore.h | 11 ++ src/core/hle/kernel/server_port.cpp | 9 +- src/core/hle/kernel/server_port.h | 2 - src/core/hle/kernel/server_session.cpp | 5 +- src/core/hle/kernel/server_session.h | 2 +- src/core/hle/kernel/thread.cpp | 9 +- src/core/hle/kernel/thread.h | 2 +- src/core/hle/kernel/vm_manager.h | 28 +++- src/core/hle/kernel/wait_object.h | 14 ++ src/core/hle/service/err_f.cpp | 1 + src/core/memory.cpp | 23 +-- src/core/mmio.h | 7 + src/video_core/pica_state.h | 6 +- src/video_core/shader/shader.h | 52 ++++++ 33 files changed, 576 insertions(+), 68 deletions(-) create mode 100644 src/common/serialization/atomic.h create mode 100644 src/common/serialization/boost_vector.hpp diff --git a/externals/boost b/externals/boost index d2a5baa1ad..48130d3879 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit d2a5baa1ad701671a7ef547ef71cb0f0c80ce2cf +Subproject commit 48130d387975d17aed1b34ef75c21020f2d710a8 diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 5abf93dbc7..b0577f9d9c 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -90,6 +90,8 @@ add_library(common STATIC scm_rev.cpp scm_rev.h scope_exit.h + serialization/atomic.h + serialization/boost_vector.hpp string_util.cpp string_util.h swap.h diff --git a/src/common/serialization/atomic.h b/src/common/serialization/atomic.h new file mode 100644 index 0000000000..ef33202ffd --- /dev/null +++ b/src/common/serialization/atomic.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + +namespace boost::serialization +{ + template + void serialize(Archive& ar, std::atomic& value, const unsigned int file_version) + { + boost::serialization::split_free(ar, value, file_version); + } + + template + void save(Archive& ar, const std::atomic& value, const unsigned int file_version) + { + ar << value.load(); + } + + template + void load(Archive& ar, std::atomic& value, const unsigned int file_version) + { + T tmp; + ar >> tmp; + value.store(tmp); + } + +} // namespace boost::serialization diff --git a/src/common/serialization/boost_vector.hpp b/src/common/serialization/boost_vector.hpp new file mode 100644 index 0000000000..d97ebd2085 --- /dev/null +++ b/src/common/serialization/boost_vector.hpp @@ -0,0 +1,189 @@ +#ifndef BOOST_SERIALIZATION_BOOST_VECTOR_HPP +#define BOOST_SERIALIZATION_BOOST_VECTOR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// boost_vector.hpp: serialization for boost vector templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// fast array serialization (C) Copyright 2005 Matthias Troyer +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +// default is being compatible with version 1.34.1 files, not 1.35 files +#ifndef BOOST_SERIALIZATION_VECTOR_VERSIONED +#define BOOST_SERIALIZATION_VECTOR_VERSIONED(V) (V==4 || V==5) +#endif + +namespace boost { +namespace serialization { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// vector< T > + +// the default versions + +template +inline void save( + Archive & ar, + const boost::container::vector &t, + const unsigned int /* file_version */, + mpl::false_ +){ + boost::serialization::stl::save_collection >( + ar, t + ); +} + +template +inline void load( + Archive & ar, + boost::container::vector &t, + const unsigned int /* file_version */, + mpl::false_ +){ + const boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + t.reserve(count); + stl::collection_load_impl(ar, t, count, item_version); +} + +// the optimized versions + +template +inline void save( + Archive & ar, + const boost::container::vector &t, + const unsigned int /* file_version */, + mpl::true_ +){ + const collection_size_type count(t.size()); + ar << BOOST_SERIALIZATION_NVP(count); + if (!t.empty()) + // explict template arguments to pass intel C++ compiler + ar << serialization::make_array( + static_cast(&t[0]), + count + ); +} + +template +inline void load( + Archive & ar, + boost::container::vector &t, + const unsigned int /* file_version */, + mpl::true_ +){ + collection_size_type count(t.size()); + ar >> BOOST_SERIALIZATION_NVP(count); + t.resize(count); + unsigned int item_version=0; + if(BOOST_SERIALIZATION_VECTOR_VERSIONED(ar.get_library_version())) { + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + if (!t.empty()) + // explict template arguments to pass intel C++ compiler + ar >> serialization::make_array( + static_cast(&t[0]), + count + ); + } + +// dispatch to either default or optimized versions + +template +inline void save( + Archive & ar, + const boost::container::vector &t, + const unsigned int file_version +){ + typedef typename + boost::serialization::use_array_optimization::template apply< + typename remove_const::type + >::type use_optimized; + save(ar,t,file_version, use_optimized()); +} + +template +inline void load( + Archive & ar, + boost::container::vector &t, + const unsigned int file_version +){ +#ifdef BOOST_SERIALIZATION_VECTOR_135_HPP + if (ar.get_library_version()==boost::archive::library_version_type(5)) + { + load(ar,t,file_version, boost::is_arithmetic()); + return; + } +#endif + typedef typename + boost::serialization::use_array_optimization::template apply< + typename remove_const::type + >::type use_optimized; + load(ar,t,file_version, use_optimized()); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + boost::container::vector & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + boost::container::vector & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(boost::container::vector) + +#endif // BOOST_SERIALIZATION_VECTOR_HPP diff --git a/src/core/core.cpp b/src/core/core.cpp index 63730214f0..902340d413 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -5,7 +5,6 @@ #include #include #include "boost/serialization/array.hpp" -#include "boost/serialization/unique_ptr.hpp" #include "audio_core/dsp_interface.h" #include "audio_core/hle/hle.h" #include "audio_core/lle/lle.h" @@ -205,6 +204,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo kernel = std::make_unique(*memory, *timing, [this] { PrepareReschedule(); }, system_mode); + Kernel::g_kernel = kernel.get(); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 @@ -368,6 +368,7 @@ void System::Shutdown() { service_manager.reset(); dsp_core.reset(); cpu_core.reset(); + Kernel::g_kernel = nullptr; kernel.reset(); timing.reset(); app_loader.reset(); @@ -400,7 +401,8 @@ void System::serialize(Archive & ar, const unsigned int file_version) ar & GPU::g_regs; ar & LCD::g_regs; ar & dsp_core->GetDspMemory(); - ar & memory; + ar & *memory.get(); + ar & *kernel.get(); } void System::Save(std::ostream &stream) const diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index d217dfb7c1..dc0e08d9d0 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -13,9 +13,6 @@ namespace Kernel { -ClientPort::ClientPort(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} -ClientPort::~ClientPort() = default; - ResultVal> ClientPort::Connect() { // Note: Threads do not wait for the server endpoint to call // AcceptSession before returning from this call. @@ -26,7 +23,7 @@ ResultVal> ClientPort::Connect() { active_sessions++; // Create a new session pair, let the created sessions inherit the parent port's HLE handler. - auto [server, client] = kernel.CreateSessionPair(server_port->GetName(), SharedFrom(this)); + auto [server, client] = g_kernel->CreateSessionPair(server_port->GetName(), SharedFrom(this)); if (server_port->hle_handler) server_port->hle_handler->ClientConnected(server); diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h index 423db01723..35544e37e8 100644 --- a/src/core/hle/kernel/client_port.h +++ b/src/core/hle/kernel/client_port.h @@ -17,8 +17,6 @@ class ClientSession; class ClientPort final : public Object { public: - explicit ClientPort(KernelSystem& kernel); - ~ClientPort() override; friend class ServerPort; std::string GetTypeName() const override { @@ -52,13 +50,25 @@ public: void ConnectionClosed(); private: - KernelSystem& kernel; std::shared_ptr server_port; ///< ServerPort associated with this client port. u32 max_sessions = 0; ///< Maximum number of simultaneous sessions the port can have u32 active_sessions = 0; ///< Number of currently open sessions to this port std::string name; ///< Name of client port (optional) friend class KernelSystem; + + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & server_port; + ar & max_sessions; + ar & active_sessions; + ar & name; + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index efc4a0c283..9e9da267a0 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h @@ -49,6 +49,16 @@ private: std::string name; ///< Name of event (optional) friend class KernelSystem; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & reset_type; + ar & signaled; + ar & name; + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h index bd5a5df6af..eabf06c26a 100644 --- a/src/core/hle/kernel/handle_table.h +++ b/src/core/hle/kernel/handle_table.h @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/result.h" @@ -116,6 +118,16 @@ private: u16 next_free_slot; KernelSystem& kernel; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & objects; + ar & generations; + ar & next_generation; + ar & next_free_slot; + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index ceb2f14f5f..d8bd0f0344 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" +#include "common/serialization/atomic.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/config_mem.h" #include "core/hle/kernel/handle_table.h" @@ -16,6 +18,8 @@ namespace Kernel { +KernelSystem* g_kernel; + /// Initialize the kernel KernelSystem::KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing, std::function prepare_reschedule_callback, u32 system_mode) @@ -101,4 +105,23 @@ void KernelSystem::AddNamedPort(std::string name, std::shared_ptr po named_ports.emplace(std::move(name), std::move(port)); } +template +void KernelSystem::serialize(Archive& ar, const unsigned int file_version) +{ + ar & named_ports; + // TODO: CPU + // NB: subsystem references and prepare_reschedule_callback are constant + ar & *resource_limits.get(); + ar & next_object_id; + //ar & *timer_manager.get(); + ar & next_process_id; + ar & process_list; + ar & current_process; + // ar & *thread_manager.get(); + //ar & *config_mem_handler.get(); + //ar & *shared_page_handler.get(); +} + +SERIALIZE_IMPL(KernelSystem) + } // namespace Kernel diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 58f63938be..c662882f58 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -11,6 +11,9 @@ #include #include #include +#include +#include +#include #include "common/common_types.h" #include "core/hle/kernel/memory.h" #include "core/hle/result.h" @@ -283,6 +286,12 @@ private: std::unique_ptr shared_page_handler; std::unique_ptr ipc_recorder; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version); }; +extern KernelSystem* g_kernel; + } // namespace Kernel diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h index bb4e174f79..9e9fe5eb43 100644 --- a/src/core/hle/kernel/memory.h +++ b/src/core/hle/kernel/memory.h @@ -60,6 +60,17 @@ struct MemoryRegionInfo { * @param size the size of the region to free. */ void Free(u32 offset, u32 size); + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & base; + ar & size; + ar & used; + // TODO: boost icl / free_blocks + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 1f6358909c..6186854519 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -58,6 +58,18 @@ public: private: KernelSystem& kernel; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & lock_count; + ar & priority; + ar & name; + ar & holding_thread; + ar & kernel; // TODO: Check that this works! + } }; /** diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp index f9ca682182..6ab1b1769f 100644 --- a/src/core/hle/kernel/object.cpp +++ b/src/core/hle/kernel/object.cpp @@ -8,7 +8,17 @@ namespace Kernel { -Object::Object(KernelSystem& kernel) : object_id{kernel.GenerateObjectID()} {} +// TODO: Remove this +Object::Object(KernelSystem& kernel) +{ +} + +Object::Object() = default; + +void Object::Init(KernelSystem& kernel) +{ + object_id = kernel.GenerateObjectID(); +} Object::~Object() = default; diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index 9547a83ed2..8998cb88d6 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "common/common_types.h" #include "core/hle/kernel/kernel.h" @@ -41,8 +42,11 @@ enum { class Object : NonCopyable, public std::enable_shared_from_this { public: explicit Object(KernelSystem& kernel); + Object(); virtual ~Object(); + virtual void Init(KernelSystem& kernel); + /// Returns a unique identifier for the object. For debugging purposes only. u32 GetObjectId() const { return object_id.load(std::memory_order_relaxed); @@ -64,6 +68,13 @@ public: private: std::atomic object_id; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & object_id; + } }; template diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index c6aa2b8954..63a5c3b68d 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -18,7 +18,8 @@ namespace Kernel { std::shared_ptr KernelSystem::CreateCodeSet(std::string name, u64 program_id) { - auto codeset{std::make_shared(*this)}; + auto codeset{std::make_shared()}; + codeset->Init(*this); codeset->name = std::move(name); codeset->program_id = program_id; @@ -26,11 +27,9 @@ std::shared_ptr KernelSystem::CreateCodeSet(std::string name, u64 progr return codeset; } -CodeSet::CodeSet(KernelSystem& kernel) : Object(kernel) {} -CodeSet::~CodeSet() {} - std::shared_ptr KernelSystem::CreateProcess(std::shared_ptr code_set) { - auto process{std::make_shared(*this)}; + auto process{std::make_shared()}; + process->Init(*this); process->codeset = std::move(code_set); process->flags.raw = 0; @@ -401,9 +400,8 @@ ResultCode Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission pe return RESULT_SUCCESS; } -Kernel::Process::Process(KernelSystem& kernel) - : Object(kernel), handle_table(kernel), vm_manager(kernel.memory), kernel(kernel) { - +Kernel::Process::Process() : kernel(*g_kernel), handle_table(*g_kernel), vm_manager(g_kernel->memory) +{ kernel.memory.RegisterPageTable(&vm_manager.page_table); } Kernel::Process::~Process() { diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index dc2c878b8c..6defd42c6d 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -11,8 +11,13 @@ #include #include #include +#include +#include +#include +#include #include "common/bit_field.h" #include "common/common_types.h" +#include "common/serialization/boost_vector.hpp" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/vm_manager.h" @@ -25,6 +30,17 @@ struct AddressMapping { u32 size; bool read_only; bool unk_flag; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & address; + ar & size; + ar & read_only; + ar & unk_flag; + } }; union ProcessFlags { @@ -52,13 +68,20 @@ struct MemoryRegionInfo; class CodeSet final : public Object { public: - explicit CodeSet(KernelSystem& kernel); - ~CodeSet() override; - struct Segment { std::size_t offset = 0; VAddr addr = 0; u32 size = 0; + + private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & offset; + ar & addr; + ar & size; + } }; std::string GetTypeName() const override { @@ -106,11 +129,24 @@ public: std::string name; /// Title ID corresponding to the process u64 program_id; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + // TODO: memory reference + ar & segments; + ar & entrypoint; + ar & name; + ar & program_id; + } }; class Process final : public Object { public: - explicit Process(Kernel::KernelSystem& kernel); + explicit Process(); ~Process() override; std::string GetTypeName() const override { @@ -195,5 +231,26 @@ public: private: KernelSystem& kernel; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & handle_table; + ar & codeset; + ar & resource_limit; + ar & svc_access_mask; + ar & handle_table_size; + ar & (boost::container::vector >&)address_mappings; + ar & flags.raw; + ar & kernel_version; + ar & ideal_processor; + ar & process_id; + ar & vm_manager; + ar & memory_used; + ar & memory_region; + ar & tls_slots; + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp index 8691c142ec..fe19caff9d 100644 --- a/src/core/hle/kernel/resource_limit.cpp +++ b/src/core/hle/kernel/resource_limit.cpp @@ -9,11 +9,9 @@ namespace Kernel { -ResourceLimit::ResourceLimit(KernelSystem& kernel) : Object(kernel) {} -ResourceLimit::~ResourceLimit() {} - std::shared_ptr ResourceLimit::Create(KernelSystem& kernel, std::string name) { - auto resource_limit{std::make_shared(kernel)}; + auto resource_limit{std::make_shared()}; + resource_limit->Init(kernel); resource_limit->name = std::move(name); return resource_limit; diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h index 99ae8f2cf4..06fe71587e 100644 --- a/src/core/hle/kernel/resource_limit.h +++ b/src/core/hle/kernel/resource_limit.h @@ -6,6 +6,8 @@ #include #include +#include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" @@ -33,8 +35,6 @@ enum ResourceTypes { class ResourceLimit final : public Object { public: - explicit ResourceLimit(KernelSystem& kernel); - ~ResourceLimit() override; /** * Creates a resource limit object. @@ -110,6 +110,35 @@ public: /// Current CPU time that the processes in this category are utilizing s32 current_cpu_time = 0; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + // NB most of these aren't used at all currently, but we're adding them here for forwards compatibility + ar & name; + ar & max_priority; + ar & max_commit; + ar & max_threads; + ar & max_events; + ar & max_mutexes; + ar & max_semaphores; + ar & max_timers; + ar & max_shared_mems; + ar & max_address_arbiters; + ar & max_cpu_time; + ar & current_commit; + ar & current_threads; + ar & current_events; + ar & current_mutexes; + ar & current_semaphores; + ar & current_timers; + ar & current_shared_mems; + ar & current_address_arbiters; + ar & current_cpu_time; + } }; class ResourceLimitList { @@ -126,6 +155,13 @@ public: private: std::array, 4> resource_limits; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & resource_limits; + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h index 47b3eabf10..526be6812a 100644 --- a/src/core/hle/kernel/semaphore.h +++ b/src/core/hle/kernel/semaphore.h @@ -43,6 +43,17 @@ public: * @return The number of free slots the semaphore had before this call */ ResultVal Release(s32 release_count); + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & max_count; + ar & available_count; + ar & name; + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index a69b427780..ca4cded3d9 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -13,9 +13,6 @@ namespace Kernel { -ServerPort::ServerPort(KernelSystem& kernel) : WaitObject(kernel) {} -ServerPort::~ServerPort() {} - ResultVal> ServerPort::Accept() { if (pending_sessions.empty()) { return ERR_NO_PENDING_SESSIONS; @@ -36,8 +33,10 @@ void ServerPort::Acquire(Thread* thread) { } KernelSystem::PortPair KernelSystem::CreatePortPair(u32 max_sessions, std::string name) { - auto server_port{std::make_shared(*this)}; - auto client_port{std::make_shared(*this)}; + auto server_port{std::make_shared()}; + server_port->Init(*this); + auto client_port{std::make_shared()}; + client_port->Init(*this); server_port->name = name + "_Server"; client_port->name = name + "_Client"; diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h index 9b0f134802..c500fd1b2c 100644 --- a/src/core/hle/kernel/server_port.h +++ b/src/core/hle/kernel/server_port.h @@ -20,8 +20,6 @@ class SessionRequestHandler; class ServerPort final : public WaitObject { public: - explicit ServerPort(KernelSystem& kernel); - ~ServerPort() override; std::string GetTypeName() const override { return "ServerPort"; diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 5855d83a5d..c6a6261a5a 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -13,7 +13,7 @@ namespace Kernel { -ServerSession::ServerSession(KernelSystem& kernel) : WaitObject(kernel), kernel(kernel) {} +ServerSession::ServerSession() : kernel(*g_kernel) {} ServerSession::~ServerSession() { // This destructor will be called automatically when the last ServerSession handle is closed by // the emulated application. @@ -30,7 +30,8 @@ ServerSession::~ServerSession() { ResultVal> ServerSession::Create(KernelSystem& kernel, std::string name) { - auto server_session{std::make_shared(kernel)}; + auto server_session{std::make_shared()}; + server_session->Init(kernel); server_session->name = std::move(name); server_session->parent = nullptr; diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 940f38f9b5..3536bcbd18 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -38,7 +38,7 @@ class Thread; class ServerSession final : public WaitObject { public: ~ServerSession() override; - explicit ServerSession(KernelSystem& kernel); + explicit ServerSession(); std::string GetName() const override { return name; diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 3b15ec35e0..4c2344dcbe 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -37,9 +37,9 @@ u32 ThreadManager::NewThreadId() { return next_thread_id++; } -Thread::Thread(KernelSystem& kernel) - : WaitObject(kernel), context(kernel.GetThreadManager().NewContext()), - thread_manager(kernel.GetThreadManager()) {} +Thread::Thread() + : context(g_kernel->GetThreadManager().NewContext()), + thread_manager(g_kernel->GetThreadManager()) {} Thread::~Thread() {} Thread* ThreadManager::GetCurrentThread() const { @@ -309,7 +309,8 @@ ResultVal> KernelSystem::CreateThread(std::string name, ErrorSummary::InvalidArgument, ErrorLevel::Permanent); } - auto thread{std::make_shared(*this)}; + auto thread{std::make_shared()}; + thread->Init(*this); thread_manager->thread_list.push_back(thread); thread_manager->ready_queue.prepare(priority); diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index f2ef767efa..2db5dda91d 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -149,7 +149,7 @@ private: class Thread final : public WaitObject { public: - explicit Thread(KernelSystem&); + explicit Thread(); ~Thread() override; std::string GetName() const override { diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 0d3ae1e44d..6711c9b4d6 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -8,7 +8,8 @@ #include #include #include -#include "boost/serialization/split_member.hpp" +#include +#include #include "common/common_types.h" #include "core/hle/result.h" #include "core/memory.h" @@ -81,6 +82,21 @@ struct VirtualMemoryArea { /// Tests if this area can be merged to the right with `next`. bool CanBeMergedWith(const VirtualMemoryArea& next) const; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & base; + ar & size; + ar & type; + ar & permissions; + ar & meminfo_state; + // TODO: backing memory ref + ar & paddr; + ar & mmio_handler; + } }; /** @@ -195,9 +211,10 @@ public: private: friend class boost::serialization::access; - template - void save(Archive & ar, const unsigned int file_version) + template + void save(Archive& ar, const unsigned int file_version) const { + ar & vma_map; for (int i = 0; i < page_table.pointers.size(); i++) { ar << memory.GetFCRAMOffset(page_table.pointers[i]); } @@ -205,9 +222,10 @@ private: ar & page_table.attributes; } - template - void load(Archive & ar, const unsigned int file_version) + template + void load(Archive& ar, const unsigned int file_version) { + ar & vma_map; for (int i = 0; i < page_table.pointers.size(); i++) { u32 offset{}; ar >> offset; diff --git a/src/core/hle/kernel/wait_object.h b/src/core/hle/kernel/wait_object.h index 41e8035159..e089977214 100644 --- a/src/core/hle/kernel/wait_object.h +++ b/src/core/hle/kernel/wait_object.h @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" @@ -62,6 +65,17 @@ private: /// Function to call when this object becomes available std::function hle_notifier; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & waiting_threads; + // NB: hle_notifier *not* serialized since it's a callback! + // Fortunately it's only used in one place (DSP) so we can reconstruct it there + } }; // Specialization of DynamicObjectCast for WaitObjects diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp index 13b2c7e464..b218eb7937 100644 --- a/src/core/hle/service/err_f.cpp +++ b/src/core/hle/service/err_f.cpp @@ -14,6 +14,7 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/result.h" #include "core/hle/service/err_f.h" +#undef exception_info namespace Service::ERR { diff --git a/src/core/memory.cpp b/src/core/memory.cpp index fe33cf767d..a07cc2e13b 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -5,8 +5,7 @@ #include #include #include "boost/serialization/array.hpp" -#include "boost/serialization/nvp.hpp" -#include "boost/serialization/unique_ptr.hpp" +#include "boost/serialization/binary_object.hpp" #include "audio_core/dsp_interface.h" #include "common/archives.h" #include "common/assert.h" @@ -84,23 +83,17 @@ public: private: - template - void add_blob(Archive & ar, std::unique_ptr & var, const char *name, std::size_t size) - { - ar & boost::serialization::make_nvp( - name, - *static_cast(static_cast(var.get())) - ); - } - friend class boost::serialization::access; template void serialize(Archive & ar, const unsigned int file_version) { // TODO: Skip n3ds ram when not used? - add_blob(ar, fcram, "fcram", Memory::FCRAM_N3DS_SIZE); - add_blob(ar, vram, "vram", Memory::VRAM_SIZE); - add_blob(ar, n3ds_extra_ram, "n3ds_extra_ram", Memory::N3DS_EXTRA_RAM_SIZE); + auto s_fcram = boost::serialization::binary_object(fcram.get(), Memory::FCRAM_N3DS_SIZE); + auto s_vram = boost::serialization::binary_object(vram.get(), Memory::VRAM_SIZE); + auto s_extra = boost::serialization::binary_object(n3ds_extra_ram.get(), Memory::N3DS_EXTRA_RAM_SIZE); + ar & s_fcram; + ar & s_vram; + ar & s_extra; ar & cache_marker; // TODO: How the hell to do page tables.. // ar & page_table_list; @@ -114,7 +107,7 @@ MemorySystem::~MemorySystem() = default; template void MemorySystem::serialize(Archive & ar, const unsigned int file_version) { - ar & impl; + ar & *impl.get(); } SERIALIZE_IMPL(MemorySystem) diff --git a/src/core/mmio.h b/src/core/mmio.h index 30bafaf5f7..0a8249c9ae 100644 --- a/src/core/mmio.h +++ b/src/core/mmio.h @@ -32,6 +32,13 @@ public: virtual void Write64(VAddr addr, u64 data) = 0; virtual bool WriteBlock(VAddr dest_addr, const void* src_buffer, std::size_t size) = 0; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + } }; using MMIORegionPointer = std::shared_ptr; diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 10d1e637b6..3768653973 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -161,8 +161,6 @@ struct State { UnionArray lut; } fog; -#undef SERIALIZE_RAW - /// Current Pica command list struct { PAddr addr; // This exists only for serialization @@ -185,7 +183,7 @@ struct State { template void serialize(Archive & ar, const unsigned int file_version) { - // ar & input_vertex; + ar & input_vertex; ar & current_attribute; ar & reset_geometry_pipeline; } @@ -220,7 +218,7 @@ private: ar & regs.reg_array; ar & vs; ar & gs; - // ar & input_default_attributes; + ar & input_default_attributes; ar & proctex; ar & lighting.luts; ar & fog.lut; diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index 3f55d30641..1a0f6ef8a1 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -10,6 +10,7 @@ #include #include #include +#include #include "common/assert.h" #include "common/common_funcs.h" #include "common/common_types.h" @@ -32,6 +33,14 @@ using SwizzleData = std::array; struct AttributeBuffer { alignas(16) Common::Vec4 attr[16]; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & attr; + } }; /// Handler type for receiving vertex outputs from vertex shader or geometry shader @@ -91,6 +100,19 @@ struct GSEmitter { GSEmitter(); ~GSEmitter(); void Emit(Common::Vec4 (&output_regs)[16]); + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & buffer; + ar & vertex_id; + ar & prim_emit; + ar & winding; + ar & output_mask; + // Handlers are ignored because they're constant + } }; static_assert(std::is_standard_layout::value, "GSEmitter is not standard layout type"); @@ -108,6 +130,16 @@ struct UnitState { alignas(16) Common::Vec4 input[16]; alignas(16) Common::Vec4 temporary[16]; alignas(16) Common::Vec4 output[16]; + + private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & input; + ar & temporary; + ar & output; + } } registers; static_assert(std::is_pod::value, "Structure is not POD"); @@ -160,6 +192,17 @@ struct UnitState { void LoadInput(const ShaderRegs& config, const AttributeBuffer& input); void WriteOutput(const ShaderRegs& config, AttributeBuffer& output); + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & registers; + ar & conditional_code; + ar & address_registers; + // TODO: emitter_ptr + } }; /** @@ -173,6 +216,15 @@ struct GSUnitState : public UnitState { void ConfigOutput(const ShaderRegs& config); GSEmitter emitter; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & emitter; + } }; struct Uniforms { From 5035e68dadbdef6c8e6d5b856f8d15462a515faf Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 11 Aug 2019 15:19:45 +0100 Subject: [PATCH 007/129] Added derived kernel objects --- externals/boost | 2 +- src/common/archives.h | 5 +++++ src/core/hle/kernel/address_arbiter.cpp | 8 ++++++-- src/core/hle/kernel/address_arbiter.h | 17 ++++++++++++++++- src/core/hle/kernel/object.h | 1 + 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/externals/boost b/externals/boost index 48130d3879..19ccdcc6fb 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit 48130d387975d17aed1b34ef75c21020f2d710a8 +Subproject commit 19ccdcc6fbd026f98ed83dea32ff0398120fbb32 diff --git a/src/common/archives.h b/src/common/archives.h index 490710d3c1..f30886d907 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -12,3 +12,8 @@ template void A::serialize( \ oarchive & ar, \ const unsigned int file_version \ ); + +#define SERIALIZE_EXPORT_IMPL(A) \ +BOOST_SERIALIZATION_REGISTER_ARCHIVE(iarchive) \ +BOOST_SERIALIZATION_REGISTER_ARCHIVE(oarchive) \ +BOOST_CLASS_EXPORT_IMPLEMENT(A) diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index e52c0f2720..c4fb4fd994 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" #include "core/hle/kernel/address_arbiter.h" @@ -14,6 +15,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // Kernel namespace +SERIALIZE_EXPORT_IMPL(Kernel::AddressArbiter) + namespace Kernel { void AddressArbiter::WaitThread(std::shared_ptr thread, VAddr wait_address) { @@ -65,11 +68,12 @@ std::shared_ptr AddressArbiter::ResumeHighestPriorityThread(VAddr addres return thread; } -AddressArbiter::AddressArbiter(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} +AddressArbiter::AddressArbiter() : kernel(*g_kernel) {} AddressArbiter::~AddressArbiter() {} std::shared_ptr KernelSystem::CreateAddressArbiter(std::string name) { - auto address_arbiter{std::make_shared(*this)}; + auto address_arbiter{std::make_shared()}; + address_arbiter->Init(*this); address_arbiter->name = std::move(name); diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index a4aff6a6ef..3b29a84a40 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -6,6 +6,10 @@ #include #include +#include +#include +#include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/result.h" @@ -32,7 +36,7 @@ enum class ArbitrationType : u32 { class AddressArbiter final : public Object { public: - explicit AddressArbiter(KernelSystem& kernel); + explicit AddressArbiter(); ~AddressArbiter() override; std::string GetTypeName() const override { @@ -67,6 +71,17 @@ private: /// Threads waiting for the address arbiter to be signaled. std::vector> waiting_threads; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & name; + ar & waiting_threads; + } }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::AddressArbiter) diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index 8998cb88d6..6adba034ee 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h @@ -8,6 +8,7 @@ #include #include #include +#include "common/serialization/atomic.h" #include "common/common_types.h" #include "core/hle/kernel/kernel.h" From 06891d94542fcf5ec6e1c45435df097d48b8ca77 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 11 Aug 2019 22:29:00 +0100 Subject: [PATCH 008/129] Added client/server objects --- src/core/CMakeLists.txt | 1 + src/core/hle/kernel/client_port.cpp | 3 +++ src/core/hle/kernel/client_port.h | 3 +++ src/core/hle/kernel/client_session.cpp | 6 ++++-- src/core/hle/kernel/client_session.h | 17 ++++++++++++++++- src/core/hle/kernel/server_port.cpp | 3 +++ src/core/hle/kernel/server_port.h | 18 ++++++++++++++++++ src/core/hle/kernel/server_session.cpp | 7 +++++-- src/core/hle/kernel/server_session.h | 19 +++++++++++++++++++ src/core/hle/kernel/session.cpp | 18 +++++++++++++++--- src/core/hle/kernel/session.h | 6 ++++++ 11 files changed, 93 insertions(+), 8 deletions(-) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ed26424312..9ed9a856dd 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -162,6 +162,7 @@ add_library(core STATIC hle/kernel/server_session.cpp hle/kernel/server_session.h hle/kernel/session.h + hle/kernel/session.cpp hle/kernel/shared_memory.cpp hle/kernel/shared_memory.h hle/kernel/shared_page.cpp diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index dc0e08d9d0..3334a278ba 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "common/assert.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" @@ -11,6 +12,8 @@ #include "core/hle/kernel/server_port.h" #include "core/hle/kernel/server_session.h" +SERIALIZE_EXPORT_IMPL(Kernel::ClientPort) + namespace Kernel { ResultVal> ClientPort::Connect() { diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h index 35544e37e8..72cae85c30 100644 --- a/src/core/hle/kernel/client_port.h +++ b/src/core/hle/kernel/client_port.h @@ -6,6 +6,7 @@ #include #include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_port.h" @@ -72,3 +73,5 @@ private: }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::ClientPort) diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp index 3e76f1a4ef..ba9c2ec501 100644 --- a/src/core/hle/kernel/client_session.cpp +++ b/src/core/hle/kernel/client_session.cpp @@ -3,7 +3,7 @@ // Refer to the license.txt file included. #include "common/assert.h" - +#include "common/archives.h" #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/hle_ipc.h" @@ -11,9 +11,11 @@ #include "core/hle/kernel/session.h" #include "core/hle/kernel/thread.h" +SERIALIZE_EXPORT_IMPL(Kernel::ClientSession) + namespace Kernel { -ClientSession::ClientSession(KernelSystem& kernel) : Object(kernel) {} +ClientSession::ClientSession() = default; ClientSession::~ClientSession() { // This destructor will be called automatically when the last ClientSession handle is closed by // the emulated application. diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h index de2c7b0baa..2ffe68f8b8 100644 --- a/src/core/hle/kernel/client_session.h +++ b/src/core/hle/kernel/client_session.h @@ -6,6 +6,9 @@ #include #include +#include +#include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/result.h" @@ -17,7 +20,7 @@ class Thread; class ClientSession final : public Object { public: - explicit ClientSession(KernelSystem& kernel); + explicit ClientSession(); ~ClientSession() override; friend class KernelSystem; @@ -46,6 +49,18 @@ public: /// The parent session, which links to the server endpoint. std::shared_ptr parent; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & name; + ar & parent; + } }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::ClientSession) diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index ca4cded3d9..191b43ea83 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/assert.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/errors.h" @@ -11,6 +12,8 @@ #include "core/hle/kernel/server_session.h" #include "core/hle/kernel/thread.h" +SERIALIZE_EXPORT_IMPL(Kernel::ServerPort) + namespace Kernel { ResultVal> ServerPort::Accept() { diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h index c500fd1b2c..e0014ee7cb 100644 --- a/src/core/hle/kernel/server_port.h +++ b/src/core/hle/kernel/server_port.h @@ -7,8 +7,13 @@ #include #include #include +#include +#include +#include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" +#include "core/hle/kernel/server_session.h" #include "core/hle/kernel/wait_object.h" #include "core/hle/result.h" @@ -58,6 +63,19 @@ public: bool ShouldWait(const Thread* thread) const override; void Acquire(Thread* thread) override; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & name; + ar & pending_sessions; + //ar & hle_handler; + } }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::ServerPort) diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index c6a6261a5a..f2ceb899e0 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -3,7 +3,7 @@ // Refer to the license.txt file included. #include - +#include "common/archives.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/hle_ipc.h" @@ -11,6 +11,8 @@ #include "core/hle/kernel/session.h" #include "core/hle/kernel/thread.h" +SERIALIZE_EXPORT_IMPL(Kernel::ServerSession) + namespace Kernel { ServerSession::ServerSession() : kernel(*g_kernel) {} @@ -124,7 +126,8 @@ ResultCode ServerSession::HandleSyncRequest(std::shared_ptr thread) { KernelSystem::SessionPair KernelSystem::CreateSessionPair(const std::string& name, std::shared_ptr port) { auto server_session = ServerSession::Create(*this, name + "_Server").Unwrap(); - auto client_session{std::make_shared(*this)}; + auto client_session{std::make_shared()}; + client_session->Init(*this); client_session->name = name + "_Client"; std::shared_ptr parent(new Session); diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 3536bcbd18..6112eefac7 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -6,10 +6,14 @@ #include #include +#include +#include +#include #include "common/assert.h" #include "common/common_types.h" #include "core/hle/kernel/ipc.h" #include "core/hle/kernel/object.h" +#include "core/hle/kernel/session.h" #include "core/hle/kernel/wait_object.h" #include "core/hle/result.h" #include "core/memory.h" @@ -103,6 +107,21 @@ private: friend class KernelSystem; KernelSystem& kernel; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & name; + ar & parent; + //ar & hle_handler; + ar & pending_requesting_threads; + ar & currently_handling; + //ar & mapped_buffer_context; + } }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::ServerSession) diff --git a/src/core/hle/kernel/session.cpp b/src/core/hle/kernel/session.cpp index 6429147442..f264c49bdc 100644 --- a/src/core/hle/kernel/session.cpp +++ b/src/core/hle/kernel/session.cpp @@ -2,11 +2,23 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include +#include "common/archives.h" #include "core/hle/kernel/session.h" -#include "core/hle/kernel/thread.h" +#include "core/hle/kernel/client_session.h" +#include "core/hle/kernel/server_session.h" +#include "core/hle/kernel/client_port.h" + +SERIALIZE_IMPL(Kernel::Session) namespace Kernel { -Session::Session() {} -Session::~Session() {} +template +void Session::serialize(Archive& ar, const unsigned int file_version) +{ + ar & client; + ar & server; + ar & port; +} + } // namespace Kernel diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h index 17bb4d6c67..eca1a9252b 100644 --- a/src/core/hle/kernel/session.h +++ b/src/core/hle/kernel/session.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include "core/hle/kernel/object.h" namespace Kernel { @@ -24,5 +25,10 @@ public: ClientSession* client = nullptr; ///< The client endpoint of the session. ServerSession* server = nullptr; ///< The server endpoint of the session. std::shared_ptr port; ///< The port that this session is associated with (optional). + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version); }; } // namespace Kernel From f557d26b40d4cc034bd9599b801ef5bf524d537c Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 12 Aug 2019 17:01:33 +0100 Subject: [PATCH 009/129] Added CPU, mutex, process, thread, timer --- externals/boost | 2 +- src/common/CMakeLists.txt | 1 + src/common/serialization/boost_flat_set.h | 37 ++++++++ src/common/thread_queue_list.h | 31 +++++++ src/core/arm/arm_interface.h | 102 +++++++++++++++++++++- src/core/arm/dynarmic/arm_dynarmic.cpp | 2 +- src/core/arm/dynarmic/arm_dynarmic.h | 2 +- src/core/arm/dyncom/arm_dyncom.cpp | 2 +- src/core/arm/dyncom/arm_dyncom.h | 2 +- src/core/hle/kernel/config_mem.h | 9 ++ src/core/hle/kernel/kernel.cpp | 10 +-- src/core/hle/kernel/mutex.cpp | 5 +- src/core/hle/kernel/mutex.h | 3 +- src/core/hle/kernel/process.cpp | 26 ++++++ src/core/hle/kernel/process.h | 24 +---- src/core/hle/kernel/shared_page.h | 9 ++ src/core/hle/kernel/thread.cpp | 26 ++++++ src/core/hle/kernel/thread.h | 18 ++++ src/core/hle/kernel/timer.cpp | 6 +- src/core/hle/kernel/timer.h | 23 ++++- 20 files changed, 299 insertions(+), 41 deletions(-) create mode 100644 src/common/serialization/boost_flat_set.h diff --git a/externals/boost b/externals/boost index 19ccdcc6fb..f4850c2975 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit 19ccdcc6fbd026f98ed83dea32ff0398120fbb32 +Subproject commit f4850c2975a0d977b7479664b8d4a6f03300a042 diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index b0577f9d9c..c0182ed480 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -91,6 +91,7 @@ add_library(common STATIC scm_rev.h scope_exit.h serialization/atomic.h + serialization/boost_flat_set.h serialization/boost_vector.hpp string_util.cpp string_util.h diff --git a/src/common/serialization/boost_flat_set.h b/src/common/serialization/boost_flat_set.h new file mode 100644 index 0000000000..9a0ae77b0f --- /dev/null +++ b/src/common/serialization/boost_flat_set.h @@ -0,0 +1,37 @@ +#pragma once + +#include "common/common_types.h" +#include +#include + +namespace boost::serialization { + +template +void save(Archive& ar, const boost::container::flat_set& set, const unsigned int file_version) +{ + ar << static_cast(set.size()); + for (auto &v : set) { + ar << v; + } +} + +template +void load(Archive& ar, boost::container::flat_set& set, const unsigned int file_version) +{ + u64 count{}; + ar >> count; + set.clear(); + for (auto i = 0; i < count; i++) { + T value{}; + ar >> value; + set.insert(value); + } +} + +template +void serialize(Archive& ar, boost::container::flat_set& set, const unsigned int file_version) +{ + boost::serialization::split_free(ar, set, file_version); +} + +} diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h index 3e3d04b4d4..ce57c01e9e 100644 --- a/src/common/thread_queue_list.h +++ b/src/common/thread_queue_list.h @@ -6,6 +6,9 @@ #include #include +#include +#include +#include "common/common_types.h" namespace Common { @@ -156,6 +159,34 @@ private: Queue* first; // The priority level queues of thread ids. std::array queues; + + friend class boost::serialization::access; + template + void save(Archive& ar, const unsigned int file_version) const + { + s32 idx = first == UnlinkedTag() ? -1 : static_cast(first - &queues[0]); + ar << idx; + for (auto i = 0; i < NUM_QUEUES; i++) { + s32 idx1 = first == UnlinkedTag() ? -1 : static_cast(queues[i].next_nonempty - &queues[0]); + ar << idx1; + ar << queues[i].data; + } + } + + template + void load(Archive& ar, const unsigned int file_version) + { + s32 idx; + ar >> idx; + first = idx < 0 ? UnlinkedTag() : &queues[idx]; + for (auto i = 0; i < NUM_QUEUES; i++) { + ar >> idx; + queues[i].next_nonempty = idx < 0 ? UnlinkedTag() : &queues[idx]; + ar >> queues[i].data; + } + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() }; } // namespace Common diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 6e6da86265..483ba43717 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -6,6 +6,7 @@ #include #include +#include #include "common/common_types.h" #include "core/arm/skyeye_common/arm_regformat.h" #include "core/arm/skyeye_common/vfp/asm_vfp.h" @@ -16,6 +17,48 @@ public: virtual ~ARM_Interface() {} class ThreadContext { + friend class boost::serialization::access; + + template + void save(Archive& ar, const unsigned int file_version) const + { + for (auto i = 0; i < 16; i++) { + auto r = GetCpuRegister(i); + ar << r; + } + for (auto i = 0; i < 16; i++) { + auto r = GetFpuRegister(i); + ar << r; + } + auto r1 = GetCpsr(); + ar << r1; + auto r2 = GetFpscr(); + ar << r2; + auto r3 = GetFpexc(); + ar << r3; + } + + template + void load(Archive& ar, const unsigned int file_version) + { + u32 r; + for (auto i = 0; i < 16; i++) { + ar >> r; + SetCpuRegister(i, r); + } + for (auto i = 0; i < 16; i++) { + ar >> r; + SetFpuRegister(i, r); + } + ar >> r; + SetCpsr(r); + ar >> r; + SetFpscr(r); + ar >> r; + SetFpexc(r); + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() public: virtual ~ThreadContext() = default; @@ -143,7 +186,7 @@ public: * @param reg The CP15 register to retrieve the value from. * @return the value stored in the given CP15 register. */ - virtual u32 GetCP15Register(CP15Register reg) = 0; + virtual u32 GetCP15Register(CP15Register reg) const = 0; /** * Stores the given value into the indicated CP15 register. @@ -172,4 +215,61 @@ public: /// Prepare core for thread reschedule (if needed to correctly handle state) virtual void PrepareReschedule() = 0; + +private: + friend class boost::serialization::access; + + template + void save(Archive& ar, const unsigned int file_version) const + { + for (auto i = 0; i < 15; i++) { + auto r = GetReg(i); + ar << r; + } + auto pc = GetPC(); + ar << pc; + auto cpsr = GetCPSR(); + ar << cpsr; + for (auto i = 0; i < 32; i++) { + auto r = GetVFPReg(i); + ar << r; + } + for (auto i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { + auto r = GetVFPSystemReg(static_cast(i)); + ar << r; + } + for (auto i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { + auto r = GetCP15Register(static_cast(i)); + ar << r; + } + } + + template + void load(Archive& ar, const unsigned int file_version) + { + u32 r; + for (auto i = 0; i < 15; i++) { + ar >> r; + SetReg(i, r); + } + ar >> r; + SetPC(r); + ar >> r; + SetCPSR(r); + for (auto i = 0; i < 32; i++) { + ar >> r; + SetVFPReg(i, r); + } + for (auto i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { + ar >> r; + SetVFPSystemReg(static_cast(i), r); + } + for (auto i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { + ar >> r; + SetCP15Register(static_cast(i), r); + } + // TODO: Clear caches etc? + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() }; diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index f494b52286..a422db6af6 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -235,7 +235,7 @@ void ARM_Dynarmic::SetCPSR(u32 cpsr) { jit->SetCpsr(cpsr); } -u32 ARM_Dynarmic::GetCP15Register(CP15Register reg) { +u32 ARM_Dynarmic::GetCP15Register(CP15Register reg) const { return interpreter_state->CP15[reg]; } diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index 559dbf5a81..ff9a104b5c 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -40,7 +40,7 @@ public: void SetVFPSystemReg(VFPSystemRegister reg, u32 value) override; u32 GetCPSR() const override; void SetCPSR(u32 cpsr) override; - u32 GetCP15Register(CP15Register reg) override; + u32 GetCP15Register(CP15Register reg) const override; void SetCP15Register(CP15Register reg, u32 value) override; std::unique_ptr NewContext() const override; diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index d54b0cb958..6b67644e79 100644 --- a/src/core/arm/dyncom/arm_dyncom.cpp +++ b/src/core/arm/dyncom/arm_dyncom.cpp @@ -138,7 +138,7 @@ void ARM_DynCom::SetCPSR(u32 cpsr) { state->Cpsr = cpsr; } -u32 ARM_DynCom::GetCP15Register(CP15Register reg) { +u32 ARM_DynCom::GetCP15Register(CP15Register reg) const { return state->CP15[reg]; } diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h index 99c6ab4601..7497b765fb 100644 --- a/src/core/arm/dyncom/arm_dyncom.h +++ b/src/core/arm/dyncom/arm_dyncom.h @@ -41,7 +41,7 @@ public: void SetVFPSystemReg(VFPSystemRegister reg, u32 value) override; u32 GetCPSR() const override; void SetCPSR(u32 cpsr) override; - u32 GetCP15Register(CP15Register reg) override; + u32 GetCP15Register(CP15Register reg) const override; void SetCP15Register(CP15Register reg, u32 value) override; std::unique_ptr NewContext() const override; diff --git a/src/core/hle/kernel/config_mem.h b/src/core/hle/kernel/config_mem.h index ecb97c6bd2..26fc0bccbb 100644 --- a/src/core/hle/kernel/config_mem.h +++ b/src/core/hle/kernel/config_mem.h @@ -9,6 +9,7 @@ // bootrom. Because we're not emulating this, and essentially just "stubbing" the functionality, I'm // putting this as a subset of HLE for now. +#include #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" @@ -56,6 +57,14 @@ public: private: ConfigMemDef config_mem; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + auto o_config_mem = boost::serialization::binary_object(&config_mem, sizeof(config_mem)); + ar & o_config_mem; + } }; } // namespace ConfigMem diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index d8bd0f0344..32d76d0d37 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -109,17 +109,17 @@ template void KernelSystem::serialize(Archive& ar, const unsigned int file_version) { ar & named_ports; - // TODO: CPU + ar & *current_cpu.get(); // NB: subsystem references and prepare_reschedule_callback are constant ar & *resource_limits.get(); ar & next_object_id; - //ar & *timer_manager.get(); + ar & *timer_manager.get(); ar & next_process_id; ar & process_list; ar & current_process; - // ar & *thread_manager.get(); - //ar & *config_mem_handler.get(); - //ar & *shared_page_handler.get(); + ar & *thread_manager.get(); + ar & *config_mem_handler.get(); + ar & *shared_page_handler.get(); } SERIALIZE_IMPL(KernelSystem) diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 467b1ae1e3..b9a32ef235 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -23,11 +23,12 @@ void ReleaseThreadMutexes(Thread* thread) { thread->held_mutexes.clear(); } -Mutex::Mutex(KernelSystem& kernel) : WaitObject(kernel), kernel(kernel) {} +Mutex::Mutex() : kernel(*g_kernel) {} Mutex::~Mutex() {} std::shared_ptr KernelSystem::CreateMutex(bool initial_locked, std::string name) { - auto mutex{std::make_shared(*this)}; + auto mutex{std::make_shared()}; + mutex->Init(*this); mutex->lock_count = 0; mutex->name = std::move(name); diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 6186854519..4f0c2c2b56 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -17,7 +17,7 @@ class Thread; class Mutex final : public WaitObject { public: - explicit Mutex(KernelSystem& kernel); + explicit Mutex(); ~Mutex() override; std::string GetTypeName() const override { @@ -68,7 +68,6 @@ private: ar & priority; ar & name; ar & holding_thread; - ar & kernel; // TODO: Check that this works! } }; diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 63a5c3b68d..49de1e69ed 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -4,9 +4,13 @@ #include #include +#include +#include +#include "common/archives.h" #include "common/assert.h" #include "common/common_funcs.h" #include "common/logging/log.h" +#include "common/serialization/boost_vector.hpp" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/memory.h" #include "core/hle/kernel/process.h" @@ -17,6 +21,28 @@ namespace Kernel { +template +void Process::serialize(Archive& ar, const unsigned int file_version) +{ + ar & boost::serialization::base_object(*this); + ar & handle_table; + ar & codeset; + ar & resource_limit; + ar & svc_access_mask; + ar & handle_table_size; + ar & (boost::container::vector >&)address_mappings; + ar & flags.raw; + ar & kernel_version; + ar & ideal_processor; + ar & process_id; + ar & vm_manager; + ar & memory_used; + ar & memory_region; + ar & tls_slots; +} + +SERIALIZE_IMPL(Process) + std::shared_ptr KernelSystem::CreateCodeSet(std::string name, u64 program_id) { auto codeset{std::make_shared()}; codeset->Init(*this); diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 6defd42c6d..edda20c1f0 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -11,13 +11,10 @@ #include #include #include -#include -#include -#include #include +#include #include "common/bit_field.h" #include "common/common_types.h" -#include "common/serialization/boost_vector.hpp" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/vm_manager.h" @@ -234,23 +231,6 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & handle_table; - ar & codeset; - ar & resource_limit; - ar & svc_access_mask; - ar & handle_table_size; - ar & (boost::container::vector >&)address_mappings; - ar & flags.raw; - ar & kernel_version; - ar & ideal_processor; - ar & process_id; - ar & vm_manager; - ar & memory_used; - ar & memory_region; - ar & tls_slots; - } + void serialize(Archive& ar, const unsigned int file_version); }; } // namespace Kernel diff --git a/src/core/hle/kernel/shared_page.h b/src/core/hle/kernel/shared_page.h index 5092b48693..58cd463342 100644 --- a/src/core/hle/kernel/shared_page.h +++ b/src/core/hle/kernel/shared_page.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" @@ -104,6 +105,14 @@ private: std::chrono::seconds init_time; SharedPageDef shared_page; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + auto o_shared_page = boost::serialization::binary_object(&shared_page, sizeof(shared_page)); + ar & o_shared_page; + } }; } // namespace SharedPage diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 4c2344dcbe..9fa5df33ae 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -6,10 +6,12 @@ #include #include #include +#include "common/archives.h" #include "common/assert.h" #include "common/common_types.h" #include "common/logging/log.h" #include "common/math_util.h" +#include "common/serialization/boost_flat_set.h" #include "core/arm/arm_interface.h" #include "core/arm/skyeye_common/armstate.h" #include "core/core.h" @@ -25,6 +27,30 @@ namespace Kernel { +template +void Thread::serialize(Archive& ar, const unsigned int file_version) +{ + ar & *context.get(); + ar & thread_id; + ar & status; + ar & entry_point; + ar & stack_top; + ar & nominal_priority; + ar & current_priority; + ar & last_running_ticks; + ar & processor_id; + ar & tls_address; + ar & held_mutexes; + ar & pending_mutexes; + ar & owner_process; + ar & wait_objects; + ar & wait_address; + ar & name; + // TODO: How the hell to do wakeup_callback +} + +SERIALIZE_IMPL(Thread) + bool Thread::ShouldWait(const Thread* thread) const { return status != ThreadStatus::Dead; } diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 2db5dda91d..fc9170675b 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include #include "common/common_types.h" #include "common/thread_queue_list.h" #include "core/arm/arm_interface.h" @@ -145,6 +148,17 @@ private: friend class Thread; friend class KernelSystem; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & next_thread_id; + ar & current_thread; + ar & ready_queue; + ar & wakeup_callback_table; + ar & thread_list; + } }; class Thread final : public WaitObject { @@ -305,6 +319,10 @@ public: private: ThreadManager& thread_manager; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version); }; /** diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 9c3d0f7250..f073c3312b 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -14,15 +14,15 @@ namespace Kernel { -Timer::Timer(KernelSystem& kernel) - : WaitObject(kernel), kernel(kernel), timer_manager(kernel.GetTimerManager()) {} +Timer::Timer() : kernel(*g_kernel), timer_manager(g_kernel->GetTimerManager()) {} Timer::~Timer() { Cancel(); timer_manager.timer_callback_table.erase(callback_id); } std::shared_ptr KernelSystem::CreateTimer(ResetType reset_type, std::string name) { - auto timer{std::make_shared(*this)}; + auto timer{std::make_shared()}; + timer->Init(*this); timer->reset_type = reset_type; timer->signaled = false; diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index 6865f52437..6903506112 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h @@ -4,6 +4,7 @@ #pragma once +#include #include "common/common_types.h" #include "core/core_timing.h" #include "core/hle/kernel/object.h" @@ -33,11 +34,19 @@ private: friend class Timer; friend class KernelSystem; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & next_timer_callback_id; + ar & timer_callback_table; + } }; class Timer final : public WaitObject { public: - explicit Timer(KernelSystem& kernel); + explicit Timer(); ~Timer() override; std::string GetTypeName() const override { @@ -103,6 +112,18 @@ private: TimerManager& timer_manager; friend class KernelSystem; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & reset_type; + ar & initial_delay; + ar & interval_delay; + ar & signaled; + ar & name; + ar & callback_id; + } }; } // namespace Kernel From dc0d1ebc95fbaa04034b96db9523470a161f4ed4 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Tue, 13 Aug 2019 17:37:04 +0100 Subject: [PATCH 010/129] Added a TODO --- TODO | 80 ++++++++++++++++++++++++++++++++++ src/video_core/pica_state.h | 2 +- src/video_core/shader/shader.h | 2 +- 3 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 TODO diff --git a/TODO b/TODO new file mode 100644 index 0000000000..3f15f3fb56 --- /dev/null +++ b/TODO @@ -0,0 +1,80 @@ +☐ Save/load UI +✔ CPU @done(19-08-13 15:41) +✔ Memory @done(19-08-13 15:41) +✔ DSP @done(19-08-13 15:41) +☐ MMIO +☐ Movie +☐ Perf stats +☐ Settings +☐ Telemetry session +✔ HW @done(19-08-13 15:41) + ✔ GPU regs @done(19-08-13 15:41) + ✔ LCD regs @done(19-08-13 15:41) +☐ Video core @started(19-08-13 16:43) + ☐ Geometry pipeline + ✔ PICA state @done(19-08-13 15:41) + ☐ Primitive assembly + ✔ Shader @done(19-08-13 16:03) +☐ HLE @started(19-08-13 16:43) + ☐ Kernel @started(19-08-13 16:43) + ✔ Address arbiter @done(19-08-13 16:40) + ✔ Client port @done(19-08-13 16:40) + ✔ Client session @done(19-08-13 16:40) + ✔ Config mem @done(19-08-13 16:40) + ☐ Event + ✔ Handle table @done(19-08-13 16:42) + ☐ HLE IPC + ☐ IPC + ☐ Memory @started(19-08-13 16:43) + ☐ Mutex @started(19-08-13 16:43) + ✔ Object @done(19-08-13 15:41) + ☐ Process @started(19-08-13 16:43) + ✔ Resource limit @done(19-08-13 16:43) + ☐ Semaphore @started(19-08-13 16:44) + ✔ Server port @done(19-08-13 16:44) + ✔ Server session @done(19-08-13 16:44) + ✔ Session @done(19-08-13 16:44) + ☐ Shared memory + ☐ Shared page @started(19-08-13 16:44) + ☐ SVC + ☐ Thread @started(19-08-13 16:45) + ✔ Timer @done(19-08-13 16:45) + ☐ VM Manager @started(19-08-13 16:46) + ✔ Wait object @done(19-08-13 16:46) + ☐ Service + ☐ AC + ☐ ACT + ☐ AM + ☐ APT + ☐ BOSS + ☐ CAM + ☐ CECD + ☐ CGF + ☐ CSND + ☐ DLP + ☐ DSP + ☐ ERR + ☐ FRD + ☐ FS + ☐ GSP + ☐ HID + ☐ HTTP + ☐ IR + ☐ LDR_RO + ☐ MIC + ☐ MVD + ☐ NDM + ☐ NEWS + ☐ NFC + ☐ NIM + ☐ NS + ☐ NWM + ☐ PM + ☐ PS + ☐ PTM + ☐ PXI + ☐ QTM + ☐ SM + ☐ SOC + ☐ SSL + ☐ Y2R \ No newline at end of file diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 3768653973..f0a9a119d6 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -225,7 +225,7 @@ private: ar & cmd_list.addr; ar & cmd_list.length; ar & immediate; - // ar & gs_unit; + ar & gs_unit; // ar & geometry_pipeline; // ar & primitive_assembler; ar & vs_float_regs_counter; diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index 1a0f6ef8a1..ffa60f3b52 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -201,7 +201,7 @@ private: ar & registers; ar & conditional_code; ar & address_registers; - // TODO: emitter_ptr + // emitter_ptr is only set by GSUnitState and is serialized there } }; From acc89b22514d4ab61ef9d2b9f6be4143fd07ee7c Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sat, 21 Dec 2019 23:37:41 +0000 Subject: [PATCH 011/129] Fixed an include --- src/video_core/pica_state.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index f0a9a119d6..ba9f8235e9 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -9,6 +9,7 @@ #include "common/bit_field.h" #include "common/common_types.h" #include "common/vector_math.h" +#include "video_core/video_core.h" #include "video_core/geometry_pipeline.h" #include "video_core/primitive_assembly.h" #include "video_core/regs.h" From c284192a87ae7fe2ec4ff0e3b5e86863a44a445c Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 22 Dec 2019 15:53:04 +0000 Subject: [PATCH 012/129] Serialize geometry_pipeline --- TODO | 6 +- externals/boost | 2 +- src/core/hle/kernel/kernel.cpp | 3 +- src/video_core/geometry_pipeline.cpp | 139 +++++++++++++++++++++++++-- src/video_core/geometry_pipeline.h | 5 + src/video_core/pica_state.h | 2 +- 6 files changed, 144 insertions(+), 13 deletions(-) diff --git a/TODO b/TODO index 3f15f3fb56..840caba1b8 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,7 @@ ✔ GPU regs @done(19-08-13 15:41) ✔ LCD regs @done(19-08-13 15:41) ☐ Video core @started(19-08-13 16:43) - ☐ Geometry pipeline + ✔ Geometry pipeline @done(19-12-22 15:52) ✔ PICA state @done(19-08-13 15:41) ☐ Primitive assembly ✔ Shader @done(19-08-13 16:03) @@ -35,9 +35,11 @@ ✔ Server session @done(19-08-13 16:44) ✔ Session @done(19-08-13 16:44) ☐ Shared memory - ☐ Shared page @started(19-08-13 16:44) + ✘ Shared page @started(19-08-13 16:44) @cancelled(19-12-22 11:19) + Not needed right now as shared_page is read-only and derived from other data ☐ SVC ☐ Thread @started(19-08-13 16:45) + This requires refactoring wakeup_callback to be an object ref ✔ Timer @done(19-08-13 16:45) ☐ VM Manager @started(19-08-13 16:46) ✔ Wait object @done(19-08-13 16:46) diff --git a/externals/boost b/externals/boost index f4850c2975..55725b7796 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit f4850c2975a0d977b7479664b8d4a6f03300a042 +Subproject commit 55725b7796c7faa0a4af869e412d0410bd47612d diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 32d76d0d37..2dd0a34bf8 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -119,7 +119,8 @@ void KernelSystem::serialize(Archive& ar, const unsigned int file_version) ar & current_process; ar & *thread_manager.get(); ar & *config_mem_handler.get(); - ar & *shared_page_handler.get(); + // Shared page data is read-only at the moment, so doesn't need serializing + //ar & *shared_page_handler.get(); } SERIALIZE_IMPL(KernelSystem) diff --git a/src/video_core/geometry_pipeline.cpp b/src/video_core/geometry_pipeline.cpp index 3a24b71c97..44a2fd6da3 100644 --- a/src/video_core/geometry_pipeline.cpp +++ b/src/video_core/geometry_pipeline.cpp @@ -2,6 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include +#include +#include +#include "common/archives.h" #include "video_core/geometry_pipeline.h" #include "video_core/pica_state.h" #include "video_core/regs.h" @@ -30,6 +34,13 @@ public: * @return if the buffer is full and the geometry shader should be invoked */ virtual bool SubmitVertex(const Shader::AttributeBuffer& input) = 0; + +private: + template + void serialize(Archive& ar, const unsigned int file_version) + { + } + friend class boost::serialization::access; }; // In the Point mode, vertex attributes are sent to the input registers in the geometry shader unit. @@ -40,7 +51,7 @@ public: // TODO: what happens when the input size is not divisible by the output size? class GeometryPipeline_Point : public GeometryPipelineBackend { public: - GeometryPipeline_Point(const Regs& regs, Shader::GSUnitState& unit) : regs(regs), unit(unit) { + GeometryPipeline_Point() : regs(g_state.regs), unit(g_state.gs_unit) { ASSERT(regs.pipeline.variable_primitive == 0); ASSERT(regs.gs.input_to_uniform == 0); vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1; @@ -79,6 +90,39 @@ private: Common::Vec4* buffer_cur; Common::Vec4* buffer_end; unsigned int vs_output_num; + + template + static void serialize_common(Class* self, Archive& ar, const unsigned int version) + { + ar & boost::serialization::base_object(*self); + ar & self->attribute_buffer; + ar & self->vs_output_num; + } + + template + void save(Archive & ar, const unsigned int version) const + { + serialize_common(this, ar, version); + auto buffer_idx = static_cast(buffer_cur - attribute_buffer.attr); + auto buffer_size = static_cast(buffer_end - attribute_buffer.attr); + ar << buffer_idx; + ar << buffer_size; + } + + template + void load(Archive & ar, const unsigned int version) + { + serialize_common(this, ar, version); + u32 buffer_idx, buffer_size; + ar >> buffer_idx; + ar >> buffer_size; + buffer_cur = attribute_buffer.attr + buffer_idx; + buffer_end = attribute_buffer.attr + buffer_size; + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + friend class boost::serialization::access; }; // In VariablePrimitive mode, vertex attributes are buffered into the uniform registers in the @@ -86,8 +130,8 @@ private: // value in the batch. This mode is usually used for subdivision. class GeometryPipeline_VariablePrimitive : public GeometryPipelineBackend { public: - GeometryPipeline_VariablePrimitive(const Regs& regs, Shader::ShaderSetup& setup) - : regs(regs), setup(setup) { + GeometryPipeline_VariablePrimitive() + : regs(g_state.regs), setup(g_state.gs) { ASSERT(regs.pipeline.variable_primitive == 1); ASSERT(regs.gs.input_to_uniform == 1); vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1; @@ -144,6 +188,37 @@ private: unsigned int total_vertex_num; Common::Vec4* buffer_cur; unsigned int vs_output_num; + + template + static void serialize_common(Class* self, Archive& ar, const unsigned int version) + { + ar & boost::serialization::base_object(*self); + ar & self->need_index; + ar & self->main_vertex_num; + ar & self->total_vertex_num; + ar & self->vs_output_num; + } + + template + void save(Archive & ar, const unsigned int version) const + { + serialize_common(this, ar, version); + auto buffer_idx = static_cast(buffer_cur - setup.uniforms.f); + ar << buffer_idx; + } + + template + void load(Archive & ar, const unsigned int version) + { + serialize_common(this, ar, version); + u32 buffer_idx; + ar >> buffer_idx; + buffer_cur = setup.uniforms.f + buffer_idx; + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + friend class boost::serialization::access; }; // In FixedPrimitive mode, vertex attributes are buffered into the uniform registers in the geometry @@ -151,8 +226,8 @@ private: // particle system. class GeometryPipeline_FixedPrimitive : public GeometryPipelineBackend { public: - GeometryPipeline_FixedPrimitive(const Regs& regs, Shader::ShaderSetup& setup) - : regs(regs), setup(setup) { + GeometryPipeline_FixedPrimitive() + : regs(g_state.regs), setup(g_state.gs) { ASSERT(regs.pipeline.variable_primitive == 0); ASSERT(regs.gs.input_to_uniform == 1); vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1; @@ -190,6 +265,42 @@ private: Common::Vec4* buffer_cur; Common::Vec4* buffer_end; unsigned int vs_output_num; + + template + static void serialize_common(Class* self, Archive& ar, const unsigned int version) + { + ar & boost::serialization::base_object(*self); + ar & self->vs_output_num; + } + + template + void save(Archive & ar, const unsigned int version) const + { + serialize_common(this, ar, version); + auto buffer_offset = static_cast(buffer_begin - setup.uniforms.f); + auto buffer_idx = static_cast(buffer_cur - setup.uniforms.f); + auto buffer_size = static_cast(buffer_end - setup.uniforms.f); + ar << buffer_offset; + ar << buffer_idx; + ar << buffer_size; + } + + template + void load(Archive & ar, const unsigned int version) + { + serialize_common(this, ar, version); + u32 buffer_offset, buffer_idx, buffer_size; + ar >> buffer_offset; + ar >> buffer_idx; + ar >> buffer_size; + buffer_begin = setup.uniforms.f + buffer_offset; + buffer_cur = setup.uniforms.f + buffer_idx; + buffer_end = setup.uniforms.f + buffer_size; + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + friend class boost::serialization::access; }; GeometryPipeline::GeometryPipeline(State& state) : state(state) {} @@ -231,13 +342,13 @@ void GeometryPipeline::Reconfigure() { switch (state.regs.pipeline.gs_config.mode) { case PipelineRegs::GSMode::Point: - backend = std::make_unique(state.regs, state.gs_unit); + backend = std::make_unique(); break; case PipelineRegs::GSMode::VariablePrimitive: - backend = std::make_unique(state.regs, state.gs); + backend = std::make_unique(); break; case PipelineRegs::GSMode::FixedPrimitive: - backend = std::make_unique(state.regs, state.gs); + backend = std::make_unique(); break; default: UNREACHABLE(); @@ -271,4 +382,16 @@ void GeometryPipeline::SubmitVertex(const Shader::AttributeBuffer& input) { } } +template +void GeometryPipeline::serialize(Archive& ar, const unsigned int version) { + // vertex_handler and shader_engine are always set to the same value + ar & backend; +} + } // namespace Pica + +BOOST_SERIALIZATION_ASSUME_ABSTRACT(Pica::GeometryPipelineBackend) +SERIALIZE_EXPORT_IMPL(Pica::GeometryPipeline_Point) +SERIALIZE_EXPORT_IMPL(Pica::GeometryPipeline_VariablePrimitive) +SERIALIZE_EXPORT_IMPL(Pica::GeometryPipeline_FixedPrimitive) +SERIALIZE_IMPL(Pica::GeometryPipeline) diff --git a/src/video_core/geometry_pipeline.h b/src/video_core/geometry_pipeline.h index 91fdd31923..1ca2d00c4e 100644 --- a/src/video_core/geometry_pipeline.h +++ b/src/video_core/geometry_pipeline.h @@ -45,5 +45,10 @@ private: Shader::ShaderEngine* shader_engine; std::unique_ptr backend; State& state; + + template + void serialize(Archive& ar, const unsigned int version); + + friend class boost::serialization::access; }; } // namespace Pica diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index ba9f8235e9..d7ae04c1b4 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -227,7 +227,7 @@ private: ar & cmd_list.length; ar & immediate; ar & gs_unit; - // ar & geometry_pipeline; + ar & geometry_pipeline; // ar & primitive_assembler; ar & vs_float_regs_counter; ar & vs_uniform_write_buffer; From 050c3bdee59a41858cfc69f03adf5f14698090a3 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 22 Dec 2019 16:06:26 +0000 Subject: [PATCH 013/129] Serialize primitive_assembly --- TODO | 5 ++++- src/video_core/pica_state.h | 2 +- src/video_core/primitive_assembly.h | 12 ++++++++++++ src/video_core/shader/shader.h | 3 +++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 840caba1b8..95bdaa9266 100644 --- a/TODO +++ b/TODO @@ -7,16 +7,19 @@ ☐ Perf stats ☐ Settings ☐ Telemetry session +☐ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE ✔ HW @done(19-08-13 15:41) ✔ GPU regs @done(19-08-13 15:41) ✔ LCD regs @done(19-08-13 15:41) ☐ Video core @started(19-08-13 16:43) ✔ Geometry pipeline @done(19-12-22 15:52) + Required more use of g_state ✔ PICA state @done(19-08-13 15:41) - ☐ Primitive assembly + ✔ Primitive assembly @done(19-12-22 16:05) ✔ Shader @done(19-08-13 16:03) ☐ HLE @started(19-08-13 16:43) ☐ Kernel @started(19-08-13 16:43) + Most of these require adding g_kernel ✔ Address arbiter @done(19-08-13 16:40) ✔ Client port @done(19-08-13 16:40) ✔ Client session @done(19-08-13 16:40) diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index d7ae04c1b4..95ee776628 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -228,7 +228,7 @@ private: ar & immediate; ar & gs_unit; ar & geometry_pipeline; - // ar & primitive_assembler; + ar & primitive_assembler; ar & vs_float_regs_counter; ar & vs_uniform_write_buffer; ar & gs_float_regs_counter; diff --git a/src/video_core/primitive_assembly.h b/src/video_core/primitive_assembly.h index fd5445aa8e..1545a6b4c8 100644 --- a/src/video_core/primitive_assembly.h +++ b/src/video_core/primitive_assembly.h @@ -6,6 +6,7 @@ #include #include "video_core/regs_pipeline.h" +namespace boost::serialization { class access; } namespace Pica { @@ -62,6 +63,17 @@ private: VertexType buffer[2]; bool strip_ready = false; bool winding = false; + + template + void serialize(Archive& ar, const unsigned int version) + { + ar & topology; + ar & buffer_index; + ar & buffer; + ar & strip_ready; + ar & winding; + } + friend class boost::serialization::access; }; } // namespace Pica diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index ffa60f3b52..f20e08d981 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -16,6 +16,7 @@ #include "common/common_types.h" #include "common/hash.h" #include "common/vector_math.h" +#include "common/pod.h" #include "video_core/pica_types.h" #include "video_core/regs_rasterizer.h" #include "video_core/regs_shader.h" @@ -64,6 +65,8 @@ struct OutputVertex { static void ValidateSemantics(const RasterizerRegs& regs); static OutputVertex FromAttributeBuffer(const RasterizerRegs& regs, const AttributeBuffer& output); + + SERIALIZE_AS_POD }; #define ASSERT_POS(var, pos) \ static_assert(offsetof(OutputVertex, var) == pos * sizeof(float24), "Semantic at wrong " \ From 8c81500deec2e8368c112fbce98770c7b518f40e Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 22 Dec 2019 18:35:03 +0000 Subject: [PATCH 014/129] Serialize kernel/hle/memory --- TODO | 4 +-- .../serialization/boost_discrete_interval.hpp | 33 +++++++++++++++++++ src/core/hle/kernel/kernel.cpp | 2 +- src/core/hle/kernel/memory.h | 5 ++- 4 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 src/common/serialization/boost_discrete_interval.hpp diff --git a/TODO b/TODO index 95bdaa9266..cad91b958d 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,7 @@ ✔ HW @done(19-08-13 15:41) ✔ GPU regs @done(19-08-13 15:41) ✔ LCD regs @done(19-08-13 15:41) -☐ Video core @started(19-08-13 16:43) +✔ Video core @started(19-08-13 16:43) @done(19-12-22 16:06) ✔ Geometry pipeline @done(19-12-22 15:52) Required more use of g_state ✔ PICA state @done(19-08-13 15:41) @@ -28,7 +28,7 @@ ✔ Handle table @done(19-08-13 16:42) ☐ HLE IPC ☐ IPC - ☐ Memory @started(19-08-13 16:43) + ✔ Memory @started(19-08-13 16:43) @done(19-12-22 18:34) ☐ Mutex @started(19-08-13 16:43) ✔ Object @done(19-08-13 15:41) ☐ Process @started(19-08-13 16:43) diff --git a/src/common/serialization/boost_discrete_interval.hpp b/src/common/serialization/boost_discrete_interval.hpp new file mode 100644 index 0000000000..dc920e439f --- /dev/null +++ b/src/common/serialization/boost_discrete_interval.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include "common/common_types.h" +#include + +namespace boost::serialization { + +template +void save(Archive& ar, const boost::icl::discrete_interval& obj, const unsigned int file_version) +{ + ar << obj.lower(); + ar << obj.upper(); + ar << obj.bounds()._bits; +} + +template +void load(Archive& ar, boost::icl::discrete_interval& obj, const unsigned int file_version) +{ + DomainT upper, lower; + boost::icl::bound_type bounds; + ar >> upper; + ar >> lower; + ar >> bounds; + obj = boost::icl::discrete_interval(upper, lower, boost::icl::interval_bounds(bounds)); +} + +template +void serialize(Archive& ar, boost::icl::discrete_interval& obj, const unsigned int file_version) +{ + boost::serialization::split_free(ar, obj, file_version); +} + +} diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 2dd0a34bf8..6248311b99 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -108,6 +108,7 @@ void KernelSystem::AddNamedPort(std::string name, std::shared_ptr po template void KernelSystem::serialize(Archive& ar, const unsigned int file_version) { + ar & memory_regions; ar & named_ports; ar & *current_cpu.get(); // NB: subsystem references and prepare_reschedule_callback are constant @@ -120,7 +121,6 @@ void KernelSystem::serialize(Archive& ar, const unsigned int file_version) ar & *thread_manager.get(); ar & *config_mem_handler.get(); // Shared page data is read-only at the moment, so doesn't need serializing - //ar & *shared_page_handler.get(); } SERIALIZE_IMPL(KernelSystem) diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h index 9e9fe5eb43..ed4ea12965 100644 --- a/src/core/hle/kernel/memory.h +++ b/src/core/hle/kernel/memory.h @@ -6,6 +6,8 @@ #include #include +#include +#include "common/serialization/boost_discrete_interval.hpp" #include "common/common_types.h" namespace Kernel { @@ -69,7 +71,8 @@ private: ar & base; ar & size; ar & used; - // TODO: boost icl / free_blocks + // This works because interval_set has exactly one member of type ImplSetT + ar & *(reinterpret_cast(&free_blocks)); } }; From 4f95575d418195d833a61704c54df29f4c58ec86 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 22 Dec 2019 23:37:17 +0000 Subject: [PATCH 015/129] Serialize some more kernel objects --- TODO | 21 +++++++++++++++------ src/common/archives.h | 1 + src/core/core.cpp | 2 ++ src/core/hle/kernel/event.cpp | 7 +++++-- src/core/hle/kernel/event.h | 5 ++++- src/core/hle/kernel/kernel.cpp | 1 + src/core/hle/kernel/mutex.cpp | 3 +++ src/core/hle/kernel/mutex.h | 3 +++ src/core/hle/kernel/process.cpp | 1 + src/core/hle/kernel/semaphore.cpp | 7 +++++-- src/core/hle/kernel/semaphore.h | 5 ++++- src/core/hle/kernel/shared_memory.h | 16 ++++++++++++++++ src/core/hle/kernel/thread.cpp | 2 ++ src/core/hle/kernel/thread.h | 3 +++ src/core/hle/kernel/vm_manager.h | 1 + 15 files changed, 66 insertions(+), 12 deletions(-) diff --git a/TODO b/TODO index cad91b958d..6397b4ba99 100644 --- a/TODO +++ b/TODO @@ -2,6 +2,10 @@ ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) ✔ DSP @done(19-08-13 15:41) +☐ Service manager +☐ App loader +☐ Archive manager +☐ Custom texture cache ☐ MMIO ☐ Movie ☐ Perf stats @@ -24,27 +28,32 @@ ✔ Client port @done(19-08-13 16:40) ✔ Client session @done(19-08-13 16:40) ✔ Config mem @done(19-08-13 16:40) - ☐ Event + ✔ Event @done(19-12-22 18:44) ✔ Handle table @done(19-08-13 16:42) ☐ HLE IPC ☐ IPC ✔ Memory @started(19-08-13 16:43) @done(19-12-22 18:34) - ☐ Mutex @started(19-08-13 16:43) + ✔ Mutex @done(19-08-13 16:43) ✔ Object @done(19-08-13 15:41) - ☐ Process @started(19-08-13 16:43) + ✔ Process @started(19-08-13 16:43) @done(19-12-22 18:41) + ☐ Code set @started(19-12-22 18:41) + Needs a way to reference loaded images (so we don't serialize the entire ROM as well) ✔ Resource limit @done(19-08-13 16:43) - ☐ Semaphore @started(19-08-13 16:44) + ✔ Semaphore @done(19-08-13 16:44) ✔ Server port @done(19-08-13 16:44) ✔ Server session @done(19-08-13 16:44) ✔ Session @done(19-08-13 16:44) - ☐ Shared memory + ☐ Shared memory @started(19-12-22 21:20) + Need to figure out backing memory (a u8*) ✘ Shared page @started(19-08-13 16:44) @cancelled(19-12-22 11:19) Not needed right now as shared_page is read-only and derived from other data - ☐ SVC + ✔ SVC @done(19-12-22 21:32) + Nothing to do - all data is constant ☐ Thread @started(19-08-13 16:45) This requires refactoring wakeup_callback to be an object ref ✔ Timer @done(19-08-13 16:45) ☐ 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 diff --git a/src/common/archives.h b/src/common/archives.h index f30886d907..a27afe80c3 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -1,5 +1,6 @@ #include "boost/archive/binary_iarchive.hpp" #include "boost/archive/binary_oarchive.hpp" +#include "boost/serialization/export.hpp" using iarchive = boost::archive::binary_iarchive; using oarchive = boost::archive::binary_oarchive; diff --git a/src/core/core.cpp b/src/core/core.cpp index 902340d413..9aecf84c9f 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -398,6 +398,8 @@ void System::Reset() { template void System::serialize(Archive & ar, const unsigned int file_version) { + ar & *cpu_core.get(); + //ar & *service_manager.get(); ar & GPU::g_regs; ar & LCD::g_regs; ar & dsp_core->GetDspMemory(); diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index f31162e35b..7af667739d 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -6,17 +6,20 @@ #include #include #include "common/assert.h" +#include "common/archives.h" #include "core/hle/kernel/event.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/thread.h" +SERIALIZE_EXPORT_IMPL(Kernel::Event) + namespace Kernel { -Event::Event(KernelSystem& kernel) : WaitObject(kernel) {} +Event::Event() : WaitObject() {} Event::~Event() {} std::shared_ptr KernelSystem::CreateEvent(ResetType reset_type, std::string name) { - auto evt{std::make_shared(*this)}; + auto evt{std::make_shared()}; evt->signaled = false; evt->reset_type = reset_type; diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index 9e9da267a0..bb97f6eb14 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h @@ -4,6 +4,7 @@ #pragma once +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/wait_object.h" @@ -12,7 +13,7 @@ namespace Kernel { class Event final : public WaitObject { public: - explicit Event(KernelSystem& kernel); + explicit Event(); ~Event() override; std::string GetTypeName() const override { @@ -62,3 +63,5 @@ private: }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::Event) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 6248311b99..4f9a02410e 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -121,6 +121,7 @@ void KernelSystem::serialize(Archive& ar, const unsigned int file_version) ar & *thread_manager.get(); ar & *config_mem_handler.get(); // Shared page data is read-only at the moment, so doesn't need serializing + // Deliberately don't include debugger info to allow debugging through loads } SERIALIZE_IMPL(KernelSystem) diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index b9a32ef235..b8a3d143bb 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/archives.h" #include "common/assert.h" #include "core/core.h" #include "core/hle/kernel/errors.h" @@ -12,6 +13,8 @@ #include "core/hle/kernel/object.h" #include "core/hle/kernel/thread.h" +SERIALIZE_EXPORT_IMPL(Kernel::Mutex) + namespace Kernel { void ReleaseThreadMutexes(Thread* thread) { diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 4f0c2c2b56..f4449c0f28 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -6,6 +6,7 @@ #include #include +#include #include "common/common_types.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/wait_object.h" @@ -78,3 +79,5 @@ private: void ReleaseThreadMutexes(Thread* thread); } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::Mutex) diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 49de1e69ed..5fad4fd854 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -34,6 +34,7 @@ void Process::serialize(Archive& ar, const unsigned int file_version) ar & flags.raw; ar & kernel_version; ar & ideal_processor; + ar & status; ar & process_id; ar & vm_manager; ar & memory_used; diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp index bbc8a385f8..f60a653e55 100644 --- a/src/core/hle/kernel/semaphore.cpp +++ b/src/core/hle/kernel/semaphore.cpp @@ -3,14 +3,17 @@ // Refer to the license.txt file included. #include "common/assert.h" +#include "common/archives.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/semaphore.h" #include "core/hle/kernel/thread.h" +SERIALIZE_EXPORT_IMPL(Kernel::Semaphore) + namespace Kernel { -Semaphore::Semaphore(KernelSystem& kernel) : WaitObject(kernel) {} +Semaphore::Semaphore() : WaitObject() {} Semaphore::~Semaphore() {} ResultVal> KernelSystem::CreateSemaphore(s32 initial_count, @@ -20,7 +23,7 @@ ResultVal> KernelSystem::CreateSemaphore(s32 initial_ if (initial_count > max_count) return ERR_INVALID_COMBINATION_KERNEL; - auto semaphore{std::make_shared(*this)}; + auto semaphore{std::make_shared()}; // When the semaphore is created, some slots are reserved for other threads, // and the rest is reserved for the caller thread diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h index 526be6812a..ff6a4434a6 100644 --- a/src/core/hle/kernel/semaphore.h +++ b/src/core/hle/kernel/semaphore.h @@ -6,6 +6,7 @@ #include #include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/wait_object.h" @@ -15,7 +16,7 @@ namespace Kernel { class Semaphore final : public WaitObject { public: - explicit Semaphore(KernelSystem& kernel); + explicit Semaphore(); ~Semaphore() override; std::string GetTypeName() const override { @@ -57,3 +58,5 @@ private: }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::Semaphore) diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 0d781cfcc8..42d783513e 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -6,6 +6,7 @@ #include #include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/process.h" @@ -104,6 +105,21 @@ private: friend class KernelSystem; KernelSystem& kernel; + + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & linear_heap_phys_offset; + // TODO: backing blocks u8* (this is always FCRAM I think) + ar & size; + ar & permissions; + ar & other_permissions; + ar & owner_process; + ar & base_address; + ar & name; + ar & *(reinterpret_cast(&holding_memory));; + } + friend class boost::serialization::access; }; } // namespace Kernel diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 9fa5df33ae..409dcc8861 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -25,6 +25,8 @@ #include "core/hle/result.h" #include "core/memory.h" +SERIALIZE_EXPORT_IMPL(Kernel::Thread) + namespace Kernel { template diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index fc9170675b..b423392e32 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -12,6 +12,7 @@ #include #include #include +#include #include "common/common_types.h" #include "common/thread_queue_list.h" #include "core/arm/arm_interface.h" @@ -337,3 +338,5 @@ std::shared_ptr SetupMainThread(KernelSystem& kernel, u32 entry_point, u std::shared_ptr owner_process); } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::Thread) diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 6711c9b4d6..e930fc64ab 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -94,6 +94,7 @@ private: ar & permissions; ar & meminfo_state; // TODO: backing memory ref + // backing memory can be: Physical/FCRAM pointer, config mem, shared page ar & paddr; ar & mmio_handler; } From 7a5bde0b44b86d4d64e049ede824286942408fad Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 23 Dec 2019 11:41:07 +0000 Subject: [PATCH 016/129] Serialize service manager, server prt --- TODO | 9 ++++++--- src/core/core.cpp | 4 ++-- src/core/core.h | 2 +- src/core/hle/kernel/hle_ipc.h | 26 ++++++++++++++++++++++++++ src/core/hle/kernel/ipc.h | 15 +++++++++++++++ src/core/hle/kernel/server_port.cpp | 11 +++++++++++ src/core/hle/kernel/server_port.h | 8 +------- src/core/hle/kernel/server_session.h | 4 ++-- src/core/hle/kernel/session.cpp | 1 + src/core/hle/kernel/shared_memory.h | 2 +- src/core/hle/service/sm/sm.h | 11 +++++++++++ 11 files changed, 77 insertions(+), 16 deletions(-) diff --git a/TODO b/TODO index 6397b4ba99..f3e1ea9435 100644 --- a/TODO +++ b/TODO @@ -2,7 +2,8 @@ ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) ✔ DSP @done(19-08-13 15:41) -☐ Service manager +✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) + ☐ Fix or ignore inverse map ☐ App loader ☐ Archive manager ☐ Custom texture cache @@ -30,8 +31,8 @@ ✔ Config mem @done(19-08-13 16:40) ✔ Event @done(19-12-22 18:44) ✔ Handle table @done(19-08-13 16:42) - ☐ HLE IPC - ☐ IPC + ✔ HLE IPC @done(19-12-23 00:36) + ✔ IPC @done(19-12-23 00:36) ✔ Memory @started(19-08-13 16:43) @done(19-12-22 18:34) ✔ Mutex @done(19-08-13 16:43) ✔ Object @done(19-08-13 15:41) @@ -42,6 +43,8 @@ ✔ Semaphore @done(19-08-13 16:44) ✔ Server port @done(19-08-13 16:44) ✔ Server session @done(19-08-13 16:44) + ☐ Mapped buffer context + This may not be needed! ✔ Session @done(19-08-13 16:44) ☐ Shared memory @started(19-12-22 21:20) Need to figure out backing memory (a u8*) diff --git a/src/core/core.cpp b/src/core/core.cpp index 9aecf84c9f..8ca3a2ab57 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -235,7 +235,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo rpc_server = std::make_unique(); - service_manager = std::make_shared(*this); + service_manager = std::make_unique(*this); archive_manager = std::make_unique(*this); HW::Init(*memory); @@ -399,7 +399,7 @@ template void System::serialize(Archive & ar, const unsigned int file_version) { ar & *cpu_core.get(); - //ar & *service_manager.get(); + ar & *service_manager.get(); ar & GPU::g_regs; ar & LCD::g_regs; ar & dsp_core->GetDspMemory(); diff --git a/src/core/core.h b/src/core/core.h index b811badbaa..8bf04d3656 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -305,7 +305,7 @@ private: std::unique_ptr telemetry_session; /// Service manager - std::shared_ptr service_manager; + std::unique_ptr service_manager; /// Frontend applets std::shared_ptr registered_mii_selector; diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 26942fe6b1..be3a20e790 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -11,12 +11,19 @@ #include #include #include +#include +#include +#include +#include #include "common/common_types.h" #include "common/swap.h" #include "core/hle/ipc.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_session.h" +BOOST_SERIALIZATION_ASSUME_ABSTRACT(Kernel::SessionRequestHandler) +BOOST_SERIALIZATION_ASSUME_ABSTRACT(Kernel::SessionRequestHandler::SessionDataBase) + namespace Service { class ServiceFrameworkBase; } @@ -90,12 +97,31 @@ protected: std::shared_ptr session; std::unique_ptr data; + + private: + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & session; + ar & data; + } + friend class boost::serialization::access; }; /// List of sessions that are connected to this handler. A ServerSession whose server endpoint /// is an HLE implementation is kept alive by this list for the duration of the connection. std::vector connected_sessions; + +private: + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & connected_sessions; + } + friend class boost::serialization::access; }; +// NOTE: The below classes are ephemeral and don't need serialization + class MappedBuffer { public: MappedBuffer(Memory::MemorySystem& memory, const Process& process, u32 descriptor, diff --git a/src/core/hle/kernel/ipc.h b/src/core/hle/kernel/ipc.h index b060799586..46d86a5282 100644 --- a/src/core/hle/kernel/ipc.h +++ b/src/core/hle/kernel/ipc.h @@ -6,6 +6,7 @@ #include #include +#include #include "common/common_types.h" #include "core/hle/ipc.h" #include "core/hle/kernel/thread.h" @@ -26,6 +27,20 @@ struct MappedBufferContext { std::unique_ptr buffer; std::unique_ptr reserve_buffer; + +private: + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & permissions; + ar & size; + ar & source_address; + ar & target_address; + // TODO: Check whether we need these. If we do, add a field for the size and/or change to a 'vector' + //ar & buffer; + //ar & reserve_buffer; + } + friend class boost::serialization::access; }; /// Performs IPC command buffer translation from one process to another. diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index 191b43ea83..0aeb86a783 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -11,6 +11,7 @@ #include "core/hle/kernel/server_port.h" #include "core/hle/kernel/server_session.h" #include "core/hle/kernel/thread.h" +#include "core/hle/kernel/hle_ipc.h" SERIALIZE_EXPORT_IMPL(Kernel::ServerPort) @@ -50,4 +51,14 @@ KernelSystem::PortPair KernelSystem::CreatePortPair(u32 max_sessions, std::strin return std::make_pair(std::move(server_port), std::move(client_port)); } +template +void ServerPort::serialize(Archive& ar, const unsigned int file_version) +{ + ar & boost::serialization::base_object(*this); + ar & name; + ar & pending_sessions; + ar & hle_handler; +} +SERIALIZE_IMPL(ServerPort) + } // namespace Kernel diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h index e0014ee7cb..f055cd2672 100644 --- a/src/core/hle/kernel/server_port.h +++ b/src/core/hle/kernel/server_port.h @@ -67,13 +67,7 @@ public: private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & name; - ar & pending_sessions; - //ar & hle_handler; - } + void serialize(Archive& ar, const unsigned int file_version); }; } // namespace Kernel diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 6112eefac7..05b469c380 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -115,10 +115,10 @@ private: ar & boost::serialization::base_object(*this); ar & name; ar & parent; - //ar & hle_handler; + ar & hle_handler; ar & pending_requesting_threads; ar & currently_handling; - //ar & mapped_buffer_context; + ar & mapped_buffer_context; } }; diff --git a/src/core/hle/kernel/session.cpp b/src/core/hle/kernel/session.cpp index f264c49bdc..a2a1f90f9b 100644 --- a/src/core/hle/kernel/session.cpp +++ b/src/core/hle/kernel/session.cpp @@ -8,6 +8,7 @@ #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/server_session.h" #include "core/hle/kernel/client_port.h" +#include "core/hle/kernel/hle_ipc.h" SERIALIZE_IMPL(Kernel::Session) diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 42d783513e..8aaf3df1f0 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -117,7 +117,7 @@ private: ar & owner_process; ar & base_address; ar & name; - ar & *(reinterpret_cast(&holding_memory));; + ar & *(reinterpret_cast(&holding_memory)); } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index 6e47fd1525..9cdaff72dc 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_port.h" @@ -80,6 +83,14 @@ private: // For IPC Recorder /// client port Object id -> service name std::unordered_map registered_services_inverse; + + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & registered_services; + ar & registered_services_inverse; // TODO: Instead, compute this from registered_services + } + friend class boost::serialization::access; }; } // namespace Service::SM From ac0337d8dfcd1a95090b5a8a6982d3bc91218e32 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Tue, 24 Dec 2019 17:49:56 +0000 Subject: [PATCH 017/129] 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 f3e1ea9435..bc62720d61 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 0000000000..28f4cc3491 --- /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 be3a20e790..da89ad39a7 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 9d40b9661b..acae47fd53 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 f3554c876d..12e304f598 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 db6a0ad233..f05c15f237 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 9cdaff72dc..d91732da9b 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 a07cc2e13b..7264e1ec4e 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) From 3fd5c431f157964bd08fcde73b0352979ff15f91 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Tue, 24 Dec 2019 22:39:02 +0000 Subject: [PATCH 018/129] Service serialization framework; done AC --- TODO | 2 +- src/common/construct.h | 4 --- src/core/hle/service/ac/ac.cpp | 14 +++++++++-- src/core/hle/service/ac/ac.h | 43 +++----------------------------- src/core/hle/service/ac/ac_i.cpp | 3 +++ src/core/hle/service/ac/ac_i.h | 7 ++++++ src/core/hle/service/service.h | 25 +++++++++++++++++++ 7 files changed, 51 insertions(+), 47 deletions(-) diff --git a/TODO b/TODO index bc62720d61..b9f4fe46b0 100644 --- a/TODO +++ b/TODO @@ -61,7 +61,7 @@ Just need to figure out backing_mem (a u8*) ✔ Wait object @done(19-08-13 16:46) ☐ Service @started(19-12-23 12:49) - ☐ AC @started(19-12-23 12:48) + ✔ AC @started(19-12-23 12:48) @done(19-12-24 22:38) @lasted(1d9h50m3s) ☐ ACT ☐ AM ☐ APT diff --git a/src/common/construct.h b/src/common/construct.h index 28f4cc3491..6ef9af1efe 100644 --- a/src/common/construct.h +++ b/src/common/construct.h @@ -1,9 +1,5 @@ #include -#define BOOST_SERIALIZATION_FRIENDS \ - friend class boost::serialization::access; \ - friend class construct_access; - class construct_access { public: template diff --git a/src/core/hle/service/ac/ac.cpp b/src/core/hle/service/ac/ac.cpp index acae47fd53..356df5a63e 100644 --- a/src/core/hle/service/ac/ac.cpp +++ b/src/core/hle/service/ac/ac.cpp @@ -17,8 +17,6 @@ #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); @@ -182,4 +180,16 @@ void InstallInterfaces(Core::System& system) { std::make_shared(ac)->InstallAsService(service_manager); } +template +void Module::serialize(Archive& ar, const unsigned int) +{ + ar & ac_connected; + ar & close_event; + ar & connect_event; + ar & disconnect_event; + // default_config is never written to +} + } // namespace Service::AC + +SERIALIZE_IMPL(Service::AC::Module) diff --git a/src/core/hle/service/ac/ac.h b/src/core/hle/service/ac/ac.h index 12e304f598..b7a079b33b 100644 --- a/src/core/hle/service/ac/ac.h +++ b/src/core/hle/service/ac/ac.h @@ -8,7 +8,6 @@ #include #include #include -#include "common/construct.h" #include "core/hle/service/service.h" namespace Core { @@ -19,6 +18,8 @@ namespace Kernel { class Event; } +BOOST_SERIALIZATION_ASSUME_ABSTRACT(Service::AC::Module::Interface) + namespace Service::AC { class Module final { public: @@ -142,34 +143,6 @@ 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: @@ -187,20 +160,10 @@ protected: 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 - } + void serialize(Archive& ar, const unsigned int file_version); 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/ac/ac_i.cpp b/src/core/hle/service/ac/ac_i.cpp index 0dde7bf90b..e4cc4c1f1a 100644 --- a/src/core/hle/service/ac/ac_i.cpp +++ b/src/core/hle/service/ac/ac_i.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/ac/ac_i.h" +#include "common/archives.h" namespace Service::AC { @@ -33,3 +34,5 @@ AC_I::AC_I(std::shared_ptr ac) : Module::Interface(std::move(ac), "ac:i" } } // namespace Service::AC + +SERIALIZE_EXPORT_IMPL(Service::AC::AC_I) diff --git a/src/core/hle/service/ac/ac_i.h b/src/core/hle/service/ac/ac_i.h index bca91aabe3..d7ab22b258 100644 --- a/src/core/hle/service/ac/ac_i.h +++ b/src/core/hle/service/ac/ac_i.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include "core/hle/service/ac/ac.h" namespace Service::AC { @@ -12,6 +13,12 @@ namespace Service::AC { class AC_I final : public Module::Interface { public: explicit AC_I(std::shared_ptr ac); + +private: + SERVICE_SERIALIZATION(AC_I, ac) }; } // namespace Service::AC + +BOOST_CLASS_EXPORT_KEY(Service::AC::AC_I) +BOOST_SERIALIZATION_CONSTRUCT(Service::AC::AC_I) diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index f05c15f237..d124b0070d 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -10,7 +10,9 @@ #include #include #include +#include #include "common/common_types.h" +#include "common/construct.h" #include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/object.h" #include "core/hle/service/sm/sm.h" @@ -194,3 +196,26 @@ struct ServiceModuleInfo { extern const std::array service_module_map; } // namespace Service + +#define SERVICE_SERIALIZATION(T, MFIELD) \ + template \ + void save_construct(Archive& ar, const unsigned int file_version) const \ + { \ + ar << MFIELD; \ + } \ + \ + template \ + static void load_construct(Archive& ar, T* t, const unsigned int file_version) \ + { \ + std::shared_ptr MFIELD; \ + ar >> MFIELD; \ + ::new(t)T(MFIELD); \ + } \ + \ + template \ + void serialize(Archive& ar, const unsigned int) \ + { \ + ar & boost::serialization::base_object(*this); \ + } \ + friend class boost::serialization::access; \ + friend class construct_access; From 89e4e49a63e53d7ed73170091037067a5c137be1 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Tue, 24 Dec 2019 23:17:24 +0000 Subject: [PATCH 019/129] Finished AC and ACT service serialization --- TODO | 2 +- src/core/hle/service/ac/ac.h | 2 -- src/core/hle/service/ac/ac_i.h | 1 - src/core/hle/service/ac/ac_u.cpp | 3 +++ src/core/hle/service/ac/ac_u.h | 6 ++++++ src/core/hle/service/act/act.h | 6 +++++- src/core/hle/service/act/act_a.cpp | 3 +++ src/core/hle/service/act/act_a.h | 5 +++++ src/core/hle/service/act/act_u.cpp | 3 +++ src/core/hle/service/act/act_u.h | 5 +++++ src/core/hle/service/service.h | 2 ++ 11 files changed, 33 insertions(+), 5 deletions(-) diff --git a/TODO b/TODO index b9f4fe46b0..a7488a20fd 100644 --- a/TODO +++ b/TODO @@ -62,7 +62,7 @@ ✔ Wait object @done(19-08-13 16:46) ☐ Service @started(19-12-23 12:49) ✔ AC @started(19-12-23 12:48) @done(19-12-24 22:38) @lasted(1d9h50m3s) - ☐ ACT + ✔ ACT @done(19-12-24 23:17) ☐ AM ☐ APT ☐ BOSS diff --git a/src/core/hle/service/ac/ac.h b/src/core/hle/service/ac/ac.h index b7a079b33b..0f31ca1b4b 100644 --- a/src/core/hle/service/ac/ac.h +++ b/src/core/hle/service/ac/ac.h @@ -6,8 +6,6 @@ #include #include -#include -#include #include "core/hle/service/service.h" namespace Core { diff --git a/src/core/hle/service/ac/ac_i.h b/src/core/hle/service/ac/ac_i.h index d7ab22b258..e05bac803c 100644 --- a/src/core/hle/service/ac/ac_i.h +++ b/src/core/hle/service/ac/ac_i.h @@ -5,7 +5,6 @@ #pragma once #include -#include #include "core/hle/service/ac/ac.h" namespace Service::AC { diff --git a/src/core/hle/service/ac/ac_u.cpp b/src/core/hle/service/ac/ac_u.cpp index d62d7ccb6c..429942f7d5 100644 --- a/src/core/hle/service/ac/ac_u.cpp +++ b/src/core/hle/service/ac/ac_u.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/ac/ac_u.h" +#include "common/archives.h" namespace Service::AC { @@ -33,3 +34,5 @@ AC_U::AC_U(std::shared_ptr ac) : Module::Interface(std::move(ac), "ac:u" } } // namespace Service::AC + +SERIALIZE_EXPORT_IMPL(Service::AC::AC_U) diff --git a/src/core/hle/service/ac/ac_u.h b/src/core/hle/service/ac/ac_u.h index 18efcd1e68..c15870b519 100644 --- a/src/core/hle/service/ac/ac_u.h +++ b/src/core/hle/service/ac/ac_u.h @@ -12,6 +12,12 @@ namespace Service::AC { class AC_U final : public Module::Interface { public: explicit AC_U(std::shared_ptr ac); + +private: + SERVICE_SERIALIZATION(AC_U, ac) }; } // namespace Service::AC + +BOOST_CLASS_EXPORT_KEY(Service::AC::AC_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::AC::AC_U) diff --git a/src/core/hle/service/act/act.h b/src/core/hle/service/act/act.h index 8846788906..c327cdaef0 100644 --- a/src/core/hle/service/act/act.h +++ b/src/core/hle/service/act/act.h @@ -20,9 +20,13 @@ public: Interface(std::shared_ptr act, const char* name); ~Interface(); - private: + protected: std::shared_ptr act; }; +private: + template + inline void serialize(Archive& ar, const unsigned int file_version) { } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); diff --git a/src/core/hle/service/act/act_a.cpp b/src/core/hle/service/act/act_a.cpp index 7a33f9175d..b4bf750f78 100644 --- a/src/core/hle/service/act/act_a.cpp +++ b/src/core/hle/service/act/act_a.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/act/act_a.h" +#include "common/archives.h" namespace Service::ACT { @@ -24,3 +25,5 @@ ACT_A::ACT_A(std::shared_ptr act) : Module::Interface(std::move(act), "a } } // namespace Service::ACT + +SERIALIZE_EXPORT_IMPL(Service::ACT::ACT_A) diff --git a/src/core/hle/service/act/act_a.h b/src/core/hle/service/act/act_a.h index 48a79aab7e..036a96182d 100644 --- a/src/core/hle/service/act/act_a.h +++ b/src/core/hle/service/act/act_a.h @@ -11,6 +11,11 @@ namespace Service::ACT { class ACT_A final : public Module::Interface { public: explicit ACT_A(std::shared_ptr act); +private: + SERVICE_SERIALIZATION(ACT_A, act) }; } // namespace Service::ACT + +BOOST_CLASS_EXPORT_KEY(Service::ACT::ACT_A) +BOOST_SERIALIZATION_CONSTRUCT(Service::ACT::ACT_A) diff --git a/src/core/hle/service/act/act_u.cpp b/src/core/hle/service/act/act_u.cpp index 99978d9cab..599bec18a6 100644 --- a/src/core/hle/service/act/act_u.cpp +++ b/src/core/hle/service/act/act_u.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/act/act_u.h" +#include "common/archives.h" namespace Service::ACT { @@ -20,3 +21,5 @@ ACT_U::ACT_U(std::shared_ptr act) : Module::Interface(std::move(act), "a } } // namespace Service::ACT + +SERIALIZE_EXPORT_IMPL(Service::ACT::ACT_U) diff --git a/src/core/hle/service/act/act_u.h b/src/core/hle/service/act/act_u.h index 3aca428e63..14d924025b 100644 --- a/src/core/hle/service/act/act_u.h +++ b/src/core/hle/service/act/act_u.h @@ -11,6 +11,11 @@ namespace Service::ACT { class ACT_U final : public Module::Interface { public: explicit ACT_U(std::shared_ptr act); +private: + SERVICE_SERIALIZATION(ACT_U, act) }; } // namespace Service::ACT + +BOOST_CLASS_EXPORT_KEY(Service::ACT::ACT_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::ACT::ACT_U) diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index d124b0070d..bdad47ea86 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include "common/common_types.h" #include "common/construct.h" #include "core/hle/kernel/hle_ipc.h" From e707685c2a1cfbede81e30594d865b11268a5362 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Tue, 24 Dec 2019 23:53:51 +0000 Subject: [PATCH 020/129] Serialize AM services --- TODO | 2 +- src/core/hle/service/am/am.cpp | 8 +++++--- src/core/hle/service/am/am.h | 26 ++++++++++++++++++++++++-- src/core/hle/service/am/am_app.cpp | 3 +++ src/core/hle/service/am/am_app.h | 5 +++++ src/core/hle/service/am/am_net.cpp | 3 +++ src/core/hle/service/am/am_net.h | 5 +++++ src/core/hle/service/am/am_sys.cpp | 3 +++ src/core/hle/service/am/am_sys.h | 5 +++++ src/core/hle/service/am/am_u.cpp | 3 +++ src/core/hle/service/am/am_u.h | 5 +++++ src/core/hle/service/fs/archive.cpp | 3 ++- src/core/hle/service/fs/file.cpp | 10 +++++----- src/core/hle/service/fs/file.h | 4 ++-- 14 files changed, 71 insertions(+), 14 deletions(-) diff --git a/TODO b/TODO index a7488a20fd..673ef0a140 100644 --- a/TODO +++ b/TODO @@ -63,7 +63,7 @@ ☐ Service @started(19-12-23 12:49) ✔ AC @started(19-12-23 12:48) @done(19-12-24 22:38) @lasted(1d9h50m3s) ✔ ACT @done(19-12-24 23:17) - ☐ AM + ✔ AM @started(19-12-24 23:17) @done(19-12-24 23:53) @lasted(36m8s) ☐ APT ☐ BOSS ☐ CAM diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 65b9c3e016..45ed29e6c4 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -1021,7 +1021,7 @@ void Module::Interface::BeginImportProgram(Kernel::HLERequestContext& ctx) { // Citra will store contents out to sdmc/nand const FileSys::Path cia_path = {}; auto file = std::make_shared( - am->system, std::make_unique(media_type), cia_path); + am->kernel, std::make_unique(media_type), cia_path); am->cia_installing = true; @@ -1048,7 +1048,7 @@ void Module::Interface::BeginImportProgramTemporarily(Kernel::HLERequestContext& // contents out to sdmc/nand const FileSys::Path cia_path = {}; auto file = std::make_shared( - am->system, std::make_unique(FS::MediaType::NAND), cia_path); + am->kernel, std::make_unique(FS::MediaType::NAND), cia_path); am->cia_installing = true; @@ -1450,11 +1450,13 @@ void Module::Interface::GetMetaDataFromCia(Kernel::HLERequestContext& ctx) { rb.PushMappedBuffer(output_buffer); } -Module::Module(Core::System& system) : system(system) { +Module::Module(Core::System& system) : kernel(system.Kernel()) { ScanForAllTitles(); system_updater_mutex = system.Kernel().CreateMutex(false, "AM::SystemUpdaterMutex"); } +Module::Module(Kernel::KernelSystem& kernel) : kernel(kernel) { } + Module::~Module() = default; void InstallInterfaces(Core::System& system) { diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 0912dde409..88a70bf10f 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include #include "common/common_types.h" #include "core/file_sys/cia_container.h" #include "core/file_sys/file_backend.h" @@ -150,6 +153,8 @@ std::string GetMediaTitlePath(Service::FS::MediaType media_type); class Module final { public: explicit Module(Core::System& system); + explicit Module(Kernel::KernelSystem& kernel); + Module() = default; ~Module(); class Interface : public ServiceFramework { @@ -557,7 +562,7 @@ public: */ void GetMetaDataFromCia(Kernel::HLERequestContext& ctx); - private: + protected: std::shared_ptr am; }; @@ -573,12 +578,29 @@ private: */ void ScanForAllTitles(); - Core::System& system; + Kernel::KernelSystem& kernel; bool cia_installing = false; std::array, 3> am_title_list; std::shared_ptr system_updater_mutex; + + template + void serialize(Archive& ar, const unsigned int) + { + ar & cia_installing; + ar & am_title_list; + ar & system_updater_mutex; + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::AM + +namespace boost::serialization { + template + inline void load_construct_data(Archive& ar, Service::AM::Module* t, const unsigned int) + { + ::new(t)Service::AM::Module(*Kernel::g_kernel); + } +} diff --git a/src/core/hle/service/am/am_app.cpp b/src/core/hle/service/am/am_app.cpp index cee1aa81b6..52d256ca21 100644 --- a/src/core/hle/service/am/am_app.cpp +++ b/src/core/hle/service/am/am_app.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/am/am_app.h" +#include "common/archives.h" namespace Service::AM { @@ -26,3 +27,5 @@ AM_APP::AM_APP(std::shared_ptr am) : Module::Interface(std::move(am), "a } } // namespace Service::AM + +SERIALIZE_EXPORT_IMPL(Service::AM::AM_APP) diff --git a/src/core/hle/service/am/am_app.h b/src/core/hle/service/am/am_app.h index 67cf8ba2e6..e78b5ef70f 100644 --- a/src/core/hle/service/am/am_app.h +++ b/src/core/hle/service/am/am_app.h @@ -11,6 +11,11 @@ namespace Service::AM { class AM_APP final : public Module::Interface { public: explicit AM_APP(std::shared_ptr am); +private: + SERVICE_SERIALIZATION(AM_APP, am) }; } // namespace Service::AM + +BOOST_CLASS_EXPORT_KEY(Service::AM::AM_APP) +BOOST_SERIALIZATION_CONSTRUCT(Service::AM::AM_APP) diff --git a/src/core/hle/service/am/am_net.cpp b/src/core/hle/service/am/am_net.cpp index 120ee53e78..44c852c19f 100644 --- a/src/core/hle/service/am/am_net.cpp +++ b/src/core/hle/service/am/am_net.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/am/am_net.h" +#include "common/archives.h" namespace Service::AM { @@ -123,3 +124,5 @@ AM_NET::AM_NET(std::shared_ptr am) : Module::Interface(std::move(am), "a } } // namespace Service::AM + +SERIALIZE_EXPORT_IMPL(Service::AM::AM_NET) diff --git a/src/core/hle/service/am/am_net.h b/src/core/hle/service/am/am_net.h index a5adbd7e57..74e335b763 100644 --- a/src/core/hle/service/am/am_net.h +++ b/src/core/hle/service/am/am_net.h @@ -11,6 +11,11 @@ namespace Service::AM { class AM_NET final : public Module::Interface { public: explicit AM_NET(std::shared_ptr am); +private: + SERVICE_SERIALIZATION(AM_NET, am) }; } // namespace Service::AM + +BOOST_CLASS_EXPORT_KEY(Service::AM::AM_NET) +BOOST_SERIALIZATION_CONSTRUCT(Service::AM::AM_NET) diff --git a/src/core/hle/service/am/am_sys.cpp b/src/core/hle/service/am/am_sys.cpp index ca4affbc22..c6817fe870 100644 --- a/src/core/hle/service/am/am_sys.cpp +++ b/src/core/hle/service/am/am_sys.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/am/am_sys.h" +#include "common/archives.h" namespace Service::AM { @@ -71,3 +72,5 @@ AM_SYS::AM_SYS(std::shared_ptr am) : Module::Interface(std::move(am), "a } } // namespace Service::AM + +SERIALIZE_EXPORT_IMPL(Service::AM::AM_SYS) diff --git a/src/core/hle/service/am/am_sys.h b/src/core/hle/service/am/am_sys.h index b142916ca9..028837f3d7 100644 --- a/src/core/hle/service/am/am_sys.h +++ b/src/core/hle/service/am/am_sys.h @@ -11,6 +11,11 @@ namespace Service::AM { class AM_SYS final : public Module::Interface { public: explicit AM_SYS(std::shared_ptr am); +private: + SERVICE_SERIALIZATION(AM_SYS, am) }; } // namespace Service::AM + +BOOST_CLASS_EXPORT_KEY(Service::AM::AM_SYS) +BOOST_SERIALIZATION_CONSTRUCT(Service::AM::AM_SYS) diff --git a/src/core/hle/service/am/am_u.cpp b/src/core/hle/service/am/am_u.cpp index 840860ec0b..c9b80bf06f 100644 --- a/src/core/hle/service/am/am_u.cpp +++ b/src/core/hle/service/am/am_u.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/am/am_u.h" +#include "common/archives.h" namespace Service::AM { @@ -83,3 +84,5 @@ AM_U::AM_U(std::shared_ptr am) : Module::Interface(std::move(am), "am:u" } } // namespace Service::AM + +SERIALIZE_EXPORT_IMPL(Service::AM::AM_U) diff --git a/src/core/hle/service/am/am_u.h b/src/core/hle/service/am/am_u.h index 1d732c90ae..b19d481674 100644 --- a/src/core/hle/service/am/am_u.h +++ b/src/core/hle/service/am/am_u.h @@ -11,6 +11,11 @@ namespace Service::AM { class AM_U final : public Module::Interface { public: explicit AM_U(std::shared_ptr am); +private: + SERVICE_SERIALIZATION(AM_U, am) }; } // namespace Service::AM + +BOOST_CLASS_EXPORT_KEY(Service::AM::AM_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::AM::AM_U) diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 6e179978bc..90dfad62f5 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -27,6 +27,7 @@ #include "core/file_sys/file_backend.h" #include "core/hle/result.h" #include "core/hle/service/fs/archive.h" +#include "core/core.h" namespace Service::FS { @@ -90,7 +91,7 @@ ArchiveManager::OpenFileFromArchive(ArchiveHandle archive_handle, const FileSys: if (backend.Failed()) return std::make_tuple(backend.Code(), open_timeout_ns); - auto file = std::shared_ptr(new File(system, std::move(backend).Unwrap(), path)); + auto file = std::shared_ptr(new File(system.Kernel(), std::move(backend).Unwrap(), path)); return std::make_tuple(MakeResult>(std::move(file)), open_timeout_ns); } diff --git a/src/core/hle/service/fs/file.cpp b/src/core/hle/service/fs/file.cpp index e31f89d0e7..946e27211c 100644 --- a/src/core/hle/service/fs/file.cpp +++ b/src/core/hle/service/fs/file.cpp @@ -15,9 +15,9 @@ namespace Service::FS { -File::File(Core::System& system, std::unique_ptr&& backend, +File::File(Kernel::KernelSystem& kernel, std::unique_ptr&& backend, const FileSys::Path& path) - : ServiceFramework("", 1), path(path), backend(std::move(backend)), system(system) { + : ServiceFramework("", 1), path(path), backend(std::move(backend)), kernel(kernel) { static const FunctionInfo functions[] = { {0x08010100, &File::OpenSubFile, "OpenSubFile"}, {0x080200C2, &File::Read, "Read"}, @@ -197,7 +197,7 @@ void File::OpenLinkFile(Kernel::HLERequestContext& ctx) { using Kernel::ServerSession; IPC::RequestParser rp(ctx, 0x080C, 0, 0); IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); - auto [server, client] = system.Kernel().CreateSessionPair(GetName()); + auto [server, client] = kernel.CreateSessionPair(GetName()); ClientConnected(server); FileSessionSlot* slot = GetSessionData(server); @@ -243,7 +243,7 @@ void File::OpenSubFile(Kernel::HLERequestContext& ctx) { using Kernel::ClientSession; using Kernel::ServerSession; - auto [server, client] = system.Kernel().CreateSessionPair(GetName()); + auto [server, client] = kernel.CreateSessionPair(GetName()); ClientConnected(server); FileSessionSlot* slot = GetSessionData(server); @@ -257,7 +257,7 @@ void File::OpenSubFile(Kernel::HLERequestContext& ctx) { } std::shared_ptr File::Connect() { - auto [server, client] = system.Kernel().CreateSessionPair(GetName()); + auto [server, client] = kernel.CreateSessionPair(GetName()); ClientConnected(server); FileSessionSlot* slot = GetSessionData(server); diff --git a/src/core/hle/service/fs/file.h b/src/core/hle/service/fs/file.h index 062fcd5e71..ff4a5670a3 100644 --- a/src/core/hle/service/fs/file.h +++ b/src/core/hle/service/fs/file.h @@ -25,7 +25,7 @@ struct FileSessionSlot : public Kernel::SessionRequestHandler::SessionDataBase { // Consider splitting ServiceFramework interface. class File final : public ServiceFramework { public: - File(Core::System& system, std::unique_ptr&& backend, + File(Kernel::KernelSystem& kernel, std::unique_ptr&& backend, const FileSys::Path& path); ~File() = default; @@ -59,7 +59,7 @@ private: void OpenLinkFile(Kernel::HLERequestContext& ctx); void OpenSubFile(Kernel::HLERequestContext& ctx); - Core::System& system; + Kernel::KernelSystem& kernel; }; } // namespace Service::FS From 3e752002c4245746b4c1bf47f75af48ed866cd97 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 25 Dec 2019 18:51:56 +0000 Subject: [PATCH 021/129] Replace g_kernel with Core::Global etc. --- TODO | 2 +- src/core/core.cpp | 9 +++++++-- src/core/global.h | 6 ++++++ src/core/hle/kernel/address_arbiter.cpp | 3 ++- src/core/hle/kernel/client_port.cpp | 3 ++- src/core/hle/kernel/kernel.cpp | 2 -- src/core/hle/kernel/kernel.h | 2 -- src/core/hle/kernel/mutex.cpp | 3 ++- src/core/hle/kernel/process.cpp | 7 ++++++- src/core/hle/kernel/process.h | 3 ++- src/core/hle/kernel/server_session.cpp | 3 ++- src/core/hle/kernel/thread.cpp | 5 +++-- src/core/hle/kernel/timer.cpp | 3 ++- src/core/hle/service/am/am.h | 3 ++- src/video_core/pica.cpp | 6 ++++++ 15 files changed, 43 insertions(+), 17 deletions(-) create mode 100644 src/core/global.h diff --git a/TODO b/TODO index 673ef0a140..7309acb1a9 100644 --- a/TODO +++ b/TODO @@ -26,7 +26,7 @@ ✔ Shader @done(19-08-13 16:03) ☐ HLE @started(19-08-13 16:43) ☐ Kernel @started(19-08-13 16:43) - Most of these require adding g_kernel + Most of these require adding Core::Global ✔ Address arbiter @done(19-08-13 16:40) ✔ Client port @done(19-08-13 16:40) ✔ Client session @done(19-08-13 16:40) diff --git a/src/core/core.cpp b/src/core/core.cpp index 8ca3a2ab57..055eadae24 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -25,6 +25,7 @@ #endif #include "core/custom_tex_cache.h" #include "core/gdbstub/gdbstub.h" +#include "core/global.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/process.h" @@ -46,6 +47,12 @@ namespace Core { /*static*/ System System::s_instance; +template <> +Core::System& Global() { return System::GetInstance(); } + +template <> +Kernel::KernelSystem& Global() { return System::GetInstance().Kernel(); } + System::ResultStatus System::RunLoop(bool tight_loop) { status = ResultStatus::Success; if (!cpu_core) { @@ -204,7 +211,6 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo kernel = std::make_unique(*memory, *timing, [this] { PrepareReschedule(); }, system_mode); - Kernel::g_kernel = kernel.get(); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 @@ -368,7 +374,6 @@ void System::Shutdown() { service_manager.reset(); dsp_core.reset(); cpu_core.reset(); - Kernel::g_kernel = nullptr; kernel.reset(); timing.reset(); app_loader.reset(); diff --git a/src/core/global.h b/src/core/global.h new file mode 100644 index 0000000000..8dfd022d8e --- /dev/null +++ b/src/core/global.h @@ -0,0 +1,6 @@ +namespace Core { + +template +T& Global(); + +} // namespace Core diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index c4fb4fd994..ca120e6f9f 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -11,6 +11,7 @@ #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/thread.h" #include "core/memory.h" +#include "core/global.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // Kernel namespace @@ -68,7 +69,7 @@ std::shared_ptr AddressArbiter::ResumeHighestPriorityThread(VAddr addres return thread; } -AddressArbiter::AddressArbiter() : kernel(*g_kernel) {} +AddressArbiter::AddressArbiter() : kernel(Core::Global()) {} AddressArbiter::~AddressArbiter() {} std::shared_ptr KernelSystem::CreateAddressArbiter(std::string name) { diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index 3334a278ba..f9202035cb 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -11,6 +11,7 @@ #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_port.h" #include "core/hle/kernel/server_session.h" +#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::ClientPort) @@ -26,7 +27,7 @@ ResultVal> ClientPort::Connect() { active_sessions++; // Create a new session pair, let the created sessions inherit the parent port's HLE handler. - auto [server, client] = g_kernel->CreateSessionPair(server_port->GetName(), SharedFrom(this)); + auto [server, client] = Core::Global().CreateSessionPair(server_port->GetName(), SharedFrom(this)); if (server_port->hle_handler) server_port->hle_handler->ClientConnected(server); diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 4f9a02410e..a459739687 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -18,8 +18,6 @@ namespace Kernel { -KernelSystem* g_kernel; - /// Initialize the kernel KernelSystem::KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing, std::function prepare_reschedule_callback, u32 system_mode) diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index c662882f58..6ca3267fb6 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -292,6 +292,4 @@ private: void serialize(Archive& ar, const unsigned int file_version); }; -extern KernelSystem* g_kernel; - } // namespace Kernel diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index b8a3d143bb..16bcd3af2a 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -12,6 +12,7 @@ #include "core/hle/kernel/mutex.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/thread.h" +#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::Mutex) @@ -26,7 +27,7 @@ void ReleaseThreadMutexes(Thread* thread) { thread->held_mutexes.clear(); } -Mutex::Mutex() : kernel(*g_kernel) {} +Mutex::Mutex() : kernel(Core::Global()) {} Mutex::~Mutex() {} std::shared_ptr KernelSystem::CreateMutex(bool initial_locked, std::string name) { diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 5fad4fd854..72f882c564 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -18,6 +18,7 @@ #include "core/hle/kernel/thread.h" #include "core/hle/kernel/vm_manager.h" #include "core/memory.h" +#include "core/global.h" namespace Kernel { @@ -427,7 +428,11 @@ ResultCode Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission pe return RESULT_SUCCESS; } -Kernel::Process::Process() : kernel(*g_kernel), handle_table(*g_kernel), vm_manager(g_kernel->memory) +Kernel::Process::Process() : Kernel::Process::Process(Core::Global()) +{ +} + +Kernel::Process::Process(KernelSystem& kernel) : kernel(kernel), handle_table(kernel), vm_manager(kernel.memory) { kernel.memory.RegisterPageTable(&vm_manager.page_table); } diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index edda20c1f0..70a5f212ba 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -143,7 +143,8 @@ private: class Process final : public Object { public: - explicit Process(); + Process(); + explicit Process(KernelSystem& kernel); ~Process() override; std::string GetTypeName() const override { diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index f2ceb899e0..146142f080 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -10,12 +10,13 @@ #include "core/hle/kernel/server_session.h" #include "core/hle/kernel/session.h" #include "core/hle/kernel/thread.h" +#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::ServerSession) namespace Kernel { -ServerSession::ServerSession() : kernel(*g_kernel) {} +ServerSession::ServerSession() : kernel(Core::Global()) {} ServerSession::~ServerSession() { // This destructor will be called automatically when the last ServerSession handle is closed by // the emulated application. diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 409dcc8861..98fe851758 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -24,6 +24,7 @@ #include "core/hle/kernel/thread.h" #include "core/hle/result.h" #include "core/memory.h" +#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::Thread) @@ -66,8 +67,8 @@ u32 ThreadManager::NewThreadId() { } Thread::Thread() - : context(g_kernel->GetThreadManager().NewContext()), - thread_manager(g_kernel->GetThreadManager()) {} + : context(Core::Global().GetThreadManager().NewContext()), + thread_manager(Core::Global().GetThreadManager()) {} Thread::~Thread() {} Thread* ThreadManager::GetCurrentThread() const { diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index f073c3312b..422cf990cd 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -11,10 +11,11 @@ #include "core/hle/kernel/object.h" #include "core/hle/kernel/thread.h" #include "core/hle/kernel/timer.h" +#include "core/global.h" namespace Kernel { -Timer::Timer() : kernel(*g_kernel), timer_manager(g_kernel->GetTimerManager()) {} +Timer::Timer() : kernel(Core::Global()), timer_manager(Core::Global().GetTimerManager()) {} Timer::~Timer() { Cancel(); timer_manager.timer_callback_table.erase(callback_id); diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 88a70bf10f..771bbfb53a 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -18,6 +18,7 @@ #include "core/hle/kernel/mutex.h" #include "core/hle/result.h" #include "core/hle/service/service.h" +#include "core/global.h" namespace Core { class System; @@ -601,6 +602,6 @@ namespace boost::serialization { template inline void load_construct_data(Archive& ar, Service::AM::Module* t, const unsigned int) { - ::new(t)Service::AM::Module(*Kernel::g_kernel); + ::new(t)Service::AM::Module(Core::Global()); } } diff --git a/src/video_core/pica.cpp b/src/video_core/pica.cpp index 1475e3a927..0b5aaa6822 100644 --- a/src/video_core/pica.cpp +++ b/src/video_core/pica.cpp @@ -8,6 +8,12 @@ #include "video_core/pica_state.h" #include "video_core/renderer_base.h" #include "video_core/video_core.h" +#include "core/global.h" + +namespace Core { + template <> + Pica::State& Global() { return Pica::g_state; } +} namespace Pica { From 5265c79056c4e3546b3550018f0f1cfc4b7d4414 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 25 Dec 2019 21:43:51 +0000 Subject: [PATCH 022/129] APT service serialization --- TODO | 2 +- src/common/serialization/optional.h | 91 +++++++++++++++++++++++ src/core/global.h | 5 ++ src/core/hle/kernel/shared_memory.cpp | 7 +- src/core/hle/kernel/shared_memory.h | 2 +- src/core/hle/service/ac/ac_i.h | 2 +- src/core/hle/service/ac/ac_u.h | 2 +- src/core/hle/service/act/act_a.h | 2 +- src/core/hle/service/act/act_u.h | 2 +- src/core/hle/service/am/am_app.h | 2 +- src/core/hle/service/am/am_net.h | 2 +- src/core/hle/service/am/am_sys.h | 2 +- src/core/hle/service/am/am_u.h | 2 +- src/core/hle/service/apt/applet_manager.h | 60 +++++++++++++++ src/core/hle/service/apt/apt.cpp | 28 +++++++ src/core/hle/service/apt/apt.h | 17 ++++- src/core/hle/service/apt/apt_a.cpp | 3 + src/core/hle/service/apt/apt_a.h | 5 ++ src/core/hle/service/apt/apt_s.cpp | 3 + src/core/hle/service/apt/apt_s.h | 5 ++ src/core/hle/service/apt/apt_u.cpp | 3 + src/core/hle/service/apt/apt_u.h | 5 ++ src/core/hle/service/apt/ns_s.cpp | 3 + src/core/hle/service/apt/ns_s.h | 5 ++ src/core/hle/service/service.h | 4 +- 25 files changed, 247 insertions(+), 17 deletions(-) create mode 100644 src/common/serialization/optional.h diff --git a/TODO b/TODO index 7309acb1a9..9e591af8d9 100644 --- a/TODO +++ b/TODO @@ -64,7 +64,7 @@ ✔ AC @started(19-12-23 12:48) @done(19-12-24 22:38) @lasted(1d9h50m3s) ✔ ACT @done(19-12-24 23:17) ✔ AM @started(19-12-24 23:17) @done(19-12-24 23:53) @lasted(36m8s) - ☐ APT + ✔ APT @done(19-12-25 21:41) ☐ BOSS ☐ CAM ☐ CECD diff --git a/src/common/serialization/optional.h b/src/common/serialization/optional.h new file mode 100644 index 0000000000..5ab6af9b81 --- /dev/null +++ b/src/common/serialization/optional.h @@ -0,0 +1,91 @@ +#pragma once + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// function specializations must be defined in the appropriate +// namespace - boost::serialization +namespace boost { +namespace serialization { + +template +void save( + Archive & ar, + const std::optional< T > & t, + const unsigned int /*version*/ +){ + // It is an inherent limitation to the serialization of optional.hpp + // that the underlying type must be either a pointer or must have a + // default constructor. It's possible that this could change sometime + // in the future, but for now, one will have to work around it. This can + // be done by serialization the optional as optional + #if ! defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) + BOOST_STATIC_ASSERT( + boost::serialization::detail::is_default_constructible::value + || boost::is_pointer::value + ); + #endif + const bool tflag = t.has_value(); + ar << boost::serialization::make_nvp("initialized", tflag); + if (tflag){ + ar << boost::serialization::make_nvp("value", *t); + } +} + +template +void load( + Archive & ar, + std::optional< T > & t, + const unsigned int version +){ + bool tflag; + ar >> boost::serialization::make_nvp("initialized", tflag); + if(! tflag){ + t.reset(); + return; + } + + if(0 == version){ + boost::serialization::item_version_type item_version(0); + boost::archive::library_version_type library_version( + ar.get_library_version() + ); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + } + if(! t.has_value()) + t = T(); + ar >> boost::serialization::make_nvp("value", *t); +} + +template +void serialize( + Archive & ar, + std::optional< T > & t, + const unsigned int version +){ + boost::serialization::split_free(ar, t, version); +} + +template +struct version > { + BOOST_STATIC_CONSTANT(int, value = 1); +}; + +} // serialization +} // boost diff --git a/src/core/global.h b/src/core/global.h index 8dfd022d8e..d2e1cd97d6 100644 --- a/src/core/global.h +++ b/src/core/global.h @@ -3,4 +3,9 @@ namespace Core { template T& Global(); +// Declare explicit specialisation to prevent im +class System; +template <> +System& Global(); + } // namespace Core diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 4cd3055085..c76cdfa19f 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -8,10 +8,11 @@ #include "core/hle/kernel/memory.h" #include "core/hle/kernel/shared_memory.h" #include "core/memory.h" +#include "core/global.h" namespace Kernel { -SharedMemory::SharedMemory(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} +SharedMemory::SharedMemory() : Object(Core::Global()), kernel(Core::Global()) {} SharedMemory::~SharedMemory() { for (const auto& interval : holding_memory) { kernel.GetMemoryRegion(MemoryRegion::SYSTEM) @@ -27,7 +28,7 @@ SharedMemory::~SharedMemory() { ResultVal> KernelSystem::CreateSharedMemory( Process* owner_process, u32 size, MemoryPermission permissions, MemoryPermission other_permissions, VAddr address, MemoryRegion region, std::string name) { - auto shared_memory{std::make_shared(*this)}; + auto shared_memory{std::make_shared()}; shared_memory->owner_process = owner_process; shared_memory->name = std::move(name); @@ -72,7 +73,7 @@ ResultVal> KernelSystem::CreateSharedMemory( std::shared_ptr KernelSystem::CreateSharedMemoryForApplet( u32 offset, u32 size, MemoryPermission permissions, MemoryPermission other_permissions, std::string name) { - auto shared_memory{std::make_shared(*this)}; + auto shared_memory{std::make_shared()}; // Allocate memory in heap MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::SYSTEM); diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 8aaf3df1f0..925f7783cc 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -16,7 +16,7 @@ namespace Kernel { class SharedMemory final : public Object { public: - explicit SharedMemory(KernelSystem& kernel); + explicit SharedMemory(); ~SharedMemory() override; std::string GetTypeName() const override { diff --git a/src/core/hle/service/ac/ac_i.h b/src/core/hle/service/ac/ac_i.h index e05bac803c..8e852fb9b2 100644 --- a/src/core/hle/service/ac/ac_i.h +++ b/src/core/hle/service/ac/ac_i.h @@ -14,7 +14,7 @@ public: explicit AC_I(std::shared_ptr ac); private: - SERVICE_SERIALIZATION(AC_I, ac) + SERVICE_SERIALIZATION(AC_I, ac, Module) }; } // namespace Service::AC diff --git a/src/core/hle/service/ac/ac_u.h b/src/core/hle/service/ac/ac_u.h index c15870b519..117269f1f6 100644 --- a/src/core/hle/service/ac/ac_u.h +++ b/src/core/hle/service/ac/ac_u.h @@ -14,7 +14,7 @@ public: explicit AC_U(std::shared_ptr ac); private: - SERVICE_SERIALIZATION(AC_U, ac) + SERVICE_SERIALIZATION(AC_U, ac, Module) }; } // namespace Service::AC diff --git a/src/core/hle/service/act/act_a.h b/src/core/hle/service/act/act_a.h index 036a96182d..1e37c9bde8 100644 --- a/src/core/hle/service/act/act_a.h +++ b/src/core/hle/service/act/act_a.h @@ -12,7 +12,7 @@ class ACT_A final : public Module::Interface { public: explicit ACT_A(std::shared_ptr act); private: - SERVICE_SERIALIZATION(ACT_A, act) + SERVICE_SERIALIZATION(ACT_A, act, Module) }; } // namespace Service::ACT diff --git a/src/core/hle/service/act/act_u.h b/src/core/hle/service/act/act_u.h index 14d924025b..820aa862a6 100644 --- a/src/core/hle/service/act/act_u.h +++ b/src/core/hle/service/act/act_u.h @@ -12,7 +12,7 @@ class ACT_U final : public Module::Interface { public: explicit ACT_U(std::shared_ptr act); private: - SERVICE_SERIALIZATION(ACT_U, act) + SERVICE_SERIALIZATION(ACT_U, act, Module) }; } // namespace Service::ACT diff --git a/src/core/hle/service/am/am_app.h b/src/core/hle/service/am/am_app.h index e78b5ef70f..fae22d96fe 100644 --- a/src/core/hle/service/am/am_app.h +++ b/src/core/hle/service/am/am_app.h @@ -12,7 +12,7 @@ class AM_APP final : public Module::Interface { public: explicit AM_APP(std::shared_ptr am); private: - SERVICE_SERIALIZATION(AM_APP, am) + SERVICE_SERIALIZATION(AM_APP, am, Module) }; } // namespace Service::AM diff --git a/src/core/hle/service/am/am_net.h b/src/core/hle/service/am/am_net.h index 74e335b763..4a50c6c07a 100644 --- a/src/core/hle/service/am/am_net.h +++ b/src/core/hle/service/am/am_net.h @@ -12,7 +12,7 @@ class AM_NET final : public Module::Interface { public: explicit AM_NET(std::shared_ptr am); private: - SERVICE_SERIALIZATION(AM_NET, am) + SERVICE_SERIALIZATION(AM_NET, am, Module) }; } // namespace Service::AM diff --git a/src/core/hle/service/am/am_sys.h b/src/core/hle/service/am/am_sys.h index 028837f3d7..c670523021 100644 --- a/src/core/hle/service/am/am_sys.h +++ b/src/core/hle/service/am/am_sys.h @@ -12,7 +12,7 @@ class AM_SYS final : public Module::Interface { public: explicit AM_SYS(std::shared_ptr am); private: - SERVICE_SERIALIZATION(AM_SYS, am) + SERVICE_SERIALIZATION(AM_SYS, am, Module) }; } // namespace Service::AM diff --git a/src/core/hle/service/am/am_u.h b/src/core/hle/service/am/am_u.h index b19d481674..c09e27c091 100644 --- a/src/core/hle/service/am/am_u.h +++ b/src/core/hle/service/am/am_u.h @@ -12,7 +12,7 @@ class AM_U final : public Module::Interface { public: explicit AM_U(std::shared_ptr am); private: - SERVICE_SERIALIZATION(AM_U, am) + SERVICE_SERIALIZATION(AM_U, am, Module) }; } // namespace Service::AM diff --git a/src/core/hle/service/apt/applet_manager.h b/src/core/hle/service/apt/applet_manager.h index 6bc880bd46..9410b6b549 100644 --- a/src/core/hle/service/apt/applet_manager.h +++ b/src/core/hle/service/apt/applet_manager.h @@ -8,9 +8,12 @@ #include #include #include +#include +#include "common/serialization/optional.h" #include "core/hle/kernel/event.h" #include "core/hle/result.h" #include "core/hle/service/fs/archive.h" +#include "core/global.h" namespace Core { class System; @@ -84,6 +87,18 @@ struct MessageParameter { SignalType signal = SignalType::None; std::shared_ptr object = nullptr; std::vector buffer; + +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & sender_id; + ar & destination_id; + ar & signal; + ar & object; + ar & buffer; + } + friend class boost::serialization::access; }; /// Holds information about the parameters used in StartLibraryApplet @@ -161,6 +176,17 @@ public: u64 current_title_id; FS::MediaType current_media_type; + + private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & next_title_id; + ar & next_media_type; + ar & current_title_id; + ar & current_media_type; + } + friend class boost::serialization::access; }; ApplicationJumpParameters GetApplicationJumpParameters() const { @@ -199,6 +225,21 @@ private: title_id = 0; attributes.raw = 0; } + + private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & applet_id; + ar & slot; + ar & title_id; + ar & registered; + ar & loaded; + ar & attributes.raw; + ar & notification_event; + ar & parameter_event; + } + friend class boost::serialization::access; }; ApplicationJumpParameters app_jump_parameters{}; @@ -216,6 +257,25 @@ private: SignalType library_applet_closing_command; Core::System& system; + +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & next_parameter; + ar & app_jump_parameters; + ar & applet_slots; + ar & library_applet_closing_command; + } + friend class boost::serialization::access; }; } // namespace Service::APT + +namespace boost::serialization { + template + inline void load_construct_data(Archive& ar, Service::APT::AppletManager* t, const unsigned int) + { + ::new(t)Service::APT::AppletManager(Core::Global()); + } +} diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index f7fb0660fe..8e02d2bd49 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -5,6 +5,7 @@ #include "common/common_paths.h" #include "common/file_util.h" #include "common/logging/log.h" +#include "common/archives.h" #include "core/core.h" #include "core/file_sys/archive_ncch.h" #include "core/file_sys/file_backend.h" @@ -26,8 +27,35 @@ #include "core/hw/aes/ccm.h" #include "core/hw/aes/key.h" +namespace boost::serialization { + template + void load_construct_data(Archive& ar, Service::APT::Module* t, const unsigned int) + { + ::new(t)Service::APT::Module(Core::Global()); + } + + template + void load_construct_data(iarchive& ar, Service::APT::Module* t, const unsigned int); +} + namespace Service::APT { +template +void Module::serialize(Archive& ar, const unsigned int) +{ + ar & shared_font_mem; + ar & shared_font_loaded; + ar & shared_font_relocated; + ar & lock; + ar & cpu_percent; + ar & unknown_ns_state_field; + ar & screen_capture_buffer; + ar & screen_capture_post_permission; + ar & applet_manager; +} + +SERIALIZE_IMPL(Module) + Module::NSInterface::NSInterface(std::shared_ptr apt, const char* name, u32 max_session) : ServiceFramework(name, max_session), apt(std::move(apt)) {} diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index 2e2c219cd4..c12dc3f552 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -6,11 +6,15 @@ #include #include +#include +#include +#include "common/archives.h" #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" #include "core/hle/kernel/kernel.h" #include "core/hle/service/service.h" +#include "core/global.h" namespace Core { class System; @@ -65,7 +69,7 @@ public: NSInterface(std::shared_ptr apt, const char* name, u32 max_session); ~NSInterface(); - private: + protected: std::shared_ptr apt; }; @@ -601,7 +605,7 @@ public: */ void CheckNew3DS(Kernel::HLERequestContext& ctx); - private: + protected: bool application_reset_prepared{}; std::shared_ptr apt; }; @@ -630,8 +634,17 @@ private: ScreencapPostPermission::CleanThePermission; // TODO(JamePeng): verify the initial value std::shared_ptr applet_manager; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::APT + +namespace boost::serialization { + template + void load_construct_data(Archive& ar, Service::APT::Module* t, const unsigned int); +} diff --git a/src/core/hle/service/apt/apt_a.cpp b/src/core/hle/service/apt/apt_a.cpp index 7d5c96139e..db49c57d88 100644 --- a/src/core/hle/service/apt/apt_a.cpp +++ b/src/core/hle/service/apt/apt_a.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/apt/apt_a.h" +#include "common/archives.h" namespace Service::APT { @@ -105,3 +106,5 @@ APT_A::APT_A(std::shared_ptr apt) } } // namespace Service::APT + +SERIALIZE_EXPORT_IMPL(Service::APT::APT_A) diff --git a/src/core/hle/service/apt/apt_a.h b/src/core/hle/service/apt/apt_a.h index f481fa1c90..1b81022df4 100644 --- a/src/core/hle/service/apt/apt_a.h +++ b/src/core/hle/service/apt/apt_a.h @@ -11,6 +11,11 @@ namespace Service::APT { class APT_A final : public Module::APTInterface { public: explicit APT_A(std::shared_ptr apt); +private: + SERVICE_SERIALIZATION(APT_A, apt, Module) }; } // namespace Service::APT + +BOOST_CLASS_EXPORT_KEY(Service::APT::APT_A) +BOOST_SERIALIZATION_CONSTRUCT(Service::APT::APT_A) diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp index 1843bdd9aa..4d151fb3d4 100644 --- a/src/core/hle/service/apt/apt_s.cpp +++ b/src/core/hle/service/apt/apt_s.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/apt/apt_s.h" +#include "common/archives.h" namespace Service::APT { @@ -105,3 +106,5 @@ APT_S::APT_S(std::shared_ptr apt) } } // namespace Service::APT + +SERIALIZE_EXPORT_IMPL(Service::APT::APT_S) diff --git a/src/core/hle/service/apt/apt_s.h b/src/core/hle/service/apt/apt_s.h index 7e041cbda2..ef1c235b08 100644 --- a/src/core/hle/service/apt/apt_s.h +++ b/src/core/hle/service/apt/apt_s.h @@ -18,6 +18,11 @@ namespace Service::APT { class APT_S final : public Module::APTInterface { public: explicit APT_S(std::shared_ptr apt); +private: + SERVICE_SERIALIZATION(APT_S, apt, Module) }; } // namespace Service::APT + +BOOST_CLASS_EXPORT_KEY(Service::APT::APT_S) +BOOST_SERIALIZATION_CONSTRUCT(Service::APT::APT_S) diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp index 0ecbd65da4..7ebaf86e36 100644 --- a/src/core/hle/service/apt/apt_u.cpp +++ b/src/core/hle/service/apt/apt_u.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/apt/apt_u.h" +#include "common/archives.h" namespace Service::APT { @@ -102,3 +103,5 @@ APT_U::APT_U(std::shared_ptr apt) } } // namespace Service::APT + +SERIALIZE_EXPORT_IMPL(Service::APT::APT_U) diff --git a/src/core/hle/service/apt/apt_u.h b/src/core/hle/service/apt/apt_u.h index 3b342ed555..79d2df6515 100644 --- a/src/core/hle/service/apt/apt_u.h +++ b/src/core/hle/service/apt/apt_u.h @@ -18,6 +18,11 @@ namespace Service::APT { class APT_U final : public Module::APTInterface { public: explicit APT_U(std::shared_ptr apt); +private: + SERVICE_SERIALIZATION(APT_U, apt, Module) }; } // namespace Service::APT + +BOOST_CLASS_EXPORT_KEY(Service::APT::APT_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::APT::APT_U) diff --git a/src/core/hle/service/apt/ns_s.cpp b/src/core/hle/service/apt/ns_s.cpp index e9eb871744..b556845d31 100644 --- a/src/core/hle/service/apt/ns_s.cpp +++ b/src/core/hle/service/apt/ns_s.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/apt/ns_s.h" +#include "common/archives.h" namespace Service::NS { @@ -29,3 +30,5 @@ NS_S::NS_S(std::shared_ptr apt) } } // namespace Service::NS + +SERIALIZE_EXPORT_IMPL(Service::NS::NS_S) diff --git a/src/core/hle/service/apt/ns_s.h b/src/core/hle/service/apt/ns_s.h index 5a5b311b06..8f023e2042 100644 --- a/src/core/hle/service/apt/ns_s.h +++ b/src/core/hle/service/apt/ns_s.h @@ -14,6 +14,11 @@ namespace Service::NS { class NS_S final : public Service::APT::Module::NSInterface { public: explicit NS_S(std::shared_ptr apt); +private: + SERVICE_SERIALIZATION(NS_S, apt, Service::APT::Module) }; } // namespace Service::NS + +BOOST_CLASS_EXPORT_KEY(Service::NS::NS_S) +BOOST_SERIALIZATION_CONSTRUCT(Service::NS::NS_S) diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index bdad47ea86..c0c48892ad 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -199,7 +199,7 @@ extern const std::array service_module_map; } // namespace Service -#define SERVICE_SERIALIZATION(T, MFIELD) \ +#define SERVICE_SERIALIZATION(T, MFIELD, TMODULE) \ template \ void save_construct(Archive& ar, const unsigned int file_version) const \ { \ @@ -209,7 +209,7 @@ extern const std::array service_module_map; template \ static void load_construct(Archive& ar, T* t, const unsigned int file_version) \ { \ - std::shared_ptr MFIELD; \ + std::shared_ptr MFIELD; \ ar >> MFIELD; \ ::new(t)T(MFIELD); \ } \ From 1185d627924b9bd5dd13461e7581850a777e9d22 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 25 Dec 2019 23:19:01 +0000 Subject: [PATCH 023/129] BOSS service serialization --- TODO | 2 +- src/core/hle/service/apt/apt.h | 8 ++++++++ src/core/hle/service/boss/boss.h | 30 +++++++++++++++++++++++++++- src/core/hle/service/boss/boss_p.cpp | 3 +++ src/core/hle/service/boss/boss_p.h | 6 ++++++ src/core/hle/service/boss/boss_u.cpp | 3 +++ src/core/hle/service/boss/boss_u.h | 6 ++++++ 7 files changed, 56 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 9e591af8d9..c6e3366e32 100644 --- a/TODO +++ b/TODO @@ -65,7 +65,7 @@ ✔ ACT @done(19-12-24 23:17) ✔ AM @started(19-12-24 23:17) @done(19-12-24 23:53) @lasted(36m8s) ✔ APT @done(19-12-25 21:41) - ☐ BOSS + ✔ BOSS @started(19-12-25 21:48) @done(19-12-25 23:18) @lasted(1h30m14s) ☐ CAM ☐ CECD ☐ CGF diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index c12dc3f552..45a93b3501 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -608,6 +608,14 @@ public: protected: bool application_reset_prepared{}; std::shared_ptr apt; + + private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & application_reset_prepared; + } + friend class boost::serialization::access; }; private: diff --git a/src/core/hle/service/boss/boss.h b/src/core/hle/service/boss/boss.h index e0cb39b372..7017ce2b65 100644 --- a/src/core/hle/service/boss/boss.h +++ b/src/core/hle/service/boss/boss.h @@ -5,8 +5,10 @@ #pragma once #include +#include #include "core/hle/kernel/event.h" #include "core/hle/service/service.h" +#include "core/global.h" namespace Core { class System; @@ -952,19 +954,45 @@ public: */ void GetNsDataNewFlagPrivileged(Kernel::HLERequestContext& ctx); - private: + protected: std::shared_ptr boss; + private: u8 new_arrival_flag; u8 ns_data_new_flag; u8 ns_data_new_flag_privileged; u8 output_flag; + + template + void serialize(Archive& ar, const unsigned int) + { + ar & new_arrival_flag; + ar & ns_data_new_flag; + ar & ns_data_new_flag_privileged; + ar & output_flag; + } + friend class boost::serialization::access; }; private: std::shared_ptr task_finish_event; + + template + void serialize(Archive& ar, const unsigned int) + { + ar & task_finish_event; + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::BOSS + +namespace boost::serialization { + template + inline void load_construct_data(Archive& ar, Service::BOSS::Module* t, const unsigned int) + { + ::new(t)Service::BOSS::Module(Core::Global()); + } +} diff --git a/src/core/hle/service/boss/boss_p.cpp b/src/core/hle/service/boss/boss_p.cpp index cdc8f10364..4e48fe8f3d 100644 --- a/src/core/hle/service/boss/boss_p.cpp +++ b/src/core/hle/service/boss/boss_p.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/boss/boss_p.h" +#include "common/archives.h" namespace Service::BOSS { @@ -84,3 +85,5 @@ BOSS_P::BOSS_P(std::shared_ptr boss) } } // namespace Service::BOSS + +SERIALIZE_EXPORT_IMPL(Service::BOSS::BOSS_P) diff --git a/src/core/hle/service/boss/boss_p.h b/src/core/hle/service/boss/boss_p.h index 9c84a1e9d2..56f0cd4fcf 100644 --- a/src/core/hle/service/boss/boss_p.h +++ b/src/core/hle/service/boss/boss_p.h @@ -11,6 +11,12 @@ namespace Service::BOSS { class BOSS_P final : public Module::Interface { public: explicit BOSS_P(std::shared_ptr boss); + +private: + SERVICE_SERIALIZATION(BOSS_P, boss, Module) }; } // namespace Service::BOSS + +BOOST_CLASS_EXPORT_KEY(Service::BOSS::BOSS_P) +BOOST_SERIALIZATION_CONSTRUCT(Service::BOSS::BOSS_P) diff --git a/src/core/hle/service/boss/boss_u.cpp b/src/core/hle/service/boss/boss_u.cpp index c6aaba8888..f839e92922 100644 --- a/src/core/hle/service/boss/boss_u.cpp +++ b/src/core/hle/service/boss/boss_u.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/boss/boss_u.h" +#include "common/archives.h" namespace Service::BOSS { @@ -72,3 +73,5 @@ BOSS_U::BOSS_U(std::shared_ptr boss) } } // namespace Service::BOSS + +SERIALIZE_EXPORT_IMPL(Service::BOSS::BOSS_U) diff --git a/src/core/hle/service/boss/boss_u.h b/src/core/hle/service/boss/boss_u.h index a93b4e5024..195783b406 100644 --- a/src/core/hle/service/boss/boss_u.h +++ b/src/core/hle/service/boss/boss_u.h @@ -11,6 +11,12 @@ namespace Service::BOSS { class BOSS_U final : public Module::Interface { public: explicit BOSS_U(std::shared_ptr boss); + +private: + SERVICE_SERIALIZATION(BOSS_U, boss, Module) }; } // namespace Service::BOSS + +BOOST_CLASS_EXPORT_KEY(Service::BOSS::BOSS_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::BOSS::BOSS_U) From 17b9cbefef78aa006075d69855c328e569af280d Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 26 Dec 2019 10:37:43 +0000 Subject: [PATCH 024/129] CAM service serialization --- TODO | 3 +- src/core/hle/service/cam/cam.cpp | 11 +++++ src/core/hle/service/cam/cam.h | 79 +++++++++++++++++++++++++++++- src/core/hle/service/cam/cam_c.cpp | 3 ++ src/core/hle/service/cam/cam_c.h | 6 +++ src/core/hle/service/cam/cam_q.cpp | 3 ++ src/core/hle/service/cam/cam_q.h | 9 ++++ src/core/hle/service/cam/cam_s.cpp | 3 ++ src/core/hle/service/cam/cam_s.h | 6 +++ src/core/hle/service/cam/cam_u.cpp | 3 ++ src/core/hle/service/cam/cam_u.h | 6 +++ 11 files changed, 129 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index c6e3366e32..354e61a2f0 100644 --- a/TODO +++ b/TODO @@ -66,7 +66,8 @@ ✔ AM @started(19-12-24 23:17) @done(19-12-24 23:53) @lasted(36m8s) ✔ APT @done(19-12-25 21:41) ✔ BOSS @started(19-12-25 21:48) @done(19-12-25 23:18) @lasted(1h30m14s) - ☐ CAM + ☐ CAM @started(19-12-26 10:37) + Need to check capture_result ☐ CECD ☐ CGF ☐ CSND diff --git a/src/core/hle/service/cam/cam.cpp b/src/core/hle/service/cam/cam.cpp index bf1bab8c0c..b7acd307c0 100644 --- a/src/core/hle/service/cam/cam.cpp +++ b/src/core/hle/service/cam/cam.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/bit_set.h" #include "common/logging/log.h" #include "core/core.h" @@ -22,6 +23,16 @@ namespace Service::CAM { +template +void Module::serialize(Archive& ar, const unsigned int) +{ + ar & cameras; + ar & ports; + ar & is_camera_reload_pending; +} + +SERIALIZE_IMPL(Module) + // built-in resolution parameters constexpr std::array PRESET_RESOLUTION{{ {640, 480, 0, 0, 639, 479}, // VGA diff --git a/src/core/hle/service/cam/cam.h b/src/core/hle/service/cam/cam.h index 9f3d819901..229c882b51 100644 --- a/src/core/hle/service/cam/cam.h +++ b/src/core/hle/service/cam/cam.h @@ -12,6 +12,7 @@ #include "common/swap.h" #include "core/hle/result.h" #include "core/hle/service/service.h" +#include "core/global.h" namespace Core { class System; @@ -179,6 +180,19 @@ struct Resolution { u16 crop_y0; u16 crop_x1; u16 crop_y1; + +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & width; + ar & height; + ar & crop_x0; + ar & crop_y0; + ar & crop_x1; + ar & crop_y1; + } + friend class boost::serialization::access; }; struct PackageParameterWithoutContext { @@ -710,7 +724,7 @@ public: */ void DriverFinalize(Kernel::HLERequestContext& ctx); - private: + protected: std::shared_ptr cam; }; @@ -738,6 +752,17 @@ private: Effect effect{Effect::None}; OutputFormat format{OutputFormat::YUV422}; Resolution resolution = {0, 0, 0, 0, 0, 0}; + + private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & flip; + ar & effect; + ar & format; + ar & resolution; + } + friend class boost::serialization::access; }; struct CameraConfig { @@ -745,6 +770,17 @@ private: std::array contexts; int current_context{0}; FrameRate frame_rate{FrameRate::Rate_5}; + + private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & impl; + ar & contexts; + ar & current_context; + ar & frame_rate; + } + friend class boost::serialization::access; }; struct PortConfig { @@ -779,6 +815,32 @@ private: u32 dest_size{0}; // the destination size of the receiving process void Clear(); + + private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & camera_id; + ar & is_active; + ar & is_pending_receiving; + ar & is_busy; + ar & is_receiving; + ar & is_trimming; + ar & x0; + ar & y0; + ar & x1; + ar & y1; + ar & transfer_bytes; + ar & completion_event; + ar & buffer_error_interrupt_event; + ar & vsync_interrupt_event; + // TODO: Check if this is ever needed: + //ar & capture_result; + ar & dest_process; + ar & dest; + ar & dest_size; + } + friend class boost::serialization::access; }; void LoadCameraImplementation(CameraConfig& camera, int camera_id); @@ -786,8 +848,13 @@ private: Core::System& system; std::array cameras; std::array ports; - Core::TimingEventType* completion_event_callback; + // TODO: Make this *const + const Core::TimingEventType* completion_event_callback; std::atomic is_camera_reload_pending{false}; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; std::shared_ptr GetModule(Core::System& system); @@ -795,3 +862,11 @@ std::shared_ptr GetModule(Core::System& system); void InstallInterfaces(Core::System& system); } // namespace Service::CAM + +namespace boost::serialization { + template + inline void load_construct_data(Archive& ar, Service::CAM::Module* t, const unsigned int) + { + ::new(t)Service::CAM::Module(Core::Global()); + } +} diff --git a/src/core/hle/service/cam/cam_c.cpp b/src/core/hle/service/cam/cam_c.cpp index 80816c9237..a29e9db3ea 100644 --- a/src/core/hle/service/cam/cam_c.cpp +++ b/src/core/hle/service/cam/cam_c.cpp @@ -4,6 +4,7 @@ #include "core/hle/service/cam/cam.h" #include "core/hle/service/cam/cam_c.h" +#include "common/archives.h" namespace Service::CAM { @@ -79,3 +80,5 @@ CAM_C::CAM_C(std::shared_ptr cam) : Module::Interface(std::move(cam), "c } } // namespace Service::CAM + +SERIALIZE_EXPORT_IMPL(Service::CAM::CAM_C) diff --git a/src/core/hle/service/cam/cam_c.h b/src/core/hle/service/cam/cam_c.h index d6dfcd6c58..c1ed355ac4 100644 --- a/src/core/hle/service/cam/cam_c.h +++ b/src/core/hle/service/cam/cam_c.h @@ -11,6 +11,12 @@ namespace Service::CAM { class CAM_C final : public Module::Interface { public: explicit CAM_C(std::shared_ptr cam); + +private: + SERVICE_SERIALIZATION(CAM_C, cam, Module) }; } // namespace Service::CAM + +BOOST_CLASS_EXPORT_KEY(Service::CAM::CAM_C) +BOOST_SERIALIZATION_CONSTRUCT(Service::CAM::CAM_C) diff --git a/src/core/hle/service/cam/cam_q.cpp b/src/core/hle/service/cam/cam_q.cpp index 71fc127d22..ac477bf040 100644 --- a/src/core/hle/service/cam/cam_q.cpp +++ b/src/core/hle/service/cam/cam_q.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/cam/cam_q.h" +#include "common/archives.h" namespace Service::CAM { @@ -13,3 +14,5 @@ CAM_Q::CAM_Q() : ServiceFramework("cam:q", 1 /*TODO: find the true value*/) { } } // namespace Service::CAM + +SERIALIZE_EXPORT_IMPL(Service::CAM::CAM_Q) diff --git a/src/core/hle/service/cam/cam_q.h b/src/core/hle/service/cam/cam_q.h index d1124493b3..33943ca214 100644 --- a/src/core/hle/service/cam/cam_q.h +++ b/src/core/hle/service/cam/cam_q.h @@ -11,6 +11,15 @@ namespace Service::CAM { class CAM_Q : public ServiceFramework { public: CAM_Q(); +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & boost::serialization::base_object(*this); + } + friend class boost::serialization::access; }; } // namespace Service::CAM + +BOOST_CLASS_EXPORT_KEY(Service::CAM::CAM_Q) diff --git a/src/core/hle/service/cam/cam_s.cpp b/src/core/hle/service/cam/cam_s.cpp index c4936f9b54..0797ed4e1d 100644 --- a/src/core/hle/service/cam/cam_s.cpp +++ b/src/core/hle/service/cam/cam_s.cpp @@ -4,6 +4,7 @@ #include "core/hle/service/cam/cam.h" #include "core/hle/service/cam/cam_s.h" +#include "common/archives.h" namespace Service::CAM { @@ -79,3 +80,5 @@ CAM_S::CAM_S(std::shared_ptr cam) : Module::Interface(std::move(cam), "c } } // namespace Service::CAM + +SERIALIZE_EXPORT_IMPL(Service::CAM::CAM_S) diff --git a/src/core/hle/service/cam/cam_s.h b/src/core/hle/service/cam/cam_s.h index 0c9d266447..cceb99b87f 100644 --- a/src/core/hle/service/cam/cam_s.h +++ b/src/core/hle/service/cam/cam_s.h @@ -11,6 +11,12 @@ namespace Service::CAM { class CAM_S final : public Module::Interface { public: explicit CAM_S(std::shared_ptr cam); + +private: + SERVICE_SERIALIZATION(CAM_S, cam, Module) }; } // namespace Service::CAM + +BOOST_CLASS_EXPORT_KEY(Service::CAM::CAM_S) +BOOST_SERIALIZATION_CONSTRUCT(Service::CAM::CAM_S) diff --git a/src/core/hle/service/cam/cam_u.cpp b/src/core/hle/service/cam/cam_u.cpp index 3c3c4b17df..16c652a263 100644 --- a/src/core/hle/service/cam/cam_u.cpp +++ b/src/core/hle/service/cam/cam_u.cpp @@ -4,6 +4,7 @@ #include "core/hle/service/cam/cam.h" #include "core/hle/service/cam/cam_u.h" +#include "common/archives.h" namespace Service::CAM { @@ -79,3 +80,5 @@ CAM_U::CAM_U(std::shared_ptr cam) : Module::Interface(std::move(cam), "c } } // namespace Service::CAM + +SERIALIZE_EXPORT_IMPL(Service::CAM::CAM_U) diff --git a/src/core/hle/service/cam/cam_u.h b/src/core/hle/service/cam/cam_u.h index 85b12559af..2b775a0352 100644 --- a/src/core/hle/service/cam/cam_u.h +++ b/src/core/hle/service/cam/cam_u.h @@ -11,6 +11,12 @@ namespace Service::CAM { class CAM_U final : public Module::Interface { public: explicit CAM_U(std::shared_ptr cam); + +private: + SERVICE_SERIALIZATION(CAM_U, cam, Module) }; } // namespace Service::CAM + +BOOST_CLASS_EXPORT_KEY(Service::CAM::CAM_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::CAM::CAM_U) From a0c3b9178525df5d192048d266e3e1d0f8c1e3ef Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 26 Dec 2019 17:56:44 +0000 Subject: [PATCH 025/129] Added CSND serialization --- TODO | 7 +++- src/core/hle/service/csnd/csnd_snd.cpp | 14 +++++++ src/core/hle/service/csnd/csnd_snd.h | 56 ++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 354e61a2f0..e485f33a70 100644 --- a/TODO +++ b/TODO @@ -15,6 +15,7 @@ ☐ Settings ☐ Telemetry session ☐ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE +☐ Review constructor/initialization code ✔ HW @done(19-08-13 15:41) ✔ GPU regs @done(19-08-13 15:41) ✔ LCD regs @done(19-08-13 15:41) @@ -69,8 +70,10 @@ ☐ CAM @started(19-12-26 10:37) Need to check capture_result ☐ CECD - ☐ CGF - ☐ CSND + ☐ Archive backend / file handles + ☐ CFG + Also needs archive backend.. + ✔ CSND @started(19-12-26 17:51) @done(19-12-26 17:56) @lasted(5m30s) ☐ DLP ☐ DSP ☐ ERR diff --git a/src/core/hle/service/csnd/csnd_snd.cpp b/src/core/hle/service/csnd/csnd_snd.cpp index 5c9fa13e94..d011a1c66f 100644 --- a/src/core/hle/service/csnd/csnd_snd.cpp +++ b/src/core/hle/service/csnd/csnd_snd.cpp @@ -3,11 +3,25 @@ // Refer to the license.txt file included. #include "common/alignment.h" +#include "common/archives.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" #include "core/hle/result.h" #include "core/hle/service/csnd/csnd_snd.h" +namespace boost::serialization { + template + void load_construct_data(Archive& ar, Service::CSND::CSND_SND* t, const unsigned int) + { + ::new(t)Service::CSND::CSND_SND(Core::Global()); + } + + template + void load_construct_data(iarchive& ar, Service::CSND::CSND_SND* t, const unsigned int); +} + +SERIALIZE_EXPORT_IMPL(Service::CSND::CSND_SND) + namespace Service::CSND { enum class CommandId : u16 { diff --git a/src/core/hle/service/csnd/csnd_snd.h b/src/core/hle/service/csnd/csnd_snd.h index afdc3b1a8b..0e2dd8cd81 100644 --- a/src/core/hle/service/csnd/csnd_snd.h +++ b/src/core/hle/service/csnd/csnd_snd.h @@ -5,6 +5,8 @@ #pragma once #include +#include +#include #include "core/hle/kernel/mutex.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/service/service.h" @@ -33,6 +35,15 @@ enum class LoopMode : u8 { struct AdpcmState { s16 predictor = 0; u8 step_index = 0; + +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & predictor; + ar & step_index; + } + friend class boost::serialization::access; }; struct Channel { @@ -52,6 +63,29 @@ struct Channel { LoopMode loop_mode = LoopMode::Manual; Encoding encoding = Encoding::Pcm8; u8 psg_duty = 0; + +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & block1_address; + ar & block2_address; + ar & block1_size; + ar & block2_size; + ar & block1_adpcm_state; + ar & block2_adpcm_state; + ar & block2_adpcm_reload; + ar & left_channel_volume; + ar & right_channel_volume; + ar & left_capture_volume; + ar & right_capture_volume; + ar & sample_rate; + ar & linear_interpolation; + ar & loop_mode; + ar & encoding; + ar & psg_duty; + } + friend class boost::serialization::access; }; class CSND_SND final : public ServiceFramework { @@ -222,9 +256,31 @@ private: u32 type1_command_offset = 0; u32 acquired_channel_mask = 0; + + template + void serialize(Archive& ar, const unsigned int) + { + ar & mutex; + ar & shared_memory; + ar & capture_units; + ar & channels; + ar & master_state_offset; + ar & channel_state_offset; + ar & capture_state_offset; + ar & type1_command_offset; + ar & acquired_channel_mask; + } + friend class boost::serialization::access; }; /// Initializes the CSND_SND Service void InstallInterfaces(Core::System& system); } // namespace Service::CSND + +BOOST_CLASS_EXPORT_KEY(Service::CSND::CSND_SND) + +namespace boost::serialization { + template + void load_construct_data(Archive& ar, Service::CSND::CSND_SND* t, const unsigned int); +} From 30fe2bfe38fb251989acb50df561ba512d9f27b6 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 26 Dec 2019 18:02:59 +0000 Subject: [PATCH 026/129] Added DLP service serialization --- TODO | 2 +- src/core/hle/service/dlp/dlp_clnt.cpp | 3 +++ src/core/hle/service/dlp/dlp_clnt.h | 9 +++++++++ src/core/hle/service/dlp/dlp_fkcl.cpp | 3 +++ src/core/hle/service/dlp/dlp_fkcl.h | 9 +++++++++ src/core/hle/service/dlp/dlp_srvr.cpp | 3 +++ src/core/hle/service/dlp/dlp_srvr.h | 9 +++++++++ 7 files changed, 37 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index e485f33a70..27f720dca2 100644 --- a/TODO +++ b/TODO @@ -74,7 +74,7 @@ ☐ CFG Also needs archive backend.. ✔ CSND @started(19-12-26 17:51) @done(19-12-26 17:56) @lasted(5m30s) - ☐ DLP + ✔ DLP @done(19-12-26 18:02) ☐ DSP ☐ ERR ☐ FRD diff --git a/src/core/hle/service/dlp/dlp_clnt.cpp b/src/core/hle/service/dlp/dlp_clnt.cpp index 63308f57e2..df5b755e1d 100644 --- a/src/core/hle/service/dlp/dlp_clnt.cpp +++ b/src/core/hle/service/dlp/dlp_clnt.cpp @@ -4,6 +4,9 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/service/dlp/dlp_clnt.h" +#include "common/archives.h" + +SERIALIZE_EXPORT_IMPL(Service::DLP::DLP_CLNT) namespace Service::DLP { diff --git a/src/core/hle/service/dlp/dlp_clnt.h b/src/core/hle/service/dlp/dlp_clnt.h index db506b985e..3f90208639 100644 --- a/src/core/hle/service/dlp/dlp_clnt.h +++ b/src/core/hle/service/dlp/dlp_clnt.h @@ -12,6 +12,15 @@ class DLP_CLNT final : public ServiceFramework { public: DLP_CLNT(); ~DLP_CLNT() = default; +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & boost::serialization::base_object(*this); + } + friend class boost::serialization::access; }; } // namespace Service::DLP + +BOOST_CLASS_EXPORT_KEY(Service::DLP::DLP_CLNT) diff --git a/src/core/hle/service/dlp/dlp_fkcl.cpp b/src/core/hle/service/dlp/dlp_fkcl.cpp index 30a98c4bf1..607c211d47 100644 --- a/src/core/hle/service/dlp/dlp_fkcl.cpp +++ b/src/core/hle/service/dlp/dlp_fkcl.cpp @@ -4,6 +4,9 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/service/dlp/dlp_fkcl.h" +#include "common/archives.h" + +SERIALIZE_EXPORT_IMPL(Service::DLP::DLP_FKCL) namespace Service::DLP { diff --git a/src/core/hle/service/dlp/dlp_fkcl.h b/src/core/hle/service/dlp/dlp_fkcl.h index a3b2ac86de..ae26b62209 100644 --- a/src/core/hle/service/dlp/dlp_fkcl.h +++ b/src/core/hle/service/dlp/dlp_fkcl.h @@ -12,6 +12,15 @@ class DLP_FKCL final : public ServiceFramework { public: DLP_FKCL(); ~DLP_FKCL() = default; +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & boost::serialization::base_object(*this); + } + friend class boost::serialization::access; }; } // namespace Service::DLP + +BOOST_CLASS_EXPORT_KEY(Service::DLP::DLP_FKCL) diff --git a/src/core/hle/service/dlp/dlp_srvr.cpp b/src/core/hle/service/dlp/dlp_srvr.cpp index 9d74059416..0cff2e2bc7 100644 --- a/src/core/hle/service/dlp/dlp_srvr.cpp +++ b/src/core/hle/service/dlp/dlp_srvr.cpp @@ -7,6 +7,9 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/result.h" #include "core/hle/service/dlp/dlp_srvr.h" +#include "common/archives.h" + +SERIALIZE_EXPORT_IMPL(Service::DLP::DLP_SRVR) namespace Service::DLP { diff --git a/src/core/hle/service/dlp/dlp_srvr.h b/src/core/hle/service/dlp/dlp_srvr.h index 50d8d92b25..6af350c8ed 100644 --- a/src/core/hle/service/dlp/dlp_srvr.h +++ b/src/core/hle/service/dlp/dlp_srvr.h @@ -15,6 +15,15 @@ public: private: void IsChild(Kernel::HLERequestContext& ctx); + + template + void serialize(Archive& ar, const unsigned int) + { + ar & boost::serialization::base_object(*this); + } + friend class boost::serialization::access; }; } // namespace Service::DLP + +BOOST_CLASS_EXPORT_KEY(Service::DLP::DLP_SRVR) From 452ae2e3714ba6f8de7902c8b6046e22a8f2f957 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 26 Dec 2019 18:10:38 +0000 Subject: [PATCH 027/129] Added DSP service serialization --- TODO | 2 +- src/core/hle/service/dsp/dsp_dsp.cpp | 14 ++++++++++++++ src/core/hle/service/dsp/dsp_dsp.h | 19 +++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index 27f720dca2..c3e8a57d7f 100644 --- a/TODO +++ b/TODO @@ -75,7 +75,7 @@ Also needs archive backend.. ✔ CSND @started(19-12-26 17:51) @done(19-12-26 17:56) @lasted(5m30s) ✔ DLP @done(19-12-26 18:02) - ☐ DSP + ✔ DSP @done(19-12-26 18:10) ☐ ERR ☐ FRD ☐ FS diff --git a/src/core/hle/service/dsp/dsp_dsp.cpp b/src/core/hle/service/dsp/dsp_dsp.cpp index 37682edcc3..519d39b0c3 100644 --- a/src/core/hle/service/dsp/dsp_dsp.cpp +++ b/src/core/hle/service/dsp/dsp_dsp.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "audio_core/audio_types.h" +#include "common/archives.h" #include "common/assert.h" #include "common/logging/log.h" #include "core/core.h" @@ -13,6 +14,19 @@ using DspPipe = AudioCore::DspPipe; using InterruptType = Service::DSP::DSP_DSP::InterruptType; +SERIALIZE_EXPORT_IMPL(Service::DSP::DSP_DSP) + +namespace boost::serialization { + template + void load_construct_data(Archive& ar, Service::DSP::DSP_DSP* t, const unsigned int) + { + ::new(t)Service::DSP::DSP_DSP(Core::Global()); + } + + template + void load_construct_data(iarchive& ar, Service::DSP::DSP_DSP* t, const unsigned int); +} + namespace AudioCore { enum class DspPipe; } diff --git a/src/core/hle/service/dsp/dsp_dsp.h b/src/core/hle/service/dsp/dsp_dsp.h index ef1f0b76df..b4c727091e 100644 --- a/src/core/hle/service/dsp/dsp_dsp.h +++ b/src/core/hle/service/dsp/dsp_dsp.h @@ -264,8 +264,27 @@ private: /// Each DSP pipe has an associated interrupt std::array, AudioCore::num_dsp_pipe> pipes = {{}}; + + template + void serialize(Archive& ar, const unsigned int) + { + ar & boost::serialization::base_object(*this); + ar & semaphore_event; + ar & preset_semaphore; + ar & interrupt_zero; + ar & interrupt_one; + ar & pipes; + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::DSP + +BOOST_CLASS_EXPORT_KEY(Service::DSP::DSP_DSP) + +namespace boost::serialization { + template + void load_construct_data(Archive& ar, Service::DSP::DSP_DSP* t, const unsigned int); +} From 4354179156e38bac0819ba6c10c1a2245ba879d7 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 26 Dec 2019 18:14:22 +0000 Subject: [PATCH 028/129] Added ERR service serialization --- TODO | 2 +- src/core/hle/service/err_f.cpp | 14 ++++++++++++++ src/core/hle/service/err_f.h | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index c3e8a57d7f..4a07c0608d 100644 --- a/TODO +++ b/TODO @@ -76,7 +76,7 @@ ✔ CSND @started(19-12-26 17:51) @done(19-12-26 17:56) @lasted(5m30s) ✔ DLP @done(19-12-26 18:02) ✔ DSP @done(19-12-26 18:10) - ☐ ERR + ✔ ERR @done(19-12-26 18:14) ☐ FRD ☐ FS ☐ GSP diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp index b218eb7937..0efc600e8c 100644 --- a/src/core/hle/service/err_f.cpp +++ b/src/core/hle/service/err_f.cpp @@ -6,6 +6,7 @@ #include #include #include +#include "common/archives.h" #include "common/bit_field.h" #include "common/common_types.h" #include "common/logging/log.h" @@ -16,6 +17,19 @@ #include "core/hle/service/err_f.h" #undef exception_info +SERIALIZE_EXPORT_IMPL(Service::ERR::ERR_F) + +namespace boost::serialization { + template + void load_construct_data(Archive& ar, Service::ERR::ERR_F* t, const unsigned int) + { + ::new(t)Service::ERR::ERR_F(Core::Global()); + } + + template + void load_construct_data(iarchive& ar, Service::ERR::ERR_F* t, const unsigned int); +} + namespace Service::ERR { enum class FatalErrType : u32 { diff --git a/src/core/hle/service/err_f.h b/src/core/hle/service/err_f.h index 4a1684cafc..a3d0cf11e3 100644 --- a/src/core/hle/service/err_f.h +++ b/src/core/hle/service/err_f.h @@ -34,8 +34,22 @@ private: void ThrowFatalError(Kernel::HLERequestContext& ctx); Core::System& system; + + template + void serialize(Archive& ar, const unsigned int) + { + ar & boost::serialization::base_object(*this); + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::ERR + +BOOST_CLASS_EXPORT_KEY(Service::ERR::ERR_F) + +namespace boost::serialization { + template + void load_construct_data(Archive& ar, Service::ERR::ERR_F* t, const unsigned int); +} From d1096de24525aa00b1cbdd490e4b4b76b6c8d915 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 26 Dec 2019 19:09:55 +0000 Subject: [PATCH 029/129] Added FRD service serialization --- TODO | 2 +- src/core/hle/service/frd/frd.h | 28 +++++++++++++++++++++++++++- src/core/hle/service/frd/frd_a.cpp | 3 +++ src/core/hle/service/frd/frd_a.h | 5 +++++ src/core/hle/service/frd/frd_u.cpp | 3 +++ src/core/hle/service/frd/frd_u.h | 5 +++++ 6 files changed, 44 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 4a07c0608d..5a483dc84e 100644 --- a/TODO +++ b/TODO @@ -77,7 +77,7 @@ ✔ DLP @done(19-12-26 18:02) ✔ DSP @done(19-12-26 18:10) ✔ ERR @done(19-12-26 18:14) - ☐ FRD + ✔ FRD @done(19-12-26 19:09) ☐ FS ☐ GSP ☐ HID diff --git a/src/core/hle/service/frd/frd.h b/src/core/hle/service/frd/frd.h index 200b51ebe4..46dc96cadd 100644 --- a/src/core/hle/service/frd/frd.h +++ b/src/core/hle/service/frd/frd.h @@ -18,10 +18,28 @@ struct FriendKey { u32 friend_id; u32 unknown; u64 friend_code; + +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & friend_id; + ar & unknown; + ar & friend_code; + } + friend class boost::serialization::access; }; struct MyPresence { u8 unknown[0x12C]; + +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & unknown; + } + friend class boost::serialization::access; }; struct Profile { @@ -130,13 +148,21 @@ public: */ void SetClientSdkVersion(Kernel::HLERequestContext& ctx); - private: + protected: std::shared_ptr frd; }; private: FriendKey my_friend_key = {0, 0, 0ull}; MyPresence my_presence = {}; + + template + void serialize(Archive& ar, const unsigned int) + { + ar & my_friend_key; + ar & my_presence; + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); diff --git a/src/core/hle/service/frd/frd_a.cpp b/src/core/hle/service/frd/frd_a.cpp index c68689cc00..6248891af0 100644 --- a/src/core/hle/service/frd/frd_a.cpp +++ b/src/core/hle/service/frd/frd_a.cpp @@ -3,6 +3,9 @@ // Refer to the license.txt file included. #include "core/hle/service/frd/frd_a.h" +#include "common/archives.h" + +SERIALIZE_EXPORT_IMPL(Service::FRD::FRD_A) namespace Service::FRD { diff --git a/src/core/hle/service/frd/frd_a.h b/src/core/hle/service/frd/frd_a.h index 97657a072f..133d40dc1b 100644 --- a/src/core/hle/service/frd/frd_a.h +++ b/src/core/hle/service/frd/frd_a.h @@ -11,6 +11,11 @@ namespace Service::FRD { class FRD_A final : public Module::Interface { public: explicit FRD_A(std::shared_ptr frd); +private: + SERVICE_SERIALIZATION(FRD_A, frd, Module) }; } // namespace Service::FRD + +BOOST_CLASS_EXPORT_KEY(Service::FRD::FRD_A) +BOOST_SERIALIZATION_CONSTRUCT(Service::FRD::FRD_A) diff --git a/src/core/hle/service/frd/frd_u.cpp b/src/core/hle/service/frd/frd_u.cpp index 2cbc64243e..ba499dd2be 100644 --- a/src/core/hle/service/frd/frd_u.cpp +++ b/src/core/hle/service/frd/frd_u.cpp @@ -3,6 +3,9 @@ // Refer to the license.txt file included. #include "core/hle/service/frd/frd_u.h" +#include "common/archives.h" + +SERIALIZE_EXPORT_IMPL(Service::FRD::FRD_U) namespace Service::FRD { diff --git a/src/core/hle/service/frd/frd_u.h b/src/core/hle/service/frd/frd_u.h index 5704d5e11a..281334f516 100644 --- a/src/core/hle/service/frd/frd_u.h +++ b/src/core/hle/service/frd/frd_u.h @@ -11,6 +11,11 @@ namespace Service::FRD { class FRD_U final : public Module::Interface { public: explicit FRD_U(std::shared_ptr frd); +private: + SERVICE_SERIALIZATION(FRD_U, frd, Module) }; } // namespace Service::FRD + +BOOST_CLASS_EXPORT_KEY(Service::FRD::FRD_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::FRD::FRD_U) From 3ed8d95866eeebc8edfe3d886b4e24f84148563d Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 27 Dec 2019 11:46:10 +0000 Subject: [PATCH 030/129] Serialize FS service; some compiler fixes --- src/core/hle/kernel/hle_ipc.h | 3 ++- src/core/hle/service/apt/apt.cpp | 11 +---------- src/core/hle/service/csnd/csnd_snd.cpp | 12 +----------- src/core/hle/service/csnd/csnd_snd.h | 1 + src/core/hle/service/dsp/dsp_dsp.cpp | 12 +----------- src/core/hle/service/fs/fs_user.cpp | 5 +++++ src/core/hle/service/fs/fs_user.h | 20 ++++++++++++++++++++ src/core/hle/service/service.h | 19 ++++++++++++++++++- src/tests/core/hle/kernel/hle_ipc.cpp | 3 +++ src/video_core/pica_state.h | 21 ++++++++++----------- 10 files changed, 62 insertions(+), 45 deletions(-) diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index da89ad39a7..162a2eb39e 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -22,7 +22,6 @@ #include "core/hle/kernel/server_session.h" BOOST_SERIALIZATION_ASSUME_ABSTRACT(Kernel::SessionRequestHandler) -BOOST_SERIALIZATION_ASSUME_ABSTRACT(Kernel::SessionRequestHandler::SessionDataBase) namespace Service { class ServiceFrameworkBase; @@ -282,3 +281,5 @@ private: }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::SessionRequestHandler::SessionDataBase) diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 8e02d2bd49..d5a7fb0018 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -27,16 +27,7 @@ #include "core/hw/aes/ccm.h" #include "core/hw/aes/key.h" -namespace boost::serialization { - template - void load_construct_data(Archive& ar, Service::APT::Module* t, const unsigned int) - { - ::new(t)Service::APT::Module(Core::Global()); - } - - template - void load_construct_data(iarchive& ar, Service::APT::Module* t, const unsigned int); -} +SERVICE_CONSTRUCT_IMPL(Service::APT::Module) namespace Service::APT { diff --git a/src/core/hle/service/csnd/csnd_snd.cpp b/src/core/hle/service/csnd/csnd_snd.cpp index d011a1c66f..1a7a009645 100644 --- a/src/core/hle/service/csnd/csnd_snd.cpp +++ b/src/core/hle/service/csnd/csnd_snd.cpp @@ -9,17 +9,7 @@ #include "core/hle/result.h" #include "core/hle/service/csnd/csnd_snd.h" -namespace boost::serialization { - template - void load_construct_data(Archive& ar, Service::CSND::CSND_SND* t, const unsigned int) - { - ::new(t)Service::CSND::CSND_SND(Core::Global()); - } - - template - void load_construct_data(iarchive& ar, Service::CSND::CSND_SND* t, const unsigned int); -} - +SERVICE_CONSTRUCT_IMPL(Service::CSND::CSND_SND) SERIALIZE_EXPORT_IMPL(Service::CSND::CSND_SND) namespace Service::CSND { diff --git a/src/core/hle/service/csnd/csnd_snd.h b/src/core/hle/service/csnd/csnd_snd.h index 0e2dd8cd81..44e4c030ca 100644 --- a/src/core/hle/service/csnd/csnd_snd.h +++ b/src/core/hle/service/csnd/csnd_snd.h @@ -260,6 +260,7 @@ private: template void serialize(Archive& ar, const unsigned int) { + ar & boost::serialization::base_object(*this); ar & mutex; ar & shared_memory; ar & capture_units; diff --git a/src/core/hle/service/dsp/dsp_dsp.cpp b/src/core/hle/service/dsp/dsp_dsp.cpp index 519d39b0c3..9b0ef89866 100644 --- a/src/core/hle/service/dsp/dsp_dsp.cpp +++ b/src/core/hle/service/dsp/dsp_dsp.cpp @@ -15,17 +15,7 @@ using DspPipe = AudioCore::DspPipe; using InterruptType = Service::DSP::DSP_DSP::InterruptType; SERIALIZE_EXPORT_IMPL(Service::DSP::DSP_DSP) - -namespace boost::serialization { - template - void load_construct_data(Archive& ar, Service::DSP::DSP_DSP* t, const unsigned int) - { - ::new(t)Service::DSP::DSP_DSP(Core::Global()); - } - - template - void load_construct_data(iarchive& ar, Service::DSP::DSP_DSP* t, const unsigned int); -} +SERVICE_CONSTRUCT_IMPL(Service::DSP::DSP_DSP) namespace AudioCore { enum class DspPipe; diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index bca8e77e53..e027e837fe 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/assert.h" #include "common/common_types.h" #include "common/file_util.h" @@ -25,6 +26,10 @@ #include "core/hle/service/fs/fs_user.h" #include "core/settings.h" +SERVICE_CONSTRUCT_IMPL(Service::FS::FS_USER) +SERIALIZE_EXPORT_IMPL(Service::FS::FS_USER) +SERIALIZE_EXPORT_IMPL(Service::FS::ClientSlot) + //////////////////////////////////////////////////////////////////////////////////////////////////// // Namespace FS_User diff --git a/src/core/hle/service/fs/fs_user.h b/src/core/hle/service/fs/fs_user.h index 97b45714b2..c001be0c54 100644 --- a/src/core/hle/service/fs/fs_user.h +++ b/src/core/hle/service/fs/fs_user.h @@ -22,6 +22,14 @@ struct ClientSlot : public Kernel::SessionRequestHandler::SessionDataBase { // behaviour is modified. Since we don't emulate fs:REG mechanism, we assume the program ID is // the same as codeset ID and fetch from there directly. u64 program_id = 0; + +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & program_id; + } + friend class boost::serialization::access; }; class FS_USER final : public ServiceFramework { @@ -545,8 +553,20 @@ private: Core::System& system; ArchiveManager& archives; + + template + void serialize(Archive& ar, const unsigned int) + { + ar & boost::serialization::base_object(*this); + ar & priority; + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::FS + +SERVICE_CONSTRUCT(Service::FS::FS_USER) +BOOST_CLASS_EXPORT_KEY(Service::FS::FS_USER) +BOOST_CLASS_EXPORT_KEY(Service::FS::ClientSlot) diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index c0c48892ad..4961678df1 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -220,4 +220,21 @@ extern const std::array service_module_map; ar & boost::serialization::base_object(*this); \ } \ friend class boost::serialization::access; \ - friend class construct_access; + friend class ::construct_access; + +#define SERVICE_CONSTRUCT(T) \ +namespace boost::serialization { \ + template \ + void load_construct_data(Archive& ar, T* t, const unsigned int); \ +} + +#define SERVICE_CONSTRUCT_IMPL(T) \ +namespace boost::serialization { \ + template \ + void load_construct_data(Archive& ar, T* t, const unsigned int) \ + { \ + ::new(t)T(Core::Global()); \ + } \ + template \ + void load_construct_data(iarchive& ar, T* t, const unsigned int); \ +} \ No newline at end of file diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index fb549f829d..e405f67290 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "core/core.h" #include "core/core_timing.h" #include "core/hle/ipc.h" @@ -14,6 +15,8 @@ #include "core/hle/kernel/process.h" #include "core/hle/kernel/server_session.h" +SERIALIZE_EXPORT_IMPL(Kernel::SessionRequestHandler::SessionDataBase) + namespace Kernel { static std::shared_ptr MakeObject(Kernel::KernelSystem& kernel) { diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 95ee776628..30cef34964 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -18,18 +18,17 @@ // Boost::serialization doesn't like union types for some reason, // so we need to mark arrays of union values with a special serialization method template -struct UnionArray : public std::array { }; - -namespace boost::serialization { - -template -void serialize(Archive& ar, UnionArray& array, const unsigned int version) +struct UnionArray : public std::array { - static_assert(sizeof(Value) == sizeof(u32)); - ar & *static_cast(static_cast(array.data())); -} - -} +private: + template + void serialize(Archive& ar, const unsigned int) + { + static_assert(sizeof(Value) == sizeof(u32)); + ar & *static_cast(static_cast(this->data())); + } + friend class boost::serialization::access; +}; namespace Pica { From 6917eaf53b0260cf9ef0d1311a59d460f6329715 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 27 Dec 2019 18:52:33 +0000 Subject: [PATCH 031/129] Use load_construct_data for kernel objects --- TODO | 5 ++-- src/audio_core/dsp_interface.h | 1 - src/common/CMakeLists.txt | 4 +++ src/common/archives.h | 12 ++++----- src/common/construct.h | 30 ++++++++++----------- src/common/serialization/atomic.h | 36 ++++++++++++------------- src/core/core.cpp | 2 +- src/core/hle/kernel/address_arbiter.cpp | 5 ++-- src/core/hle/kernel/address_arbiter.h | 3 ++- src/core/hle/kernel/client_port.cpp | 5 +++- src/core/hle/kernel/client_port.h | 4 +++ src/core/hle/kernel/client_session.cpp | 2 +- src/core/hle/kernel/client_session.h | 3 ++- src/core/hle/kernel/event.cpp | 4 +-- src/core/hle/kernel/event.h | 3 ++- src/core/hle/kernel/mutex.cpp | 5 ++-- src/core/hle/kernel/mutex.h | 3 ++- src/core/hle/kernel/object.cpp | 12 +-------- src/core/hle/kernel/object.h | 17 +++++++++--- src/core/hle/kernel/process.cpp | 20 +++++++------- src/core/hle/kernel/process.h | 11 ++++++-- src/core/hle/kernel/resource_limit.cpp | 9 +++++-- src/core/hle/kernel/resource_limit.h | 5 ++++ src/core/hle/kernel/semaphore.cpp | 4 +-- src/core/hle/kernel/semaphore.h | 3 ++- src/core/hle/kernel/server_port.cpp | 9 ++++--- src/core/hle/kernel/server_port.h | 3 +++ src/core/hle/kernel/server_session.cpp | 8 +++--- src/core/hle/kernel/server_session.h | 3 ++- src/core/hle/kernel/shared_memory.cpp | 9 ++++--- src/core/hle/kernel/shared_memory.h | 5 +++- src/core/hle/kernel/thread.cpp | 9 +++---- src/core/hle/kernel/thread.h | 3 ++- src/core/hle/kernel/timer.cpp | 9 ++++--- src/core/hle/kernel/timer.h | 5 +++- 35 files changed, 158 insertions(+), 113 deletions(-) diff --git a/TODO b/TODO index 5a483dc84e..be118365db 100644 --- a/TODO +++ b/TODO @@ -3,7 +3,7 @@ ✔ Memory @done(19-08-13 15:41) ☐ Page tables ☐ Skip N3DS RAM if unused -✔ DSP @done(19-08-13 15:41) +☐ DSP ✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) ✔ Fix or ignore inverse map @done(19-12-23 12:46) ☐ App loader @@ -16,6 +16,7 @@ ☐ Telemetry session ☐ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE ☐ Review constructor/initialization code +☐ Fix CI ✔ HW @done(19-08-13 15:41) ✔ GPU regs @done(19-08-13 15:41) ✔ LCD regs @done(19-08-13 15:41) @@ -78,7 +79,7 @@ ✔ DSP @done(19-12-26 18:10) ✔ ERR @done(19-12-26 18:14) ✔ FRD @done(19-12-26 19:09) - ☐ FS + ✔ FS @done(19-12-27 11:46) ☐ GSP ☐ HID ☐ HTTP diff --git a/src/audio_core/dsp_interface.h b/src/audio_core/dsp_interface.h index 29ec13d613..fc3d7cab2d 100644 --- a/src/audio_core/dsp_interface.h +++ b/src/audio_core/dsp_interface.h @@ -6,7 +6,6 @@ #include #include -#include "boost/serialization/array.hpp" #include "audio_core/audio_types.h" #include "audio_core/time_stretch.h" #include "common/common_types.h" diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index c0182ed480..ac745d8684 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -54,6 +54,7 @@ add_custom_command(OUTPUT scm_rev.cpp add_library(common STATIC alignment.h announce_multiplayer_room.h + archives.h assert.h detached_tasks.cpp detached_tasks.h @@ -66,6 +67,7 @@ add_library(common STATIC common_funcs.h common_paths.h common_types.h + construct.h file_util.cpp file_util.h hash.h @@ -91,8 +93,10 @@ add_library(common STATIC scm_rev.h scope_exit.h serialization/atomic.h + serialization/boost_discrete_interval.hpp serialization/boost_flat_set.h serialization/boost_vector.hpp + serialization/optional.h string_util.cpp string_util.h swap.h diff --git a/src/common/archives.h b/src/common/archives.h index a27afe80c3..74cd9e08f5 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -6,12 +6,12 @@ using iarchive = boost::archive::binary_iarchive; using oarchive = boost::archive::binary_oarchive; #define SERIALIZE_IMPL(A) template void A::serialize( \ - iarchive & ar, \ - const unsigned int file_version \ -); \ -template void A::serialize( \ - oarchive & ar, \ - const unsigned int file_version \ + iarchive & ar, \ + const unsigned int file_version \ +); \ +template void A::serialize( \ + oarchive & ar, \ + const unsigned int file_version \ ); #define SERIALIZE_EXPORT_IMPL(A) \ diff --git a/src/common/construct.h b/src/common/construct.h index 6ef9af1efe..4e230ca43b 100644 --- a/src/common/construct.h +++ b/src/common/construct.h @@ -12,20 +12,18 @@ public: } }; -#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); \ - } \ +#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/common/serialization/atomic.h b/src/common/serialization/atomic.h index ef33202ffd..665914df31 100644 --- a/src/common/serialization/atomic.h +++ b/src/common/serialization/atomic.h @@ -3,26 +3,26 @@ #include #include -namespace boost::serialization +namespace boost::serialization { + +template +void serialize(Archive& ar, std::atomic& value, const unsigned int file_version) { - template - void serialize(Archive& ar, std::atomic& value, const unsigned int file_version) - { - boost::serialization::split_free(ar, value, file_version); - } + boost::serialization::split_free(ar, value, file_version); +} - template - void save(Archive& ar, const std::atomic& value, const unsigned int file_version) - { - ar << value.load(); - } +template +void save(Archive& ar, const std::atomic& value, const unsigned int file_version) +{ + ar << value.load(); +} - template - void load(Archive& ar, std::atomic& value, const unsigned int file_version) - { - T tmp; - ar >> tmp; - value.store(tmp); - } +template +void load(Archive& ar, std::atomic& value, const unsigned int file_version) +{ + T tmp; + ar >> tmp; + value.store(tmp); +} } // namespace boost::serialization diff --git a/src/core/core.cpp b/src/core/core.cpp index 055eadae24..2df38f3ed6 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -4,7 +4,7 @@ #include #include -#include "boost/serialization/array.hpp" +#include #include "audio_core/dsp_interface.h" #include "audio_core/hle/hle.h" #include "audio_core/lle/lle.h" diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index ca120e6f9f..e5e017daaf 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -69,12 +69,11 @@ std::shared_ptr AddressArbiter::ResumeHighestPriorityThread(VAddr addres return thread; } -AddressArbiter::AddressArbiter() : kernel(Core::Global()) {} +AddressArbiter::AddressArbiter(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} AddressArbiter::~AddressArbiter() {} std::shared_ptr KernelSystem::CreateAddressArbiter(std::string name) { - auto address_arbiter{std::make_shared()}; - address_arbiter->Init(*this); + auto address_arbiter{std::make_shared(*this)}; address_arbiter->name = std::move(name); diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index 3b29a84a40..793d274ca5 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -36,7 +36,7 @@ enum class ArbitrationType : u32 { class AddressArbiter final : public Object { public: - explicit AddressArbiter(); + explicit AddressArbiter(KernelSystem& kernel); ~AddressArbiter() override; std::string GetTypeName() const override { @@ -85,3 +85,4 @@ private: } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::AddressArbiter) +CONSTRUCT_KERNEL_OBJECT(Kernel::AddressArbiter) diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index f9202035cb..618c7d0d75 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -17,6 +17,9 @@ SERIALIZE_EXPORT_IMPL(Kernel::ClientPort) namespace Kernel { +ClientPort::ClientPort(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} +ClientPort::~ClientPort() = default; + ResultVal> ClientPort::Connect() { // Note: Threads do not wait for the server endpoint to call // AcceptSession before returning from this call. @@ -27,7 +30,7 @@ ResultVal> ClientPort::Connect() { active_sessions++; // Create a new session pair, let the created sessions inherit the parent port's HLE handler. - auto [server, client] = Core::Global().CreateSessionPair(server_port->GetName(), SharedFrom(this)); + auto [server, client] = kernel.CreateSessionPair(server_port->GetName(), SharedFrom(this)); if (server_port->hle_handler) server_port->hle_handler->ClientConnected(server); diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h index 72cae85c30..c5b032f1f2 100644 --- a/src/core/hle/kernel/client_port.h +++ b/src/core/hle/kernel/client_port.h @@ -18,6 +18,8 @@ class ClientSession; class ClientPort final : public Object { public: + explicit ClientPort(KernelSystem& kernel); + ~ClientPort() override; friend class ServerPort; std::string GetTypeName() const override { @@ -51,6 +53,7 @@ public: void ConnectionClosed(); private: + KernelSystem& kernel; std::shared_ptr server_port; ///< ServerPort associated with this client port. u32 max_sessions = 0; ///< Maximum number of simultaneous sessions the port can have u32 active_sessions = 0; ///< Number of currently open sessions to this port @@ -75,3 +78,4 @@ private: } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::ClientPort) +CONSTRUCT_KERNEL_OBJECT(Kernel::ClientPort) diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp index ba9c2ec501..0b00576d34 100644 --- a/src/core/hle/kernel/client_session.cpp +++ b/src/core/hle/kernel/client_session.cpp @@ -15,7 +15,7 @@ SERIALIZE_EXPORT_IMPL(Kernel::ClientSession) namespace Kernel { -ClientSession::ClientSession() = default; +ClientSession::ClientSession(KernelSystem& kernel) : Object(kernel) {} ClientSession::~ClientSession() { // This destructor will be called automatically when the last ClientSession handle is closed by // the emulated application. diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h index 2ffe68f8b8..1ddbfb3482 100644 --- a/src/core/hle/kernel/client_session.h +++ b/src/core/hle/kernel/client_session.h @@ -20,7 +20,7 @@ class Thread; class ClientSession final : public Object { public: - explicit ClientSession(); + explicit ClientSession(KernelSystem& kernel); ~ClientSession() override; friend class KernelSystem; @@ -64,3 +64,4 @@ private: } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::ClientSession) +CONSTRUCT_KERNEL_OBJECT(Kernel::ClientSession) diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 7af667739d..2375d67337 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -15,11 +15,11 @@ SERIALIZE_EXPORT_IMPL(Kernel::Event) namespace Kernel { -Event::Event() : WaitObject() {} +Event::Event(KernelSystem& kernel) : WaitObject(kernel) {} Event::~Event() {} std::shared_ptr KernelSystem::CreateEvent(ResetType reset_type, std::string name) { - auto evt{std::make_shared()}; + auto evt{std::make_shared(*this)}; evt->signaled = false; evt->reset_type = reset_type; diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index bb97f6eb14..509ab5c6c1 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h @@ -13,7 +13,7 @@ namespace Kernel { class Event final : public WaitObject { public: - explicit Event(); + explicit Event(KernelSystem& kernel); ~Event() override; std::string GetTypeName() const override { @@ -65,3 +65,4 @@ private: } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::Event) +CONSTRUCT_KERNEL_OBJECT(Kernel::Event) diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 16bcd3af2a..4badd88ced 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -27,12 +27,11 @@ void ReleaseThreadMutexes(Thread* thread) { thread->held_mutexes.clear(); } -Mutex::Mutex() : kernel(Core::Global()) {} +Mutex::Mutex(KernelSystem& kernel) : WaitObject(kernel), kernel(kernel) {} Mutex::~Mutex() {} std::shared_ptr KernelSystem::CreateMutex(bool initial_locked, std::string name) { - auto mutex{std::make_shared()}; - mutex->Init(*this); + auto mutex{std::make_shared(*this)}; mutex->lock_count = 0; mutex->name = std::move(name); diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index f4449c0f28..a164b70da6 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -18,7 +18,7 @@ class Thread; class Mutex final : public WaitObject { public: - explicit Mutex(); + explicit Mutex(KernelSystem& kernel); ~Mutex() override; std::string GetTypeName() const override { @@ -81,3 +81,4 @@ void ReleaseThreadMutexes(Thread* thread); } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::Mutex) +CONSTRUCT_KERNEL_OBJECT(Kernel::Mutex) diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp index 6ab1b1769f..f9ca682182 100644 --- a/src/core/hle/kernel/object.cpp +++ b/src/core/hle/kernel/object.cpp @@ -8,17 +8,7 @@ namespace Kernel { -// TODO: Remove this -Object::Object(KernelSystem& kernel) -{ -} - -Object::Object() = default; - -void Object::Init(KernelSystem& kernel) -{ - object_id = kernel.GenerateObjectID(); -} +Object::Object(KernelSystem& kernel) : object_id{kernel.GenerateObjectID()} {} Object::~Object() = default; diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index 6adba034ee..a61e47c17d 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h @@ -8,9 +8,12 @@ #include #include #include +#include +#include #include "common/serialization/atomic.h" #include "common/common_types.h" #include "core/hle/kernel/kernel.h" +#include "core/global.h" namespace Kernel { @@ -43,11 +46,8 @@ enum { class Object : NonCopyable, public std::enable_shared_from_this { public: explicit Object(KernelSystem& kernel); - Object(); virtual ~Object(); - virtual void Init(KernelSystem& kernel); - /// Returns a unique identifier for the object. For debugging purposes only. u32 GetObjectId() const { return object_id.load(std::memory_order_relaxed); @@ -99,3 +99,14 @@ inline std::shared_ptr DynamicObjectCast(std::shared_ptr object) { } } // namespace Kernel + +BOOST_SERIALIZATION_ASSUME_ABSTRACT(Kernel::Object) + +#define CONSTRUCT_KERNEL_OBJECT(T) \ +namespace boost::serialization { \ +template \ +inline void load_construct_data( \ + Archive & ar, T * t, const unsigned int file_version \ +){ \ + ::new(t)T(Core::Global()); \ +}} diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 72f882c564..12afe1f897 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -20,6 +20,9 @@ #include "core/memory.h" #include "core/global.h" +SERIALIZE_EXPORT_IMPL(Kernel::Process) +SERIALIZE_EXPORT_IMPL(Kernel::CodeSet) + namespace Kernel { template @@ -46,8 +49,7 @@ void Process::serialize(Archive& ar, const unsigned int file_version) SERIALIZE_IMPL(Process) std::shared_ptr KernelSystem::CreateCodeSet(std::string name, u64 program_id) { - auto codeset{std::make_shared()}; - codeset->Init(*this); + auto codeset{std::make_shared(*this)}; codeset->name = std::move(name); codeset->program_id = program_id; @@ -55,9 +57,11 @@ std::shared_ptr KernelSystem::CreateCodeSet(std::string name, u64 progr return codeset; } +CodeSet::CodeSet(KernelSystem& kernel) : Object(kernel) {} +CodeSet::~CodeSet() {} + std::shared_ptr KernelSystem::CreateProcess(std::shared_ptr code_set) { - auto process{std::make_shared()}; - process->Init(*this); + auto process{std::make_shared(*this)}; process->codeset = std::move(code_set); process->flags.raw = 0; @@ -428,12 +432,8 @@ ResultCode Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission pe return RESULT_SUCCESS; } -Kernel::Process::Process() : Kernel::Process::Process(Core::Global()) -{ -} - -Kernel::Process::Process(KernelSystem& kernel) : kernel(kernel), handle_table(kernel), vm_manager(kernel.memory) -{ +Kernel::Process::Process(KernelSystem& kernel) + : Object(kernel), handle_table(kernel), vm_manager(kernel.memory), kernel(kernel) { kernel.memory.RegisterPageTable(&vm_manager.page_table); } Kernel::Process::~Process() { diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 70a5f212ba..5746a1c6ae 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -65,6 +65,9 @@ struct MemoryRegionInfo; class CodeSet final : public Object { public: + explicit CodeSet(KernelSystem& kernel); + ~CodeSet() override; + struct Segment { std::size_t offset = 0; VAddr addr = 0; @@ -143,8 +146,7 @@ private: class Process final : public Object { public: - Process(); - explicit Process(KernelSystem& kernel); + explicit Process(Kernel::KernelSystem& kernel); ~Process() override; std::string GetTypeName() const override { @@ -235,3 +237,8 @@ private: void serialize(Archive& ar, const unsigned int file_version); }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::CodeSet) +BOOST_CLASS_EXPORT_KEY(Kernel::Process) +CONSTRUCT_KERNEL_OBJECT(Kernel::CodeSet) +CONSTRUCT_KERNEL_OBJECT(Kernel::Process) diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp index fe19caff9d..9affa685a0 100644 --- a/src/core/hle/kernel/resource_limit.cpp +++ b/src/core/hle/kernel/resource_limit.cpp @@ -3,15 +3,20 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/assert.h" #include "common/logging/log.h" #include "core/hle/kernel/resource_limit.h" +SERIALIZE_EXPORT_IMPL(Kernel::ResourceLimit) + namespace Kernel { +ResourceLimit::ResourceLimit(KernelSystem& kernel) : Object(kernel) {} +ResourceLimit::~ResourceLimit() {} + std::shared_ptr ResourceLimit::Create(KernelSystem& kernel, std::string name) { - auto resource_limit{std::make_shared()}; - resource_limit->Init(kernel); + auto resource_limit{std::make_shared(kernel)}; resource_limit->name = std::move(name); return resource_limit; diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h index 06fe71587e..0d64f12166 100644 --- a/src/core/hle/kernel/resource_limit.h +++ b/src/core/hle/kernel/resource_limit.h @@ -35,6 +35,8 @@ enum ResourceTypes { class ResourceLimit final : public Object { public: + explicit ResourceLimit(KernelSystem& kernel); + ~ResourceLimit() override; /** * Creates a resource limit object. @@ -165,3 +167,6 @@ private: }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::ResourceLimit) +CONSTRUCT_KERNEL_OBJECT(Kernel::ResourceLimit) diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp index f60a653e55..c637f5f4d9 100644 --- a/src/core/hle/kernel/semaphore.cpp +++ b/src/core/hle/kernel/semaphore.cpp @@ -13,7 +13,7 @@ SERIALIZE_EXPORT_IMPL(Kernel::Semaphore) namespace Kernel { -Semaphore::Semaphore() : WaitObject() {} +Semaphore::Semaphore(KernelSystem& kernel) : WaitObject(kernel) {} Semaphore::~Semaphore() {} ResultVal> KernelSystem::CreateSemaphore(s32 initial_count, @@ -23,7 +23,7 @@ ResultVal> KernelSystem::CreateSemaphore(s32 initial_ if (initial_count > max_count) return ERR_INVALID_COMBINATION_KERNEL; - auto semaphore{std::make_shared()}; + auto semaphore{std::make_shared(*this)}; // When the semaphore is created, some slots are reserved for other threads, // and the rest is reserved for the caller thread diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h index ff6a4434a6..f28c30ec7d 100644 --- a/src/core/hle/kernel/semaphore.h +++ b/src/core/hle/kernel/semaphore.h @@ -16,7 +16,7 @@ namespace Kernel { class Semaphore final : public WaitObject { public: - explicit Semaphore(); + explicit Semaphore(KernelSystem& kernel); ~Semaphore() override; std::string GetTypeName() const override { @@ -60,3 +60,4 @@ private: } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::Semaphore) +CONSTRUCT_KERNEL_OBJECT(Kernel::Semaphore) diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index 0aeb86a783..46aa8f7586 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -17,6 +17,9 @@ SERIALIZE_EXPORT_IMPL(Kernel::ServerPort) namespace Kernel { +ServerPort::ServerPort(KernelSystem& kernel) : WaitObject(kernel) {} +ServerPort::~ServerPort() {} + ResultVal> ServerPort::Accept() { if (pending_sessions.empty()) { return ERR_NO_PENDING_SESSIONS; @@ -37,10 +40,8 @@ void ServerPort::Acquire(Thread* thread) { } KernelSystem::PortPair KernelSystem::CreatePortPair(u32 max_sessions, std::string name) { - auto server_port{std::make_shared()}; - server_port->Init(*this); - auto client_port{std::make_shared()}; - client_port->Init(*this); + auto server_port{std::make_shared(*this)}; + auto client_port{std::make_shared(*this)}; server_port->name = name + "_Server"; client_port->name = name + "_Client"; diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h index f055cd2672..2f00e586ea 100644 --- a/src/core/hle/kernel/server_port.h +++ b/src/core/hle/kernel/server_port.h @@ -25,6 +25,8 @@ class SessionRequestHandler; class ServerPort final : public WaitObject { public: + explicit ServerPort(KernelSystem& kernel); + ~ServerPort() override; std::string GetTypeName() const override { return "ServerPort"; @@ -73,3 +75,4 @@ private: } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::ServerPort) +CONSTRUCT_KERNEL_OBJECT(Kernel::ServerPort) diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 146142f080..e0c4087f11 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -16,7 +16,7 @@ SERIALIZE_EXPORT_IMPL(Kernel::ServerSession) namespace Kernel { -ServerSession::ServerSession() : kernel(Core::Global()) {} +ServerSession::ServerSession(KernelSystem& kernel) : WaitObject(kernel), kernel(kernel) {} ServerSession::~ServerSession() { // This destructor will be called automatically when the last ServerSession handle is closed by // the emulated application. @@ -33,8 +33,7 @@ ServerSession::~ServerSession() { ResultVal> ServerSession::Create(KernelSystem& kernel, std::string name) { - auto server_session{std::make_shared()}; - server_session->Init(kernel); + auto server_session{std::make_shared(kernel)}; server_session->name = std::move(name); server_session->parent = nullptr; @@ -127,8 +126,7 @@ ResultCode ServerSession::HandleSyncRequest(std::shared_ptr thread) { KernelSystem::SessionPair KernelSystem::CreateSessionPair(const std::string& name, std::shared_ptr port) { auto server_session = ServerSession::Create(*this, name + "_Server").Unwrap(); - auto client_session{std::make_shared()}; - client_session->Init(*this); + auto client_session{std::make_shared(*this)}; client_session->name = name + "_Client"; std::shared_ptr parent(new Session); diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 05b469c380..6eb5673f6a 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -42,7 +42,7 @@ class Thread; class ServerSession final : public WaitObject { public: ~ServerSession() override; - explicit ServerSession(); + explicit ServerSession(KernelSystem& kernel); std::string GetName() const override { return name; @@ -125,3 +125,4 @@ private: } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::ServerSession) +CONSTRUCT_KERNEL_OBJECT(Kernel::ServerSession) diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index c76cdfa19f..14c9751e8c 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/logging/log.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/memory.h" @@ -10,9 +11,11 @@ #include "core/memory.h" #include "core/global.h" +SERIALIZE_EXPORT_IMPL(Kernel::SharedMemory) + namespace Kernel { -SharedMemory::SharedMemory() : Object(Core::Global()), kernel(Core::Global()) {} +SharedMemory::SharedMemory(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} SharedMemory::~SharedMemory() { for (const auto& interval : holding_memory) { kernel.GetMemoryRegion(MemoryRegion::SYSTEM) @@ -28,7 +31,7 @@ SharedMemory::~SharedMemory() { ResultVal> KernelSystem::CreateSharedMemory( Process* owner_process, u32 size, MemoryPermission permissions, MemoryPermission other_permissions, VAddr address, MemoryRegion region, std::string name) { - auto shared_memory{std::make_shared()}; + auto shared_memory{std::make_shared(*this)}; shared_memory->owner_process = owner_process; shared_memory->name = std::move(name); @@ -73,7 +76,7 @@ ResultVal> KernelSystem::CreateSharedMemory( std::shared_ptr KernelSystem::CreateSharedMemoryForApplet( u32 offset, u32 size, MemoryPermission permissions, MemoryPermission other_permissions, std::string name) { - auto shared_memory{std::make_shared()}; + auto shared_memory{std::make_shared(*this)}; // Allocate memory in heap MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::SYSTEM); diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 925f7783cc..88727be6da 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -16,7 +16,7 @@ namespace Kernel { class SharedMemory final : public Object { public: - explicit SharedMemory(); + explicit SharedMemory(KernelSystem& kernel); ~SharedMemory() override; std::string GetTypeName() const override { @@ -123,3 +123,6 @@ private: }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::SharedMemory) +CONSTRUCT_KERNEL_OBJECT(Kernel::SharedMemory) diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 98fe851758..c824b58a61 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -66,9 +66,9 @@ u32 ThreadManager::NewThreadId() { return next_thread_id++; } -Thread::Thread() - : context(Core::Global().GetThreadManager().NewContext()), - thread_manager(Core::Global().GetThreadManager()) {} +Thread::Thread(KernelSystem& kernel) + : WaitObject(kernel), context(kernel.GetThreadManager().NewContext()), + thread_manager(kernel.GetThreadManager()) {} Thread::~Thread() {} Thread* ThreadManager::GetCurrentThread() const { @@ -338,8 +338,7 @@ ResultVal> KernelSystem::CreateThread(std::string name, ErrorSummary::InvalidArgument, ErrorLevel::Permanent); } - auto thread{std::make_shared()}; - thread->Init(*this); + auto thread{std::make_shared(*this)}; thread_manager->thread_list.push_back(thread); thread_manager->ready_queue.prepare(priority); diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index b423392e32..09341560a0 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -164,7 +164,7 @@ private: class Thread final : public WaitObject { public: - explicit Thread(); + explicit Thread(KernelSystem&); ~Thread() override; std::string GetName() const override { @@ -340,3 +340,4 @@ std::shared_ptr SetupMainThread(KernelSystem& kernel, u32 entry_point, u } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::Thread) +CONSTRUCT_KERNEL_OBJECT(Kernel::Thread) diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 422cf990cd..f1a31cdf9c 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/archives.h" #include "common/assert.h" #include "common/logging/log.h" #include "core/core.h" @@ -13,17 +14,19 @@ #include "core/hle/kernel/timer.h" #include "core/global.h" +SERIALIZE_EXPORT_IMPL(Kernel::Timer) + namespace Kernel { -Timer::Timer() : kernel(Core::Global()), timer_manager(Core::Global().GetTimerManager()) {} +Timer::Timer(KernelSystem& kernel) + : WaitObject(kernel), kernel(kernel), timer_manager(kernel.GetTimerManager()) {} Timer::~Timer() { Cancel(); timer_manager.timer_callback_table.erase(callback_id); } std::shared_ptr KernelSystem::CreateTimer(ResetType reset_type, std::string name) { - auto timer{std::make_shared()}; - timer->Init(*this); + auto timer{std::make_shared(*this)}; timer->reset_type = reset_type; timer->signaled = false; diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index 6903506112..f61ec1c116 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h @@ -46,7 +46,7 @@ private: class Timer final : public WaitObject { public: - explicit Timer(); + explicit Timer(KernelSystem& kernel); ~Timer() override; std::string GetTypeName() const override { @@ -127,3 +127,6 @@ private: }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::Timer) +CONSTRUCT_KERNEL_OBJECT(Kernel::Timer) From d482fb359c306bf4301b1aa523afc514d4ed8217 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 27 Dec 2019 20:36:17 +0000 Subject: [PATCH 032/129] Attempting to fix mingw on windows --- src/core/hle/service/apt/apt.h | 1 + src/core/hle/service/service.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index 45a93b3501..14c07feb3c 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -13,6 +13,7 @@ #include "common/common_types.h" #include "common/swap.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/service/apt/applet_manager.h" #include "core/hle/service/service.h" #include "core/global.h" diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 4961678df1..b16a4065f3 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -237,4 +237,4 @@ namespace boost::serialization { \ } \ template \ void load_construct_data(iarchive& ar, T* t, const unsigned int); \ -} \ No newline at end of file +} From 7b846ffa9891fb86ad7f236cdc76bd63d6839f11 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 27 Dec 2019 21:07:29 +0000 Subject: [PATCH 033/129] clang-format fixes --- src/common/archives.h | 19 ++-- src/common/construct.h | 36 ++++---- src/common/pod.h | 31 +++---- src/common/serialization/atomic.h | 9 +- src/common/serialization/boost_flat_set.h | 15 ++-- src/common/serialization/optional.h | 75 +++++++--------- src/common/thread_queue_list.h | 10 +-- src/common/vector_math.h | 33 ++++--- src/core/arm/arm_interface.h | 12 +-- src/core/core.cpp | 39 +++++---- src/core/core.h | 8 +- src/core/hle/kernel/address_arbiter.cpp | 2 +- src/core/hle/kernel/address_arbiter.h | 9 +- src/core/hle/kernel/client_port.cpp | 2 +- src/core/hle/kernel/client_port.h | 14 ++- src/core/hle/kernel/client_session.cpp | 2 +- src/core/hle/kernel/client_session.h | 9 +- src/core/hle/kernel/config_mem.h | 5 +- src/core/hle/kernel/event.cpp | 2 +- src/core/hle/kernel/event.h | 11 ++- src/core/hle/kernel/handle_table.h | 11 ++- src/core/hle/kernel/hle_ipc.h | 21 +++-- src/core/hle/kernel/ipc.h | 18 ++-- src/core/hle/kernel/kernel.cpp | 25 +++--- src/core/hle/kernel/memory.h | 13 ++- src/core/hle/kernel/mutex.cpp | 2 +- src/core/hle/kernel/mutex.h | 13 ++- src/core/hle/kernel/object.h | 24 +++-- src/core/hle/kernel/process.cpp | 39 +++++---- src/core/hle/kernel/process.h | 35 ++++---- src/core/hle/kernel/resource_limit.h | 53 ++++++------ src/core/hle/kernel/semaphore.cpp | 2 +- src/core/hle/kernel/semaphore.h | 13 ++- src/core/hle/kernel/server_port.cpp | 13 ++- src/core/hle/kernel/server_session.cpp | 2 +- src/core/hle/kernel/server_session.h | 17 ++-- src/core/hle/kernel/session.cpp | 15 ++-- src/core/hle/kernel/shared_memory.cpp | 2 +- src/core/hle/kernel/shared_memory.h | 19 ++-- src/core/hle/kernel/shared_page.h | 5 +- src/core/hle/kernel/thread.cpp | 37 ++++---- src/core/hle/kernel/thread.h | 15 ++-- src/core/hle/kernel/timer.cpp | 2 +- src/core/hle/kernel/timer.h | 22 +++-- src/core/hle/kernel/vm_manager.h | 35 ++++---- src/core/hle/kernel/wait_object.h | 7 +- src/core/hle/service/ac/ac.cpp | 13 ++- src/core/hle/service/ac/ac_i.cpp | 2 +- src/core/hle/service/ac/ac_u.cpp | 2 +- src/core/hle/service/act/act.h | 3 +- src/core/hle/service/act/act_a.cpp | 2 +- src/core/hle/service/act/act_a.h | 1 + src/core/hle/service/act/act_u.cpp | 2 +- src/core/hle/service/act/act_u.h | 1 + src/core/hle/service/am/am.cpp | 2 +- src/core/hle/service/am/am.h | 22 +++-- src/core/hle/service/am/am_app.cpp | 2 +- src/core/hle/service/am/am_app.h | 1 + src/core/hle/service/am/am_net.cpp | 2 +- src/core/hle/service/am/am_net.h | 1 + src/core/hle/service/am/am_sys.cpp | 2 +- src/core/hle/service/am/am_sys.h | 1 + src/core/hle/service/am/am_u.cpp | 2 +- src/core/hle/service/am/am_u.h | 1 + src/core/hle/service/apt/applet_manager.h | 65 +++++++------- src/core/hle/service/apt/apt.cpp | 23 +++-- src/core/hle/service/apt/apt.h | 14 ++- src/core/hle/service/apt/apt_a.cpp | 2 +- src/core/hle/service/apt/apt_a.h | 1 + src/core/hle/service/apt/apt_s.cpp | 2 +- src/core/hle/service/apt/apt_s.h | 1 + src/core/hle/service/apt/apt_u.cpp | 2 +- src/core/hle/service/apt/apt_u.h | 1 + src/core/hle/service/apt/ns_s.cpp | 2 +- src/core/hle/service/apt/ns_s.h | 1 + src/core/hle/service/boss/boss.h | 27 +++--- src/core/hle/service/boss/boss_p.cpp | 2 +- src/core/hle/service/boss/boss_u.cpp | 2 +- src/core/hle/service/cam/cam.cpp | 9 +- src/core/hle/service/cam/cam.h | 87 +++++++++---------- src/core/hle/service/cam/cam_c.cpp | 2 +- src/core/hle/service/cam/cam_q.cpp | 2 +- src/core/hle/service/cam/cam_q.h | 6 +- src/core/hle/service/cam/cam_s.cpp | 2 +- src/core/hle/service/cam/cam_u.cpp | 2 +- src/core/hle/service/csnd/csnd_snd.h | 69 +++++++-------- src/core/hle/service/dlp/dlp_clnt.cpp | 2 +- src/core/hle/service/dlp/dlp_clnt.h | 6 +- src/core/hle/service/dlp/dlp_fkcl.cpp | 2 +- src/core/hle/service/dlp/dlp_fkcl.h | 6 +- src/core/hle/service/dlp/dlp_srvr.cpp | 2 +- src/core/hle/service/dlp/dlp_srvr.h | 5 +- src/core/hle/service/dsp/dsp_dsp.h | 19 ++-- src/core/hle/service/err_f.cpp | 15 ++-- src/core/hle/service/err_f.h | 9 +- src/core/hle/service/frd/frd.h | 21 ++--- src/core/hle/service/frd/frd_a.cpp | 2 +- src/core/hle/service/frd/frd_a.h | 1 + src/core/hle/service/frd/frd_u.cpp | 2 +- src/core/hle/service/frd/frd_u.h | 1 + src/core/hle/service/fs/archive.cpp | 2 +- src/core/hle/service/fs/fs_user.h | 12 ++- src/core/hle/service/service.h | 69 +++++++-------- src/core/hle/service/sm/sm.h | 8 +- src/core/memory.cpp | 37 ++++---- src/core/memory.h | 15 ++-- src/core/mmio.h | 4 +- src/tests/core/hle/kernel/hle_ipc.cpp | 6 +- src/video_core/command_processor.cpp | 3 +- src/video_core/geometry_pipeline.cpp | 57 +++++------- src/video_core/pica.cpp | 8 +- src/video_core/pica_state.h | 101 ++++++++++------------ src/video_core/pica_types.h | 7 +- src/video_core/primitive_assembly.h | 17 ++-- src/video_core/shader/shader.h | 77 ++++++++--------- src/video_core/video_core.cpp | 11 +-- src/video_core/video_core.h | 6 +- 117 files changed, 797 insertions(+), 925 deletions(-) diff --git a/src/common/archives.h b/src/common/archives.h index 74cd9e08f5..29f23865bb 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -5,16 +5,11 @@ using iarchive = boost::archive::binary_iarchive; using oarchive = boost::archive::binary_oarchive; -#define SERIALIZE_IMPL(A) template void A::serialize( \ - iarchive & ar, \ - const unsigned int file_version \ -); \ -template void A::serialize( \ - oarchive & ar, \ - const unsigned int file_version \ -); +#define SERIALIZE_IMPL(A) \ + template void A::serialize(iarchive & ar, const unsigned int file_version); \ + template void A::serialize(oarchive & ar, const unsigned int file_version); -#define SERIALIZE_EXPORT_IMPL(A) \ -BOOST_SERIALIZATION_REGISTER_ARCHIVE(iarchive) \ -BOOST_SERIALIZATION_REGISTER_ARCHIVE(oarchive) \ -BOOST_CLASS_EXPORT_IMPLEMENT(A) +#define SERIALIZE_EXPORT_IMPL(A) \ + BOOST_SERIALIZATION_REGISTER_ARCHIVE(iarchive) \ + BOOST_SERIALIZATION_REGISTER_ARCHIVE(oarchive) \ + BOOST_CLASS_EXPORT_IMPLEMENT(A) diff --git a/src/common/construct.h b/src/common/construct.h index 4e230ca43b..6b2b3ceebd 100644 --- a/src/common/construct.h +++ b/src/common/construct.h @@ -2,28 +2,26 @@ class construct_access { public: - template - static inline void save_construct(Archive & ar, const T * t, const unsigned int file_version) { + 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) { + 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); \ -} \ -}} +#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/common/pod.h b/src/common/pod.h index e7224644a3..bb70954177 100644 --- a/src/common/pod.h +++ b/src/common/pod.h @@ -1,20 +1,17 @@ #include "boost/serialization/split_member.hpp" -#define SERIALIZE_AS_POD \ - private: \ - friend class boost::serialization::access; \ - template \ - void save(Archive & ar, const unsigned int file_version) const { \ - ar.save_binary(this, sizeof(*this)); \ - } \ - template \ - void load(Archive & ar, const unsigned int file_version) { \ - ar.load_binary(this, sizeof(*this)); \ - } \ - template \ - void serialize( \ - Archive &ar, \ - const unsigned int file_version \ - ){ \ - boost::serialization::split_member(ar, *this, file_version); \ +#define SERIALIZE_AS_POD \ +private: \ + friend class boost::serialization::access; \ + template \ + void save(Archive& ar, const unsigned int file_version) const { \ + ar.save_binary(this, sizeof(*this)); \ + } \ + template \ + void load(Archive& ar, const unsigned int file_version) { \ + ar.load_binary(this, sizeof(*this)); \ + } \ + template \ + void serialize(Archive& ar, const unsigned int file_version) { \ + boost::serialization::split_member(ar, *this, file_version); \ } diff --git a/src/common/serialization/atomic.h b/src/common/serialization/atomic.h index 665914df31..dbc4c0dece 100644 --- a/src/common/serialization/atomic.h +++ b/src/common/serialization/atomic.h @@ -6,20 +6,17 @@ namespace boost::serialization { template -void serialize(Archive& ar, std::atomic& value, const unsigned int file_version) -{ +void serialize(Archive& ar, std::atomic& value, const unsigned int file_version) { boost::serialization::split_free(ar, value, file_version); } template -void save(Archive& ar, const std::atomic& value, const unsigned int file_version) -{ +void save(Archive& ar, const std::atomic& value, const unsigned int file_version) { ar << value.load(); } template -void load(Archive& ar, std::atomic& value, const unsigned int file_version) -{ +void load(Archive& ar, std::atomic& value, const unsigned int file_version) { T tmp; ar >> tmp; value.store(tmp); diff --git a/src/common/serialization/boost_flat_set.h b/src/common/serialization/boost_flat_set.h index 9a0ae77b0f..7fe0fe0977 100644 --- a/src/common/serialization/boost_flat_set.h +++ b/src/common/serialization/boost_flat_set.h @@ -1,23 +1,21 @@ #pragma once -#include "common/common_types.h" #include #include +#include "common/common_types.h" namespace boost::serialization { template -void save(Archive& ar, const boost::container::flat_set& set, const unsigned int file_version) -{ +void save(Archive& ar, const boost::container::flat_set& set, const unsigned int file_version) { ar << static_cast(set.size()); - for (auto &v : set) { + for (auto& v : set) { ar << v; } } template -void load(Archive& ar, boost::container::flat_set& set, const unsigned int file_version) -{ +void load(Archive& ar, boost::container::flat_set& set, const unsigned int file_version) { u64 count{}; ar >> count; set.clear(); @@ -29,9 +27,8 @@ void load(Archive& ar, boost::container::flat_set& set, const unsigned int fi } template -void serialize(Archive& ar, boost::container::flat_set& set, const unsigned int file_version) -{ +void serialize(Archive& ar, boost::container::flat_set& set, const unsigned int file_version) { boost::serialization::split_free(ar, set, file_version); } -} +} // namespace boost::serialization diff --git a/src/common/serialization/optional.h b/src/common/serialization/optional.h index 5ab6af9b81..4e794058ed 100644 --- a/src/common/serialization/optional.h +++ b/src/common/serialization/optional.h @@ -7,85 +7,70 @@ #include #include +#include +#include +#include #include -#include #include #include +#include #include #include -#include -#include -#include // function specializations must be defined in the appropriate // namespace - boost::serialization namespace boost { namespace serialization { -template -void save( - Archive & ar, - const std::optional< T > & t, - const unsigned int /*version*/ -){ - // It is an inherent limitation to the serialization of optional.hpp - // that the underlying type must be either a pointer or must have a - // default constructor. It's possible that this could change sometime - // in the future, but for now, one will have to work around it. This can - // be done by serialization the optional as optional - #if ! defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) - BOOST_STATIC_ASSERT( - boost::serialization::detail::is_default_constructible::value - || boost::is_pointer::value - ); - #endif +template +void save(Archive& ar, const std::optional& t, const unsigned int /*version*/ +) { +// It is an inherent limitation to the serialization of optional.hpp +// that the underlying type must be either a pointer or must have a +// default constructor. It's possible that this could change sometime +// in the future, but for now, one will have to work around it. This can +// be done by serialization the optional as optional +#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) + BOOST_STATIC_ASSERT(boost::serialization::detail::is_default_constructible::value || + boost::is_pointer::value); +#endif const bool tflag = t.has_value(); ar << boost::serialization::make_nvp("initialized", tflag); - if (tflag){ + if (tflag) { ar << boost::serialization::make_nvp("value", *t); } } -template -void load( - Archive & ar, - std::optional< T > & t, - const unsigned int version -){ +template +void load(Archive& ar, std::optional& t, const unsigned int version) { bool tflag; ar >> boost::serialization::make_nvp("initialized", tflag); - if(! tflag){ + if (!tflag) { t.reset(); return; } - if(0 == version){ + if (0 == version) { boost::serialization::item_version_type item_version(0); - boost::archive::library_version_type library_version( - ar.get_library_version() - ); - if(boost::archive::library_version_type(3) < library_version){ + boost::archive::library_version_type library_version(ar.get_library_version()); + if (boost::archive::library_version_type(3) < library_version) { ar >> BOOST_SERIALIZATION_NVP(item_version); } } - if(! t.has_value()) + if (!t.has_value()) t = T(); ar >> boost::serialization::make_nvp("value", *t); } -template -void serialize( - Archive & ar, - std::optional< T > & t, - const unsigned int version -){ +template +void serialize(Archive& ar, std::optional& t, const unsigned int version) { boost::serialization::split_free(ar, t, version); } -template -struct version > { +template +struct version> { BOOST_STATIC_CONSTANT(int, value = 1); }; -} // serialization -} // boost +} // namespace serialization +} // namespace boost diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h index ce57c01e9e..093d867817 100644 --- a/src/common/thread_queue_list.h +++ b/src/common/thread_queue_list.h @@ -162,20 +162,20 @@ private: friend class boost::serialization::access; template - void save(Archive& ar, const unsigned int file_version) const - { + void save(Archive& ar, const unsigned int file_version) const { s32 idx = first == UnlinkedTag() ? -1 : static_cast(first - &queues[0]); ar << idx; for (auto i = 0; i < NUM_QUEUES; i++) { - s32 idx1 = first == UnlinkedTag() ? -1 : static_cast(queues[i].next_nonempty - &queues[0]); + s32 idx1 = first == UnlinkedTag() + ? -1 + : static_cast(queues[i].next_nonempty - &queues[0]); ar << idx1; ar << queues[i].data; } } template - void load(Archive& ar, const unsigned int file_version) - { + void load(Archive& ar, const unsigned int file_version) { s32 idx; ar >> idx; first = idx < 0 ? UnlinkedTag() : &queues[idx]; diff --git a/src/common/vector_math.h b/src/common/vector_math.h index 171d4ebfd4..ba7bd1aa79 100644 --- a/src/common/vector_math.h +++ b/src/common/vector_math.h @@ -46,11 +46,10 @@ class Vec4; template class Vec2 { friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & x; - ar & y; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& x; + ar& y; } public: @@ -201,12 +200,11 @@ inline float Vec2::Normalize() { template class Vec3 { friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & x; - ar & y; - ar & z; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& x; + ar& y; + ar& z; } public: @@ -418,13 +416,12 @@ using Vec3f = Vec3; template class Vec4 { friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & x; - ar & y; - ar & z; - ar & w; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& x; + ar& y; + ar& z; + ar& w; } public: diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 483ba43717..be30499d1a 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -20,8 +20,7 @@ public: friend class boost::serialization::access; template - void save(Archive& ar, const unsigned int file_version) const - { + void save(Archive& ar, const unsigned int file_version) const { for (auto i = 0; i < 16; i++) { auto r = GetCpuRegister(i); ar << r; @@ -39,8 +38,7 @@ public: } template - void load(Archive& ar, const unsigned int file_version) - { + void load(Archive& ar, const unsigned int file_version) { u32 r; for (auto i = 0; i < 16; i++) { ar >> r; @@ -220,8 +218,7 @@ private: friend class boost::serialization::access; template - void save(Archive& ar, const unsigned int file_version) const - { + void save(Archive& ar, const unsigned int file_version) const { for (auto i = 0; i < 15; i++) { auto r = GetReg(i); ar << r; @@ -245,8 +242,7 @@ private: } template - void load(Archive& ar, const unsigned int file_version) - { + void load(Archive& ar, const unsigned int file_version) { u32 r; for (auto i = 0; i < 15; i++) { ar >> r; diff --git a/src/core/core.cpp b/src/core/core.cpp index 2df38f3ed6..6812a9474e 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -48,10 +48,14 @@ namespace Core { /*static*/ System System::s_instance; template <> -Core::System& Global() { return System::GetInstance(); } +Core::System& Global() { + return System::GetInstance(); +} template <> -Kernel::KernelSystem& Global() { return System::GetInstance().Kernel(); } +Kernel::KernelSystem& Global() { + return System::GetInstance().Kernel(); +} System::ResultStatus System::RunLoop(bool tight_loop) { status = ResultStatus::Success; @@ -209,8 +213,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo timing = std::make_unique(); - kernel = std::make_unique(*memory, *timing, - [this] { PrepareReschedule(); }, system_mode); + kernel = std::make_unique( + *memory, *timing, [this] { PrepareReschedule(); }, system_mode); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 @@ -400,32 +404,29 @@ void System::Reset() { Load(*m_emu_window, m_filepath); } -template -void System::serialize(Archive & ar, const unsigned int file_version) -{ - ar & *cpu_core.get(); - ar & *service_manager.get(); - ar & GPU::g_regs; - ar & LCD::g_regs; +template +void System::serialize(Archive& ar, const unsigned int file_version) { + ar&* cpu_core.get(); + ar&* service_manager.get(); + ar& GPU::g_regs; + ar& LCD::g_regs; ar & dsp_core->GetDspMemory(); - ar & *memory.get(); - ar & *kernel.get(); + ar&* memory.get(); + ar&* kernel.get(); } -void System::Save(std::ostream &stream) const -{ +void System::Save(std::ostream& stream) const { { oarchive oa{stream}; - oa & *this; + oa&* this; } VideoCore::Save(stream); } -void System::Load(std::istream &stream) -{ +void System::Load(std::istream& stream) { { iarchive ia{stream}; - ia & *this; + ia&* this; } VideoCore::Load(stream); } diff --git a/src/core/core.h b/src/core/core.h index 8bf04d3656..75e0e1a545 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -272,9 +272,9 @@ public: return registered_image_interface; } - void Save(std::ostream &stream) const; + void Save(std::ostream& stream) const; - void Load(std::istream &stream); + void Load(std::istream& stream); private: /** @@ -345,8 +345,8 @@ private: std::atomic shutdown_requested; friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version); + template + void serialize(Archive& ar, const unsigned int file_version); }; inline ARM_Interface& CPU() { diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index e5e017daaf..7b8329c4d4 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -6,12 +6,12 @@ #include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" +#include "core/global.h" #include "core/hle/kernel/address_arbiter.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/thread.h" #include "core/memory.h" -#include "core/global.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // Kernel namespace diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index 793d274ca5..19b80315f8 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -74,11 +74,10 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & name; - ar & waiting_threads; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& name; + ar& waiting_threads; } }; diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index 618c7d0d75..e7e8a80140 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -4,6 +4,7 @@ #include "common/archives.h" #include "common/assert.h" +#include "core/global.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/errors.h" @@ -11,7 +12,6 @@ #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_port.h" #include "core/hle/kernel/server_session.h" -#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::ClientPort) diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h index c5b032f1f2..1d0f5c0249 100644 --- a/src/core/hle/kernel/client_port.h +++ b/src/core/hle/kernel/client_port.h @@ -61,17 +61,15 @@ private: friend class KernelSystem; - private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & server_port; - ar & max_sessions; - ar & active_sessions; - ar & name; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& server_port; + ar& max_sessions; + ar& active_sessions; + ar& name; } }; diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp index 0b00576d34..a47e6411b1 100644 --- a/src/core/hle/kernel/client_session.cpp +++ b/src/core/hle/kernel/client_session.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/assert.h" #include "common/archives.h" +#include "common/assert.h" #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/hle_ipc.h" diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h index 1ddbfb3482..38f39c2991 100644 --- a/src/core/hle/kernel/client_session.h +++ b/src/core/hle/kernel/client_session.h @@ -53,11 +53,10 @@ public: private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & name; - ar & parent; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& name; + ar& parent; } }; diff --git a/src/core/hle/kernel/config_mem.h b/src/core/hle/kernel/config_mem.h index 26fc0bccbb..e4e8955165 100644 --- a/src/core/hle/kernel/config_mem.h +++ b/src/core/hle/kernel/config_mem.h @@ -60,10 +60,9 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { + void serialize(Archive& ar, const unsigned int file_version) { auto o_config_mem = boost::serialization::binary_object(&config_mem, sizeof(config_mem)); - ar & o_config_mem; + ar& o_config_mem; } }; diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 2375d67337..9f26847b03 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -5,8 +5,8 @@ #include #include #include -#include "common/assert.h" #include "common/archives.h" +#include "common/assert.h" #include "core/hle/kernel/event.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/thread.h" diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index 509ab5c6c1..892718533b 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h @@ -53,12 +53,11 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & reset_type; - ar & signaled; - ar & name; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& reset_type; + ar& signaled; + ar& name; } }; diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h index eabf06c26a..728ab5fa31 100644 --- a/src/core/hle/kernel/handle_table.h +++ b/src/core/hle/kernel/handle_table.h @@ -121,12 +121,11 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & objects; - ar & generations; - ar & next_generation; - ar & next_free_slot; + void serialize(Archive& ar, const unsigned int file_version) { + ar& objects; + ar& generations; + ar& next_generation; + ar& next_free_slot; } }; diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 162a2eb39e..2177b733ea 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -11,10 +11,10 @@ #include #include #include -#include -#include -#include #include +#include +#include +#include #include "common/common_types.h" #include "common/swap.h" #include "core/hle/ipc.h" @@ -74,9 +74,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) { } + void serialize(Archive& ar, const unsigned int file_version) {} friend class boost::serialization::access; }; @@ -104,10 +105,9 @@ protected: private: template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & session; - ar & data; + void serialize(Archive& ar, const unsigned int file_version) { + ar& session; + ar& data; } friend class boost::serialization::access; }; @@ -117,9 +117,8 @@ protected: private: template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & connected_sessions; + void serialize(Archive& ar, const unsigned int file_version) { + ar& connected_sessions; } friend class boost::serialization::access; }; diff --git a/src/core/hle/kernel/ipc.h b/src/core/hle/kernel/ipc.h index 46d86a5282..2c69617d4e 100644 --- a/src/core/hle/kernel/ipc.h +++ b/src/core/hle/kernel/ipc.h @@ -30,15 +30,15 @@ struct MappedBufferContext { private: template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & permissions; - ar & size; - ar & source_address; - ar & target_address; - // TODO: Check whether we need these. If we do, add a field for the size and/or change to a 'vector' - //ar & buffer; - //ar & reserve_buffer; + void serialize(Archive& ar, const unsigned int file_version) { + ar& permissions; + ar& size; + ar& source_address; + ar& target_address; + // TODO: Check whether we need these. If we do, add a field for the size and/or change to a + // 'vector' + // ar & buffer; + // ar & reserve_buffer; } friend class boost::serialization::access; }; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index a459739687..7edef25055 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -104,20 +104,19 @@ void KernelSystem::AddNamedPort(std::string name, std::shared_ptr po } template -void KernelSystem::serialize(Archive& ar, const unsigned int file_version) -{ - ar & memory_regions; - ar & named_ports; - ar & *current_cpu.get(); +void KernelSystem::serialize(Archive& ar, const unsigned int file_version) { + ar& memory_regions; + ar& named_ports; + ar&* current_cpu.get(); // NB: subsystem references and prepare_reschedule_callback are constant - ar & *resource_limits.get(); - ar & next_object_id; - ar & *timer_manager.get(); - ar & next_process_id; - ar & process_list; - ar & current_process; - ar & *thread_manager.get(); - ar & *config_mem_handler.get(); + ar&* resource_limits.get(); + ar& next_object_id; + ar&* timer_manager.get(); + ar& next_process_id; + ar& process_list; + ar& current_process; + ar&* thread_manager.get(); + ar&* config_mem_handler.get(); // Shared page data is read-only at the moment, so doesn't need serializing // Deliberately don't include debugger info to allow debugging through loads } diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h index ed4ea12965..f4b0a6d98e 100644 --- a/src/core/hle/kernel/memory.h +++ b/src/core/hle/kernel/memory.h @@ -7,8 +7,8 @@ #include #include #include -#include "common/serialization/boost_discrete_interval.hpp" #include "common/common_types.h" +#include "common/serialization/boost_discrete_interval.hpp" namespace Kernel { @@ -66,13 +66,12 @@ struct MemoryRegionInfo { private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & base; - ar & size; - ar & used; + void serialize(Archive& ar, const unsigned int file_version) { + ar& base; + ar& size; + ar& used; // This works because interval_set has exactly one member of type ImplSetT - ar & *(reinterpret_cast(&free_blocks)); + ar&*(reinterpret_cast(&free_blocks)); } }; diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 4badd88ced..6aff802243 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -7,12 +7,12 @@ #include "common/archives.h" #include "common/assert.h" #include "core/core.h" +#include "core/global.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/mutex.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/thread.h" -#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::Mutex) diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index a164b70da6..4adf674c33 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -62,13 +62,12 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & lock_count; - ar & priority; - ar & name; - ar & holding_thread; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& lock_count; + ar& priority; + ar& name; + ar& holding_thread; } }; diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index a61e47c17d..57b208dc14 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h @@ -10,10 +10,10 @@ #include #include #include -#include "common/serialization/atomic.h" #include "common/common_types.h" -#include "core/hle/kernel/kernel.h" +#include "common/serialization/atomic.h" #include "core/global.h" +#include "core/hle/kernel/kernel.h" namespace Kernel { @@ -72,9 +72,8 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & object_id; + void serialize(Archive& ar, const unsigned int file_version) { + ar& object_id; } }; @@ -102,11 +101,10 @@ inline std::shared_ptr DynamicObjectCast(std::shared_ptr object) { BOOST_SERIALIZATION_ASSUME_ABSTRACT(Kernel::Object) -#define CONSTRUCT_KERNEL_OBJECT(T) \ -namespace boost::serialization { \ -template \ -inline void load_construct_data( \ - Archive & ar, T * t, const unsigned int file_version \ -){ \ - ::new(t)T(Core::Global()); \ -}} +#define CONSTRUCT_KERNEL_OBJECT(T) \ + namespace boost::serialization { \ + template \ + inline void load_construct_data(Archive& ar, T* t, const unsigned int file_version) { \ + ::new (t) T(Core::Global()); \ + } \ + } diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 12afe1f897..78b695e978 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -11,6 +11,7 @@ #include "common/common_funcs.h" #include "common/logging/log.h" #include "common/serialization/boost_vector.hpp" +#include "core/global.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/memory.h" #include "core/hle/kernel/process.h" @@ -18,7 +19,6 @@ #include "core/hle/kernel/thread.h" #include "core/hle/kernel/vm_manager.h" #include "core/memory.h" -#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::Process) SERIALIZE_EXPORT_IMPL(Kernel::CodeSet) @@ -26,24 +26,25 @@ SERIALIZE_EXPORT_IMPL(Kernel::CodeSet) namespace Kernel { template -void Process::serialize(Archive& ar, const unsigned int file_version) -{ - ar & boost::serialization::base_object(*this); - ar & handle_table; - ar & codeset; - ar & resource_limit; - ar & svc_access_mask; - ar & handle_table_size; - ar & (boost::container::vector >&)address_mappings; - ar & flags.raw; - ar & kernel_version; - ar & ideal_processor; - ar & status; - ar & process_id; - ar & vm_manager; - ar & memory_used; - ar & memory_region; - ar & tls_slots; +void Process::serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& handle_table; + ar& codeset; + ar& resource_limit; + ar& svc_access_mask; + ar& handle_table_size; + ar&(boost::container::vector< + AddressMapping, boost::container::dtl::static_storage_allocator>&) + address_mappings; + ar& flags.raw; + ar& kernel_version; + ar& ideal_processor; + ar& status; + ar& process_id; + ar& vm_manager; + ar& memory_used; + ar& memory_region; + ar& tls_slots; } SERIALIZE_IMPL(Process) diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 5746a1c6ae..f9aa76c67a 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -11,8 +11,8 @@ #include #include #include -#include #include +#include #include "common/bit_field.h" #include "common/common_types.h" #include "core/hle/kernel/handle_table.h" @@ -31,12 +31,11 @@ struct AddressMapping { private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & address; - ar & size; - ar & read_only; - ar & unk_flag; + void serialize(Archive& ar, const unsigned int file_version) { + ar& address; + ar& size; + ar& read_only; + ar& unk_flag; } }; @@ -76,11 +75,10 @@ public: private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & offset; - ar & addr; - ar & size; + void serialize(Archive& ar, const unsigned int file_version) { + ar& offset; + ar& addr; + ar& size; } }; @@ -133,14 +131,13 @@ public: private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); // TODO: memory reference - ar & segments; - ar & entrypoint; - ar & name; - ar & program_id; + ar& segments; + ar& entrypoint; + ar& name; + ar& program_id; } }; diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h index 0d64f12166..8593a03a34 100644 --- a/src/core/hle/kernel/resource_limit.h +++ b/src/core/hle/kernel/resource_limit.h @@ -116,30 +116,30 @@ public: private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - // NB most of these aren't used at all currently, but we're adding them here for forwards compatibility - ar & name; - ar & max_priority; - ar & max_commit; - ar & max_threads; - ar & max_events; - ar & max_mutexes; - ar & max_semaphores; - ar & max_timers; - ar & max_shared_mems; - ar & max_address_arbiters; - ar & max_cpu_time; - ar & current_commit; - ar & current_threads; - ar & current_events; - ar & current_mutexes; - ar & current_semaphores; - ar & current_timers; - ar & current_shared_mems; - ar & current_address_arbiters; - ar & current_cpu_time; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + // NB most of these aren't used at all currently, but we're adding them here for forwards + // compatibility + ar& name; + ar& max_priority; + ar& max_commit; + ar& max_threads; + ar& max_events; + ar& max_mutexes; + ar& max_semaphores; + ar& max_timers; + ar& max_shared_mems; + ar& max_address_arbiters; + ar& max_cpu_time; + ar& current_commit; + ar& current_threads; + ar& current_events; + ar& current_mutexes; + ar& current_semaphores; + ar& current_timers; + ar& current_shared_mems; + ar& current_address_arbiters; + ar& current_cpu_time; } }; @@ -160,9 +160,8 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & resource_limits; + void serialize(Archive& ar, const unsigned int file_version) { + ar& resource_limits; } }; diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp index c637f5f4d9..7aefc86054 100644 --- a/src/core/hle/kernel/semaphore.cpp +++ b/src/core/hle/kernel/semaphore.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/assert.h" #include "common/archives.h" +#include "common/assert.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/semaphore.h" diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h index f28c30ec7d..a7ab192a6c 100644 --- a/src/core/hle/kernel/semaphore.h +++ b/src/core/hle/kernel/semaphore.h @@ -5,8 +5,8 @@ #pragma once #include -#include #include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/wait_object.h" @@ -48,12 +48,11 @@ public: private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & max_count; - ar & available_count; - ar & name; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& max_count; + ar& available_count; + ar& name; } }; diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index 46aa8f7586..0771502225 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -7,11 +7,11 @@ #include "common/assert.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/errors.h" +#include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_port.h" #include "core/hle/kernel/server_session.h" #include "core/hle/kernel/thread.h" -#include "core/hle/kernel/hle_ipc.h" SERIALIZE_EXPORT_IMPL(Kernel::ServerPort) @@ -53,12 +53,11 @@ KernelSystem::PortPair KernelSystem::CreatePortPair(u32 max_sessions, std::strin } template -void ServerPort::serialize(Archive& ar, const unsigned int file_version) -{ - ar & boost::serialization::base_object(*this); - ar & name; - ar & pending_sessions; - ar & hle_handler; +void ServerPort::serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& name; + ar& pending_sessions; + ar& hle_handler; } SERIALIZE_IMPL(ServerPort) diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index e0c4087f11..4b393b63d9 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -4,13 +4,13 @@ #include #include "common/archives.h" +#include "core/global.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/server_session.h" #include "core/hle/kernel/session.h" #include "core/hle/kernel/thread.h" -#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::ServerSession) diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 6eb5673f6a..331ac83971 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -110,15 +110,14 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & name; - ar & parent; - ar & hle_handler; - ar & pending_requesting_threads; - ar & currently_handling; - ar & mapped_buffer_context; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& name; + ar& parent; + ar& hle_handler; + ar& pending_requesting_threads; + ar& currently_handling; + ar& mapped_buffer_context; } }; diff --git a/src/core/hle/kernel/session.cpp b/src/core/hle/kernel/session.cpp index a2a1f90f9b..1ec1039dcc 100644 --- a/src/core/hle/kernel/session.cpp +++ b/src/core/hle/kernel/session.cpp @@ -4,22 +4,21 @@ #include #include "common/archives.h" -#include "core/hle/kernel/session.h" -#include "core/hle/kernel/client_session.h" -#include "core/hle/kernel/server_session.h" #include "core/hle/kernel/client_port.h" +#include "core/hle/kernel/client_session.h" #include "core/hle/kernel/hle_ipc.h" +#include "core/hle/kernel/server_session.h" +#include "core/hle/kernel/session.h" SERIALIZE_IMPL(Kernel::Session) namespace Kernel { template -void Session::serialize(Archive& ar, const unsigned int file_version) -{ - ar & client; - ar & server; - ar & port; +void Session::serialize(Archive& ar, const unsigned int file_version) { + ar& client; + ar& server; + ar& port; } } // namespace Kernel diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 14c9751e8c..55c374dc56 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -5,11 +5,11 @@ #include #include "common/archives.h" #include "common/logging/log.h" +#include "core/global.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/memory.h" #include "core/hle/kernel/shared_memory.h" #include "core/memory.h" -#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::SharedMemory) diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 88727be6da..f2fa1a7286 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -107,17 +107,16 @@ private: KernelSystem& kernel; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & linear_heap_phys_offset; + void serialize(Archive& ar, const unsigned int file_version) { + ar& linear_heap_phys_offset; // TODO: backing blocks u8* (this is always FCRAM I think) - ar & size; - ar & permissions; - ar & other_permissions; - ar & owner_process; - ar & base_address; - ar & name; - ar & *(reinterpret_cast(&holding_memory)); + ar& size; + ar& permissions; + ar& other_permissions; + ar& owner_process; + ar& base_address; + ar& name; + ar&*(reinterpret_cast(&holding_memory)); } friend class boost::serialization::access; }; diff --git a/src/core/hle/kernel/shared_page.h b/src/core/hle/kernel/shared_page.h index 58cd463342..b3e1a48b65 100644 --- a/src/core/hle/kernel/shared_page.h +++ b/src/core/hle/kernel/shared_page.h @@ -108,10 +108,9 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { + void serialize(Archive& ar, const unsigned int file_version) { auto o_shared_page = boost::serialization::binary_object(&shared_page, sizeof(shared_page)); - ar & o_shared_page; + ar& o_shared_page; } }; diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index c824b58a61..c3c5da7d41 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -15,6 +15,7 @@ #include "core/arm/arm_interface.h" #include "core/arm/skyeye_common/armstate.h" #include "core/core.h" +#include "core/global.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/kernel.h" @@ -24,31 +25,29 @@ #include "core/hle/kernel/thread.h" #include "core/hle/result.h" #include "core/memory.h" -#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::Thread) namespace Kernel { template -void Thread::serialize(Archive& ar, const unsigned int file_version) -{ - ar & *context.get(); - ar & thread_id; - ar & status; - ar & entry_point; - ar & stack_top; - ar & nominal_priority; - ar & current_priority; - ar & last_running_ticks; - ar & processor_id; - ar & tls_address; - ar & held_mutexes; - ar & pending_mutexes; - ar & owner_process; - ar & wait_objects; - ar & wait_address; - ar & name; +void Thread::serialize(Archive& ar, const unsigned int file_version) { + ar&* context.get(); + ar& thread_id; + ar& status; + ar& entry_point; + ar& stack_top; + ar& nominal_priority; + ar& current_priority; + ar& last_running_ticks; + ar& processor_id; + ar& tls_address; + ar& held_mutexes; + ar& pending_mutexes; + ar& owner_process; + ar& wait_objects; + ar& wait_address; + ar& name; // TODO: How the hell to do wakeup_callback } diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 09341560a0..219db9f2d9 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -9,10 +9,10 @@ #include #include #include +#include #include #include #include -#include #include "common/common_types.h" #include "common/thread_queue_list.h" #include "core/arm/arm_interface.h" @@ -152,13 +152,12 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & next_thread_id; - ar & current_thread; - ar & ready_queue; - ar & wakeup_callback_table; - ar & thread_list; + void serialize(Archive& ar, const unsigned int file_version) { + ar& next_thread_id; + ar& current_thread; + ar& ready_queue; + ar& wakeup_callback_table; + ar& thread_list; } }; diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index f1a31cdf9c..d29b259861 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -8,11 +8,11 @@ #include "common/assert.h" #include "common/logging/log.h" #include "core/core.h" +#include "core/global.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/thread.h" #include "core/hle/kernel/timer.h" -#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::Timer) diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index f61ec1c116..d2c513024d 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h @@ -37,10 +37,9 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & next_timer_callback_id; - ar & timer_callback_table; + void serialize(Archive& ar, const unsigned int file_version) { + ar& next_timer_callback_id; + ar& timer_callback_table; } }; @@ -115,14 +114,13 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & reset_type; - ar & initial_delay; - ar & interval_delay; - ar & signaled; - ar & name; - ar & callback_id; + void serialize(Archive& ar, const unsigned int file_version) { + ar& reset_type; + ar& initial_delay; + ar& interval_delay; + ar& signaled; + ar& name; + ar& callback_id; } }; diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index e930fc64ab..5fd6d87402 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -86,17 +86,16 @@ struct VirtualMemoryArea { private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & base; - ar & size; - ar & type; - ar & permissions; - ar & meminfo_state; + void serialize(Archive& ar, const unsigned int file_version) { + ar& base; + ar& size; + ar& type; + ar& permissions; + ar& meminfo_state; // TODO: backing memory ref // backing memory can be: Physical/FCRAM pointer, config mem, shared page - ar & paddr; - ar & mmio_handler; + ar& paddr; + ar& mmio_handler; } }; @@ -213,27 +212,25 @@ public: private: friend class boost::serialization::access; template - void save(Archive& ar, const unsigned int file_version) const - { - ar & vma_map; + void save(Archive& ar, const unsigned int file_version) const { + ar& vma_map; for (int i = 0; i < page_table.pointers.size(); i++) { ar << memory.GetFCRAMOffset(page_table.pointers[i]); } - ar & page_table.special_regions; - ar & page_table.attributes; + ar& page_table.special_regions; + ar& page_table.attributes; } template - void load(Archive& ar, const unsigned int file_version) - { - ar & vma_map; + void load(Archive& ar, const unsigned int file_version) { + ar& vma_map; for (int i = 0; i < page_table.pointers.size(); i++) { u32 offset{}; ar >> offset; page_table.pointers[i] = memory.GetFCRAMPointer(offset); } - ar & page_table.special_regions; - ar & page_table.attributes; + ar& page_table.special_regions; + ar& page_table.attributes; } BOOST_SERIALIZATION_SPLIT_MEMBER() diff --git a/src/core/hle/kernel/wait_object.h b/src/core/hle/kernel/wait_object.h index e089977214..c07290e8ad 100644 --- a/src/core/hle/kernel/wait_object.h +++ b/src/core/hle/kernel/wait_object.h @@ -69,10 +69,9 @@ private: private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & waiting_threads; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& waiting_threads; // NB: hle_notifier *not* serialized since it's a callback! // Fortunately it's only used in one place (DSP) so we can reconstruct it there } diff --git a/src/core/hle/service/ac/ac.cpp b/src/core/hle/service/ac/ac.cpp index 356df5a63e..d9f1085c81 100644 --- a/src/core/hle/service/ac/ac.cpp +++ b/src/core/hle/service/ac/ac.cpp @@ -3,9 +3,9 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #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" @@ -181,12 +181,11 @@ void InstallInterfaces(Core::System& system) { } template -void Module::serialize(Archive& ar, const unsigned int) -{ - ar & ac_connected; - ar & close_event; - ar & connect_event; - ar & disconnect_event; +void Module::serialize(Archive& ar, const unsigned int) { + ar& ac_connected; + ar& close_event; + ar& connect_event; + ar& disconnect_event; // default_config is never written to } diff --git a/src/core/hle/service/ac/ac_i.cpp b/src/core/hle/service/ac/ac_i.cpp index e4cc4c1f1a..ff4fb954cb 100644 --- a/src/core/hle/service/ac/ac_i.cpp +++ b/src/core/hle/service/ac/ac_i.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/ac/ac_i.h" #include "common/archives.h" +#include "core/hle/service/ac/ac_i.h" namespace Service::AC { diff --git a/src/core/hle/service/ac/ac_u.cpp b/src/core/hle/service/ac/ac_u.cpp index 429942f7d5..e88cdd1640 100644 --- a/src/core/hle/service/ac/ac_u.cpp +++ b/src/core/hle/service/ac/ac_u.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/ac/ac_u.h" #include "common/archives.h" +#include "core/hle/service/ac/ac_u.h" namespace Service::AC { diff --git a/src/core/hle/service/act/act.h b/src/core/hle/service/act/act.h index c327cdaef0..11812bcfe5 100644 --- a/src/core/hle/service/act/act.h +++ b/src/core/hle/service/act/act.h @@ -23,9 +23,10 @@ public: protected: std::shared_ptr act; }; + private: template - inline void serialize(Archive& ar, const unsigned int file_version) { } + inline void serialize(Archive& ar, const unsigned int file_version) {} friend class boost::serialization::access; }; diff --git a/src/core/hle/service/act/act_a.cpp b/src/core/hle/service/act/act_a.cpp index b4bf750f78..b85a17183f 100644 --- a/src/core/hle/service/act/act_a.cpp +++ b/src/core/hle/service/act/act_a.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/act/act_a.h" #include "common/archives.h" +#include "core/hle/service/act/act_a.h" namespace Service::ACT { diff --git a/src/core/hle/service/act/act_a.h b/src/core/hle/service/act/act_a.h index 1e37c9bde8..1454441d5f 100644 --- a/src/core/hle/service/act/act_a.h +++ b/src/core/hle/service/act/act_a.h @@ -11,6 +11,7 @@ namespace Service::ACT { class ACT_A final : public Module::Interface { public: explicit ACT_A(std::shared_ptr act); + private: SERVICE_SERIALIZATION(ACT_A, act, Module) }; diff --git a/src/core/hle/service/act/act_u.cpp b/src/core/hle/service/act/act_u.cpp index 599bec18a6..a0058d5734 100644 --- a/src/core/hle/service/act/act_u.cpp +++ b/src/core/hle/service/act/act_u.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/act/act_u.h" #include "common/archives.h" +#include "core/hle/service/act/act_u.h" namespace Service::ACT { diff --git a/src/core/hle/service/act/act_u.h b/src/core/hle/service/act/act_u.h index 820aa862a6..bcd2d653e9 100644 --- a/src/core/hle/service/act/act_u.h +++ b/src/core/hle/service/act/act_u.h @@ -11,6 +11,7 @@ namespace Service::ACT { class ACT_U final : public Module::Interface { public: explicit ACT_U(std::shared_ptr act); + private: SERVICE_SERIALIZATION(ACT_U, act, Module) }; diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 45ed29e6c4..b3bd037ea7 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -1455,7 +1455,7 @@ Module::Module(Core::System& system) : kernel(system.Kernel()) { system_updater_mutex = system.Kernel().CreateMutex(false, "AM::SystemUpdaterMutex"); } -Module::Module(Kernel::KernelSystem& kernel) : kernel(kernel) { } +Module::Module(Kernel::KernelSystem& kernel) : kernel(kernel) {} Module::~Module() = default; diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 771bbfb53a..22481179ea 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -10,15 +10,15 @@ #include #include #include -#include #include +#include #include "common/common_types.h" #include "core/file_sys/cia_container.h" #include "core/file_sys/file_backend.h" +#include "core/global.h" #include "core/hle/kernel/mutex.h" #include "core/hle/result.h" #include "core/hle/service/service.h" -#include "core/global.h" namespace Core { class System; @@ -585,11 +585,10 @@ private: std::shared_ptr system_updater_mutex; template - void serialize(Archive& ar, const unsigned int) - { - ar & cia_installing; - ar & am_title_list; - ar & system_updater_mutex; + void serialize(Archive& ar, const unsigned int) { + ar& cia_installing; + ar& am_title_list; + ar& system_updater_mutex; } friend class boost::serialization::access; }; @@ -599,9 +598,8 @@ void InstallInterfaces(Core::System& system); } // namespace Service::AM namespace boost::serialization { - template - inline void load_construct_data(Archive& ar, Service::AM::Module* t, const unsigned int) - { - ::new(t)Service::AM::Module(Core::Global()); - } +template +inline void load_construct_data(Archive& ar, Service::AM::Module* t, const unsigned int) { + ::new (t) Service::AM::Module(Core::Global()); } +} // namespace boost::serialization diff --git a/src/core/hle/service/am/am_app.cpp b/src/core/hle/service/am/am_app.cpp index 52d256ca21..788ee090c2 100644 --- a/src/core/hle/service/am/am_app.cpp +++ b/src/core/hle/service/am/am_app.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/am/am_app.h" #include "common/archives.h" +#include "core/hle/service/am/am_app.h" namespace Service::AM { diff --git a/src/core/hle/service/am/am_app.h b/src/core/hle/service/am/am_app.h index fae22d96fe..b8e858cb48 100644 --- a/src/core/hle/service/am/am_app.h +++ b/src/core/hle/service/am/am_app.h @@ -11,6 +11,7 @@ namespace Service::AM { class AM_APP final : public Module::Interface { public: explicit AM_APP(std::shared_ptr am); + private: SERVICE_SERIALIZATION(AM_APP, am, Module) }; diff --git a/src/core/hle/service/am/am_net.cpp b/src/core/hle/service/am/am_net.cpp index 44c852c19f..cd88965afc 100644 --- a/src/core/hle/service/am/am_net.cpp +++ b/src/core/hle/service/am/am_net.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/am/am_net.h" #include "common/archives.h" +#include "core/hle/service/am/am_net.h" namespace Service::AM { diff --git a/src/core/hle/service/am/am_net.h b/src/core/hle/service/am/am_net.h index 4a50c6c07a..b73610df9e 100644 --- a/src/core/hle/service/am/am_net.h +++ b/src/core/hle/service/am/am_net.h @@ -11,6 +11,7 @@ namespace Service::AM { class AM_NET final : public Module::Interface { public: explicit AM_NET(std::shared_ptr am); + private: SERVICE_SERIALIZATION(AM_NET, am, Module) }; diff --git a/src/core/hle/service/am/am_sys.cpp b/src/core/hle/service/am/am_sys.cpp index c6817fe870..6c7e992350 100644 --- a/src/core/hle/service/am/am_sys.cpp +++ b/src/core/hle/service/am/am_sys.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/am/am_sys.h" #include "common/archives.h" +#include "core/hle/service/am/am_sys.h" namespace Service::AM { diff --git a/src/core/hle/service/am/am_sys.h b/src/core/hle/service/am/am_sys.h index c670523021..fdee63b134 100644 --- a/src/core/hle/service/am/am_sys.h +++ b/src/core/hle/service/am/am_sys.h @@ -11,6 +11,7 @@ namespace Service::AM { class AM_SYS final : public Module::Interface { public: explicit AM_SYS(std::shared_ptr am); + private: SERVICE_SERIALIZATION(AM_SYS, am, Module) }; diff --git a/src/core/hle/service/am/am_u.cpp b/src/core/hle/service/am/am_u.cpp index c9b80bf06f..cffb883886 100644 --- a/src/core/hle/service/am/am_u.cpp +++ b/src/core/hle/service/am/am_u.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/am/am_u.h" #include "common/archives.h" +#include "core/hle/service/am/am_u.h" namespace Service::AM { diff --git a/src/core/hle/service/am/am_u.h b/src/core/hle/service/am/am_u.h index c09e27c091..d71bf722c0 100644 --- a/src/core/hle/service/am/am_u.h +++ b/src/core/hle/service/am/am_u.h @@ -11,6 +11,7 @@ namespace Service::AM { class AM_U final : public Module::Interface { public: explicit AM_U(std::shared_ptr am); + private: SERVICE_SERIALIZATION(AM_U, am, Module) }; diff --git a/src/core/hle/service/apt/applet_manager.h b/src/core/hle/service/apt/applet_manager.h index 9410b6b549..e799c92d2e 100644 --- a/src/core/hle/service/apt/applet_manager.h +++ b/src/core/hle/service/apt/applet_manager.h @@ -10,10 +10,10 @@ #include #include #include "common/serialization/optional.h" +#include "core/global.h" #include "core/hle/kernel/event.h" #include "core/hle/result.h" #include "core/hle/service/fs/archive.h" -#include "core/global.h" namespace Core { class System; @@ -90,13 +90,12 @@ struct MessageParameter { private: template - void serialize(Archive& ar, const unsigned int) - { - ar & sender_id; - ar & destination_id; - ar & signal; - ar & object; - ar & buffer; + void serialize(Archive& ar, const unsigned int) { + ar& sender_id; + ar& destination_id; + ar& signal; + ar& object; + ar& buffer; } friend class boost::serialization::access; }; @@ -179,12 +178,11 @@ public: private: template - void serialize(Archive& ar, const unsigned int) - { - ar & next_title_id; - ar & next_media_type; - ar & current_title_id; - ar & current_media_type; + void serialize(Archive& ar, const unsigned int) { + ar& next_title_id; + ar& next_media_type; + ar& current_title_id; + ar& current_media_type; } friend class boost::serialization::access; }; @@ -228,16 +226,15 @@ private: private: template - void serialize(Archive& ar, const unsigned int) - { - ar & applet_id; - ar & slot; - ar & title_id; - ar & registered; - ar & loaded; - ar & attributes.raw; - ar & notification_event; - ar & parameter_event; + void serialize(Archive& ar, const unsigned int) { + ar& applet_id; + ar& slot; + ar& title_id; + ar& registered; + ar& loaded; + ar& attributes.raw; + ar& notification_event; + ar& parameter_event; } friend class boost::serialization::access; }; @@ -260,12 +257,11 @@ private: private: template - void serialize(Archive& ar, const unsigned int) - { - ar & next_parameter; - ar & app_jump_parameters; - ar & applet_slots; - ar & library_applet_closing_command; + void serialize(Archive& ar, const unsigned int) { + ar& next_parameter; + ar& app_jump_parameters; + ar& applet_slots; + ar& library_applet_closing_command; } friend class boost::serialization::access; }; @@ -273,9 +269,8 @@ private: } // namespace Service::APT namespace boost::serialization { - template - inline void load_construct_data(Archive& ar, Service::APT::AppletManager* t, const unsigned int) - { - ::new(t)Service::APT::AppletManager(Core::Global()); - } +template +inline void load_construct_data(Archive& ar, Service::APT::AppletManager* t, const unsigned int) { + ::new (t) Service::APT::AppletManager(Core::Global()); } +} // namespace boost::serialization diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index d5a7fb0018..8780f67e06 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -2,10 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "common/common_paths.h" #include "common/file_util.h" #include "common/logging/log.h" -#include "common/archives.h" #include "core/core.h" #include "core/file_sys/archive_ncch.h" #include "core/file_sys/file_backend.h" @@ -32,17 +32,16 @@ SERVICE_CONSTRUCT_IMPL(Service::APT::Module) namespace Service::APT { template -void Module::serialize(Archive& ar, const unsigned int) -{ - ar & shared_font_mem; - ar & shared_font_loaded; - ar & shared_font_relocated; - ar & lock; - ar & cpu_percent; - ar & unknown_ns_state_field; - ar & screen_capture_buffer; - ar & screen_capture_post_permission; - ar & applet_manager; +void Module::serialize(Archive& ar, const unsigned int) { + ar& shared_font_mem; + ar& shared_font_loaded; + ar& shared_font_relocated; + ar& lock; + ar& cpu_percent; + ar& unknown_ns_state_field; + ar& screen_capture_buffer; + ar& screen_capture_post_permission; + ar& applet_manager; } SERIALIZE_IMPL(Module) diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index 14c07feb3c..aa480331c2 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -12,10 +12,9 @@ #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" -#include "core/hle/kernel/kernel.h" -#include "core/hle/service/apt/applet_manager.h" -#include "core/hle/service/service.h" #include "core/global.h" +#include "core/hle/kernel/kernel.h" +#include "core/hle/service/service.h" namespace Core { class System; @@ -612,9 +611,8 @@ public: private: template - void serialize(Archive& ar, const unsigned int) - { - ar & application_reset_prepared; + void serialize(Archive& ar, const unsigned int) { + ar& application_reset_prepared; } friend class boost::serialization::access; }; @@ -654,6 +652,6 @@ void InstallInterfaces(Core::System& system); } // namespace Service::APT namespace boost::serialization { - template - void load_construct_data(Archive& ar, Service::APT::Module* t, const unsigned int); +template +void load_construct_data(Archive& ar, Service::APT::Module* t, const unsigned int); } diff --git a/src/core/hle/service/apt/apt_a.cpp b/src/core/hle/service/apt/apt_a.cpp index db49c57d88..0d6e64d301 100644 --- a/src/core/hle/service/apt/apt_a.cpp +++ b/src/core/hle/service/apt/apt_a.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/apt/apt_a.h" #include "common/archives.h" +#include "core/hle/service/apt/apt_a.h" namespace Service::APT { diff --git a/src/core/hle/service/apt/apt_a.h b/src/core/hle/service/apt/apt_a.h index 1b81022df4..e17e2f3234 100644 --- a/src/core/hle/service/apt/apt_a.h +++ b/src/core/hle/service/apt/apt_a.h @@ -11,6 +11,7 @@ namespace Service::APT { class APT_A final : public Module::APTInterface { public: explicit APT_A(std::shared_ptr apt); + private: SERVICE_SERIALIZATION(APT_A, apt, Module) }; diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp index 4d151fb3d4..d0e5f55266 100644 --- a/src/core/hle/service/apt/apt_s.cpp +++ b/src/core/hle/service/apt/apt_s.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/apt/apt_s.h" #include "common/archives.h" +#include "core/hle/service/apt/apt_s.h" namespace Service::APT { diff --git a/src/core/hle/service/apt/apt_s.h b/src/core/hle/service/apt/apt_s.h index ef1c235b08..d1dd27ff14 100644 --- a/src/core/hle/service/apt/apt_s.h +++ b/src/core/hle/service/apt/apt_s.h @@ -18,6 +18,7 @@ namespace Service::APT { class APT_S final : public Module::APTInterface { public: explicit APT_S(std::shared_ptr apt); + private: SERVICE_SERIALIZATION(APT_S, apt, Module) }; diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp index 7ebaf86e36..05f531a833 100644 --- a/src/core/hle/service/apt/apt_u.cpp +++ b/src/core/hle/service/apt/apt_u.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/apt/apt_u.h" #include "common/archives.h" +#include "core/hle/service/apt/apt_u.h" namespace Service::APT { diff --git a/src/core/hle/service/apt/apt_u.h b/src/core/hle/service/apt/apt_u.h index 79d2df6515..b8a8fe205a 100644 --- a/src/core/hle/service/apt/apt_u.h +++ b/src/core/hle/service/apt/apt_u.h @@ -18,6 +18,7 @@ namespace Service::APT { class APT_U final : public Module::APTInterface { public: explicit APT_U(std::shared_ptr apt); + private: SERVICE_SERIALIZATION(APT_U, apt, Module) }; diff --git a/src/core/hle/service/apt/ns_s.cpp b/src/core/hle/service/apt/ns_s.cpp index b556845d31..1f86b9a61c 100644 --- a/src/core/hle/service/apt/ns_s.cpp +++ b/src/core/hle/service/apt/ns_s.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/apt/ns_s.h" #include "common/archives.h" +#include "core/hle/service/apt/ns_s.h" namespace Service::NS { diff --git a/src/core/hle/service/apt/ns_s.h b/src/core/hle/service/apt/ns_s.h index 8f023e2042..eaa0ad9d37 100644 --- a/src/core/hle/service/apt/ns_s.h +++ b/src/core/hle/service/apt/ns_s.h @@ -14,6 +14,7 @@ namespace Service::NS { class NS_S final : public Service::APT::Module::NSInterface { public: explicit NS_S(std::shared_ptr apt); + private: SERVICE_SERIALIZATION(NS_S, apt, Service::APT::Module) }; diff --git a/src/core/hle/service/boss/boss.h b/src/core/hle/service/boss/boss.h index 7017ce2b65..4dae148f9e 100644 --- a/src/core/hle/service/boss/boss.h +++ b/src/core/hle/service/boss/boss.h @@ -6,9 +6,9 @@ #include #include +#include "core/global.h" #include "core/hle/kernel/event.h" #include "core/hle/service/service.h" -#include "core/global.h" namespace Core { class System; @@ -964,12 +964,11 @@ public: u8 output_flag; template - void serialize(Archive& ar, const unsigned int) - { - ar & new_arrival_flag; - ar & ns_data_new_flag; - ar & ns_data_new_flag_privileged; - ar & output_flag; + void serialize(Archive& ar, const unsigned int) { + ar& new_arrival_flag; + ar& ns_data_new_flag; + ar& ns_data_new_flag_privileged; + ar& output_flag; } friend class boost::serialization::access; }; @@ -978,9 +977,8 @@ private: std::shared_ptr task_finish_event; template - void serialize(Archive& ar, const unsigned int) - { - ar & task_finish_event; + void serialize(Archive& ar, const unsigned int) { + ar& task_finish_event; } friend class boost::serialization::access; }; @@ -990,9 +988,8 @@ void InstallInterfaces(Core::System& system); } // namespace Service::BOSS namespace boost::serialization { - template - inline void load_construct_data(Archive& ar, Service::BOSS::Module* t, const unsigned int) - { - ::new(t)Service::BOSS::Module(Core::Global()); - } +template +inline void load_construct_data(Archive& ar, Service::BOSS::Module* t, const unsigned int) { + ::new (t) Service::BOSS::Module(Core::Global()); } +} // namespace boost::serialization diff --git a/src/core/hle/service/boss/boss_p.cpp b/src/core/hle/service/boss/boss_p.cpp index 4e48fe8f3d..802f2643a4 100644 --- a/src/core/hle/service/boss/boss_p.cpp +++ b/src/core/hle/service/boss/boss_p.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/boss/boss_p.h" #include "common/archives.h" +#include "core/hle/service/boss/boss_p.h" namespace Service::BOSS { diff --git a/src/core/hle/service/boss/boss_u.cpp b/src/core/hle/service/boss/boss_u.cpp index f839e92922..68a30510d4 100644 --- a/src/core/hle/service/boss/boss_u.cpp +++ b/src/core/hle/service/boss/boss_u.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/boss/boss_u.h" #include "common/archives.h" +#include "core/hle/service/boss/boss_u.h" namespace Service::BOSS { diff --git a/src/core/hle/service/cam/cam.cpp b/src/core/hle/service/cam/cam.cpp index b7acd307c0..6f9a81e75f 100644 --- a/src/core/hle/service/cam/cam.cpp +++ b/src/core/hle/service/cam/cam.cpp @@ -24,11 +24,10 @@ namespace Service::CAM { template -void Module::serialize(Archive& ar, const unsigned int) -{ - ar & cameras; - ar & ports; - ar & is_camera_reload_pending; +void Module::serialize(Archive& ar, const unsigned int) { + ar& cameras; + ar& ports; + ar& is_camera_reload_pending; } SERIALIZE_IMPL(Module) diff --git a/src/core/hle/service/cam/cam.h b/src/core/hle/service/cam/cam.h index 229c882b51..876e2e1851 100644 --- a/src/core/hle/service/cam/cam.h +++ b/src/core/hle/service/cam/cam.h @@ -10,9 +10,9 @@ #include #include "common/common_types.h" #include "common/swap.h" +#include "core/global.h" #include "core/hle/result.h" #include "core/hle/service/service.h" -#include "core/global.h" namespace Core { class System; @@ -183,14 +183,13 @@ struct Resolution { private: template - void serialize(Archive& ar, const unsigned int) - { - ar & width; - ar & height; - ar & crop_x0; - ar & crop_y0; - ar & crop_x1; - ar & crop_y1; + void serialize(Archive& ar, const unsigned int) { + ar& width; + ar& height; + ar& crop_x0; + ar& crop_y0; + ar& crop_x1; + ar& crop_y1; } friend class boost::serialization::access; }; @@ -755,12 +754,11 @@ private: private: template - void serialize(Archive& ar, const unsigned int) - { - ar & flip; - ar & effect; - ar & format; - ar & resolution; + void serialize(Archive& ar, const unsigned int) { + ar& flip; + ar& effect; + ar& format; + ar& resolution; } friend class boost::serialization::access; }; @@ -773,12 +771,11 @@ private: private: template - void serialize(Archive& ar, const unsigned int) - { - ar & impl; - ar & contexts; - ar & current_context; - ar & frame_rate; + void serialize(Archive& ar, const unsigned int) { + ar& impl; + ar& contexts; + ar& current_context; + ar& frame_rate; } friend class boost::serialization::access; }; @@ -818,27 +815,26 @@ private: private: template - void serialize(Archive& ar, const unsigned int) - { - ar & camera_id; - ar & is_active; - ar & is_pending_receiving; - ar & is_busy; - ar & is_receiving; - ar & is_trimming; - ar & x0; - ar & y0; - ar & x1; - ar & y1; - ar & transfer_bytes; - ar & completion_event; - ar & buffer_error_interrupt_event; - ar & vsync_interrupt_event; + void serialize(Archive& ar, const unsigned int) { + ar& camera_id; + ar& is_active; + ar& is_pending_receiving; + ar& is_busy; + ar& is_receiving; + ar& is_trimming; + ar& x0; + ar& y0; + ar& x1; + ar& y1; + ar& transfer_bytes; + ar& completion_event; + ar& buffer_error_interrupt_event; + ar& vsync_interrupt_event; // TODO: Check if this is ever needed: - //ar & capture_result; - ar & dest_process; - ar & dest; - ar & dest_size; + // ar & capture_result; + ar& dest_process; + ar& dest; + ar& dest_size; } friend class boost::serialization::access; }; @@ -864,9 +860,8 @@ void InstallInterfaces(Core::System& system); } // namespace Service::CAM namespace boost::serialization { - template - inline void load_construct_data(Archive& ar, Service::CAM::Module* t, const unsigned int) - { - ::new(t)Service::CAM::Module(Core::Global()); - } +template +inline void load_construct_data(Archive& ar, Service::CAM::Module* t, const unsigned int) { + ::new (t) Service::CAM::Module(Core::Global()); } +} // namespace boost::serialization diff --git a/src/core/hle/service/cam/cam_c.cpp b/src/core/hle/service/cam/cam_c.cpp index a29e9db3ea..e86d331159 100644 --- a/src/core/hle/service/cam/cam_c.cpp +++ b/src/core/hle/service/cam/cam_c.cpp @@ -2,9 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cam/cam.h" #include "core/hle/service/cam/cam_c.h" -#include "common/archives.h" namespace Service::CAM { diff --git a/src/core/hle/service/cam/cam_q.cpp b/src/core/hle/service/cam/cam_q.cpp index ac477bf040..6f0c04598a 100644 --- a/src/core/hle/service/cam/cam_q.cpp +++ b/src/core/hle/service/cam/cam_q.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/cam/cam_q.h" #include "common/archives.h" +#include "core/hle/service/cam/cam_q.h" namespace Service::CAM { diff --git a/src/core/hle/service/cam/cam_q.h b/src/core/hle/service/cam/cam_q.h index 33943ca214..ab901cf85c 100644 --- a/src/core/hle/service/cam/cam_q.h +++ b/src/core/hle/service/cam/cam_q.h @@ -11,11 +11,11 @@ namespace Service::CAM { class CAM_Q : public ServiceFramework { public: CAM_Q(); + private: template - void serialize(Archive& ar, const unsigned int) - { - ar & boost::serialization::base_object(*this); + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/cam/cam_s.cpp b/src/core/hle/service/cam/cam_s.cpp index 0797ed4e1d..8cfd3c1d7c 100644 --- a/src/core/hle/service/cam/cam_s.cpp +++ b/src/core/hle/service/cam/cam_s.cpp @@ -2,9 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cam/cam.h" #include "core/hle/service/cam/cam_s.h" -#include "common/archives.h" namespace Service::CAM { diff --git a/src/core/hle/service/cam/cam_u.cpp b/src/core/hle/service/cam/cam_u.cpp index 16c652a263..72a62c04e8 100644 --- a/src/core/hle/service/cam/cam_u.cpp +++ b/src/core/hle/service/cam/cam_u.cpp @@ -2,9 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cam/cam.h" #include "core/hle/service/cam/cam_u.h" -#include "common/archives.h" namespace Service::CAM { diff --git a/src/core/hle/service/csnd/csnd_snd.h b/src/core/hle/service/csnd/csnd_snd.h index 44e4c030ca..6ac5d68766 100644 --- a/src/core/hle/service/csnd/csnd_snd.h +++ b/src/core/hle/service/csnd/csnd_snd.h @@ -38,10 +38,9 @@ struct AdpcmState { private: template - void serialize(Archive& ar, const unsigned int) - { - ar & predictor; - ar & step_index; + void serialize(Archive& ar, const unsigned int) { + ar& predictor; + ar& step_index; } friend class boost::serialization::access; }; @@ -66,24 +65,23 @@ struct Channel { private: template - void serialize(Archive& ar, const unsigned int) - { - ar & block1_address; - ar & block2_address; - ar & block1_size; - ar & block2_size; - ar & block1_adpcm_state; - ar & block2_adpcm_state; - ar & block2_adpcm_reload; - ar & left_channel_volume; - ar & right_channel_volume; - ar & left_capture_volume; - ar & right_capture_volume; - ar & sample_rate; - ar & linear_interpolation; - ar & loop_mode; - ar & encoding; - ar & psg_duty; + void serialize(Archive& ar, const unsigned int) { + ar& block1_address; + ar& block2_address; + ar& block1_size; + ar& block2_size; + ar& block1_adpcm_state; + ar& block2_adpcm_state; + ar& block2_adpcm_reload; + ar& left_channel_volume; + ar& right_channel_volume; + ar& left_capture_volume; + ar& right_capture_volume; + ar& sample_rate; + ar& linear_interpolation; + ar& loop_mode; + ar& encoding; + ar& psg_duty; } friend class boost::serialization::access; }; @@ -258,18 +256,17 @@ private: u32 acquired_channel_mask = 0; template - void serialize(Archive& ar, const unsigned int) - { - ar & boost::serialization::base_object(*this); - ar & mutex; - ar & shared_memory; - ar & capture_units; - ar & channels; - ar & master_state_offset; - ar & channel_state_offset; - ar & capture_state_offset; - ar & type1_command_offset; - ar & acquired_channel_mask; + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& mutex; + ar& shared_memory; + ar& capture_units; + ar& channels; + ar& master_state_offset; + ar& channel_state_offset; + ar& capture_state_offset; + ar& type1_command_offset; + ar& acquired_channel_mask; } friend class boost::serialization::access; }; @@ -282,6 +279,6 @@ void InstallInterfaces(Core::System& system); BOOST_CLASS_EXPORT_KEY(Service::CSND::CSND_SND) namespace boost::serialization { - template - void load_construct_data(Archive& ar, Service::CSND::CSND_SND* t, const unsigned int); +template +void load_construct_data(Archive& ar, Service::CSND::CSND_SND* t, const unsigned int); } diff --git a/src/core/hle/service/dlp/dlp_clnt.cpp b/src/core/hle/service/dlp/dlp_clnt.cpp index df5b755e1d..f8b315c00b 100644 --- a/src/core/hle/service/dlp/dlp_clnt.cpp +++ b/src/core/hle/service/dlp/dlp_clnt.cpp @@ -2,9 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/dlp/dlp_clnt.h" -#include "common/archives.h" SERIALIZE_EXPORT_IMPL(Service::DLP::DLP_CLNT) diff --git a/src/core/hle/service/dlp/dlp_clnt.h b/src/core/hle/service/dlp/dlp_clnt.h index 3f90208639..835d017482 100644 --- a/src/core/hle/service/dlp/dlp_clnt.h +++ b/src/core/hle/service/dlp/dlp_clnt.h @@ -12,11 +12,11 @@ class DLP_CLNT final : public ServiceFramework { public: DLP_CLNT(); ~DLP_CLNT() = default; + private: template - void serialize(Archive& ar, const unsigned int) - { - ar & boost::serialization::base_object(*this); + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/dlp/dlp_fkcl.cpp b/src/core/hle/service/dlp/dlp_fkcl.cpp index 607c211d47..948b25b673 100644 --- a/src/core/hle/service/dlp/dlp_fkcl.cpp +++ b/src/core/hle/service/dlp/dlp_fkcl.cpp @@ -2,9 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/dlp/dlp_fkcl.h" -#include "common/archives.h" SERIALIZE_EXPORT_IMPL(Service::DLP::DLP_FKCL) diff --git a/src/core/hle/service/dlp/dlp_fkcl.h b/src/core/hle/service/dlp/dlp_fkcl.h index ae26b62209..d778ace8b6 100644 --- a/src/core/hle/service/dlp/dlp_fkcl.h +++ b/src/core/hle/service/dlp/dlp_fkcl.h @@ -12,11 +12,11 @@ class DLP_FKCL final : public ServiceFramework { public: DLP_FKCL(); ~DLP_FKCL() = default; + private: template - void serialize(Archive& ar, const unsigned int) - { - ar & boost::serialization::base_object(*this); + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/dlp/dlp_srvr.cpp b/src/core/hle/service/dlp/dlp_srvr.cpp index 0cff2e2bc7..87733b71f0 100644 --- a/src/core/hle/service/dlp/dlp_srvr.cpp +++ b/src/core/hle/service/dlp/dlp_srvr.cpp @@ -2,12 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" #include "core/hle/ipc_helpers.h" #include "core/hle/result.h" #include "core/hle/service/dlp/dlp_srvr.h" -#include "common/archives.h" SERIALIZE_EXPORT_IMPL(Service::DLP::DLP_SRVR) diff --git a/src/core/hle/service/dlp/dlp_srvr.h b/src/core/hle/service/dlp/dlp_srvr.h index 6af350c8ed..1f171f9506 100644 --- a/src/core/hle/service/dlp/dlp_srvr.h +++ b/src/core/hle/service/dlp/dlp_srvr.h @@ -17,9 +17,8 @@ private: void IsChild(Kernel::HLERequestContext& ctx); template - void serialize(Archive& ar, const unsigned int) - { - ar & boost::serialization::base_object(*this); + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/dsp/dsp_dsp.h b/src/core/hle/service/dsp/dsp_dsp.h index b4c727091e..90dd17f653 100644 --- a/src/core/hle/service/dsp/dsp_dsp.h +++ b/src/core/hle/service/dsp/dsp_dsp.h @@ -266,14 +266,13 @@ private: std::array, AudioCore::num_dsp_pipe> pipes = {{}}; template - void serialize(Archive& ar, const unsigned int) - { - ar & boost::serialization::base_object(*this); - ar & semaphore_event; - ar & preset_semaphore; - ar & interrupt_zero; - ar & interrupt_one; - ar & pipes; + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& semaphore_event; + ar& preset_semaphore; + ar& interrupt_zero; + ar& interrupt_one; + ar& pipes; } friend class boost::serialization::access; }; @@ -285,6 +284,6 @@ void InstallInterfaces(Core::System& system); BOOST_CLASS_EXPORT_KEY(Service::DSP::DSP_DSP) namespace boost::serialization { - template - void load_construct_data(Archive& ar, Service::DSP::DSP_DSP* t, const unsigned int); +template +void load_construct_data(Archive& ar, Service::DSP::DSP_DSP* t, const unsigned int); } diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp index 0efc600e8c..f88ffef192 100644 --- a/src/core/hle/service/err_f.cpp +++ b/src/core/hle/service/err_f.cpp @@ -20,16 +20,15 @@ SERIALIZE_EXPORT_IMPL(Service::ERR::ERR_F) namespace boost::serialization { - template - void load_construct_data(Archive& ar, Service::ERR::ERR_F* t, const unsigned int) - { - ::new(t)Service::ERR::ERR_F(Core::Global()); - } - - template - void load_construct_data(iarchive& ar, Service::ERR::ERR_F* t, const unsigned int); +template +void load_construct_data(Archive& ar, Service::ERR::ERR_F* t, const unsigned int) { + ::new (t) Service::ERR::ERR_F(Core::Global()); } +template void load_construct_data(iarchive& ar, Service::ERR::ERR_F* t, + const unsigned int); +} // namespace boost::serialization + namespace Service::ERR { enum class FatalErrType : u32 { diff --git a/src/core/hle/service/err_f.h b/src/core/hle/service/err_f.h index a3d0cf11e3..de92fed050 100644 --- a/src/core/hle/service/err_f.h +++ b/src/core/hle/service/err_f.h @@ -36,9 +36,8 @@ private: Core::System& system; template - void serialize(Archive& ar, const unsigned int) - { - ar & boost::serialization::base_object(*this); + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); } friend class boost::serialization::access; }; @@ -50,6 +49,6 @@ void InstallInterfaces(Core::System& system); BOOST_CLASS_EXPORT_KEY(Service::ERR::ERR_F) namespace boost::serialization { - template - void load_construct_data(Archive& ar, Service::ERR::ERR_F* t, const unsigned int); +template +void load_construct_data(Archive& ar, Service::ERR::ERR_F* t, const unsigned int); } diff --git a/src/core/hle/service/frd/frd.h b/src/core/hle/service/frd/frd.h index 46dc96cadd..1f34e61fa6 100644 --- a/src/core/hle/service/frd/frd.h +++ b/src/core/hle/service/frd/frd.h @@ -21,11 +21,10 @@ struct FriendKey { private: template - void serialize(Archive& ar, const unsigned int) - { - ar & friend_id; - ar & unknown; - ar & friend_code; + void serialize(Archive& ar, const unsigned int) { + ar& friend_id; + ar& unknown; + ar& friend_code; } friend class boost::serialization::access; }; @@ -35,9 +34,8 @@ struct MyPresence { private: template - void serialize(Archive& ar, const unsigned int) - { - ar & unknown; + void serialize(Archive& ar, const unsigned int) { + ar& unknown; } friend class boost::serialization::access; }; @@ -157,10 +155,9 @@ private: MyPresence my_presence = {}; template - void serialize(Archive& ar, const unsigned int) - { - ar & my_friend_key; - ar & my_presence; + void serialize(Archive& ar, const unsigned int) { + ar& my_friend_key; + ar& my_presence; } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/frd/frd_a.cpp b/src/core/hle/service/frd/frd_a.cpp index 6248891af0..23a83a55e2 100644 --- a/src/core/hle/service/frd/frd_a.cpp +++ b/src/core/hle/service/frd/frd_a.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/frd/frd_a.h" #include "common/archives.h" +#include "core/hle/service/frd/frd_a.h" SERIALIZE_EXPORT_IMPL(Service::FRD::FRD_A) diff --git a/src/core/hle/service/frd/frd_a.h b/src/core/hle/service/frd/frd_a.h index 133d40dc1b..0bdd875252 100644 --- a/src/core/hle/service/frd/frd_a.h +++ b/src/core/hle/service/frd/frd_a.h @@ -11,6 +11,7 @@ namespace Service::FRD { class FRD_A final : public Module::Interface { public: explicit FRD_A(std::shared_ptr frd); + private: SERVICE_SERIALIZATION(FRD_A, frd, Module) }; diff --git a/src/core/hle/service/frd/frd_u.cpp b/src/core/hle/service/frd/frd_u.cpp index ba499dd2be..d83c8ac8c4 100644 --- a/src/core/hle/service/frd/frd_u.cpp +++ b/src/core/hle/service/frd/frd_u.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/frd/frd_u.h" #include "common/archives.h" +#include "core/hle/service/frd/frd_u.h" SERIALIZE_EXPORT_IMPL(Service::FRD::FRD_U) diff --git a/src/core/hle/service/frd/frd_u.h b/src/core/hle/service/frd/frd_u.h index 281334f516..e6adc37fbb 100644 --- a/src/core/hle/service/frd/frd_u.h +++ b/src/core/hle/service/frd/frd_u.h @@ -11,6 +11,7 @@ namespace Service::FRD { class FRD_U final : public Module::Interface { public: explicit FRD_U(std::shared_ptr frd); + private: SERVICE_SERIALIZATION(FRD_U, frd, Module) }; diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 90dfad62f5..767faf1679 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -13,6 +13,7 @@ #include "common/common_types.h" #include "common/file_util.h" #include "common/logging/log.h" +#include "core/core.h" #include "core/file_sys/archive_backend.h" #include "core/file_sys/archive_extsavedata.h" #include "core/file_sys/archive_ncch.h" @@ -27,7 +28,6 @@ #include "core/file_sys/file_backend.h" #include "core/hle/result.h" #include "core/hle/service/fs/archive.h" -#include "core/core.h" namespace Service::FS { diff --git a/src/core/hle/service/fs/fs_user.h b/src/core/hle/service/fs/fs_user.h index c001be0c54..29b47a99c1 100644 --- a/src/core/hle/service/fs/fs_user.h +++ b/src/core/hle/service/fs/fs_user.h @@ -25,9 +25,8 @@ struct ClientSlot : public Kernel::SessionRequestHandler::SessionDataBase { private: template - void serialize(Archive& ar, const unsigned int) - { - ar & program_id; + void serialize(Archive& ar, const unsigned int) { + ar& program_id; } friend class boost::serialization::access; }; @@ -555,10 +554,9 @@ private: ArchiveManager& archives; template - void serialize(Archive& ar, const unsigned int) - { - ar & boost::serialization::base_object(*this); - ar & priority; + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& priority; } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index b16a4065f3..d39e72aca4 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -11,8 +11,8 @@ #include #include #include -#include #include +#include #include "common/common_types.h" #include "common/construct.h" #include "core/hle/kernel/hle_ipc.h" @@ -199,42 +199,37 @@ extern const std::array service_module_map; } // namespace Service -#define SERVICE_SERIALIZATION(T, MFIELD, TMODULE) \ - template \ - void save_construct(Archive& ar, const unsigned int file_version) const \ - { \ - ar << MFIELD; \ - } \ - \ - template \ - static void load_construct(Archive& ar, T* t, const unsigned int file_version) \ - { \ - std::shared_ptr MFIELD; \ - ar >> MFIELD; \ - ::new(t)T(MFIELD); \ - } \ - \ - template \ - void serialize(Archive& ar, const unsigned int) \ - { \ - ar & boost::serialization::base_object(*this); \ - } \ - friend class boost::serialization::access; \ +#define SERVICE_SERIALIZATION(T, MFIELD, TMODULE) \ + template \ + void save_construct(Archive& ar, const unsigned int file_version) const { \ + ar << MFIELD; \ + } \ + \ + template \ + static void load_construct(Archive& ar, T* t, const unsigned int file_version) { \ + std::shared_ptr MFIELD; \ + ar >> MFIELD; \ + ::new (t) T(MFIELD); \ + } \ + \ + template \ + void serialize(Archive& ar, const unsigned int) { \ + ar& boost::serialization::base_object(*this); \ + } \ + friend class boost::serialization::access; \ friend class ::construct_access; -#define SERVICE_CONSTRUCT(T) \ -namespace boost::serialization { \ - template \ - void load_construct_data(Archive& ar, T* t, const unsigned int); \ -} +#define SERVICE_CONSTRUCT(T) \ + namespace boost::serialization { \ + template \ + void load_construct_data(Archive& ar, T* t, const unsigned int); \ + } -#define SERVICE_CONSTRUCT_IMPL(T) \ -namespace boost::serialization { \ - template \ - void load_construct_data(Archive& ar, T* t, const unsigned int) \ - { \ - ::new(t)T(Core::Global()); \ - } \ - template \ - void load_construct_data(iarchive& ar, T* t, const unsigned int); \ -} +#define SERVICE_CONSTRUCT_IMPL(T) \ + namespace boost::serialization { \ + template \ + void load_construct_data(Archive& ar, T* t, const unsigned int) { \ + ::new (t) T(Core::Global()); \ + } \ + template void load_construct_data(iarchive & ar, T* t, const unsigned int); \ + } diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index d91732da9b..659e14afb7 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -9,9 +9,9 @@ #include #include #include +#include #include #include -#include #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_port.h" @@ -86,14 +86,12 @@ private: std::unordered_map registered_services_inverse; template - void save(Archive& ar, const unsigned int file_version) const - { + void save(Archive& ar, const unsigned int file_version) const { ar << registered_services; } template - void load(Archive& ar, const unsigned int file_version) - { + void load(Archive& ar, const unsigned int file_version) { ar >> registered_services; registered_services_inverse.clear(); for (const auto& pair : registered_services) { diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 7264e1ec4e..6a41ca9572 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -4,9 +4,9 @@ #include #include +#include "audio_core/dsp_interface.h" #include "boost/serialization/array.hpp" #include "boost/serialization/binary_object.hpp" -#include "audio_core/dsp_interface.h" #include "common/archives.h" #include "common/assert.h" #include "common/common_types.h" @@ -58,12 +58,11 @@ private: static_assert(sizeof(bool) == 1); friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & vram; - ar & linear_heap; - ar & new_linear_heap; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& vram; + ar& linear_heap; + ar& new_linear_heap; } }; @@ -82,19 +81,18 @@ public: AudioCore::DspInterface* dsp = nullptr; private: - friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { + template + void serialize(Archive& ar, const unsigned int file_version) { // TODO: Skip n3ds ram when not used? auto s_fcram = boost::serialization::binary_object(fcram.get(), Memory::FCRAM_N3DS_SIZE); auto s_vram = boost::serialization::binary_object(vram.get(), Memory::VRAM_SIZE); - auto s_extra = boost::serialization::binary_object(n3ds_extra_ram.get(), Memory::N3DS_EXTRA_RAM_SIZE); - ar & s_fcram; - ar & s_vram; - ar & s_extra; - ar & cache_marker; + auto s_extra = + boost::serialization::binary_object(n3ds_extra_ram.get(), Memory::N3DS_EXTRA_RAM_SIZE); + ar& s_fcram; + ar& s_vram; + ar& s_extra; + ar& cache_marker; // TODO: How the hell to do page tables.. // ar & page_table_list; // ar & current_page_table; @@ -104,10 +102,9 @@ private: MemorySystem::MemorySystem() : impl(std::make_unique()) {} MemorySystem::~MemorySystem() = default; -template -void MemorySystem::serialize(Archive & ar, const unsigned int file_version) -{ - ar & *impl.get(); +template +void MemorySystem::serialize(Archive& ar, const unsigned int file_version) { + ar&* impl.get(); } SERIALIZE_IMPL(MemorySystem) diff --git a/src/core/memory.h b/src/core/memory.h index 9c1455a806..aac57af26a 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -54,12 +54,11 @@ struct SpecialRegion { u32 size; MMIORegionPointer handler; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & base; - ar & size; - ar & handler; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& base; + ar& size; + ar& handler; } }; @@ -326,8 +325,8 @@ private: std::unique_ptr impl; friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version); + template + void serialize(Archive& ar, const unsigned int file_version); }; /// Determines if the given VAddr is valid for the specified process. diff --git a/src/core/mmio.h b/src/core/mmio.h index 0a8249c9ae..2e6323b49f 100644 --- a/src/core/mmio.h +++ b/src/core/mmio.h @@ -36,9 +36,7 @@ public: private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - } + void serialize(Archive& ar, const unsigned int file_version) {} }; using MMIORegionPointer = std::shared_ptr; diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index e405f67290..62cad0e357 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -26,7 +26,8 @@ static std::shared_ptr MakeObject(Kernel::KernelSystem& kernel) { TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") { Core::Timing timing; Memory::MemorySystem memory; - Kernel::KernelSystem kernel(memory, timing, [] {}, 0); + Kernel::KernelSystem kernel( + memory, timing, [] {}, 0); auto [server, client] = kernel.CreateSessionPair(); HLERequestContext context(kernel, std::move(server), nullptr); @@ -238,7 +239,8 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { Core::Timing timing; Memory::MemorySystem memory; - Kernel::KernelSystem kernel(memory, timing, [] {}, 0); + Kernel::KernelSystem kernel( + memory, timing, [] {}, 0); auto [server, client] = kernel.CreateSessionPair(); HLERequestContext context(kernel, std::move(server), nullptr); diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 3a5b35236a..1c633cf5c4 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -645,8 +645,7 @@ void ProcessCommandList(PAddr list, u32 size) { u32* buffer = (u32*)VideoCore::g_memory->GetPhysicalPointer(list); if (Pica::g_debug_context && Pica::g_debug_context->recorder) { - Pica::g_debug_context->recorder->MemoryAccessed((u8*)buffer, size, - list); + Pica::g_debug_context->recorder->MemoryAccessed((u8*)buffer, size, list); } g_state.cmd_list.addr = list; diff --git a/src/video_core/geometry_pipeline.cpp b/src/video_core/geometry_pipeline.cpp index 44a2fd6da3..159f1df0b2 100644 --- a/src/video_core/geometry_pipeline.cpp +++ b/src/video_core/geometry_pipeline.cpp @@ -37,9 +37,7 @@ public: private: template - void serialize(Archive& ar, const unsigned int file_version) - { - } + void serialize(Archive& ar, const unsigned int file_version) {} friend class boost::serialization::access; }; @@ -92,16 +90,14 @@ private: unsigned int vs_output_num; template - static void serialize_common(Class* self, Archive& ar, const unsigned int version) - { - ar & boost::serialization::base_object(*self); + static void serialize_common(Class* self, Archive& ar, const unsigned int version) { + ar& boost::serialization::base_object(*self); ar & self->attribute_buffer; ar & self->vs_output_num; } - template - void save(Archive & ar, const unsigned int version) const - { + template + void save(Archive& ar, const unsigned int version) const { serialize_common(this, ar, version); auto buffer_idx = static_cast(buffer_cur - attribute_buffer.attr); auto buffer_size = static_cast(buffer_end - attribute_buffer.attr); @@ -109,9 +105,8 @@ private: ar << buffer_size; } - template - void load(Archive & ar, const unsigned int version) - { + template + void load(Archive& ar, const unsigned int version) { serialize_common(this, ar, version); u32 buffer_idx, buffer_size; ar >> buffer_idx; @@ -130,8 +125,7 @@ private: // value in the batch. This mode is usually used for subdivision. class GeometryPipeline_VariablePrimitive : public GeometryPipelineBackend { public: - GeometryPipeline_VariablePrimitive() - : regs(g_state.regs), setup(g_state.gs) { + GeometryPipeline_VariablePrimitive() : regs(g_state.regs), setup(g_state.gs) { ASSERT(regs.pipeline.variable_primitive == 1); ASSERT(regs.gs.input_to_uniform == 1); vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1; @@ -190,26 +184,23 @@ private: unsigned int vs_output_num; template - static void serialize_common(Class* self, Archive& ar, const unsigned int version) - { - ar & boost::serialization::base_object(*self); + static void serialize_common(Class* self, Archive& ar, const unsigned int version) { + ar& boost::serialization::base_object(*self); ar & self->need_index; ar & self->main_vertex_num; ar & self->total_vertex_num; ar & self->vs_output_num; } - template - void save(Archive & ar, const unsigned int version) const - { + template + void save(Archive& ar, const unsigned int version) const { serialize_common(this, ar, version); auto buffer_idx = static_cast(buffer_cur - setup.uniforms.f); ar << buffer_idx; } - template - void load(Archive & ar, const unsigned int version) - { + template + void load(Archive& ar, const unsigned int version) { serialize_common(this, ar, version); u32 buffer_idx; ar >> buffer_idx; @@ -226,8 +217,7 @@ private: // particle system. class GeometryPipeline_FixedPrimitive : public GeometryPipelineBackend { public: - GeometryPipeline_FixedPrimitive() - : regs(g_state.regs), setup(g_state.gs) { + GeometryPipeline_FixedPrimitive() : regs(g_state.regs), setup(g_state.gs) { ASSERT(regs.pipeline.variable_primitive == 0); ASSERT(regs.gs.input_to_uniform == 1); vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1; @@ -267,15 +257,13 @@ private: unsigned int vs_output_num; template - static void serialize_common(Class* self, Archive& ar, const unsigned int version) - { - ar & boost::serialization::base_object(*self); + static void serialize_common(Class* self, Archive& ar, const unsigned int version) { + ar& boost::serialization::base_object(*self); ar & self->vs_output_num; } - template - void save(Archive & ar, const unsigned int version) const - { + template + void save(Archive& ar, const unsigned int version) const { serialize_common(this, ar, version); auto buffer_offset = static_cast(buffer_begin - setup.uniforms.f); auto buffer_idx = static_cast(buffer_cur - setup.uniforms.f); @@ -285,9 +273,8 @@ private: ar << buffer_size; } - template - void load(Archive & ar, const unsigned int version) - { + template + void load(Archive& ar, const unsigned int version) { serialize_common(this, ar, version); u32 buffer_offset, buffer_idx, buffer_size; ar >> buffer_offset; @@ -385,7 +372,7 @@ void GeometryPipeline::SubmitVertex(const Shader::AttributeBuffer& input) { template void GeometryPipeline::serialize(Archive& ar, const unsigned int version) { // vertex_handler and shader_engine are always set to the same value - ar & backend; + ar& backend; } } // namespace Pica diff --git a/src/video_core/pica.cpp b/src/video_core/pica.cpp index 0b5aaa6822..5e0c2d480a 100644 --- a/src/video_core/pica.cpp +++ b/src/video_core/pica.cpp @@ -3,17 +3,19 @@ // Refer to the license.txt file included. #include +#include "core/global.h" #include "video_core/geometry_pipeline.h" #include "video_core/pica.h" #include "video_core/pica_state.h" #include "video_core/renderer_base.h" #include "video_core/video_core.h" -#include "core/global.h" namespace Core { - template <> - Pica::State& Global() { return Pica::g_state; } +template <> +Pica::State& Global() { + return Pica::g_state; } +} // namespace Core namespace Pica { diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 30cef34964..4e5a5f16b9 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -9,23 +9,21 @@ #include "common/bit_field.h" #include "common/common_types.h" #include "common/vector_math.h" -#include "video_core/video_core.h" #include "video_core/geometry_pipeline.h" #include "video_core/primitive_assembly.h" #include "video_core/regs.h" #include "video_core/shader/shader.h" +#include "video_core/video_core.h" // Boost::serialization doesn't like union types for some reason, // so we need to mark arrays of union values with a special serialization method -template -struct UnionArray : public std::array -{ +template +struct UnionArray : public std::array { private: - template - void serialize(Archive& ar, const unsigned int) - { + template + void serialize(Archive& ar, const unsigned int) { static_assert(sizeof(Value) == sizeof(u32)); - ar & *static_cast(static_cast(this->data())); + ar&* static_cast(static_cast(this->data())); } friend class boost::serialization::access; }; @@ -99,14 +97,13 @@ struct State { private: friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & noise_table; - ar & color_map_table; - ar & alpha_map_table; - ar & color_table; - ar & color_diff_table; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& noise_table; + ar& color_map_table; + ar& alpha_map_table; + ar& color_table; + ar& color_diff_table; } } proctex; @@ -131,10 +128,9 @@ struct State { return neg_difference ? -diff : diff; } - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & raw; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& raw; } }; @@ -180,12 +176,11 @@ struct State { private: friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & input_vertex; - ar & current_attribute; - ar & reset_geometry_pipeline; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& input_vertex; + ar& current_attribute; + ar& reset_geometry_pipeline; } } immediate; @@ -210,42 +205,38 @@ struct State { u32 default_attr_write_buffer[3]{}; private: - friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & regs.reg_array; - ar & vs; - ar & gs; - ar & input_default_attributes; - ar & proctex; - ar & lighting.luts; - ar & fog.lut; - ar & cmd_list.addr; - ar & cmd_list.length; - ar & immediate; - ar & gs_unit; - ar & geometry_pipeline; - ar & primitive_assembler; - ar & vs_float_regs_counter; - ar & vs_uniform_write_buffer; - ar & gs_float_regs_counter; - ar & gs_uniform_write_buffer; - ar & default_attr_counter; - ar & default_attr_write_buffer; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& regs.reg_array; + ar& vs; + ar& gs; + ar& input_default_attributes; + ar& proctex; + ar& lighting.luts; + ar& fog.lut; + ar& cmd_list.addr; + ar& cmd_list.length; + ar& immediate; + ar& gs_unit; + ar& geometry_pipeline; + ar& primitive_assembler; + ar& vs_float_regs_counter; + ar& vs_uniform_write_buffer; + ar& gs_float_regs_counter; + ar& gs_uniform_write_buffer; + ar& default_attr_counter; + ar& default_attr_write_buffer; boost::serialization::split_member(ar, *this, file_version); } - template - void save(Archive & ar, const unsigned int file_version) const - { + template + void save(Archive& ar, const unsigned int file_version) const { ar << static_cast(cmd_list.current_ptr - cmd_list.head_ptr); } - template - void load(Archive & ar, const unsigned int file_version) - { + template + void load(Archive& ar, const unsigned int file_version) { u32 offset{}; ar >> offset; cmd_list.head_ptr = (u32*)VideoCore::g_memory->GetPhysicalPointer(cmd_list.addr); diff --git a/src/video_core/pica_types.h b/src/video_core/pica_types.h index bef256e131..33012c2595 100644 --- a/src/video_core/pica_types.h +++ b/src/video_core/pica_types.h @@ -143,10 +143,9 @@ private: float value; friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & value; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& value; } }; diff --git a/src/video_core/primitive_assembly.h b/src/video_core/primitive_assembly.h index 1545a6b4c8..d6547dddd4 100644 --- a/src/video_core/primitive_assembly.h +++ b/src/video_core/primitive_assembly.h @@ -6,7 +6,9 @@ #include #include "video_core/regs_pipeline.h" -namespace boost::serialization { class access; } +namespace boost::serialization { +class access; +} namespace Pica { @@ -65,13 +67,12 @@ private: bool winding = false; template - void serialize(Archive& ar, const unsigned int version) - { - ar & topology; - ar & buffer_index; - ar & buffer; - ar & strip_ready; - ar & winding; + void serialize(Archive& ar, const unsigned int version) { + ar& topology; + ar& buffer_index; + ar& buffer; + ar& strip_ready; + ar& winding; } friend class boost::serialization::access; }; diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index f20e08d981..a6e42b3bff 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -8,15 +8,15 @@ #include #include #include -#include #include #include +#include #include "common/assert.h" #include "common/common_funcs.h" #include "common/common_types.h" #include "common/hash.h" -#include "common/vector_math.h" #include "common/pod.h" +#include "common/vector_math.h" #include "video_core/pica_types.h" #include "video_core/regs_rasterizer.h" #include "video_core/regs_shader.h" @@ -38,9 +38,8 @@ struct AttributeBuffer { private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & attr; + void serialize(Archive& ar, const unsigned int file_version) { + ar& attr; } }; @@ -107,13 +106,12 @@ struct GSEmitter { private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & buffer; - ar & vertex_id; - ar & prim_emit; - ar & winding; - ar & output_mask; + void serialize(Archive& ar, const unsigned int file_version) { + ar& buffer; + ar& vertex_id; + ar& prim_emit; + ar& winding; + ar& output_mask; // Handlers are ignored because they're constant } }; @@ -137,11 +135,10 @@ struct UnitState { private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & input; - ar & temporary; - ar & output; + void serialize(Archive& ar, const unsigned int file_version) { + ar& input; + ar& temporary; + ar& output; } } registers; static_assert(std::is_pod::value, "Structure is not POD"); @@ -199,11 +196,10 @@ struct UnitState { private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & registers; - ar & conditional_code; - ar & address_registers; + void serialize(Archive& ar, const unsigned int file_version) { + ar& registers; + ar& conditional_code; + ar& address_registers; // emitter_ptr is only set by GSUnitState and is serialized there } }; @@ -223,10 +219,9 @@ struct GSUnitState : public UnitState { private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & emitter; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& emitter; } }; @@ -252,12 +247,11 @@ struct Uniforms { private: friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & f; - ar & b; - ar & i; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& f; + ar& b; + ar& i; } }; @@ -305,16 +299,15 @@ private: u64 swizzle_data_hash = 0xDEADC0DE; friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & uniforms; - ar & program_code; - ar & swizzle_data; - ar & program_code_hash_dirty; - ar & swizzle_data_hash_dirty; - ar & program_code_hash; - ar & swizzle_data_hash; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& uniforms; + ar& program_code; + ar& swizzle_data; + ar& program_code_hash_dirty; + ar& swizzle_data_hash_dirty; + ar& program_code_hash; + ar& swizzle_data_hash; } }; diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index 5bc1e87026..a89b41e96c 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp @@ -87,18 +87,15 @@ u16 GetResolutionScaleFactor() { } } -void Save(std::ostream &stream) -{ +void Save(std::ostream& stream) { oarchive oa{stream}; - oa & Pica::g_state; + oa& Pica::g_state; } -void Load(std::istream &stream) -{ +void Load(std::istream& stream) { iarchive ia{stream}; - ia & Pica::g_state; + ia& Pica::g_state; // TODO: Flush/reset things - } } // namespace VideoCore diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h index 1ec69f802d..10b0d39b6f 100644 --- a/src/video_core/video_core.h +++ b/src/video_core/video_core.h @@ -4,8 +4,8 @@ #pragma once -#include #include +#include #include #include "core/frontend/emu_window.h" @@ -62,7 +62,7 @@ void RequestScreenshot(void* data, std::function callback, u16 GetResolutionScaleFactor(); -void Save(std::ostream &stream); -void Load(std::istream &stream); +void Save(std::ostream& stream); +void Load(std::istream& stream); } // namespace VideoCore From d6862c2fca114c23be7a1f98b800d5b360d731a8 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 27 Dec 2019 22:45:00 +0000 Subject: [PATCH 034/129] Some CI fixes --- src/core/core.cpp | 4 ++-- src/tests/core/hle/kernel/hle_ipc.cpp | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 6812a9474e..5b9b4fca03 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -213,8 +213,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo timing = std::make_unique(); - kernel = std::make_unique( - *memory, *timing, [this] { PrepareReschedule(); }, system_mode); + kernel = std::make_unique(*memory, *timing, + [this] { PrepareReschedule(); }, system_mode); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index 62cad0e357..e405f67290 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -26,8 +26,7 @@ static std::shared_ptr MakeObject(Kernel::KernelSystem& kernel) { TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") { Core::Timing timing; Memory::MemorySystem memory; - Kernel::KernelSystem kernel( - memory, timing, [] {}, 0); + Kernel::KernelSystem kernel(memory, timing, [] {}, 0); auto [server, client] = kernel.CreateSessionPair(); HLERequestContext context(kernel, std::move(server), nullptr); @@ -239,8 +238,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { Core::Timing timing; Memory::MemorySystem memory; - Kernel::KernelSystem kernel( - memory, timing, [] {}, 0); + Kernel::KernelSystem kernel(memory, timing, [] {}, 0); auto [server, client] = kernel.CreateSessionPair(); HLERequestContext context(kernel, std::move(server), nullptr); From c7106e232f1d042c6ba0a129b68e7e0e563d63ef Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sat, 28 Dec 2019 13:53:12 +0000 Subject: [PATCH 035/129] Fix a bug on mingw --- externals/boost | 2 +- src/core/hle/service/apt/applet_manager.cpp | 2 ++ src/core/hle/service/apt/applet_manager.h | 14 +++++--------- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/externals/boost b/externals/boost index 55725b7796..1c857c0419 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit 55725b7796c7faa0a4af869e412d0410bd47612d +Subproject commit 1c857c04195db89c66c347ddfad93a7f3666f2d3 diff --git a/src/core/hle/service/apt/applet_manager.cpp b/src/core/hle/service/apt/applet_manager.cpp index 8a24595ff2..6612a720e4 100644 --- a/src/core/hle/service/apt/applet_manager.cpp +++ b/src/core/hle/service/apt/applet_manager.cpp @@ -10,6 +10,8 @@ #include "core/hle/service/apt/ns.h" #include "core/hle/service/cfg/cfg.h" +SERVICE_CONSTRUCT_IMPL(Service::APT::AppletManager) + namespace Service::APT { enum class AppletPos { Application = 0, Library = 1, System = 2, SysLibrary = 3, Resident = 4 }; diff --git a/src/core/hle/service/apt/applet_manager.h b/src/core/hle/service/apt/applet_manager.h index e799c92d2e..0f28e57c87 100644 --- a/src/core/hle/service/apt/applet_manager.h +++ b/src/core/hle/service/apt/applet_manager.h @@ -6,10 +6,10 @@ #include #include -#include #include #include -#include "common/serialization/optional.h" +#include +#include #include "core/global.h" #include "core/hle/kernel/event.h" #include "core/hle/result.h" @@ -193,7 +193,8 @@ public: private: /// Parameter data to be returned in the next call to Glance/ReceiveParameter. - std::optional next_parameter; + // NOTE: A bug in gcc prevents serializing std::optional + boost::optional next_parameter; static constexpr std::size_t NumAppletSlot = 4; @@ -268,9 +269,4 @@ private: } // namespace Service::APT -namespace boost::serialization { -template -inline void load_construct_data(Archive& ar, Service::APT::AppletManager* t, const unsigned int) { - ::new (t) Service::APT::AppletManager(Core::Global()); -} -} // namespace boost::serialization +SERVICE_CONSTRUCT(Service::APT::AppletManager) From d041901a3002b80eafc8a4b2ab955f8f6b23ecda Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sat, 28 Dec 2019 23:13:39 +0000 Subject: [PATCH 036/129] Some more CI fixes --- CMakeLists.txt | 4 +- TODO | 3 +- src/CMakeLists.txt | 8 ++- src/common/CMakeLists.txt | 1 - src/common/serialization/optional.h | 76 ----------------------- src/core/hle/service/apt/applet_manager.h | 2 +- 6 files changed, 11 insertions(+), 83 deletions(-) delete mode 100644 src/common/serialization/optional.h diff --git a/CMakeLists.txt b/CMakeLists.txt index df8081f059..ac05c91c76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -126,9 +126,9 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) add_library(boost_libs INTERFACE) -find_package(Boost 1.66.0 QUIET) +find_package(Boost 1.70.0 QUIET EXACT) if (NOT Boost_FOUND) - message(STATUS "Boost 1.66.0 or newer not found, falling back to externals") + message(STATUS "Boost 1.70.0 not found, falling back to externals") set(BOOST_ROOT "${PROJECT_SOURCE_DIR}/externals/boost") set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost") diff --git a/TODO b/TODO index be118365db..45e6ae3b74 100644 --- a/TODO +++ b/TODO @@ -3,7 +3,8 @@ ✔ Memory @done(19-08-13 15:41) ☐ Page tables ☐ Skip N3DS RAM if unused -☐ DSP +✔ DSP @done(19-12-28 16:57) + Memory only ✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) ✔ Fix or ignore inverse map @done(19-12-23 12:46) ☐ App loader diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4a4c39f175..c13337efe1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -33,7 +33,6 @@ if (MSVC) # /Zc:throwingNew - Let codegen assume `operator new` (without std::nothrow) will never return null add_compile_options( /W3 - /MP /Zi /Zo /permissive- @@ -42,8 +41,13 @@ if (MSVC) /volatile:iso /Zc:externConstexpr /Zc:inline - /Zc:throwingNew ) + if (CMAKE_C_COMPILER_ID MATCHES "MSVC") + add_compile_options( + /MP + /Zc:throwingNew + ) + endif() # /GS- - No stack buffer overflow checks add_compile_options("$<$:/GS->") diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index ac745d8684..39ddffbcc0 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -96,7 +96,6 @@ add_library(common STATIC serialization/boost_discrete_interval.hpp serialization/boost_flat_set.h serialization/boost_vector.hpp - serialization/optional.h string_util.cpp string_util.h swap.h diff --git a/src/common/serialization/optional.h b/src/common/serialization/optional.h deleted file mode 100644 index 4e794058ed..0000000000 --- a/src/common/serialization/optional.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// function specializations must be defined in the appropriate -// namespace - boost::serialization -namespace boost { -namespace serialization { - -template -void save(Archive& ar, const std::optional& t, const unsigned int /*version*/ -) { -// It is an inherent limitation to the serialization of optional.hpp -// that the underlying type must be either a pointer or must have a -// default constructor. It's possible that this could change sometime -// in the future, but for now, one will have to work around it. This can -// be done by serialization the optional as optional -#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) - BOOST_STATIC_ASSERT(boost::serialization::detail::is_default_constructible::value || - boost::is_pointer::value); -#endif - const bool tflag = t.has_value(); - ar << boost::serialization::make_nvp("initialized", tflag); - if (tflag) { - ar << boost::serialization::make_nvp("value", *t); - } -} - -template -void load(Archive& ar, std::optional& t, const unsigned int version) { - bool tflag; - ar >> boost::serialization::make_nvp("initialized", tflag); - if (!tflag) { - t.reset(); - return; - } - - if (0 == version) { - boost::serialization::item_version_type item_version(0); - boost::archive::library_version_type library_version(ar.get_library_version()); - if (boost::archive::library_version_type(3) < library_version) { - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - } - if (!t.has_value()) - t = T(); - ar >> boost::serialization::make_nvp("value", *t); -} - -template -void serialize(Archive& ar, std::optional& t, const unsigned int version) { - boost::serialization::split_free(ar, t, version); -} - -template -struct version> { - BOOST_STATIC_CONSTANT(int, value = 1); -}; - -} // namespace serialization -} // namespace boost diff --git a/src/core/hle/service/apt/applet_manager.h b/src/core/hle/service/apt/applet_manager.h index 0f28e57c87..7260fb2d30 100644 --- a/src/core/hle/service/apt/applet_manager.h +++ b/src/core/hle/service/apt/applet_manager.h @@ -8,8 +8,8 @@ #include #include #include -#include #include +#include #include "core/global.h" #include "core/hle/kernel/event.h" #include "core/hle/result.h" From a0ac302a93aad8a537fb31011c2f7abe1b95f052 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sat, 28 Dec 2019 23:36:12 +0000 Subject: [PATCH 037/129] Definitely disable using system boost if version doesn't match --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac05c91c76..163b8e7c20 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,7 +132,7 @@ if (NOT Boost_FOUND) set(BOOST_ROOT "${PROJECT_SOURCE_DIR}/externals/boost") set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost") - set(Boost_NO_SYSTEM_PATHS OFF) + set(Boost_NO_SYSTEM_PATHS ON) add_definitions( -DBOOST_ALL_NO_LIB ) find_package(Boost QUIET REQUIRED) From 9877bf7d487ab8b7d1ac1110a2653c91a8e234be Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 30 Dec 2019 00:51:06 +0000 Subject: [PATCH 038/129] Change how the boost target works; disable external warnings in MSVC --- CMakeLists.txt | 35 ++++++++++++++++------------------- externals/CMakeLists.txt | 19 +++++++++++++++++++ src/CMakeLists.txt | 6 +++++- src/core/CMakeLists.txt | 2 +- src/video_core/CMakeLists.txt | 2 +- 5 files changed, 42 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 163b8e7c20..0d42aba93d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ # CMake 3.8 required for 17 to be a valid value for CXX_STANDARD cmake_minimum_required(VERSION 3.8) +cmake_policy(SET CMP0092 NEW) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules") include(DownloadExternals) @@ -35,6 +36,8 @@ CMAKE_DEPENDENT_OPTION(ENABLE_MF "Use Media Foundation decoder (preferred over F CMAKE_DEPENDENT_OPTION(COMPILE_WITH_DWARF "Add DWARF debugging information" ON "MINGW" OFF) +option(USE_SYSTEM_BOOST "Use the system Boost libs (instead of the bundled ones)" OFF) + if(NOT EXISTS ${PROJECT_SOURCE_DIR}/.git/hooks/pre-commit) message(STATUS "Copying pre-commit hook") file(COPY hooks/pre-commit @@ -124,25 +127,6 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) # System imported libraries # ====================== -add_library(boost_libs INTERFACE) - -find_package(Boost 1.70.0 QUIET EXACT) -if (NOT Boost_FOUND) - message(STATUS "Boost 1.70.0 not found, falling back to externals") - - set(BOOST_ROOT "${PROJECT_SOURCE_DIR}/externals/boost") - set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost") - set(Boost_NO_SYSTEM_PATHS ON) - add_definitions( -DBOOST_ALL_NO_LIB ) - find_package(Boost QUIET REQUIRED) - - # Boost external libraries - file(GLOB boost_serialization_SRC "externals/boost/libs/serialization/src/*.cpp") - add_library(boost_serialization STATIC ${boost_serialization_SRC}) - target_link_libraries(boost_serialization PUBLIC Boost::boost) - target_link_libraries(boost_libs INTERFACE boost_serialization) -endif() - # Prefer the -pthread flag on Linux. set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) @@ -340,8 +324,21 @@ git_describe(GIT_DESC --always --long --dirty) git_branch_name(GIT_BRANCH) get_timestamp(BUILD_DATE) +if (NOT USE_SYSTEM_BOOST) + add_definitions( -DBOOST_ALL_NO_LIB ) +endif() + enable_testing() add_subdirectory(externals) + +# Boost +if (USE_SYSTEM_BOOST) + find_package(Boost 1.70.0 QUIET REQUIRED) +else() + add_library(Boost::boost ALIAS boost) + add_library(Boost::serialization ALIAS boost_serialization) +endif() + add_subdirectory(src) add_subdirectory(dist/installer) diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 63159a52b5..47a92794cb 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -1,9 +1,28 @@ # Definitions for all external bundled libraries +# Suppress warnings from external libraries +if (CMAKE_C_COMPILER_ID MATCHES "MSVC") + add_compile_options(/W0) +endif() + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules) include(DownloadExternals) include(ExternalProject) +# Boost +set(BOOST_ROOT "${CMAKE_SOURCE_DIR}/externals/boost") +set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost") +set(Boost_NO_SYSTEM_PATHS ON) +add_library(boost INTERFACE) +target_include_directories(boost SYSTEM INTERFACE ${Boost_INCLUDE_DIR}) + +# Boost::serialization +file(GLOB boost_serialization_SRC "${CMAKE_SOURCE_DIR}/externals/boost/libs/serialization/src/*.cpp") +add_library(boost_serialization STATIC ${boost_serialization_SRC}) +target_link_libraries(boost_serialization PUBLIC boost) + +# Add additional boost libs here; remember to ALIAS them in the root CMakeLists! + # Catch add_library(catch-single-include INTERFACE) target_include_directories(catch-single-include INTERFACE catch/single_include) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c13337efe1..d466415701 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,7 +37,7 @@ if (MSVC) /Zo /permissive- /EHsc - /std:c++latest + /std:c++17 /volatile:iso /Zc:externConstexpr /Zc:inline @@ -46,6 +46,10 @@ if (MSVC) add_compile_options( /MP /Zc:throwingNew + /experimental:external + /external:I "${CMAKE_SOURCE_DIR}/externals" + /external:anglebrackets + /external:W0 ) endif() diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 9ed9a856dd..c6908c59a6 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -466,7 +466,7 @@ endif() create_target_directory_groups(core) target_link_libraries(core PUBLIC common PRIVATE audio_core network video_core) -target_link_libraries(core PUBLIC Boost::boost PRIVATE cryptopp fmt open_source_archives boost_libs) +target_link_libraries(core PUBLIC Boost::boost PRIVATE cryptopp fmt open_source_archives Boost::serialization) if (ENABLE_WEB_SERVICE) target_compile_definitions(core PRIVATE -DENABLE_WEB_SERVICE) target_link_libraries(core PRIVATE web_service) diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 8dbf5d8e09..17e344aa4a 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -94,7 +94,7 @@ endif() create_target_directory_groups(video_core) target_link_libraries(video_core PUBLIC common core) -target_link_libraries(video_core PRIVATE glad nihstro-headers boost_libs) +target_link_libraries(video_core PRIVATE glad nihstro-headers Boost::serialization) if (ARCHITECTURE_x86_64) target_link_libraries(video_core PUBLIC xbyak) From 754f63af1a1f027fbfd213c190b937f66dadf89f Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 30 Dec 2019 10:23:20 +0000 Subject: [PATCH 039/129] Don't require cmake 3.15 --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d42aba93d..f986a39af2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,8 @@ # CMake 3.8 required for 17 to be a valid value for CXX_STANDARD cmake_minimum_required(VERSION 3.8) -cmake_policy(SET CMP0092 NEW) +if (${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.15) + cmake_policy(SET CMP0092 NEW) +endif () list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules") include(DownloadExternals) From 30494c06a4c8f4277a6919869975e78b001092fd Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 30 Dec 2019 12:45:22 +0000 Subject: [PATCH 040/129] Serialize GSP service --- TODO | 3 ++- src/core/hle/service/gsp/gsp.cpp | 2 +- src/core/hle/service/gsp/gsp_gpu.cpp | 5 +++++ src/core/hle/service/gsp/gsp_gpu.h | 24 ++++++++++++++++++++++++ src/core/hle/service/gsp/gsp_lcd.cpp | 3 +++ src/core/hle/service/gsp/gsp_lcd.h | 2 ++ 6 files changed, 37 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 45e6ae3b74..fa627b214a 100644 --- a/TODO +++ b/TODO @@ -81,7 +81,8 @@ ✔ ERR @done(19-12-26 18:14) ✔ FRD @done(19-12-26 19:09) ✔ FS @done(19-12-27 11:46) - ☐ GSP + ✔ GSP @done(19-12-30 12:45) + ☐ Fix the global weak_ptr to gsp ☐ HID ☐ HTTP ☐ IR diff --git a/src/core/hle/service/gsp/gsp.cpp b/src/core/hle/service/gsp/gsp.cpp index 4291b99710..3d3f497b2b 100644 --- a/src/core/hle/service/gsp/gsp.cpp +++ b/src/core/hle/service/gsp/gsp.cpp @@ -10,7 +10,7 @@ namespace Service::GSP { -static std::weak_ptr gsp_gpu; +static std::weak_ptr gsp_gpu; // TODO: Fix this for the love of god void SignalInterrupt(InterruptId interrupt_id) { auto gpu = gsp_gpu.lock(); diff --git a/src/core/hle/service/gsp/gsp_gpu.cpp b/src/core/hle/service/gsp/gsp_gpu.cpp index 33558fe10f..78d84499b9 100644 --- a/src/core/hle/service/gsp/gsp_gpu.cpp +++ b/src/core/hle/service/gsp/gsp_gpu.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/bit_field.h" #include "common/microprofile.h" #include "common/swap.h" @@ -21,6 +22,10 @@ #include "video_core/debug_utils/debug_utils.h" #include "video_core/gpu_debugger.h" +SERIALIZE_EXPORT_IMPL(Service::GSP::SessionData) +SERIALIZE_EXPORT_IMPL(Service::GSP::GSP_GPU) +SERVICE_CONSTRUCT_IMPL(Service::GSP::GSP_GPU) + // Main graphics debugger object - TODO: Here is probably not the best place for this GraphicsDebugger g_debugger; diff --git a/src/core/hle/service/gsp/gsp_gpu.h b/src/core/hle/service/gsp/gsp_gpu.h index 8b43b9cea3..d1f2c0742f 100644 --- a/src/core/hle/service/gsp/gsp_gpu.h +++ b/src/core/hle/service/gsp/gsp_gpu.h @@ -199,6 +199,16 @@ public: u32 thread_id; /// Whether RegisterInterruptRelayQueue was called for this session bool registered = false; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& gsp; + ar& interrupt_event; + ar& thread_id; + ar& registered; + } + friend class boost::serialization::access; }; class GSP_GPU final : public ServiceFramework { @@ -431,8 +441,22 @@ private: std::array used_thread_ids = {false, false, false, false}; friend class SessionData; + + template + void serialize(Archive& ar, const unsigned int) { + ar& shared_memory; + ar& active_thread_id; + ar& first_initialization; + ar& used_thread_ids; + } + + friend class boost::serialization::access; }; ResultCode SetBufferSwap(u32 screen_id, const FrameBufferInfo& info); } // namespace Service::GSP + +BOOST_CLASS_EXPORT_KEY(Service::GSP::SessionData) +BOOST_CLASS_EXPORT_KEY(Service::GSP::GSP_GPU) +SERVICE_CONSTRUCT(Service::GSP::GSP_GPU) diff --git a/src/core/hle/service/gsp/gsp_lcd.cpp b/src/core/hle/service/gsp/gsp_lcd.cpp index d795b87161..67a2e76286 100644 --- a/src/core/hle/service/gsp/gsp_lcd.cpp +++ b/src/core/hle/service/gsp/gsp_lcd.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/gsp/gsp_lcd.h" +SERIALIZE_EXPORT_IMPL(Service::GSP::GSP_LCD) + namespace Service::GSP { GSP_LCD::GSP_LCD() : ServiceFramework("gsp::Lcd") { diff --git a/src/core/hle/service/gsp/gsp_lcd.h b/src/core/hle/service/gsp/gsp_lcd.h index 24e57fb42f..781d9dba8d 100644 --- a/src/core/hle/service/gsp/gsp_lcd.h +++ b/src/core/hle/service/gsp/gsp_lcd.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::GSP + +BOOST_CLASS_EXPORT_KEY(Service::GSP::GSP_LCD) From 74361fa3fbed7ab4669c59e84619fda501180ece Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 30 Dec 2019 14:46:35 +0000 Subject: [PATCH 041/129] Serialize HID service --- TODO | 2 +- src/core/hle/service/hid/hid.cpp | 25 +++++++++++++++++++++++++ src/core/hle/service/hid/hid.h | 9 ++++++++- src/core/hle/service/hid/hid_spvr.cpp | 3 +++ src/core/hle/service/hid/hid_spvr.h | 5 +++++ src/core/hle/service/hid/hid_user.cpp | 3 +++ src/core/hle/service/hid/hid_user.h | 5 +++++ 7 files changed, 50 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index fa627b214a..51cbc627c6 100644 --- a/TODO +++ b/TODO @@ -83,7 +83,7 @@ ✔ FS @done(19-12-27 11:46) ✔ GSP @done(19-12-30 12:45) ☐ Fix the global weak_ptr to gsp - ☐ HID + ✔ HID @done(19-12-30 14:46) ☐ HTTP ☐ IR ☐ LDR_RO diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index ded1809b1a..f20cebca7d 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/archives.h" #include "common/logging/log.h" #include "core/3ds.h" #include "core/core.h" @@ -20,8 +21,32 @@ #include "core/movie.h" #include "video_core/video_core.h" +SERVICE_CONSTRUCT_IMPL(Service::HID::Module) +SERIALIZE_EXPORT_IMPL(Service::HID::Module) + namespace Service::HID { +template +void Module::serialize(Archive& ar, const unsigned int) { + ar& shared_mem; + ar& event_pad_or_touch_1; + ar& event_pad_or_touch_2; + ar& event_accelerometer; + ar& event_gyroscope; + ar& event_debug_pad; + ar& next_pad_index; + ar& next_touch_index; + ar& next_accelerometer_index; + ar& next_gyroscope_index; + ar& enable_accelerometer_count; + ar& enable_gyroscope_count; + ReloadInputDevices(); + // Pad state not needed as it's always updated + // Update events are set in the constructor + // Devices are set from the implementation (and are stateless afaik) +} +SERIALIZE_IMPL(Module) + // Updating period for each HID device. These empirical values are measured from a 11.2 3DS. constexpr u64 pad_update_ticks = BASE_CLOCK_RATE_ARM11 / 234; constexpr u64 accelerometer_update_ticks = BASE_CLOCK_RATE_ARM11 / 104; diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 8d217f8356..e34c1186ab 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -294,7 +294,7 @@ public: */ void GetGyroscopeLowCalibrateParam(Kernel::HLERequestContext& ctx); - private: + protected: std::shared_ptr hid; }; @@ -342,9 +342,16 @@ private: std::unique_ptr circle_pad; std::unique_ptr motion_device; std::unique_ptr touch_device; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; std::shared_ptr GetModule(Core::System& system); void InstallInterfaces(Core::System& system); } // namespace Service::HID + +SERVICE_CONSTRUCT(Service::HID::Module) +BOOST_CLASS_EXPORT_KEY(Service::HID::Module) diff --git a/src/core/hle/service/hid/hid_spvr.cpp b/src/core/hle/service/hid/hid_spvr.cpp index 8371a61698..87791f0738 100644 --- a/src/core/hle/service/hid/hid_spvr.cpp +++ b/src/core/hle/service/hid/hid_spvr.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/hid/hid_spvr.h" +SERIALIZE_EXPORT_IMPL(Service::HID::Spvr) + namespace Service::HID { Spvr::Spvr(std::shared_ptr hid) : Module::Interface(std::move(hid), "hid:SPVR", 6) { diff --git a/src/core/hle/service/hid/hid_spvr.h b/src/core/hle/service/hid/hid_spvr.h index e2346dda57..a49101dc34 100644 --- a/src/core/hle/service/hid/hid_spvr.h +++ b/src/core/hle/service/hid/hid_spvr.h @@ -11,6 +11,11 @@ namespace Service::HID { class Spvr final : public Module::Interface { public: explicit Spvr(std::shared_ptr hid); +private: + SERVICE_SERIALIZATION(Spvr, hid, Module) }; } // namespace Service::HID + +BOOST_CLASS_EXPORT_KEY(Service::HID::Spvr) +BOOST_SERIALIZATION_CONSTRUCT(Service::HID::Spvr) diff --git a/src/core/hle/service/hid/hid_user.cpp b/src/core/hle/service/hid/hid_user.cpp index 129b3fd02d..97ce8f111f 100644 --- a/src/core/hle/service/hid/hid_user.cpp +++ b/src/core/hle/service/hid/hid_user.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/hid/hid_user.h" +SERIALIZE_EXPORT_IMPL(Service::HID::User) + namespace Service::HID { User::User(std::shared_ptr hid) : Module::Interface(std::move(hid), "hid:USER", 6) { diff --git a/src/core/hle/service/hid/hid_user.h b/src/core/hle/service/hid/hid_user.h index 813f095047..6fd9803c6d 100644 --- a/src/core/hle/service/hid/hid_user.h +++ b/src/core/hle/service/hid/hid_user.h @@ -14,6 +14,11 @@ namespace Service::HID { class User final : public Module::Interface { public: explicit User(std::shared_ptr hid); +private: + SERVICE_SERIALIZATION(User, hid, Module) }; } // namespace Service::HID + +BOOST_CLASS_EXPORT_KEY(Service::HID::User) +BOOST_SERIALIZATION_CONSTRUCT(Service::HID::User) From 8bd3e8cd27363dda33871baad57f204cc348bd43 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 30 Dec 2019 15:20:13 +0000 Subject: [PATCH 042/129] Serialize HTTP service --- TODO | 2 +- externals/boost | 2 +- src/core/hle/service/http_c.cpp | 4 + src/core/hle/service/http_c.h | 128 +++++++++++++++++++++++++++++++- 4 files changed, 130 insertions(+), 6 deletions(-) diff --git a/TODO b/TODO index 51cbc627c6..f72330fd14 100644 --- a/TODO +++ b/TODO @@ -84,7 +84,7 @@ ✔ GSP @done(19-12-30 12:45) ☐ Fix the global weak_ptr to gsp ✔ HID @done(19-12-30 14:46) - ☐ HTTP + ✔ HTTP @done(19-12-30 15:18) ☐ IR ☐ LDR_RO ☐ MIC diff --git a/externals/boost b/externals/boost index 1c857c0419..65dc954e93 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit 1c857c04195db89c66c347ddfad93a7f3666f2d3 +Subproject commit 65dc954e93b22870b8423701e225147c75e3b31b diff --git a/src/core/hle/service/http_c.cpp b/src/core/hle/service/http_c.cpp index 221f3cc202..768dd3bd8b 100644 --- a/src/core/hle/service/http_c.cpp +++ b/src/core/hle/service/http_c.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/archives.h" #include "core/core.h" #include "core/file_sys/archive_ncch.h" #include "core/file_sys/file_backend.h" @@ -14,6 +15,9 @@ #include "core/hle/service/http_c.h" #include "core/hw/aes/key.h" +SERIALIZE_EXPORT_IMPL(Service::HTTP::HTTP_C) +SERIALIZE_EXPORT_IMPL(Service::HTTP::SessionData) + namespace Service::HTTP { namespace ErrCodes { diff --git a/src/core/hle/service/http_c.h b/src/core/hle/service/http_c.h index 91a455820d..a3aa62ae0a 100644 --- a/src/core/hle/service/http_c.h +++ b/src/core/hle/service/http_c.h @@ -5,10 +5,16 @@ #pragma once #include -#include #include #include #include +#include +#include +#include +#include +#include +#include +#include #include "core/hle/kernel/shared_memory.h" #include "core/hle/service/service.h" @@ -50,6 +56,17 @@ struct ClientCertContext { u8 cert_id; std::vector certificate; std::vector private_key; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& handle; + ar& session_id; + ar& cert_id; + ar& certificate; + ar& private_key; + } + friend class boost::serialization::access; }; /// Represents a root certificate chain, it contains a list of DER-encoded certificates for @@ -61,12 +78,30 @@ struct RootCertChain { Handle handle; u32 session_id; std::vector certificate; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& handle; + ar& session_id; + ar& certificate; + } + friend class boost::serialization::access; }; using Handle = u32; Handle handle; u32 session_id; std::vector certificates; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& handle; + ar& session_id; + ar& certificates; + } + friend class boost::serialization::access; }; /// Represents an HTTP context. @@ -86,30 +121,74 @@ public: std::string username; std::string password; u16 port; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& url; + ar& username; + ar& password; + ar& port; + } + friend class boost::serialization::access; }; struct BasicAuth { std::string username; std::string password; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& username; + ar& password; + } + friend class boost::serialization::access; }; struct RequestHeader { RequestHeader(std::string name, std::string value) : name(name), value(value){}; std::string name; std::string value; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& name; + ar& value; + } + friend class boost::serialization::access; }; struct PostData { // TODO(Subv): Support Binary and Raw POST elements. PostData(std::string name, std::string value) : name(name), value(value){}; + PostData() = default; std::string name; std::string value; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& name; + ar& value; + } + friend class boost::serialization::access; }; struct SSLConfig { u32 options; std::weak_ptr client_cert_ctx; std::weak_ptr root_ca_chain; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& options; + ar& client_cert_ctx; + ar& root_ca_chain; + } + friend class boost::serialization::access; }; Handle handle; @@ -117,18 +196,35 @@ public: std::string url; RequestMethod method; RequestState state = RequestState::NotStarted; - std::optional proxy; - std::optional basic_auth; + boost::optional proxy; + boost::optional basic_auth; SSLConfig ssl_config{}; u32 socket_buffer_size; std::vector headers; std::vector post_data; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& handle; + ar& session_id; + ar& url; + ar& method; + ar& state; + ar& proxy; + ar& basic_auth; + ar& ssl_config; + ar& socket_buffer_size; + ar& headers; + ar& post_data; + } + friend class boost::serialization::access; }; struct SessionData : public Kernel::SessionRequestHandler::SessionDataBase { /// The HTTP context that is currently bound to this session, this can be empty if no context /// has been bound. Certain commands can only be called on a session with a bound context. - std::optional current_http_context; + boost::optional current_http_context; u32 session_id; @@ -140,6 +236,17 @@ struct SessionData : public Kernel::SessionRequestHandler::SessionDataBase { /// Whether this session has been initialized in some way, be it via Initialize or /// InitializeConnectionSession. bool initialized = false; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& current_http_context; + ar& session_id; + ar& num_http_contexts; + ar& num_client_certs; + ar& initialized; + } + friend class boost::serialization::access; }; class HTTP_C final : public ServiceFramework { @@ -326,8 +433,21 @@ private: std::vector private_key; bool init = false; } ClCertA; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& ClCertA.certificate; + ar& ClCertA.private_key; + ar& ClCertA.init; + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::HTTP + +BOOST_CLASS_EXPORT_KEY(Service::HTTP::HTTP_C) +BOOST_CLASS_EXPORT_KEY(Service::HTTP::SessionData) From eb67167b7c9b9262b0c6ce7b5c99732d228a3f8d Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 30 Dec 2019 16:07:03 +0000 Subject: [PATCH 043/129] Serialize IR service --- TODO | 2 +- src/core/hle/service/ir/extra_hid.h | 12 +++++++ src/core/hle/service/ir/ir_user.cpp | 51 ++++++++++++++++++++++++----- src/core/hle/service/ir/ir_user.h | 9 ++++- 4 files changed, 64 insertions(+), 10 deletions(-) diff --git a/TODO b/TODO index f72330fd14..b679a5168f 100644 --- a/TODO +++ b/TODO @@ -85,7 +85,7 @@ ☐ Fix the global weak_ptr to gsp ✔ HID @done(19-12-30 14:46) ✔ HTTP @done(19-12-30 15:18) - ☐ IR + ✔ IR @done(19-12-30 16:06) ☐ LDR_RO ☐ MIC ☐ MVD diff --git a/src/core/hle/service/ir/extra_hid.h b/src/core/hle/service/ir/extra_hid.h index d21cb393fe..7924a1e12b 100644 --- a/src/core/hle/service/ir/extra_hid.h +++ b/src/core/hle/service/ir/extra_hid.h @@ -6,6 +6,8 @@ #include #include +#include +#include #include "common/bit_field.h" #include "common/swap.h" #include "core/frontend/input.h" @@ -65,6 +67,16 @@ private: std::unique_ptr zr; std::unique_ptr c_stick; std::atomic is_device_reload_pending; + + template + void serialize(Archive& ar, const unsigned int) { + ar& hid_period; + ar& calibration_data; // This isn't writeable for now, but might be in future + RequestInputDevicesReload(); // zl, zr, c_stick are loaded here + } + friend class boost::serialization::access; }; } // namespace Service::IR + +BOOST_CLASS_EXPORT_KEY(Service::IR::ExtraHID) diff --git a/src/core/hle/service/ir/ir_user.cpp b/src/core/hle/service/ir/ir_user.cpp index d392c1983d..fd6c1b905a 100644 --- a/src/core/hle/service/ir/ir_user.cpp +++ b/src/core/hle/service/ir/ir_user.cpp @@ -15,6 +15,19 @@ namespace Service::IR { +template +void IR_USER::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& conn_status_event; + ar& send_event; + ar& receive_event; + ar& shared_memory; + ar& connected_device; + ar& *receive_buffer.get(); + ar& *extra_hid.get(); +} +SERIALIZE_IMPL(IR_USER) + // This is a header that will present in the ir:USER shared memory if it is initialized with // InitializeIrNopShared service function. Otherwise the shared memory doesn't have this header if // it is initialized with InitializeIrNop service function. @@ -139,6 +152,16 @@ private: u32_le end_index; u32_le packet_count; u32_le unknown; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& begin_index; + ar& end_index; + ar& packet_count; + ar& unknown; + } + friend class boost::serialization::access; }; static_assert(sizeof(BufferInfo) == 16, "BufferInfo has wrong size!"); @@ -179,6 +202,18 @@ private: u32 buffer_offset; u32 max_packet_count; u32 max_data_size; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& info; + ar& shared_memory; + ar& info_offset; + ar& buffer_offset; + ar& max_packet_count; + ar& max_data_size; + } + friend class boost::serialization::access; }; /// Wraps the payload into packet and puts it to the receive buffer @@ -270,8 +305,8 @@ void IR_USER::RequireConnection(Kernel::HLERequestContext& ctx) { shared_memory_ptr[offsetof(SharedMemoryHeader, connection_role)] = 2; shared_memory_ptr[offsetof(SharedMemoryHeader, connected)] = 1; - connected_device = extra_hid.get(); - connected_device->OnConnect(); + connected_device = true; + extra_hid->OnConnect(); conn_status_event->Signal(); } else { LOG_WARNING(Service_IR, "unknown device id {}. Won't connect.", device_id); @@ -305,8 +340,8 @@ void IR_USER::GetSendEvent(Kernel::HLERequestContext& ctx) { void IR_USER::Disconnect(Kernel::HLERequestContext& ctx) { if (connected_device) { - connected_device->OnDisconnect(); - connected_device = nullptr; + extra_hid->OnDisconnect(); + connected_device = false; conn_status_event->Signal(); } @@ -331,8 +366,8 @@ void IR_USER::GetConnectionStatusEvent(Kernel::HLERequestContext& ctx) { void IR_USER::FinalizeIrNop(Kernel::HLERequestContext& ctx) { if (connected_device) { - connected_device->OnDisconnect(); - connected_device = nullptr; + extra_hid->OnDisconnect(); + connected_device = false; } shared_memory = nullptr; @@ -352,7 +387,7 @@ void IR_USER::SendIrNop(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); if (connected_device) { - connected_device->OnReceive(buffer); + extra_hid->OnReceive(buffer); send_event->Signal(); rb.Push(RESULT_SUCCESS); } else { @@ -424,7 +459,7 @@ IR_USER::IR_USER(Core::System& system) : ServiceFramework("ir:USER", 1) { IR_USER::~IR_USER() { if (connected_device) { - connected_device->OnDisconnect(); + extra_hid->OnDisconnect(); } } diff --git a/src/core/hle/service/ir/ir_user.h b/src/core/hle/service/ir/ir_user.h index 54a4f3e087..75bbeb7791 100644 --- a/src/core/hle/service/ir/ir_user.h +++ b/src/core/hle/service/ir/ir_user.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "core/hle/service/service.h" namespace Kernel { @@ -45,6 +46,7 @@ protected: void Send(const std::vector& data); private: + // NOTE: This value is *not* serialized because it's always passed in the constructor const SendFunc send_func; }; @@ -164,9 +166,14 @@ private: std::shared_ptr conn_status_event, send_event, receive_event; std::shared_ptr shared_memory; - IRDevice* connected_device{nullptr}; + bool connected_device; std::unique_ptr receive_buffer; std::unique_ptr extra_hid; + +private: + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; } // namespace Service::IR From e3c0211b7418a78f43722376305593472c27e574 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 30 Dec 2019 16:15:41 +0000 Subject: [PATCH 044/129] Fix clang format --- src/core/hle/service/hid/hid_spvr.h | 1 + src/core/hle/service/hid/hid_user.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/core/hle/service/hid/hid_spvr.h b/src/core/hle/service/hid/hid_spvr.h index a49101dc34..749bd36b8b 100644 --- a/src/core/hle/service/hid/hid_spvr.h +++ b/src/core/hle/service/hid/hid_spvr.h @@ -11,6 +11,7 @@ namespace Service::HID { class Spvr final : public Module::Interface { public: explicit Spvr(std::shared_ptr hid); + private: SERVICE_SERIALIZATION(Spvr, hid, Module) }; diff --git a/src/core/hle/service/hid/hid_user.h b/src/core/hle/service/hid/hid_user.h index 6fd9803c6d..8a6763ea65 100644 --- a/src/core/hle/service/hid/hid_user.h +++ b/src/core/hle/service/hid/hid_user.h @@ -14,6 +14,7 @@ namespace Service::HID { class User final : public Module::Interface { public: explicit User(std::shared_ptr hid); + private: SERVICE_SERIALIZATION(User, hid, Module) }; From 01ec2e8a67999afbacacdb00eb5ed507ac9b1b73 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 30 Dec 2019 16:53:57 +0000 Subject: [PATCH 045/129] Serialize MIC service --- TODO | 4 +-- src/core/hle/service/ldr_ro/ldr_ro.cpp | 4 +++ src/core/hle/service/ldr_ro/ldr_ro.h | 18 ++++++++++++ src/core/hle/service/mic_u.cpp | 40 ++++++++++++++++++++++++++ src/core/hle/service/mic_u.h | 7 +++++ 5 files changed, 71 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index b679a5168f..2aff6ae689 100644 --- a/TODO +++ b/TODO @@ -86,8 +86,8 @@ ✔ HID @done(19-12-30 14:46) ✔ HTTP @done(19-12-30 15:18) ✔ IR @done(19-12-30 16:06) - ☐ LDR_RO - ☐ MIC + ✔ LDR_RO @done(19-12-30 16:25) + ✔ MIC @done(19-12-30 16:53) ☐ MVD ☐ NDM ☐ NEWS diff --git a/src/core/hle/service/ldr_ro/ldr_ro.cpp b/src/core/hle/service/ldr_ro/ldr_ro.cpp index caa063593e..0a61f4c23c 100644 --- a/src/core/hle/service/ldr_ro/ldr_ro.cpp +++ b/src/core/hle/service/ldr_ro/ldr_ro.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "common/alignment.h" +#include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" #include "core/arm/arm_interface.h" @@ -12,6 +13,9 @@ #include "core/hle/service/ldr_ro/cro_helper.h" #include "core/hle/service/ldr_ro/ldr_ro.h" +SERVICE_CONSTRUCT_IMPL(Service::LDR::RO) +SERIALIZE_EXPORT_IMPL(Service::LDR::RO) + namespace Service::LDR { static const ResultCode ERROR_ALREADY_INITIALIZED = // 0xD9612FF9 diff --git a/src/core/hle/service/ldr_ro/ldr_ro.h b/src/core/hle/service/ldr_ro/ldr_ro.h index f90005d13e..2b6f79f032 100644 --- a/src/core/hle/service/ldr_ro/ldr_ro.h +++ b/src/core/hle/service/ldr_ro/ldr_ro.h @@ -14,6 +14,13 @@ namespace Service::LDR { struct ClientSlot : public Kernel::SessionRequestHandler::SessionDataBase { VAddr loaded_crs = 0; ///< the virtual address of the static module + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& loaded_crs; + } + friend class boost::serialization::access; }; class RO final : public ServiceFramework { @@ -151,8 +158,19 @@ private: void Shutdown(Kernel::HLERequestContext& self); Core::System& system; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::LDR + +SERVICE_CONSTRUCT(Service::LDR::RO) +BOOST_CLASS_EXPORT_KEY(Service::LDR::RO) +BOOST_CLASS_EXPORT_KEY(Service::LDR::ClientSlot) diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index ba3e978072..34b16094a7 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp @@ -5,6 +5,7 @@ #ifdef HAVE_CUBEB #include "audio_core/cubeb_input.h" #endif +#include "common/archives.h" #include "common/logging/log.h" #include "core/core.h" #include "core/frontend/mic.h" @@ -17,8 +18,17 @@ #include "core/hle/service/mic_u.h" #include "core/settings.h" +SERVICE_CONSTRUCT_IMPL(Service::MIC::MIC_U) +SERIALIZE_EXPORT_IMPL(Service::MIC::MIC_U) + namespace Service::MIC { +template +void MIC_U::serialize(Archive& ar, const unsigned int) { + ar&* impl.get(); +} +SERIALIZE_IMPL(MIC_U) + /// Microphone audio encodings. enum class Encoding : u8 { PCM8 = 0, ///< Unsigned 8-bit PCM. @@ -59,6 +69,7 @@ constexpr u64 GetBufferUpdateRate(SampleRate sample_rate) { // Variables holding the current mic buffer writing state struct State { + std::shared_ptr memory_ref = nullptr; u8* sharedmem_buffer = nullptr; u32 sharedmem_size = 0; std::size_t size = 0; @@ -95,6 +106,20 @@ struct State { std::memcpy(sharedmem_buffer + (sharedmem_size - sizeof(u32)), reinterpret_cast(&off), sizeof(u32)); } + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& sharedmem_size; + ar& size; + ar& offset; + ar& initial_offset; + ar& looped_buffer; + ar& sample_size; + ar& sample_rate; + sharedmem_buffer = memory_ref ? memory_ref->GetPointer() : nullptr; + } + friend class boost::serialization::access; }; struct MIC_U::Impl { @@ -363,6 +388,21 @@ struct MIC_U::Impl { std::unique_ptr mic; Core::Timing& timing; State state{}; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& change_mic_impl_requested; + ar& buffer_full_event; + // buffer_write_event set in constructor + ar& shared_memory; + ar& client_version; + ar& allow_shell_closed; + ar& clamp; + // mic interface set in constructor + ar& state; + } + friend class boost::serialization::access; }; void MIC_U::MapSharedMem(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/mic_u.h b/src/core/hle/service/mic_u.h index 2e40ed4047..2ca95e924f 100644 --- a/src/core/hle/service/mic_u.h +++ b/src/core/hle/service/mic_u.h @@ -190,6 +190,10 @@ private: struct Impl; std::unique_ptr impl; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; void ReloadMic(Core::System& system); @@ -197,3 +201,6 @@ void ReloadMic(Core::System& system); void InstallInterfaces(Core::System& system); } // namespace Service::MIC + +SERVICE_CONSTRUCT(Service::MIC::MIC_U) +BOOST_CLASS_EXPORT_KEY(Service::MIC::MIC_U) From 3d6e372f96228fca0dfb17dc8b058af9088beefb Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 30 Dec 2019 17:02:44 +0000 Subject: [PATCH 046/129] More clang format fixes. Really need to standardise the version of this --- src/core/hle/service/ir/extra_hid.h | 2 +- src/core/hle/service/ir/ir_user.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/hle/service/ir/extra_hid.h b/src/core/hle/service/ir/extra_hid.h index 7924a1e12b..1be403167d 100644 --- a/src/core/hle/service/ir/extra_hid.h +++ b/src/core/hle/service/ir/extra_hid.h @@ -71,7 +71,7 @@ private: template void serialize(Archive& ar, const unsigned int) { ar& hid_period; - ar& calibration_data; // This isn't writeable for now, but might be in future + ar& calibration_data; // This isn't writeable for now, but might be in future RequestInputDevicesReload(); // zl, zr, c_stick are loaded here } friend class boost::serialization::access; diff --git a/src/core/hle/service/ir/ir_user.cpp b/src/core/hle/service/ir/ir_user.cpp index fd6c1b905a..64a298103e 100644 --- a/src/core/hle/service/ir/ir_user.cpp +++ b/src/core/hle/service/ir/ir_user.cpp @@ -23,8 +23,8 @@ void IR_USER::serialize(Archive& ar, const unsigned int) { ar& receive_event; ar& shared_memory; ar& connected_device; - ar& *receive_buffer.get(); - ar& *extra_hid.get(); + ar&* receive_buffer.get(); + ar&* extra_hid.get(); } SERIALIZE_IMPL(IR_USER) From 2409ee39cbafd6631a5ed1f45f8d0f9c2ccd94ee Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Tue, 31 Dec 2019 20:39:38 +0000 Subject: [PATCH 047/129] Serialize IR, MVD, NDM, NEWS, NFC --- TODO | 8 ++++---- src/core/hle/service/ir/ir_rst.cpp | 17 +++++++++++++++++ src/core/hle/service/ir/ir_rst.h | 7 +++++++ src/core/hle/service/ir/ir_u.cpp | 3 +++ src/core/hle/service/ir/ir_u.h | 2 ++ src/core/hle/service/mvd/mvd_std.cpp | 3 +++ src/core/hle/service/mvd/mvd_std.h | 9 +++++++++ src/core/hle/service/ndm/ndm_u.cpp | 3 +++ src/core/hle/service/ndm/ndm_u.h | 15 +++++++++++++++ src/core/hle/service/news/news_s.cpp | 3 +++ src/core/hle/service/news/news_s.h | 2 ++ src/core/hle/service/news/news_u.cpp | 3 +++ src/core/hle/service/news/news_u.h | 2 ++ src/core/hle/service/nfc/nfc.cpp | 13 +++++++++++++ src/core/hle/service/nfc/nfc.h | 9 ++++++++- src/core/hle/service/nfc/nfc_m.cpp | 3 +++ src/core/hle/service/nfc/nfc_m.h | 6 ++++++ src/core/hle/service/nfc/nfc_u.cpp | 3 +++ src/core/hle/service/nfc/nfc_u.h | 6 ++++++ 19 files changed, 112 insertions(+), 5 deletions(-) diff --git a/TODO b/TODO index 2aff6ae689..f9fffa60d7 100644 --- a/TODO +++ b/TODO @@ -88,10 +88,10 @@ ✔ IR @done(19-12-30 16:06) ✔ LDR_RO @done(19-12-30 16:25) ✔ MIC @done(19-12-30 16:53) - ☐ MVD - ☐ NDM - ☐ NEWS - ☐ NFC + ✔ MVD @done(19-12-31 18:26) + ✔ NDM @done(19-12-31 18:26) + ✔ NEWS @done(19-12-31 18:29) + ✔ NFC @done(19-12-31 20:35) ☐ NIM ☐ NS ☐ NWM diff --git a/src/core/hle/service/ir/ir_rst.cpp b/src/core/hle/service/ir/ir_rst.cpp index 71d16a1ce7..dc9612e624 100644 --- a/src/core/hle/service/ir/ir_rst.cpp +++ b/src/core/hle/service/ir/ir_rst.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/core.h" #include "core/core_timing.h" #include "core/hle/ipc_helpers.h" @@ -12,8 +13,24 @@ #include "core/movie.h" #include "core/settings.h" +SERIALIZE_EXPORT_IMPL(Service::IR::IR_RST) +SERVICE_CONSTRUCT_IMPL(Service::IR::IR_RST) + namespace Service::IR { +template +void IR_RST::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& update_event; + ar& shared_memory; + ar& next_pad_index; + ar& raw_c_stick; + ar& update_period; + // update_callback_id and input devices are set separately + ReloadInputDevices(); +} +SERIALIZE_IMPL(IR_RST) + struct PadDataEntry { PadState current_state; PadState delta_additions; diff --git a/src/core/hle/service/ir/ir_rst.h b/src/core/hle/service/ir/ir_rst.h index 84ad70dfcb..8e17381ad1 100644 --- a/src/core/hle/service/ir/ir_rst.h +++ b/src/core/hle/service/ir/ir_rst.h @@ -87,6 +87,13 @@ private: std::atomic is_device_reload_pending{false}; bool raw_c_stick{false}; int update_period{0}; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; } // namespace Service::IR + +BOOST_CLASS_EXPORT_KEY(Service::IR::IR_RST) +SERVICE_CONSTRUCT(Service::IR::IR_RST) diff --git a/src/core/hle/service/ir/ir_u.cpp b/src/core/hle/service/ir/ir_u.cpp index d76323e914..61618869a7 100644 --- a/src/core/hle/service/ir/ir_u.cpp +++ b/src/core/hle/service/ir/ir_u.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/ir/ir_u.h" +SERIALIZE_EXPORT_IMPL(Service::IR::IR_U) + namespace Service::IR { IR_U::IR_U() : ServiceFramework("ir:u", 1) { diff --git a/src/core/hle/service/ir/ir_u.h b/src/core/hle/service/ir/ir_u.h index ea150b0825..eaa54c6578 100644 --- a/src/core/hle/service/ir/ir_u.h +++ b/src/core/hle/service/ir/ir_u.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::IR + +BOOST_CLASS_EXPORT_KEY(Service::IR::IR_U) diff --git a/src/core/hle/service/mvd/mvd_std.cpp b/src/core/hle/service/mvd/mvd_std.cpp index 2c397f2dd1..43dbde5840 100644 --- a/src/core/hle/service/mvd/mvd_std.cpp +++ b/src/core/hle/service/mvd/mvd_std.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/mvd/mvd_std.h" +SERIALIZE_EXPORT_IMPL(Service::MVD::MVD_STD) + namespace Service::MVD { MVD_STD::MVD_STD() : ServiceFramework("mvd:std", 1) { diff --git a/src/core/hle/service/mvd/mvd_std.h b/src/core/hle/service/mvd/mvd_std.h index 6764f6ba89..6e8312e592 100644 --- a/src/core/hle/service/mvd/mvd_std.h +++ b/src/core/hle/service/mvd/mvd_std.h @@ -12,6 +12,15 @@ class MVD_STD final : public ServiceFramework { public: MVD_STD(); ~MVD_STD() = default; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + } + friend class boost::serialization::access; }; } // namespace Service::MVD + +BOOST_CLASS_EXPORT_KEY(Service::MVD::MVD_STD) diff --git a/src/core/hle/service/ndm/ndm_u.cpp b/src/core/hle/service/ndm/ndm_u.cpp index 057e68ede7..936d537996 100644 --- a/src/core/hle/service/ndm/ndm_u.cpp +++ b/src/core/hle/service/ndm/ndm_u.cpp @@ -2,10 +2,13 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/ndm/ndm_u.h" +SERIALIZE_EXPORT_IMPL(Service::NDM::NDM_U) + namespace Service::NDM { void NDM_U::EnterExclusiveState(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/ndm/ndm_u.h b/src/core/hle/service/ndm/ndm_u.h index 5f48a31824..3339478d1f 100644 --- a/src/core/hle/service/ndm/ndm_u.h +++ b/src/core/hle/service/ndm/ndm_u.h @@ -270,8 +270,23 @@ private: u32 scan_interval = DEFAULT_SCAN_INTERVAL; u32 retry_interval = DEFAULT_RETRY_INTERVAL; bool daemon_lock_enabled = false; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& daemon_bit_mask; + ar& default_daemon_bit_mask; + ar& daemon_status; + ar& exclusive_state; + ar& scan_interval; + ar& retry_interval; + ar& daemon_lock_enabled; + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::NDM + +BOOST_CLASS_EXPORT_KEY(Service::NDM::NDM_U) diff --git a/src/core/hle/service/news/news_s.cpp b/src/core/hle/service/news/news_s.cpp index 17eaa5ea8d..94cf68f4c0 100644 --- a/src/core/hle/service/news/news_s.cpp +++ b/src/core/hle/service/news/news_s.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/news/news_s.h" +SERIALIZE_EXPORT_IMPL(Service::NEWS::NEWS_S) + namespace Service::NEWS { void NEWS_S::GetTotalNotifications(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/news/news_s.h b/src/core/hle/service/news/news_s.h index e4673d22cb..711a0e99bf 100644 --- a/src/core/hle/service/news/news_s.h +++ b/src/core/hle/service/news/news_s.h @@ -27,3 +27,5 @@ private: }; } // namespace Service::NEWS + +BOOST_CLASS_EXPORT_KEY(Service::NEWS::NEWS_S) diff --git a/src/core/hle/service/news/news_u.cpp b/src/core/hle/service/news/news_u.cpp index 3d6e87f910..d91b594b8e 100644 --- a/src/core/hle/service/news/news_u.cpp +++ b/src/core/hle/service/news/news_u.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/news/news_u.h" +SERIALIZE_EXPORT_IMPL(Service::NEWS::NEWS_U) + namespace Service::NEWS { NEWS_U::NEWS_U() : ServiceFramework("news:u", 1) { diff --git a/src/core/hle/service/news/news_u.h b/src/core/hle/service/news/news_u.h index cb06bad39f..472dd579c8 100644 --- a/src/core/hle/service/news/news_u.h +++ b/src/core/hle/service/news/news_u.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::NEWS + +BOOST_CLASS_EXPORT_KEY(Service::NEWS::NEWS_U) diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp index 86eb6daeb8..0bd6121a22 100644 --- a/src/core/hle/service/nfc/nfc.cpp +++ b/src/core/hle/service/nfc/nfc.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/event.h" @@ -10,8 +11,20 @@ #include "core/hle/service/nfc/nfc_m.h" #include "core/hle/service/nfc/nfc_u.h" +SERVICE_CONSTRUCT_IMPL(Service::NFC::Module) +SERIALIZE_EXPORT_IMPL(Service::NFC::Module) + namespace Service::NFC { +template +void Module::serialize(Archive& ar, const unsigned int) { + ar& tag_in_range_event; + ar& tag_out_of_range_event; + ar& nfc_tag_state; + ar& nfc_status; +} +SERIALIZE_IMPL(Module) + struct TagInfo { u16_le id_offset_size; u8 unk1; diff --git a/src/core/hle/service/nfc/nfc.h b/src/core/hle/service/nfc/nfc.h index 64bd239acf..2d6b26d832 100644 --- a/src/core/hle/service/nfc/nfc.h +++ b/src/core/hle/service/nfc/nfc.h @@ -226,7 +226,7 @@ public: */ void GetIdentificationBlock(Kernel::HLERequestContext& ctx); - private: + protected: std::shared_ptr nfc; }; @@ -241,8 +241,15 @@ private: AmiiboData amiibo_data{}; bool amiibo_in_range = false; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::NFC + +SERVICE_CONSTRUCT(Service::NFC::Module) +BOOST_CLASS_EXPORT_KEY(Service::NFC::Module) diff --git a/src/core/hle/service/nfc/nfc_m.cpp b/src/core/hle/service/nfc/nfc_m.cpp index 310490b8f1..cd591b9c1b 100644 --- a/src/core/hle/service/nfc/nfc_m.cpp +++ b/src/core/hle/service/nfc/nfc_m.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nfc/nfc_m.h" +SERIALIZE_EXPORT_IMPL(Service::NFC::NFC_M) + namespace Service::NFC { NFC_M::NFC_M(std::shared_ptr nfc) : Module::Interface(std::move(nfc), "nfc:m", 1) { diff --git a/src/core/hle/service/nfc/nfc_m.h b/src/core/hle/service/nfc/nfc_m.h index c9fe9b1309..48a9e241b2 100644 --- a/src/core/hle/service/nfc/nfc_m.h +++ b/src/core/hle/service/nfc/nfc_m.h @@ -11,6 +11,12 @@ namespace Service::NFC { class NFC_M final : public Module::Interface { public: explicit NFC_M(std::shared_ptr nfc); + +private: + SERVICE_SERIALIZATION(NFC_M, nfc, Module) }; } // namespace Service::NFC + +BOOST_CLASS_EXPORT_KEY(Service::NFC::NFC_M) +BOOST_SERIALIZATION_CONSTRUCT(Service::NFC::NFC_M) diff --git a/src/core/hle/service/nfc/nfc_u.cpp b/src/core/hle/service/nfc/nfc_u.cpp index a6e99ace24..58d1843e42 100644 --- a/src/core/hle/service/nfc/nfc_u.cpp +++ b/src/core/hle/service/nfc/nfc_u.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nfc/nfc_u.h" +SERIALIZE_EXPORT_IMPL(Service::NFC::NFC_U) + namespace Service::NFC { NFC_U::NFC_U(std::shared_ptr nfc) : Module::Interface(std::move(nfc), "nfc:u", 1) { diff --git a/src/core/hle/service/nfc/nfc_u.h b/src/core/hle/service/nfc/nfc_u.h index aab408269c..2ed6030e67 100644 --- a/src/core/hle/service/nfc/nfc_u.h +++ b/src/core/hle/service/nfc/nfc_u.h @@ -11,6 +11,12 @@ namespace Service::NFC { class NFC_U final : public Module::Interface { public: explicit NFC_U(std::shared_ptr nfc); + +private: + SERVICE_SERIALIZATION(NFC_U, nfc, Module) }; } // namespace Service::NFC + +BOOST_CLASS_EXPORT_KEY(Service::NFC::NFC_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::NFC::NFC_U) From 571b1062f0fd2921d2ea8d559d5dbcdb087e9cd0 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 1 Jan 2020 00:58:36 +0000 Subject: [PATCH 048/129] Serialize NIM, PS, PXI, SOC, SSL services --- TODO | 15 +++++++-------- src/core/hle/service/nim/nim_aoc.cpp | 3 +++ src/core/hle/service/nim/nim_aoc.h | 2 ++ src/core/hle/service/nim/nim_s.cpp | 3 +++ src/core/hle/service/nim/nim_s.h | 2 ++ src/core/hle/service/nim/nim_u.cpp | 4 ++++ src/core/hle/service/nim/nim_u.h | 10 ++++++++++ src/core/hle/service/ps/ps_ps.cpp | 3 +++ src/core/hle/service/ps/ps_ps.h | 2 ++ src/core/hle/service/pxi/dev.cpp | 3 +++ src/core/hle/service/pxi/dev.h | 2 ++ src/core/hle/service/soc_u.cpp | 3 +++ src/core/hle/service/soc_u.h | 18 ++++++++++++++++++ src/core/hle/service/ssl_c.cpp | 2 ++ src/core/hle/service/ssl_c.h | 2 ++ 15 files changed, 66 insertions(+), 8 deletions(-) diff --git a/TODO b/TODO index f9fffa60d7..46ba9b2600 100644 --- a/TODO +++ b/TODO @@ -17,7 +17,7 @@ ☐ Telemetry session ☐ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE ☐ Review constructor/initialization code -☐ Fix CI +✔ Fix CI @done(19-12-31 21:32) ✔ HW @done(19-08-13 15:41) ✔ GPU regs @done(19-08-13 15:41) ✔ LCD regs @done(19-08-13 15:41) @@ -92,15 +92,14 @@ ✔ NDM @done(19-12-31 18:26) ✔ NEWS @done(19-12-31 18:29) ✔ NFC @done(19-12-31 20:35) - ☐ NIM - ☐ NS + ✔ NIM @done(19-12-31 21:08) + ✔ NS @done(20-01-01 00:46) ☐ NWM ☐ PM - ☐ PS + ✔ PS @done(20-01-01 00:54) ☐ PTM - ☐ PXI + ✔ PXI @done(20-01-01 00:53) ☐ QTM - ☐ SM - ☐ SOC - ☐ SSL + ✔ SOC @done(20-01-01 00:51) + ✔ SSL @done(20-01-01 00:48) ☐ Y2R \ No newline at end of file diff --git a/src/core/hle/service/nim/nim_aoc.cpp b/src/core/hle/service/nim/nim_aoc.cpp index ddd8d5e036..f20c96f69e 100644 --- a/src/core/hle/service/nim/nim_aoc.cpp +++ b/src/core/hle/service/nim/nim_aoc.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nim/nim_aoc.h" +SERIALIZE_EXPORT_IMPL(Service::NIM::NIM_AOC) + namespace Service::NIM { NIM_AOC::NIM_AOC() : ServiceFramework("nim:aoc", 2) { diff --git a/src/core/hle/service/nim/nim_aoc.h b/src/core/hle/service/nim/nim_aoc.h index 5a1f518ecf..2d06a9d1ce 100644 --- a/src/core/hle/service/nim/nim_aoc.h +++ b/src/core/hle/service/nim/nim_aoc.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::NIM + +BOOST_CLASS_EXPORT_KEY(Service::NIM::NIM_AOC) diff --git a/src/core/hle/service/nim/nim_s.cpp b/src/core/hle/service/nim/nim_s.cpp index d7236249fb..27118e406a 100644 --- a/src/core/hle/service/nim/nim_s.cpp +++ b/src/core/hle/service/nim/nim_s.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nim/nim_s.h" +SERIALIZE_EXPORT_IMPL(Service::NIM::NIM_S) + namespace Service::NIM { NIM_S::NIM_S() : ServiceFramework("nim:s", 1) { diff --git a/src/core/hle/service/nim/nim_s.h b/src/core/hle/service/nim/nim_s.h index 6485cde180..6281270f5b 100644 --- a/src/core/hle/service/nim/nim_s.h +++ b/src/core/hle/service/nim/nim_s.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::NIM + +BOOST_CLASS_EXPORT_KEY(Service::NIM::NIM_S) diff --git a/src/core/hle/service/nim/nim_u.cpp b/src/core/hle/service/nim/nim_u.cpp index dd0e4d31c8..b44ef35399 100644 --- a/src/core/hle/service/nim/nim_u.cpp +++ b/src/core/hle/service/nim/nim_u.cpp @@ -2,11 +2,15 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/event.h" #include "core/hle/service/nim/nim_u.h" +SERVICE_CONSTRUCT_IMPL(Service::NIM::NIM_U) +SERIALIZE_EXPORT_IMPL(Service::NIM::NIM_U) + namespace Service::NIM { NIM_U::NIM_U(Core::System& system) : ServiceFramework("nim:u", 2) { diff --git a/src/core/hle/service/nim/nim_u.h b/src/core/hle/service/nim/nim_u.h index 367ee6ea85..98fec69b24 100644 --- a/src/core/hle/service/nim/nim_u.h +++ b/src/core/hle/service/nim/nim_u.h @@ -41,6 +41,16 @@ private: void CheckSysUpdateAvailable(Kernel::HLERequestContext& ctx); std::shared_ptr nim_system_update_event; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& nim_system_update_event; + } + friend class boost::serialization::access; }; } // namespace Service::NIM + +SERVICE_CONSTRUCT(Service::NIM::NIM_U) +BOOST_CLASS_EXPORT_KEY(Service::NIM::NIM_U) diff --git a/src/core/hle/service/ps/ps_ps.cpp b/src/core/hle/service/ps/ps_ps.cpp index a489033482..1ba4d7f4c9 100644 --- a/src/core/hle/service/ps/ps_ps.cpp +++ b/src/core/hle/service/ps/ps_ps.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/archives.h" #include "common/logging/log.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" @@ -11,6 +12,8 @@ #include "core/hw/aes/arithmetic128.h" #include "core/hw/aes/key.h" +SERIALIZE_EXPORT_IMPL(Service::PS::PS_PS) + namespace Service::PS { enum class AlgorithmType : u8 { diff --git a/src/core/hle/service/ps/ps_ps.h b/src/core/hle/service/ps/ps_ps.h index 6e8b3ad0a2..39f6d62b28 100644 --- a/src/core/hle/service/ps/ps_ps.h +++ b/src/core/hle/service/ps/ps_ps.h @@ -231,3 +231,5 @@ private: void InstallInterfaces(Core::System& system); } // namespace Service::PS + +BOOST_CLASS_EXPORT_KEY(Service::PS::PS_PS) diff --git a/src/core/hle/service/pxi/dev.cpp b/src/core/hle/service/pxi/dev.cpp index dcea938a64..1135516905 100644 --- a/src/core/hle/service/pxi/dev.cpp +++ b/src/core/hle/service/pxi/dev.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/pxi/dev.h" +SERIALIZE_EXPORT_IMPL(Service::PXI::DEV) + namespace Service::PXI { DEV::DEV() : ServiceFramework("pxi:dev", 1) { diff --git a/src/core/hle/service/pxi/dev.h b/src/core/hle/service/pxi/dev.h index 115dc23084..ed17435b6e 100644 --- a/src/core/hle/service/pxi/dev.h +++ b/src/core/hle/service/pxi/dev.h @@ -16,3 +16,5 @@ public: }; } // namespace Service::PXI + +BOOST_CLASS_EXPORT_KEY(Service::PXI::DEV) diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp index 5ebe553563..56b48cd3a5 100644 --- a/src/core/hle/service/soc_u.cpp +++ b/src/core/hle/service/soc_u.cpp @@ -5,6 +5,7 @@ #include #include #include +#include "common/archives.h" #include "common/assert.h" #include "common/bit_field.h" #include "common/common_types.h" @@ -52,6 +53,8 @@ #define closesocket(x) close(x) #endif +SERIALIZE_EXPORT_IMPL(Service::SOC::SOC_U) + namespace Service::SOC { const s32 SOCKET_ERROR_VALUE = -1; diff --git a/src/core/hle/service/soc_u.h b/src/core/hle/service/soc_u.h index 273aac49c7..595a984f2f 100644 --- a/src/core/hle/service/soc_u.h +++ b/src/core/hle/service/soc_u.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include "core/hle/service/service.h" namespace Core { @@ -17,6 +18,14 @@ namespace Service::SOC { struct SocketHolder { u32 socket_fd; ///< The socket descriptor bool blocking; ///< Whether the socket is blocking or not, it is only read on Windows. + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& socket_fd; + ar& blocking; + } + friend class boost::serialization::access; }; class SOC_U final : public ServiceFramework { @@ -55,8 +64,17 @@ private: /// Holds info about the currently open sockets std::unordered_map open_sockets; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& open_sockets; + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::SOC + +BOOST_CLASS_EXPORT_KEY(Service::SOC::SOC_U) diff --git a/src/core/hle/service/ssl_c.cpp b/src/core/hle/service/ssl_c.cpp index b862c41f1e..8e74c1b7cf 100644 --- a/src/core/hle/service/ssl_c.cpp +++ b/src/core/hle/service/ssl_c.cpp @@ -2,12 +2,14 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "common/common_types.h" #include "core/core.h" #include "core/hle/ipc.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/ssl_c.h" +SERIALIZE_EXPORT_IMPL(Service::SSL::SSL_C) namespace Service::SSL { void SSL_C::Initialize(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/ssl_c.h b/src/core/hle/service/ssl_c.h index 807f7c7255..3984f7ecc9 100644 --- a/src/core/hle/service/ssl_c.h +++ b/src/core/hle/service/ssl_c.h @@ -28,3 +28,5 @@ private: void InstallInterfaces(Core::System& system); } // namespace Service::SSL + +BOOST_CLASS_EXPORT_KEY(Service::SSL::SSL_C) From f5e2f873b003dacaf0b28b92c60beb5d7804e9ee Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 1 Jan 2020 21:31:52 +0000 Subject: [PATCH 049/129] Serialize NWM service --- TODO | 18 ++++++++++++------ externals/boost | 2 +- src/core/hle/service/nwm/nwm_cec.cpp | 3 +++ src/core/hle/service/nwm/nwm_cec.h | 2 ++ src/core/hle/service/nwm/nwm_ext.cpp | 3 +++ src/core/hle/service/nwm/nwm_ext.h | 2 ++ src/core/hle/service/nwm/nwm_inf.cpp | 3 +++ src/core/hle/service/nwm/nwm_inf.h | 2 ++ src/core/hle/service/nwm/nwm_sap.cpp | 3 +++ src/core/hle/service/nwm/nwm_sap.h | 2 ++ src/core/hle/service/nwm/nwm_soc.cpp | 3 +++ src/core/hle/service/nwm/nwm_soc.h | 2 ++ src/core/hle/service/nwm/nwm_tst.cpp | 3 +++ src/core/hle/service/nwm/nwm_tst.h | 2 ++ src/core/hle/service/nwm/nwm_uds.cpp | 12 ++++++++++++ src/core/hle/service/nwm/nwm_uds.h | 14 ++++++++++++++ src/network/CMakeLists.txt | 2 +- src/network/room_member.h | 12 ++++++++++++ 18 files changed, 82 insertions(+), 8 deletions(-) diff --git a/TODO b/TODO index 46ba9b2600..1f29a46931 100644 --- a/TODO +++ b/TODO @@ -10,11 +10,16 @@ ☐ App loader ☐ Archive manager ☐ Custom texture cache -☐ MMIO -☐ Movie -☐ Perf stats -☐ Settings -☐ Telemetry session +✘ MMIO @cancelled(20-01-01 01:06) + Seems that this whole subsystem is only used in tests +✘ Movie @cancelled(20-01-01 01:07) + Doesn't need to be serialized here +✘ Perf stats @cancelled(20-01-01 01:09) + Doesn't need to be serialized here +✘ Settings @cancelled(20-01-01 01:11) + For now, let the settings just be whatever they are +✘ Telemetry session @cancelled(20-01-01 01:12) + Doesn't need to be serialized here ☐ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE ☐ Review constructor/initialization code ✔ Fix CI @done(19-12-31 21:32) @@ -94,7 +99,8 @@ ✔ NFC @done(19-12-31 20:35) ✔ NIM @done(19-12-31 21:08) ✔ NS @done(20-01-01 00:46) - ☐ NWM + ✔ NWM @done(20-01-01 21:31) + ☐ Fix wifi_packet_received? ☐ PM ✔ PS @done(20-01-01 00:54) ☐ PTM diff --git a/externals/boost b/externals/boost index 65dc954e93..6d7edc593b 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit 65dc954e93b22870b8423701e225147c75e3b31b +Subproject commit 6d7edc593be8e47c8de7bc5f7d6b32971fad0c24 diff --git a/src/core/hle/service/nwm/nwm_cec.cpp b/src/core/hle/service/nwm/nwm_cec.cpp index 7c47c88c70..ecd4f16e19 100644 --- a/src/core/hle/service/nwm/nwm_cec.cpp +++ b/src/core/hle/service/nwm/nwm_cec.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nwm/nwm_cec.h" +SERIALIZE_EXPORT_IMPL(Service::NWM::NWM_CEC) + namespace Service::NWM { NWM_CEC::NWM_CEC() : ServiceFramework("nwm::CEC") { diff --git a/src/core/hle/service/nwm/nwm_cec.h b/src/core/hle/service/nwm/nwm_cec.h index afdf984776..4f62f32f13 100644 --- a/src/core/hle/service/nwm/nwm_cec.h +++ b/src/core/hle/service/nwm/nwm_cec.h @@ -14,3 +14,5 @@ public: }; } // namespace Service::NWM + +BOOST_CLASS_EXPORT_KEY(Service::NWM::NWM_CEC) diff --git a/src/core/hle/service/nwm/nwm_ext.cpp b/src/core/hle/service/nwm/nwm_ext.cpp index 4bbac391fc..d69da94ffb 100644 --- a/src/core/hle/service/nwm/nwm_ext.cpp +++ b/src/core/hle/service/nwm/nwm_ext.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nwm/nwm_ext.h" +SERIALIZE_EXPORT_IMPL(Service::NWM::NWM_EXT) + namespace Service::NWM { NWM_EXT::NWM_EXT() : ServiceFramework("nwm::EXT") { diff --git a/src/core/hle/service/nwm/nwm_ext.h b/src/core/hle/service/nwm/nwm_ext.h index 1711db65ae..a8d43df70d 100644 --- a/src/core/hle/service/nwm/nwm_ext.h +++ b/src/core/hle/service/nwm/nwm_ext.h @@ -14,3 +14,5 @@ public: }; } // namespace Service::NWM + +BOOST_CLASS_EXPORT_KEY(Service::NWM::NWM_EXT) diff --git a/src/core/hle/service/nwm/nwm_inf.cpp b/src/core/hle/service/nwm/nwm_inf.cpp index 71cf118910..eaabf66673 100644 --- a/src/core/hle/service/nwm/nwm_inf.cpp +++ b/src/core/hle/service/nwm/nwm_inf.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nwm/nwm_inf.h" +SERIALIZE_EXPORT_IMPL(Service::NWM::NWM_INF) + namespace Service::NWM { NWM_INF::NWM_INF() : ServiceFramework("nwm::INF") { diff --git a/src/core/hle/service/nwm/nwm_inf.h b/src/core/hle/service/nwm/nwm_inf.h index 2c69cfb1e3..f13fd41581 100644 --- a/src/core/hle/service/nwm/nwm_inf.h +++ b/src/core/hle/service/nwm/nwm_inf.h @@ -14,3 +14,5 @@ public: }; } // namespace Service::NWM + +BOOST_CLASS_EXPORT_KEY(Service::NWM::NWM_INF) diff --git a/src/core/hle/service/nwm/nwm_sap.cpp b/src/core/hle/service/nwm/nwm_sap.cpp index 2ef196ab40..2cedf93718 100644 --- a/src/core/hle/service/nwm/nwm_sap.cpp +++ b/src/core/hle/service/nwm/nwm_sap.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nwm/nwm_sap.h" +SERIALIZE_EXPORT_IMPL(Service::NWM::NWM_SAP) + namespace Service::NWM { NWM_SAP::NWM_SAP() : ServiceFramework("nwm::SAP") { diff --git a/src/core/hle/service/nwm/nwm_sap.h b/src/core/hle/service/nwm/nwm_sap.h index b6700b8edf..1a289542cc 100644 --- a/src/core/hle/service/nwm/nwm_sap.h +++ b/src/core/hle/service/nwm/nwm_sap.h @@ -14,3 +14,5 @@ public: }; } // namespace Service::NWM + +BOOST_CLASS_EXPORT_KEY(Service::NWM::NWM_SAP) diff --git a/src/core/hle/service/nwm/nwm_soc.cpp b/src/core/hle/service/nwm/nwm_soc.cpp index 443baaf390..d6ca365aba 100644 --- a/src/core/hle/service/nwm/nwm_soc.cpp +++ b/src/core/hle/service/nwm/nwm_soc.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nwm/nwm_soc.h" +SERIALIZE_EXPORT_IMPL(Service::NWM::NWM_SOC) + namespace Service::NWM { NWM_SOC::NWM_SOC() : ServiceFramework("nwm::SOC") { diff --git a/src/core/hle/service/nwm/nwm_soc.h b/src/core/hle/service/nwm/nwm_soc.h index 8e1b922bc6..883a20854d 100644 --- a/src/core/hle/service/nwm/nwm_soc.h +++ b/src/core/hle/service/nwm/nwm_soc.h @@ -14,3 +14,5 @@ public: }; } // namespace Service::NWM + +BOOST_CLASS_EXPORT_KEY(Service::NWM::NWM_SOC) diff --git a/src/core/hle/service/nwm/nwm_tst.cpp b/src/core/hle/service/nwm/nwm_tst.cpp index 3be65200b7..65ffabfd9e 100644 --- a/src/core/hle/service/nwm/nwm_tst.cpp +++ b/src/core/hle/service/nwm/nwm_tst.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nwm/nwm_tst.h" +SERIALIZE_EXPORT_IMPL(Service::NWM::NWM_TST) + namespace Service::NWM { NWM_TST::NWM_TST() : ServiceFramework("nwm::TST") { diff --git a/src/core/hle/service/nwm/nwm_tst.h b/src/core/hle/service/nwm/nwm_tst.h index 8214e0d1d5..e58fa33714 100644 --- a/src/core/hle/service/nwm/nwm_tst.h +++ b/src/core/hle/service/nwm/nwm_tst.h @@ -14,3 +14,5 @@ public: }; } // namespace Service::NWM + +BOOST_CLASS_EXPORT_KEY(Service::NWM::NWM_TST) diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index fe8f7635f9..9a3de82fab 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -4,7 +4,10 @@ #include #include +#include +#include #include +#include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" #include "core/core.h" @@ -23,6 +26,15 @@ namespace Service::NWM { +template +void NWM_UDS::serialize(Archive& ar, const unsigned int) { + ar& node_map; + ar& connection_event; + ar& received_beacons; + // TODO: Fix wifi_packet_received? +} +SERIALIZE_IMPL(NWM_UDS) + namespace ErrCodes { enum { NotInitialized = 2, diff --git a/src/core/hle/service/nwm/nwm_uds.h b/src/core/hle/service/nwm/nwm_uds.h index 52ca386635..07dd7e9ba1 100644 --- a/src/core/hle/service/nwm/nwm_uds.h +++ b/src/core/hle/service/nwm/nwm_uds.h @@ -521,6 +521,14 @@ private: struct Node { bool connected; u16 node_id; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& connected; + ar& node_id; + } + friend class boost::serialization::access; }; std::map node_map; @@ -543,6 +551,12 @@ private: // List of the last beacons received from the network. std::list received_beacons; + + template + void serialize(Archive& ar, const unsigned int); }; } // namespace Service::NWM + +SERVICE_CONSTRUCT(Service::NWM::NWM_UDS) +BOOST_CLASS_EXPORT_KEY(Service::NWM::NWM_UDS) diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 24f7826534..382a69e2f7 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -13,4 +13,4 @@ add_library(network STATIC create_target_directory_groups(network) -target_link_libraries(network PRIVATE common enet) +target_link_libraries(network PRIVATE common enet Boost::boost) diff --git a/src/network/room_member.h b/src/network/room_member.h index ad5d14b445..d582a8552f 100644 --- a/src/network/room_member.h +++ b/src/network/room_member.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "common/common_types.h" #include "network/room.h" @@ -30,6 +31,17 @@ struct WifiPacket { MacAddress transmitter_address; ///< Mac address of the transmitter. MacAddress destination_address; ///< Mac address of the receiver. u8 channel; ///< WiFi channel where this frame was transmitted. + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& type; + ar& data; + ar& transmitter_address; + ar& destination_address; + ar& channel; + } + friend class boost::serialization::access; }; /// Represents a chat message. From 92857efca4f958f00ac5ee6eb69a6d0ba94f8a8b Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 1 Jan 2020 22:36:58 +0000 Subject: [PATCH 050/129] Serialize PTM service --- TODO | 4 ++-- src/core/hle/service/pm/pm_app.cpp | 3 +++ src/core/hle/service/pm/pm_app.h | 2 ++ src/core/hle/service/pm/pm_dbg.cpp | 3 +++ src/core/hle/service/pm/pm_dbg.h | 2 ++ src/core/hle/service/ptm/ptm.cpp | 3 +++ src/core/hle/service/ptm/ptm.h | 12 +++++++++++- src/core/hle/service/ptm/ptm_gets.cpp | 3 +++ src/core/hle/service/ptm/ptm_gets.h | 6 ++++++ src/core/hle/service/ptm/ptm_play.cpp | 3 +++ src/core/hle/service/ptm/ptm_play.h | 6 ++++++ src/core/hle/service/ptm/ptm_sets.cpp | 3 +++ src/core/hle/service/ptm/ptm_sets.h | 6 ++++++ src/core/hle/service/ptm/ptm_sysm.cpp | 4 ++++ src/core/hle/service/ptm/ptm_sysm.h | 11 +++++++++++ src/core/hle/service/ptm/ptm_u.cpp | 3 +++ src/core/hle/service/ptm/ptm_u.h | 6 ++++++ 17 files changed, 77 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 1f29a46931..0b7d5dd363 100644 --- a/TODO +++ b/TODO @@ -101,9 +101,9 @@ ✔ NS @done(20-01-01 00:46) ✔ NWM @done(20-01-01 21:31) ☐ Fix wifi_packet_received? - ☐ PM + ✔ PM @done(20-01-01 22:14) ✔ PS @done(20-01-01 00:54) - ☐ PTM + ✔ PTM @done(20-01-01 22:36) ✔ PXI @done(20-01-01 00:53) ☐ QTM ✔ SOC @done(20-01-01 00:51) diff --git a/src/core/hle/service/pm/pm_app.cpp b/src/core/hle/service/pm/pm_app.cpp index 9599dfcfcf..fd08583565 100644 --- a/src/core/hle/service/pm/pm_app.cpp +++ b/src/core/hle/service/pm/pm_app.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/pm/pm_app.h" +SERIALIZE_EXPORT_IMPL(Service::PM::PM_APP) + namespace Service::PM { PM_APP::PM_APP() : ServiceFramework("pm:app", 3) { diff --git a/src/core/hle/service/pm/pm_app.h b/src/core/hle/service/pm/pm_app.h index 8c7e375f0b..0fb290abae 100644 --- a/src/core/hle/service/pm/pm_app.h +++ b/src/core/hle/service/pm/pm_app.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::PM + +BOOST_CLASS_EXPORT_KEY(Service::PM::PM_APP) diff --git a/src/core/hle/service/pm/pm_dbg.cpp b/src/core/hle/service/pm/pm_dbg.cpp index 63879ff201..33e195a6fd 100644 --- a/src/core/hle/service/pm/pm_dbg.cpp +++ b/src/core/hle/service/pm/pm_dbg.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/pm/pm_dbg.h" +SERIALIZE_EXPORT_IMPL(Service::PM::PM_DBG) + namespace Service::PM { PM_DBG::PM_DBG() : ServiceFramework("pm:dbg", 3) { diff --git a/src/core/hle/service/pm/pm_dbg.h b/src/core/hle/service/pm/pm_dbg.h index 77b6449698..1cfdea6fe2 100644 --- a/src/core/hle/service/pm/pm_dbg.h +++ b/src/core/hle/service/pm/pm_dbg.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::PM + +BOOST_CLASS_EXPORT_KEY(Service::PM::PM_DBG) diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp index 7d30fcc5bd..69b51480b1 100644 --- a/src/core/hle/service/ptm/ptm.cpp +++ b/src/core/hle/service/ptm/ptm.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/common_paths.h" #include "common/file_util.h" #include "common/logging/log.h" @@ -18,6 +19,8 @@ #include "core/hle/service/ptm/ptm_u.h" #include "core/settings.h" +SERIALIZE_EXPORT_IMPL(Service::PTM::Module) + namespace Service::PTM { /// Values for the default gamecoin.dat file diff --git a/src/core/hle/service/ptm/ptm.h b/src/core/hle/service/ptm/ptm.h index 549e693538..ba23224d78 100644 --- a/src/core/hle/service/ptm/ptm.h +++ b/src/core/hle/service/ptm/ptm.h @@ -137,7 +137,7 @@ public: */ void CheckNew3DS(Kernel::HLERequestContext& ctx); - private: + protected: std::shared_ptr ptm; }; @@ -145,8 +145,18 @@ private: bool shell_open = true; bool battery_is_charging = true; bool pedometer_is_counting = false; + + template + void serialize(Archive& ar, const unsigned int) { + ar& shell_open; + ar& battery_is_charging; + ar& pedometer_is_counting; + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::PTM + +BOOST_CLASS_EXPORT_KEY(Service::PTM::Module) diff --git a/src/core/hle/service/ptm/ptm_gets.cpp b/src/core/hle/service/ptm/ptm_gets.cpp index e083aed6a9..6feedbf94d 100644 --- a/src/core/hle/service/ptm/ptm_gets.cpp +++ b/src/core/hle/service/ptm/ptm_gets.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/ptm/ptm_gets.h" +SERIALIZE_EXPORT_IMPL(Service::PTM::PTM_Gets) + namespace Service::PTM { PTM_Gets::PTM_Gets(std::shared_ptr ptm) diff --git a/src/core/hle/service/ptm/ptm_gets.h b/src/core/hle/service/ptm/ptm_gets.h index a8d71fdc98..57b8e5f550 100644 --- a/src/core/hle/service/ptm/ptm_gets.h +++ b/src/core/hle/service/ptm/ptm_gets.h @@ -12,6 +12,12 @@ namespace Service::PTM { class PTM_Gets final : public Module::Interface { public: explicit PTM_Gets(std::shared_ptr ptm); + +private: + SERVICE_SERIALIZATION(PTM_Gets, ptm, Module) }; } // namespace Service::PTM + +BOOST_CLASS_EXPORT_KEY(Service::PTM::PTM_Gets) +BOOST_SERIALIZATION_CONSTRUCT(Service::PTM::PTM_Gets) diff --git a/src/core/hle/service/ptm/ptm_play.cpp b/src/core/hle/service/ptm/ptm_play.cpp index 6ef45780ed..00585ccced 100644 --- a/src/core/hle/service/ptm/ptm_play.cpp +++ b/src/core/hle/service/ptm/ptm_play.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/ptm/ptm_play.h" +SERIALIZE_EXPORT_IMPL(Service::PTM::PTM_Play) + namespace Service::PTM { PTM_Play::PTM_Play(std::shared_ptr ptm) diff --git a/src/core/hle/service/ptm/ptm_play.h b/src/core/hle/service/ptm/ptm_play.h index 3a226149df..091e91d30e 100644 --- a/src/core/hle/service/ptm/ptm_play.h +++ b/src/core/hle/service/ptm/ptm_play.h @@ -12,6 +12,12 @@ namespace Service::PTM { class PTM_Play final : public Module::Interface { public: explicit PTM_Play(std::shared_ptr ptm); + +private: + SERVICE_SERIALIZATION(PTM_Play, ptm, Module) }; } // namespace Service::PTM + +BOOST_CLASS_EXPORT_KEY(Service::PTM::PTM_Play) +BOOST_SERIALIZATION_CONSTRUCT(Service::PTM::PTM_Play) diff --git a/src/core/hle/service/ptm/ptm_sets.cpp b/src/core/hle/service/ptm/ptm_sets.cpp index b925f49c95..e0f436ddc7 100644 --- a/src/core/hle/service/ptm/ptm_sets.cpp +++ b/src/core/hle/service/ptm/ptm_sets.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/ptm/ptm_sets.h" +SERIALIZE_EXPORT_IMPL(Service::PTM::PTM_Sets) + namespace Service::PTM { PTM_Sets::PTM_Sets(std::shared_ptr ptm) : Module::Interface(std::move(ptm), "ptm:sets", 1) { diff --git a/src/core/hle/service/ptm/ptm_sets.h b/src/core/hle/service/ptm/ptm_sets.h index 317781faf1..573b20dbde 100644 --- a/src/core/hle/service/ptm/ptm_sets.h +++ b/src/core/hle/service/ptm/ptm_sets.h @@ -12,6 +12,12 @@ namespace Service::PTM { class PTM_Sets final : public Module::Interface { public: explicit PTM_Sets(std::shared_ptr ptm); + +private: + SERVICE_SERIALIZATION(PTM_Sets, ptm, Module) }; } // namespace Service::PTM + +BOOST_CLASS_EXPORT_KEY(Service::PTM::PTM_Sets) +BOOST_SERIALIZATION_CONSTRUCT(Service::PTM::PTM_Sets) diff --git a/src/core/hle/service/ptm/ptm_sysm.cpp b/src/core/hle/service/ptm/ptm_sysm.cpp index 45ee1b6fc5..48b44104e7 100644 --- a/src/core/hle/service/ptm/ptm_sysm.cpp +++ b/src/core/hle/service/ptm/ptm_sysm.cpp @@ -2,8 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/ptm/ptm_sysm.h" +SERIALIZE_EXPORT_IMPL(Service::PTM::PTM_S) +SERIALIZE_EXPORT_IMPL(Service::PTM::PTM_Sysm) + namespace Service::PTM { PTM_S_Common::PTM_S_Common(std::shared_ptr ptm, const char* name) diff --git a/src/core/hle/service/ptm/ptm_sysm.h b/src/core/hle/service/ptm/ptm_sysm.h index 8667f2a954..1e01fdb2e6 100644 --- a/src/core/hle/service/ptm/ptm_sysm.h +++ b/src/core/hle/service/ptm/ptm_sysm.h @@ -17,11 +17,22 @@ public: class PTM_S final : public PTM_S_Common { public: explicit PTM_S(std::shared_ptr ptm); + +private: + SERVICE_SERIALIZATION(PTM_S, ptm, Module) }; class PTM_Sysm final : public PTM_S_Common { public: explicit PTM_Sysm(std::shared_ptr ptm); + +private: + SERVICE_SERIALIZATION(PTM_Sysm, ptm, Module) }; } // namespace Service::PTM + +BOOST_CLASS_EXPORT_KEY(Service::PTM::PTM_S) +BOOST_CLASS_EXPORT_KEY(Service::PTM::PTM_Sysm) +BOOST_SERIALIZATION_CONSTRUCT(Service::PTM::PTM_S) +BOOST_SERIALIZATION_CONSTRUCT(Service::PTM::PTM_Sysm) diff --git a/src/core/hle/service/ptm/ptm_u.cpp b/src/core/hle/service/ptm/ptm_u.cpp index 647ef59613..4c1820df45 100644 --- a/src/core/hle/service/ptm/ptm_u.cpp +++ b/src/core/hle/service/ptm/ptm_u.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/ptm/ptm_u.h" +SERIALIZE_EXPORT_IMPL(Service::PTM::PTM_U) + namespace Service::PTM { PTM_U::PTM_U(std::shared_ptr ptm) : Module::Interface(std::move(ptm), "ptm:u", 26) { diff --git a/src/core/hle/service/ptm/ptm_u.h b/src/core/hle/service/ptm/ptm_u.h index 618401cec3..213972242b 100644 --- a/src/core/hle/service/ptm/ptm_u.h +++ b/src/core/hle/service/ptm/ptm_u.h @@ -12,6 +12,12 @@ namespace Service::PTM { class PTM_U final : public Module::Interface { public: explicit PTM_U(std::shared_ptr ptm); + +private: + SERVICE_SERIALIZATION(PTM_U, ptm, Module) }; } // namespace Service::PTM + +BOOST_CLASS_EXPORT_KEY(Service::PTM::PTM_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::PTM::PTM_U) From ef2e50328133f6553046219eb54027800d88a148 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 1 Jan 2020 22:57:21 +0000 Subject: [PATCH 051/129] Serialize QTM, Y2R services --- TODO | 4 +- src/core/hle/service/qtm/qtm_c.cpp | 3 ++ src/core/hle/service/qtm/qtm_c.h | 2 + src/core/hle/service/qtm/qtm_s.cpp | 3 ++ src/core/hle/service/qtm/qtm_s.h | 2 + src/core/hle/service/qtm/qtm_sp.cpp | 3 ++ src/core/hle/service/qtm/qtm_sp.h | 2 + src/core/hle/service/qtm/qtm_u.cpp | 3 ++ src/core/hle/service/qtm/qtm_u.h | 2 + src/core/hle/service/y2r_u.cpp | 15 ++++++++ src/core/hle/service/y2r_u.h | 60 +++++++++++++++++++++++++++++ 11 files changed, 97 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 0b7d5dd363..30b51a68c6 100644 --- a/TODO +++ b/TODO @@ -105,7 +105,7 @@ ✔ PS @done(20-01-01 00:54) ✔ PTM @done(20-01-01 22:36) ✔ PXI @done(20-01-01 00:53) - ☐ QTM + ✔ QTM @done(20-01-01 22:41) ✔ SOC @done(20-01-01 00:51) ✔ SSL @done(20-01-01 00:48) - ☐ Y2R \ No newline at end of file + ✔ Y2R @done(20-01-01 22:56) \ No newline at end of file diff --git a/src/core/hle/service/qtm/qtm_c.cpp b/src/core/hle/service/qtm/qtm_c.cpp index 84baaba3ad..2adc896dff 100644 --- a/src/core/hle/service/qtm/qtm_c.cpp +++ b/src/core/hle/service/qtm/qtm_c.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/qtm/qtm_c.h" +SERIALIZE_EXPORT_IMPL(Service::QTM::QTM_C) + namespace Service::QTM { QTM_C::QTM_C() : ServiceFramework("qtm:c", 2) { diff --git a/src/core/hle/service/qtm/qtm_c.h b/src/core/hle/service/qtm/qtm_c.h index c9cad0329c..8ad05b6e18 100644 --- a/src/core/hle/service/qtm/qtm_c.h +++ b/src/core/hle/service/qtm/qtm_c.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::QTM + +BOOST_CLASS_EXPORT_KEY(Service::QTM::QTM_C) diff --git a/src/core/hle/service/qtm/qtm_s.cpp b/src/core/hle/service/qtm/qtm_s.cpp index 2af7ced7b7..6163ef4dc9 100644 --- a/src/core/hle/service/qtm/qtm_s.cpp +++ b/src/core/hle/service/qtm/qtm_s.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/qtm/qtm_s.h" +SERIALIZE_EXPORT_IMPL(Service::QTM::QTM_S) + namespace Service::QTM { QTM_S::QTM_S() : ServiceFramework("qtm:s", 2) { diff --git a/src/core/hle/service/qtm/qtm_s.h b/src/core/hle/service/qtm/qtm_s.h index 72b5e058b1..51e1a4bc85 100644 --- a/src/core/hle/service/qtm/qtm_s.h +++ b/src/core/hle/service/qtm/qtm_s.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::QTM + +BOOST_CLASS_EXPORT_KEY(Service::QTM::QTM_S) diff --git a/src/core/hle/service/qtm/qtm_sp.cpp b/src/core/hle/service/qtm/qtm_sp.cpp index bd5a716050..fdfc80003c 100644 --- a/src/core/hle/service/qtm/qtm_sp.cpp +++ b/src/core/hle/service/qtm/qtm_sp.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/qtm/qtm_sp.h" +SERIALIZE_EXPORT_IMPL(Service::QTM::QTM_SP) + namespace Service::QTM { QTM_SP::QTM_SP() : ServiceFramework("qtm:sp", 2) { diff --git a/src/core/hle/service/qtm/qtm_sp.h b/src/core/hle/service/qtm/qtm_sp.h index c3f1049a1d..3c16dea37c 100644 --- a/src/core/hle/service/qtm/qtm_sp.h +++ b/src/core/hle/service/qtm/qtm_sp.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::QTM + +BOOST_CLASS_EXPORT_KEY(Service::QTM::QTM_SP) diff --git a/src/core/hle/service/qtm/qtm_u.cpp b/src/core/hle/service/qtm/qtm_u.cpp index 471692189d..84415dde9c 100644 --- a/src/core/hle/service/qtm/qtm_u.cpp +++ b/src/core/hle/service/qtm/qtm_u.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/qtm/qtm_u.h" +SERIALIZE_EXPORT_IMPL(Service::QTM::QTM_U) + namespace Service::QTM { QTM_U::QTM_U() : ServiceFramework("qtm:u", 2) { diff --git a/src/core/hle/service/qtm/qtm_u.h b/src/core/hle/service/qtm/qtm_u.h index 01bb1e6e08..f6b54c8af5 100644 --- a/src/core/hle/service/qtm/qtm_u.h +++ b/src/core/hle/service/qtm/qtm_u.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::QTM + +BOOST_CLASS_EXPORT_KEY(Service::QTM::QTM_U) diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index 356ebd8436..0c981b545e 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/common_funcs.h" #include "common/logging/log.h" #include "core/core.h" @@ -12,8 +13,22 @@ #include "core/hle/service/y2r_u.h" #include "core/hw/y2r.h" +SERVICE_CONSTRUCT_IMPL(Service::Y2R::Y2R_U) +SERIALIZE_EXPORT_IMPL(Service::Y2R::Y2R_U) + namespace Service::Y2R { +template +void Y2R_U::serialize(Archive& ar, const unsigned int) { + ar& completion_event; + ar& conversion; + ar& dithering_weight_params; + ar& temporal_dithering_enabled; + ar& transfer_end_interrupt_enabled; + ar& spacial_dithering_enabled; +} +SERIALIZE_IMPL(Y2R_U) + static const CoefficientSet standard_coefficients[4] = { {{0x100, 0x166, 0xB6, 0x58, 0x1C5, -0x166F, 0x10EE, -0x1C5B}}, // ITU_Rec601 {{0x100, 0x193, 0x77, 0x2F, 0x1DB, -0x1933, 0xA7C, -0x1D51}}, // ITU_Rec709 diff --git a/src/core/hle/service/y2r_u.h b/src/core/hle/service/y2r_u.h index 332d3b240f..1ac675f92c 100644 --- a/src/core/hle/service/y2r_u.h +++ b/src/core/hle/service/y2r_u.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "common/common_types.h" #include "core/hle/result.h" #include "core/hle/service/service.h" @@ -91,6 +92,16 @@ struct ConversionBuffer { u16 transfer_unit; /// Amount of bytes to be skipped between copying each `transfer_unit` bytes. u16 gap; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& address; + ar& image_size; + ar& transfer_unit; + ar& gap; + } + friend class boost::serialization::access; }; struct ConversionConfiguration { @@ -112,6 +123,26 @@ struct ConversionConfiguration { ResultCode SetInputLineWidth(u16 width); ResultCode SetInputLines(u16 lines); ResultCode SetStandardCoefficient(StandardCoefficient standard_coefficient); + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& input_format; + ar& output_format; + ar& rotation; + ar& block_alignment; + ar& input_line_width; + ar& input_lines; + ar& coefficients; + ar& padding; + ar& alpha; + ar& src_Y; + ar& src_U; + ar& src_V; + ar& src_YUYV; + ar& dst; + } + friend class boost::serialization::access; }; struct DitheringWeightParams { @@ -131,6 +162,28 @@ struct DitheringWeightParams { u16 w3_xOdd_yEven; u16 w3_xEven_yOdd; u16 w3_xOdd_yOdd; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& w0_xEven_yEven; + ar& w0_xOdd_yEven; + ar& w0_xEven_yOdd; + ar& w0_xOdd_yOdd; + ar& w1_xEven_yEven; + ar& w1_xOdd_yEven; + ar& w1_xEven_yOdd; + ar& w1_xOdd_yOdd; + ar& w2_xEven_yEven; + ar& w2_xOdd_yEven; + ar& w2_xEven_yOdd; + ar& w2_xOdd_yOdd; + ar& w3_xEven_yEven; + ar& w3_xOdd_yEven; + ar& w3_xEven_yOdd; + ar& w3_xOdd_yOdd; + } + friend class boost::serialization::access; }; struct ConversionParameters { @@ -301,8 +354,15 @@ private: bool temporal_dithering_enabled = false; bool transfer_end_interrupt_enabled = false; bool spacial_dithering_enabled = false; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::Y2R + +SERVICE_CONSTRUCT(Service::Y2R::Y2R_U) +BOOST_CLASS_EXPORT_KEY(Service::Y2R::Y2R_U) From 2d2c7218ef3a6651606969219a1909c4fa1b4612 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 2 Jan 2020 00:45:58 +0000 Subject: [PATCH 052/129] Serialize CECD, CFG services --- TODO | 23 ++++++++++++++++++----- src/common/construct.h | 1 + src/core/file_sys/archive_backend.h | 11 ++++++++++- src/core/hle/kernel/shared_page.h | 7 ------- src/core/hle/service/cecd/cecd.cpp | 15 ++++++++++++++- src/core/hle/service/cecd/cecd.h | 9 ++++++++- src/core/hle/service/cecd/cecd_ndm.cpp | 3 +++ src/core/hle/service/cecd/cecd_ndm.h | 6 ++++++ src/core/hle/service/cecd/cecd_s.cpp | 3 +++ src/core/hle/service/cecd/cecd_s.h | 6 ++++++ src/core/hle/service/cecd/cecd_u.cpp | 3 +++ src/core/hle/service/cecd/cecd_u.h | 6 ++++++ src/core/hle/service/cfg/cfg.cpp | 11 +++++++++++ src/core/hle/service/cfg/cfg.h | 8 +++++++- src/core/hle/service/cfg/cfg_i.cpp | 3 +++ src/core/hle/service/cfg/cfg_i.h | 6 ++++++ src/core/hle/service/cfg/cfg_nor.cpp | 3 +++ src/core/hle/service/cfg/cfg_nor.h | 2 ++ src/core/hle/service/cfg/cfg_s.cpp | 3 +++ src/core/hle/service/cfg/cfg_s.h | 6 ++++++ src/core/hle/service/cfg/cfg_u.cpp | 3 +++ src/core/hle/service/cfg/cfg_u.h | 6 ++++++ src/core/hle/service/fs/archive.h | 7 +++++++ 23 files changed, 135 insertions(+), 16 deletions(-) diff --git a/TODO b/TODO index 30b51a68c6..5ea46f2e85 100644 --- a/TODO +++ b/TODO @@ -7,8 +7,22 @@ Memory only ✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) ✔ Fix or ignore inverse map @done(19-12-23 12:46) -☐ App loader -☐ Archive manager +✘ App loader @cancelled(20-01-01 22:59) + No relevant state +☐ Archive manager @started(20-01-01 23:03) + ☐ NCCH + ☐ Normal + ☐ Self + ☐ SaveData + ☐ Normal + ☐ Ext + ☐ Other + ☐ Source SD + ☐ System + ☐ SDMC + ☐ Normal + ☐ Write-only + ☐ File refs ☐ Custom texture cache ✘ MMIO @cancelled(20-01-01 01:06) Seems that this whole subsystem is only used in tests @@ -76,9 +90,8 @@ ✔ BOSS @started(19-12-25 21:48) @done(19-12-25 23:18) @lasted(1h30m14s) ☐ CAM @started(19-12-26 10:37) Need to check capture_result - ☐ CECD - ☐ Archive backend / file handles - ☐ CFG + ✔ CECD @done(20-01-01 23:58) + ✔ CFG @done(20-01-02 00:44) Also needs archive backend.. ✔ CSND @started(19-12-26 17:51) @done(19-12-26 17:56) @lasted(5m30s) ✔ DLP @done(19-12-26 18:02) diff --git a/src/common/construct.h b/src/common/construct.h index 6b2b3ceebd..aba4c7e892 100644 --- a/src/common/construct.h +++ b/src/common/construct.h @@ -1,3 +1,4 @@ +#pragma once #include class construct_access { diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 2df4f98c4a..05aa877a35 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -168,7 +168,12 @@ public: } protected: - std::unique_ptr delay_generator; + std::unique_ptr delay_generator; // TODO: Replace with virtual GetOpenDelayNs + +private: + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; class ArchiveFactory : NonCopyable { @@ -205,6 +210,10 @@ public: * @return Format information about the archive or error code */ virtual ResultVal GetFormatInfo(const Path& path, u64 program_id) const = 0; + + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; } // namespace FileSys diff --git a/src/core/hle/kernel/shared_page.h b/src/core/hle/kernel/shared_page.h index b3e1a48b65..45f9cd3489 100644 --- a/src/core/hle/kernel/shared_page.h +++ b/src/core/hle/kernel/shared_page.h @@ -105,13 +105,6 @@ private: std::chrono::seconds init_time; SharedPageDef shared_page; - - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int file_version) { - auto o_shared_page = boost::serialization::binary_object(&shared_page, sizeof(shared_page)); - ar& o_shared_page; - } }; } // namespace SharedPage diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index 281f480262..42ac76946a 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -5,6 +5,7 @@ #include #include #include +#include "common/archives.h" #include "common/common_paths.h" #include "common/file_util.h" #include "common/logging/log.h" @@ -24,8 +25,19 @@ #include "core/hle/service/cfg/cfg.h" #include "fmt/format.h" +SERVICE_CONSTRUCT_IMPL(Service::CECD::Module) +SERIALIZE_EXPORT_IMPL(Service::CECD::Module) + namespace Service::CECD { +template +void Module::serialize(Archive& ar, const unsigned int) { + ar& cecd_system_save_data_archive; + ar& cecinfo_event; + ar& change_state_event; +} +SERIALIZE_IMPL(Module) + using CecDataPathType = Module::CecDataPathType; using CecOpenMode = Module::CecOpenMode; using CecSystemInfoType = Module::CecSystemInfoType; @@ -1340,7 +1352,8 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ case CecDataPathType::MboxData: case CecDataPathType::MboxIcon: case CecDataPathType::MboxTitle: - default: {} + default: { + } } } diff --git a/src/core/hle/service/cecd/cecd.h b/src/core/hle/service/cecd/cecd.h index 004ef33e70..dd7fff7cb9 100644 --- a/src/core/hle/service/cecd/cecd.h +++ b/src/core/hle/service/cecd/cecd.h @@ -584,7 +584,7 @@ public: */ void GetCecInfoEventHandleSys(Kernel::HLERequestContext& ctx); - private: + protected: std::shared_ptr cecd; }; @@ -613,9 +613,16 @@ private: std::shared_ptr change_state_event; Core::System& system; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; /// Initialize CECD service(s) void InstallInterfaces(Core::System& system); } // namespace Service::CECD + +SERVICE_CONSTRUCT(Service::CECD::Module) +BOOST_CLASS_EXPORT_KEY(Service::CECD::Module) diff --git a/src/core/hle/service/cecd/cecd_ndm.cpp b/src/core/hle/service/cecd/cecd_ndm.cpp index e4366e9c62..4b571283de 100644 --- a/src/core/hle/service/cecd/cecd_ndm.cpp +++ b/src/core/hle/service/cecd/cecd_ndm.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cecd/cecd_ndm.h" +SERIALIZE_EXPORT_IMPL(Service::CECD::CECD_NDM) + namespace Service::CECD { CECD_NDM::CECD_NDM(std::shared_ptr cecd) diff --git a/src/core/hle/service/cecd/cecd_ndm.h b/src/core/hle/service/cecd/cecd_ndm.h index a9fabb1a11..9fd282585e 100644 --- a/src/core/hle/service/cecd/cecd_ndm.h +++ b/src/core/hle/service/cecd/cecd_ndm.h @@ -11,6 +11,12 @@ namespace Service::CECD { class CECD_NDM final : public Module::Interface { public: explicit CECD_NDM(std::shared_ptr cecd); + +private: + SERVICE_SERIALIZATION(CECD_NDM, cecd, Module) }; } // namespace Service::CECD + +BOOST_CLASS_EXPORT_KEY(Service::CECD::CECD_NDM) +BOOST_SERIALIZATION_CONSTRUCT(Service::CECD::CECD_NDM) diff --git a/src/core/hle/service/cecd/cecd_s.cpp b/src/core/hle/service/cecd/cecd_s.cpp index 3395c405d2..fa838d2af4 100644 --- a/src/core/hle/service/cecd/cecd_s.cpp +++ b/src/core/hle/service/cecd/cecd_s.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cecd/cecd_s.h" +SERIALIZE_EXPORT_IMPL(Service::CECD::CECD_S) + namespace Service::CECD { CECD_S::CECD_S(std::shared_ptr cecd) diff --git a/src/core/hle/service/cecd/cecd_s.h b/src/core/hle/service/cecd/cecd_s.h index 6c50b13ba9..9c6a7afec9 100644 --- a/src/core/hle/service/cecd/cecd_s.h +++ b/src/core/hle/service/cecd/cecd_s.h @@ -11,6 +11,12 @@ namespace Service::CECD { class CECD_S final : public Module::Interface { public: explicit CECD_S(std::shared_ptr cecd); + +private: + SERVICE_SERIALIZATION(CECD_S, cecd, Module) }; } // namespace Service::CECD + +BOOST_CLASS_EXPORT_KEY(Service::CECD::CECD_S) +BOOST_SERIALIZATION_CONSTRUCT(Service::CECD::CECD_S) diff --git a/src/core/hle/service/cecd/cecd_u.cpp b/src/core/hle/service/cecd/cecd_u.cpp index 81fcd1019b..e8cd7d1c9a 100644 --- a/src/core/hle/service/cecd/cecd_u.cpp +++ b/src/core/hle/service/cecd/cecd_u.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cecd/cecd_u.h" +SERIALIZE_EXPORT_IMPL(Service::CECD::CECD_U) + namespace Service::CECD { CECD_U::CECD_U(std::shared_ptr cecd) diff --git a/src/core/hle/service/cecd/cecd_u.h b/src/core/hle/service/cecd/cecd_u.h index 49ddadb690..31e7a2367d 100644 --- a/src/core/hle/service/cecd/cecd_u.h +++ b/src/core/hle/service/cecd/cecd_u.h @@ -11,6 +11,12 @@ namespace Service::CECD { class CECD_U final : public Module::Interface { public: explicit CECD_U(std::shared_ptr cecd); + +private: + SERVICE_SERIALIZATION(CECD_U, cecd, Module) }; } // namespace Service::CECD + +BOOST_CLASS_EXPORT_KEY(Service::CECD::CECD_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::CECD::CECD_U) diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index df6fd2e76e..655405e776 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp @@ -6,6 +6,7 @@ #include #include #include +#include "common/archives.h" #include "common/common_paths.h" #include "common/file_util.h" #include "common/logging/log.h" @@ -24,8 +25,18 @@ #include "core/hle/service/cfg/cfg_u.h" #include "core/settings.h" +SERIALIZE_EXPORT_IMPL(Service::CFG::Module) + namespace Service::CFG { +template +void Module::serialize(Archive& ar, const unsigned int) { + ar& cfg_config_file_buffer; + ar& cfg_system_save_data_archive; + ar& preferred_region_code; +} +SERIALIZE_IMPL(Module) + /// The maximum number of block entries that can exist in the config file static const u32 CONFIG_FILE_MAX_BLOCK_ENTRIES = 1479; diff --git a/src/core/hle/service/cfg/cfg.h b/src/core/hle/service/cfg/cfg.h index 6886d513b3..58e9145834 100644 --- a/src/core/hle/service/cfg/cfg.h +++ b/src/core/hle/service/cfg/cfg.h @@ -244,7 +244,7 @@ public: (this->*function)(ctx, id); } - private: + protected: std::shared_ptr cfg; }; @@ -426,6 +426,10 @@ private: std::array cfg_config_file_buffer; std::unique_ptr cfg_system_save_data_archive; u32 preferred_region_code = 0; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; std::shared_ptr GetModule(Core::System& system); @@ -436,3 +440,5 @@ void InstallInterfaces(Core::System& system); std::string GetConsoleIdHash(Core::System& system); } // namespace Service::CFG + +BOOST_CLASS_EXPORT_KEY(Service::CFG::Module) diff --git a/src/core/hle/service/cfg/cfg_i.cpp b/src/core/hle/service/cfg/cfg_i.cpp index 6242990762..4d3d298a20 100644 --- a/src/core/hle/service/cfg/cfg_i.cpp +++ b/src/core/hle/service/cfg/cfg_i.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cfg/cfg_i.h" +SERIALIZE_EXPORT_IMPL(Service::CFG::CFG_I) + namespace Service::CFG { CFG_I::CFG_I(std::shared_ptr cfg) : Module::Interface(std::move(cfg), "cfg:i", 23) { diff --git a/src/core/hle/service/cfg/cfg_i.h b/src/core/hle/service/cfg/cfg_i.h index 704eb4a71a..ac8ffb9906 100644 --- a/src/core/hle/service/cfg/cfg_i.h +++ b/src/core/hle/service/cfg/cfg_i.h @@ -11,6 +11,12 @@ namespace Service::CFG { class CFG_I final : public Module::Interface { public: explicit CFG_I(std::shared_ptr cfg); + +private: + SERVICE_SERIALIZATION(CFG_I, cfg, Module) }; } // namespace Service::CFG + +BOOST_CLASS_EXPORT_KEY(Service::CFG::CFG_I) +BOOST_SERIALIZATION_CONSTRUCT(Service::CFG::CFG_I) diff --git a/src/core/hle/service/cfg/cfg_nor.cpp b/src/core/hle/service/cfg/cfg_nor.cpp index 4135483133..0dd21076d5 100644 --- a/src/core/hle/service/cfg/cfg_nor.cpp +++ b/src/core/hle/service/cfg/cfg_nor.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cfg/cfg_nor.h" +SERIALIZE_EXPORT_IMPL(Service::CFG::CFG_NOR) + namespace Service::CFG { CFG_NOR::CFG_NOR() : ServiceFramework("cfg:nor", 23) { diff --git a/src/core/hle/service/cfg/cfg_nor.h b/src/core/hle/service/cfg/cfg_nor.h index 3dace92bd9..1eca85a050 100644 --- a/src/core/hle/service/cfg/cfg_nor.h +++ b/src/core/hle/service/cfg/cfg_nor.h @@ -14,3 +14,5 @@ public: }; } // namespace Service::CFG + +BOOST_CLASS_EXPORT_KEY(Service::CFG::CFG_NOR) diff --git a/src/core/hle/service/cfg/cfg_s.cpp b/src/core/hle/service/cfg/cfg_s.cpp index a211dae05b..773a412f7f 100644 --- a/src/core/hle/service/cfg/cfg_s.cpp +++ b/src/core/hle/service/cfg/cfg_s.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cfg/cfg_s.h" +SERIALIZE_EXPORT_IMPL(Service::CFG::CFG_S) + namespace Service::CFG { CFG_S::CFG_S(std::shared_ptr cfg) : Module::Interface(std::move(cfg), "cfg:s", 23) { diff --git a/src/core/hle/service/cfg/cfg_s.h b/src/core/hle/service/cfg/cfg_s.h index 7f135b3577..d0cbc7a187 100644 --- a/src/core/hle/service/cfg/cfg_s.h +++ b/src/core/hle/service/cfg/cfg_s.h @@ -11,6 +11,12 @@ namespace Service::CFG { class CFG_S final : public Module::Interface { public: explicit CFG_S(std::shared_ptr cfg); + +private: + SERVICE_SERIALIZATION(CFG_S, cfg, Module) }; } // namespace Service::CFG + +BOOST_CLASS_EXPORT_KEY(Service::CFG::CFG_S) +BOOST_SERIALIZATION_CONSTRUCT(Service::CFG::CFG_S) diff --git a/src/core/hle/service/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp index 6aa862f82f..bcc590bf87 100644 --- a/src/core/hle/service/cfg/cfg_u.cpp +++ b/src/core/hle/service/cfg/cfg_u.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cfg/cfg_u.h" +SERIALIZE_EXPORT_IMPL(Service::CFG::CFG_U) + namespace Service::CFG { CFG_U::CFG_U(std::shared_ptr cfg) : Module::Interface(std::move(cfg), "cfg:u", 23) { diff --git a/src/core/hle/service/cfg/cfg_u.h b/src/core/hle/service/cfg/cfg_u.h index 8b48e963ea..9063771244 100644 --- a/src/core/hle/service/cfg/cfg_u.h +++ b/src/core/hle/service/cfg/cfg_u.h @@ -11,6 +11,12 @@ namespace Service::CFG { class CFG_U final : public Module::Interface { public: explicit CFG_U(std::shared_ptr cfg); + +private: + SERVICE_SERIALIZATION(CFG_U, cfg, Module) }; } // namespace Service::CFG + +BOOST_CLASS_EXPORT_KEY(Service::CFG::CFG_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::CFG::CFG_U) diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index 862e749806..29965491b9 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -260,6 +260,13 @@ private: */ std::unordered_map> handle_map; ArchiveHandle next_handle = 1; + + template + void serialize(Archive& ar, const unsigned int) { + ar& id_code_map; + ar& handle_map; + ar& next_handle; + } }; } // namespace Service::FS From 2bf5b464609348e786a068074d41e74fb5331a35 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 2 Jan 2020 23:34:26 +0000 Subject: [PATCH 053/129] Basic archive backend serialization --- TODO | 23 +++++++------ src/core/file_sys/archive_extsavedata.cpp | 3 ++ src/core/file_sys/archive_extsavedata.h | 12 +++++++ src/core/file_sys/archive_ncch.cpp | 5 +++ src/core/file_sys/archive_ncch.h | 34 ++++++++++++++++++- src/core/file_sys/archive_other_savedata.cpp | 4 +++ src/core/file_sys/archive_other_savedata.h | 23 +++++++++++-- src/core/file_sys/archive_savedata.cpp | 3 ++ src/core/file_sys/archive_savedata.h | 12 ++++++- src/core/file_sys/archive_sdmc.cpp | 4 +++ src/core/file_sys/archive_sdmc.h | 21 ++++++++++++ src/core/file_sys/archive_sdmcwriteonly.cpp | 4 +++ src/core/file_sys/archive_sdmcwriteonly.h | 18 ++++++++++ .../file_sys/archive_source_sd_savedata.cpp | 3 ++ .../file_sys/archive_source_sd_savedata.h | 11 ++++++ src/core/file_sys/archive_systemsavedata.cpp | 3 ++ src/core/file_sys/archive_systemsavedata.h | 11 ++++++ src/core/file_sys/file_backend.h | 7 +++- 18 files changed, 185 insertions(+), 16 deletions(-) diff --git a/TODO b/TODO index 5ea46f2e85..c1f5e49cda 100644 --- a/TODO +++ b/TODO @@ -10,19 +10,20 @@ ✘ App loader @cancelled(20-01-01 22:59) No relevant state ☐ Archive manager @started(20-01-01 23:03) - ☐ NCCH - ☐ Normal + ☐ NCCH @started(20-01-02 22:50) + ✔ Normal @done(20-01-02 22:50) ☐ Self - ☐ SaveData - ☐ Normal - ☐ Ext - ☐ Other - ☐ Source SD - ☐ System - ☐ SDMC - ☐ Normal - ☐ Write-only + ✔ SaveData @started(20-01-02 23:03) @done(20-01-02 23:27) @lasted(25m) + ✔ Normal @done(20-01-02 23:03) + ✔ Ext @done(20-01-02 23:26) + ✔ Other @done(20-01-02 23:21) + ✔ Source SD @done(20-01-02 23:03) + ✔ System @done(20-01-02 23:13) + ✔ SDMC @done(20-01-02 23:34) + ✔ Normal @done(20-01-02 23:34) + ✔ Write-only @done(20-01-02 23:34) ☐ File refs + ☐ Replace delay generator with virtual fns ☐ Custom texture cache ✘ MMIO @cancelled(20-01-01 01:06) Seems that this whole subsystem is only used in tests diff --git a/src/core/file_sys/archive_extsavedata.cpp b/src/core/file_sys/archive_extsavedata.cpp index efcdb2d7f5..22084b690c 100644 --- a/src/core/file_sys/archive_extsavedata.cpp +++ b/src/core/file_sys/archive_extsavedata.cpp @@ -6,6 +6,7 @@ #include #include #include +#include "common/archives.h" #include "common/common_types.h" #include "common/file_util.h" #include "common/logging/log.h" @@ -19,6 +20,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_ExtSaveData) + namespace FileSys { /** diff --git a/src/core/file_sys/archive_extsavedata.h b/src/core/file_sys/archive_extsavedata.h index 7dc345c847..b00e1633d6 100644 --- a/src/core/file_sys/archive_extsavedata.h +++ b/src/core/file_sys/archive_extsavedata.h @@ -6,6 +6,8 @@ #include #include +#include +#include #include "common/common_types.h" #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -54,6 +56,14 @@ private: /// Returns a path with the correct SaveIdHigh value for Shared extdata paths. Path GetCorrectedPath(const Path& path); + + ArchiveFactory_ExtSaveData() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& shared; + ar& mount_point; + } + friend class boost::serialization::access; }; /** @@ -94,3 +104,5 @@ std::string GetExtDataContainerPath(const std::string& mount_point, bool shared) Path ConstructExtDataBinaryPath(u32 media_type, u32 high, u32 low); } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_ExtSaveData) diff --git a/src/core/file_sys/archive_ncch.cpp b/src/core/file_sys/archive_ncch.cpp index 06fe696224..789547f0e3 100644 --- a/src/core/file_sys/archive_ncch.cpp +++ b/src/core/file_sys/archive_ncch.cpp @@ -8,6 +8,7 @@ #include #include #include "bad_word_list.app.romfs.h" +#include "common/archives.h" #include "common/common_types.h" #include "common/file_util.h" #include "common/logging/log.h" @@ -28,6 +29,10 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::NCCHArchive) +SERIALIZE_EXPORT_IMPL(FileSys::NCCHFile) +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_NCCH) + namespace FileSys { struct NCCHArchivePath { diff --git a/src/core/file_sys/archive_ncch.h b/src/core/file_sys/archive_ncch.h index 28d9ff0446..52ae827c35 100644 --- a/src/core/file_sys/archive_ncch.h +++ b/src/core/file_sys/archive_ncch.h @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include "core/file_sys/archive_backend.h" #include "core/file_sys/file_backend.h" #include "core/hle/result.h" @@ -63,6 +66,17 @@ public: protected: u64 title_id; Service::FS::MediaType media_type; + +private: + NCCHArchive() = default; // NOTE: If the public ctor has behaviour, need to replace this with + // *_construct_data + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& title_id; + ar& media_type; + } + friend class boost::serialization::access; }; // File backend for NCCH files @@ -81,7 +95,16 @@ public: void Flush() const override {} private: - std::vector file_buffer; + NCCHFile() = default; // NOTE: If the public ctor has behaviour, need to replace this with + // *_construct_data + std::vector file_buffer; // TODO: Replace with file ref for serialization + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& file_buffer; + } + friend class boost::serialization::access; }; /// File system interface to the NCCH archive @@ -97,6 +120,15 @@ public: ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info, u64 program_id) override; ResultVal GetFormatInfo(const Path& path, u64 program_id) const override; + +private: + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::NCCHArchive) +BOOST_CLASS_EXPORT_KEY(FileSys::NCCHFile) +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_NCCH) diff --git a/src/core/file_sys/archive_other_savedata.cpp b/src/core/file_sys/archive_other_savedata.cpp index 1c3b071ba8..d4f8debc4b 100644 --- a/src/core/file_sys/archive_other_savedata.cpp +++ b/src/core/file_sys/archive_other_savedata.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/archives.h" #include "core/file_sys/archive_other_savedata.h" #include "core/file_sys/errors.h" #include "core/hle/kernel/process.h" @@ -12,6 +13,9 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_OtherSaveDataPermitted) +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_OtherSaveDataGeneral) + namespace FileSys { // TODO(wwylele): The storage info in exheader should be checked before accessing these archives diff --git a/src/core/file_sys/archive_other_savedata.h b/src/core/file_sys/archive_other_savedata.h index e3e8f83c33..a9deae95a9 100644 --- a/src/core/file_sys/archive_other_savedata.h +++ b/src/core/file_sys/archive_other_savedata.h @@ -4,6 +4,8 @@ #pragma once +#include +#include #include "core/file_sys/archive_source_sd_savedata.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -27,8 +29,15 @@ public: ResultVal GetFormatInfo(const Path& path, u64 program_id) const override; private: - std::string mount_point; + std::string mount_point; // TODO: Remove, unused? std::shared_ptr sd_savedata_source; + + ArchiveFactory_OtherSaveDataPermitted() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& sd_savedata_source; + } + friend class boost::serialization::access; }; /// File system interface to the OtherSaveDataGeneral archive @@ -47,8 +56,18 @@ public: ResultVal GetFormatInfo(const Path& path, u64 program_id) const override; private: - std::string mount_point; + std::string mount_point; // TODO: Remove, unused? std::shared_ptr sd_savedata_source; + + ArchiveFactory_OtherSaveDataGeneral() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& sd_savedata_source; + } + friend class boost::serialization::access; }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_OtherSaveDataPermitted) +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_OtherSaveDataGeneral) diff --git a/src/core/file_sys/archive_savedata.cpp b/src/core/file_sys/archive_savedata.cpp index c1046e2f56..fc4bd34fa2 100644 --- a/src/core/file_sys/archive_savedata.cpp +++ b/src/core/file_sys/archive_savedata.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "core/core.h" #include "core/file_sys/archive_savedata.h" #include "core/hle/kernel/process.h" @@ -10,6 +11,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_SaveData) + namespace FileSys { ArchiveFactory_SaveData::ArchiveFactory_SaveData( diff --git a/src/core/file_sys/archive_savedata.h b/src/core/file_sys/archive_savedata.h index 591a3b900c..3ebe94a63d 100644 --- a/src/core/file_sys/archive_savedata.h +++ b/src/core/file_sys/archive_savedata.h @@ -4,6 +4,7 @@ #pragma once +#include #include "core/file_sys/archive_source_sd_savedata.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -27,8 +28,17 @@ public: ResultVal GetFormatInfo(const Path& path, u64 program_id) const override; private: - std::string mount_point; + std::string mount_point; // TODO: Remove this? seems unused std::shared_ptr sd_savedata_source; + + ArchiveFactory_SaveData() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& sd_savedata_source; + } + friend class boost::serialization::access; }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SaveData) diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp index d2269fe7cc..1c51183202 100644 --- a/src/core/file_sys/archive_sdmc.cpp +++ b/src/core/file_sys/archive_sdmc.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/archives.h" #include "common/file_util.h" #include "common/logging/log.h" #include "core/file_sys/archive_sdmc.h" @@ -15,6 +16,9 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::SDMCArchive) +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_SDMC) + namespace FileSys { class SDMCDelayGenerator : public DelayGenerator { diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index 41d7b7c591..2e0abf44b2 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h @@ -6,6 +6,9 @@ #include #include +#include +#include +#include #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -42,6 +45,14 @@ public: protected: ResultVal> OpenFileBase(const Path& path, const Mode& mode) const; std::string mount_point; + + SDMCArchive() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& mount_point; + } + friend class boost::serialization::access; }; /// File system interface to the SDMC archive @@ -66,6 +77,16 @@ public: private: std::string sdmc_directory; + + ArchiveFactory_SDMC() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& sdmc_directory; + } + friend class boost::serialization::access; }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::SDMCArchive) +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SDMC) diff --git a/src/core/file_sys/archive_sdmcwriteonly.cpp b/src/core/file_sys/archive_sdmcwriteonly.cpp index 74552d751e..ea64dc8645 100644 --- a/src/core/file_sys/archive_sdmcwriteonly.cpp +++ b/src/core/file_sys/archive_sdmcwriteonly.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/file_util.h" #include "core/file_sys/archive_sdmcwriteonly.h" #include "core/file_sys/directory_backend.h" @@ -13,6 +14,9 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::SDMCWriteOnlyArchive) +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_SDMCWriteOnly) + namespace FileSys { class SDMCWriteOnlyDelayGenerator : public DelayGenerator { diff --git a/src/core/file_sys/archive_sdmcwriteonly.h b/src/core/file_sys/archive_sdmcwriteonly.h index 8191f053fb..2ba504aa70 100644 --- a/src/core/file_sys/archive_sdmcwriteonly.h +++ b/src/core/file_sys/archive_sdmcwriteonly.h @@ -31,6 +31,14 @@ public: const Mode& mode) const override; ResultVal> OpenDirectory(const Path& path) const override; + +private: + SDMCWriteOnlyArchive() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + } + friend class boost::serialization::access; }; /// File system interface to the SDMC write-only archive @@ -55,6 +63,16 @@ public: private: std::string sdmc_directory; + + ArchiveFactory_SDMCWriteOnly() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& sdmc_directory; + } + friend class boost::serialization::access; }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::SDMCWriteOnlyArchive) +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SDMCWriteOnly) diff --git a/src/core/file_sys/archive_source_sd_savedata.cpp b/src/core/file_sys/archive_source_sd_savedata.cpp index 0b8072b96f..9afbfd73c3 100644 --- a/src/core/file_sys/archive_source_sd_savedata.cpp +++ b/src/core/file_sys/archive_source_sd_savedata.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/file_util.h" #include "common/logging/log.h" #include "core/file_sys/archive_source_sd_savedata.h" @@ -13,6 +14,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveSource_SDSaveData) + namespace FileSys { namespace { diff --git a/src/core/file_sys/archive_source_sd_savedata.h b/src/core/file_sys/archive_source_sd_savedata.h index b5fe43cc16..4ac028a3d7 100644 --- a/src/core/file_sys/archive_source_sd_savedata.h +++ b/src/core/file_sys/archive_source_sd_savedata.h @@ -6,6 +6,8 @@ #include #include +#include +#include #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -27,6 +29,15 @@ public: private: std::string mount_point; + + ArchiveSource_SDSaveData() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& mount_point; + } + friend class boost::serialization::access; }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveSource_SDSaveData) diff --git a/src/core/file_sys/archive_systemsavedata.cpp b/src/core/file_sys/archive_systemsavedata.cpp index cef42e5611..ecfb342199 100644 --- a/src/core/file_sys/archive_systemsavedata.cpp +++ b/src/core/file_sys/archive_systemsavedata.cpp @@ -7,6 +7,7 @@ #include #include #include +#include "common/archives.h" #include "common/common_types.h" #include "common/file_util.h" #include "core/file_sys/archive_systemsavedata.h" @@ -17,6 +18,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_SystemSaveData) + namespace FileSys { std::string GetSystemSaveDataPath(const std::string& mount_point, const Path& path) { diff --git a/src/core/file_sys/archive_systemsavedata.h b/src/core/file_sys/archive_systemsavedata.h index e72ecce3a1..cf18cab899 100644 --- a/src/core/file_sys/archive_systemsavedata.h +++ b/src/core/file_sys/archive_systemsavedata.h @@ -6,6 +6,8 @@ #include #include +#include +#include #include "common/common_types.h" #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -31,6 +33,13 @@ public: private: std::string base_path; + + ArchiveFactory_SystemSaveData() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& base_path; + } + friend class boost::serialization::access; }; /** @@ -60,3 +69,5 @@ std::string GetSystemSaveDataContainerPath(const std::string& mount_point); Path ConstructSystemSaveDataBinaryPath(u32 high, u32 low); } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SystemSaveData) diff --git a/src/core/file_sys/file_backend.h b/src/core/file_sys/file_backend.h index c865c98e8f..03dff156da 100644 --- a/src/core/file_sys/file_backend.h +++ b/src/core/file_sys/file_backend.h @@ -89,7 +89,12 @@ public: virtual void Flush() const = 0; protected: - std::unique_ptr delay_generator; + std::unique_ptr delay_generator; // TODO: replace with virtual Get*DelayNs + +private: + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; } // namespace FileSys From 558e710e170030e1e9bc8f0105f571b44a43bb79 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 3 Jan 2020 14:00:10 +0000 Subject: [PATCH 054/129] Finished archives; remove pod.h --- TODO | 17 +++++++++++------ src/common/pod.h | 17 ----------------- src/core/file_sys/archive_backend.h | 4 +++- src/core/file_sys/archive_ncch.cpp | 1 - src/core/file_sys/archive_ncch.h | 8 -------- src/core/file_sys/archive_selfncch.cpp | 3 +++ src/core/file_sys/archive_selfncch.h | 6 +++++- src/core/file_sys/delay_generator.cpp | 3 +++ src/core/file_sys/delay_generator.h | 8 ++++++++ src/core/file_sys/file_backend.h | 7 +------ src/core/hle/result.h | 9 +++++++-- src/core/hw/gpu.h | 10 ++++++++-- src/core/hw/lcd.h | 12 ++++++++++-- src/video_core/shader/shader.h | 15 +++++++++++++-- 14 files changed, 72 insertions(+), 48 deletions(-) delete mode 100644 src/common/pod.h diff --git a/TODO b/TODO index c1f5e49cda..bc4003d444 100644 --- a/TODO +++ b/TODO @@ -9,10 +9,11 @@ ✔ Fix or ignore inverse map @done(19-12-23 12:46) ✘ App loader @cancelled(20-01-01 22:59) No relevant state -☐ Archive manager @started(20-01-01 23:03) - ☐ NCCH @started(20-01-02 22:50) +✔ Archive manager @started(20-01-01 23:03) @done(20-01-03 13:23) @lasted(1d14h20m40s) + NB that 'FileBackend' classes are not persistent + ✔ NCCH @started(20-01-02 22:50) @done(20-01-03 12:35) @lasted(13h45m50s) ✔ Normal @done(20-01-02 22:50) - ☐ Self + ✔ Self @done(20-01-03 12:35) ✔ SaveData @started(20-01-02 23:03) @done(20-01-02 23:27) @lasted(25m) ✔ Normal @done(20-01-02 23:03) ✔ Ext @done(20-01-02 23:26) @@ -22,8 +23,12 @@ ✔ SDMC @done(20-01-02 23:34) ✔ Normal @done(20-01-02 23:34) ✔ Write-only @done(20-01-02 23:34) - ☐ File refs - ☐ Replace delay generator with virtual fns + ✘ IVFC @cancelled(20-01-03 13:22) + Seems IVFCArchive is never used.. which is good because it has a file reference! + ✘ File refs @cancelled(20-01-03 13:22) + Not needed as nothing serializes file buffers + ✘ Replace delay generator with virtual fns @cancelled(20-01-03 13:16) + While they have no state, the extra refactoring here is unneeded ☐ Custom texture cache ✘ MMIO @cancelled(20-01-01 01:06) Seems that this whole subsystem is only used in tests @@ -35,7 +40,7 @@ For now, let the settings just be whatever they are ✘ Telemetry session @cancelled(20-01-01 01:12) Doesn't need to be serialized here -☐ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE +✔ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE @started(20-01-03 13:47) @done(20-01-03 13:58) @lasted(11m22s) ☐ Review constructor/initialization code ✔ Fix CI @done(19-12-31 21:32) ✔ HW @done(19-08-13 15:41) diff --git a/src/common/pod.h b/src/common/pod.h deleted file mode 100644 index bb70954177..0000000000 --- a/src/common/pod.h +++ /dev/null @@ -1,17 +0,0 @@ -#include "boost/serialization/split_member.hpp" - -#define SERIALIZE_AS_POD \ -private: \ - friend class boost::serialization::access; \ - template \ - void save(Archive& ar, const unsigned int file_version) const { \ - ar.save_binary(this, sizeof(*this)); \ - } \ - template \ - void load(Archive& ar, const unsigned int file_version) { \ - ar.load_binary(this, sizeof(*this)); \ - } \ - template \ - void serialize(Archive& ar, const unsigned int file_version) { \ - boost::serialization::split_member(ar, *this, file_version); \ - } diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 05aa877a35..756613a305 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -172,7 +172,9 @@ protected: private: template - void serialize(Archive& ar, const unsigned int) {} + void serialize(Archive& ar, const unsigned int) { + ar& delay_generator; + } friend class boost::serialization::access; }; diff --git a/src/core/file_sys/archive_ncch.cpp b/src/core/file_sys/archive_ncch.cpp index 789547f0e3..636bb81ed6 100644 --- a/src/core/file_sys/archive_ncch.cpp +++ b/src/core/file_sys/archive_ncch.cpp @@ -30,7 +30,6 @@ // FileSys namespace SERIALIZE_EXPORT_IMPL(FileSys::NCCHArchive) -SERIALIZE_EXPORT_IMPL(FileSys::NCCHFile) SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_NCCH) namespace FileSys { diff --git a/src/core/file_sys/archive_ncch.h b/src/core/file_sys/archive_ncch.h index 52ae827c35..0a3f95b5c9 100644 --- a/src/core/file_sys/archive_ncch.h +++ b/src/core/file_sys/archive_ncch.h @@ -98,13 +98,6 @@ private: NCCHFile() = default; // NOTE: If the public ctor has behaviour, need to replace this with // *_construct_data std::vector file_buffer; // TODO: Replace with file ref for serialization - - template - void serialize(Archive& ar, const unsigned int) { - ar& boost::serialization::base_object(*this); - ar& file_buffer; - } - friend class boost::serialization::access; }; /// File system interface to the NCCH archive @@ -130,5 +123,4 @@ private: } // namespace FileSys BOOST_CLASS_EXPORT_KEY(FileSys::NCCHArchive) -BOOST_CLASS_EXPORT_KEY(FileSys::NCCHFile) BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_NCCH) diff --git a/src/core/file_sys/archive_selfncch.cpp b/src/core/file_sys/archive_selfncch.cpp index 0f8dd80651..214ad7c084 100644 --- a/src/core/file_sys/archive_selfncch.cpp +++ b/src/core/file_sys/archive_selfncch.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" #include "common/swap.h" @@ -16,6 +17,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_SelfNCCH) + namespace FileSys { enum class SelfNCCHFilePathType : u32 { diff --git a/src/core/file_sys/archive_selfncch.h b/src/core/file_sys/archive_selfncch.h index 779e7e75ab..de7fd75e09 100644 --- a/src/core/file_sys/archive_selfncch.h +++ b/src/core/file_sys/archive_selfncch.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "common/common_types.h" #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -44,7 +45,10 @@ public: private: /// Mapping of ProgramId -> NCCHData - std::unordered_map ncch_data; + std::unordered_map + ncch_data; // TODO: Remove this, or actually set the values here }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SelfNCCH) diff --git a/src/core/file_sys/delay_generator.cpp b/src/core/file_sys/delay_generator.cpp index 04f877f833..137e63d696 100644 --- a/src/core/file_sys/delay_generator.cpp +++ b/src/core/file_sys/delay_generator.cpp @@ -3,8 +3,11 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "core/file_sys/delay_generator.h" +SERIALIZE_EXPORT_IMPL(FileSys::DefaultDelayGenerator) + namespace FileSys { DelayGenerator::~DelayGenerator() = default; diff --git a/src/core/file_sys/delay_generator.h b/src/core/file_sys/delay_generator.h index d530f2ee29..8fa92ac419 100644 --- a/src/core/file_sys/delay_generator.h +++ b/src/core/file_sys/delay_generator.h @@ -5,6 +5,8 @@ #pragma once #include +#include +#include #include "common/common_types.h" namespace FileSys { @@ -16,6 +18,10 @@ public: virtual u64 GetOpenDelayNs() = 0; // TODO (B3N30): Add getter for all other file/directory io operations +private: + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; class DefaultDelayGenerator : public DelayGenerator { @@ -25,3 +31,5 @@ public: }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::DefaultDelayGenerator); diff --git a/src/core/file_sys/file_backend.h b/src/core/file_sys/file_backend.h index 03dff156da..c865c98e8f 100644 --- a/src/core/file_sys/file_backend.h +++ b/src/core/file_sys/file_backend.h @@ -89,12 +89,7 @@ public: virtual void Flush() const = 0; protected: - std::unique_ptr delay_generator; // TODO: replace with virtual Get*DelayNs - -private: - template - void serialize(Archive& ar, const unsigned int) {} - friend class boost::serialization::access; + std::unique_ptr delay_generator; }; } // namespace FileSys diff --git a/src/core/hle/result.h b/src/core/hle/result.h index 4168ce36cf..40a71e369c 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h @@ -6,11 +6,11 @@ #include #include +#include #include "common/assert.h" #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" -#include "common/pod.h" // All the constants in this file come from http://3dbrew.org/wiki/Error_codes @@ -227,7 +227,12 @@ union ResultCode { return is_error.ExtractValue(raw) == 1; } - SERIALIZE_AS_POD +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& raw; + } + friend class boost::serialization::access; }; constexpr bool operator==(const ResultCode& a, const ResultCode& b) { diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h index 980b48cd77..fcf7a3137e 100644 --- a/src/core/hw/gpu.h +++ b/src/core/hw/gpu.h @@ -6,11 +6,12 @@ #include #include +#include +#include #include "common/assert.h" #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" -#include "common/pod.h" namespace Memory { class MemorySystem; @@ -298,7 +299,12 @@ private: return register_value * 8; } - SERIALIZE_AS_POD + template + void serialize(Archive& ar, const unsigned int) { + auto obj = boost::serialization::binary_object(this, sizeof(Regs)); + ar& obj; + } + friend class boost::serialization::access; }; static_assert(std::is_standard_layout::value, "Structure does not use standard layout"); diff --git a/src/core/hw/lcd.h b/src/core/hw/lcd.h index ecc9ecea41..9667c7c4c0 100644 --- a/src/core/hw/lcd.h +++ b/src/core/hw/lcd.h @@ -6,10 +6,10 @@ #include #include +#include #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" -#include "common/pod.h" #define LCD_REG_INDEX(field_name) (offsetof(LCD::Regs, field_name) / sizeof(u32)) @@ -52,7 +52,15 @@ struct Regs { return content[index]; } - SERIALIZE_AS_POD +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& color_fill_top.raw; + ar& backlight_top; + ar& color_fill_bottom.raw; + ar& backlight_bottom; + } + friend class boost::serialization::access; }; static_assert(std::is_standard_layout::value, "Structure does not use standard layout"); diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index a6e42b3bff..6a5a334193 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -15,7 +16,6 @@ #include "common/common_funcs.h" #include "common/common_types.h" #include "common/hash.h" -#include "common/pod.h" #include "common/vector_math.h" #include "video_core/pica_types.h" #include "video_core/regs_rasterizer.h" @@ -65,7 +65,18 @@ struct OutputVertex { static OutputVertex FromAttributeBuffer(const RasterizerRegs& regs, const AttributeBuffer& output); - SERIALIZE_AS_POD +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& pos; + ar& quat; + ar& tc0; + ar& tc1; + ar& tc0_w; + ar& view; + ar& tc2; + } + friend class boost::serialization::access; }; #define ASSERT_POS(var, pos) \ static_assert(offsetof(OutputVertex, var) == pos * sizeof(float24), "Semantic at wrong " \ From 26e90a99cd25685ee96184a8e21ff010913d8895 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 3 Jan 2020 17:19:59 +0000 Subject: [PATCH 055/129] Added basic UI; misc memory fixes --- TODO | 13 +++++++++---- src/citra_qt/main.cpp | 24 ++++++++++++++++++++++++ src/citra_qt/main.h | 2 ++ src/citra_qt/main.ui | 18 ++++++++++++++++++ src/common/CMakeLists.txt | 1 - src/core/hle/kernel/config_mem.h | 3 +-- src/core/hle/kernel/ipc.cpp | 12 ++++++------ src/core/hle/kernel/ipc.h | 12 +++++------- src/core/hle/kernel/process.cpp | 2 +- src/core/hle/kernel/process.h | 2 +- src/core/hw/gpu.h | 3 +-- src/core/memory.cpp | 19 ++++++++----------- src/core/memory.h | 15 ++++++++++++++- 13 files changed, 90 insertions(+), 36 deletions(-) diff --git a/TODO b/TODO index bc4003d444..ad64a00842 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,11 @@ ☐ Save/load UI + ✔ Basic version @done(20-01-03 15:27) + ☐ Multiple slots etc. ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) ☐ Page tables - ☐ Skip N3DS RAM if unused + ✘ Skip N3DS RAM if unused @cancelled(20-01-03 15:26) + Since no n3ds support, leave this for now ✔ DSP @done(19-12-28 16:57) Memory only ✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) @@ -67,14 +70,16 @@ ✔ Mutex @done(19-08-13 16:43) ✔ Object @done(19-08-13 15:41) ✔ Process @started(19-08-13 16:43) @done(19-12-22 18:41) - ☐ Code set @started(19-12-22 18:41) + ✔ Code set @started(19-12-22 18:41) @done(20-01-03 15:15) @lasted(1w4d20h34m2s) Needs a way to reference loaded images (so we don't serialize the entire ROM as well) + ☐ Serialize codeset with an apploader reference instead ✔ Resource limit @done(19-08-13 16:43) ✔ Semaphore @done(19-08-13 16:44) ✔ Server port @done(19-08-13 16:44) ✔ Server session @done(19-08-13 16:44) - ☐ Mapped buffer context - This may not be needed! + ✔ Mapped buffer context @done(20-01-03 15:25) + This is needed because IPC can take as long as it takes + Changed the unique_ptr to vector ✔ Session @done(19-08-13 16:44) ☐ Shared memory @started(19-12-22 21:20) Need to figure out backing memory (a u8*) diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index daccbb083c..08e3cac02a 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include #include #include #include @@ -606,6 +607,8 @@ void GMainWindow::ConnectMenuEvents() { &GMainWindow::OnMenuReportCompatibility); connect(ui.action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure); connect(ui.action_Cheats, &QAction::triggered, this, &GMainWindow::OnCheats); + connect(ui.action_Save, &QAction::triggered, this, &GMainWindow::OnSave); + connect(ui.action_Load, &QAction::triggered, this, &GMainWindow::OnLoad); // View connect(ui.action_Single_Window_Mode, &QAction::triggered, this, @@ -1033,6 +1036,8 @@ void GMainWindow::ShutdownGame() { ui.action_Stop->setEnabled(false); ui.action_Restart->setEnabled(false); ui.action_Cheats->setEnabled(false); + ui.action_Save->setEnabled(false); + ui.action_Load->setEnabled(false); ui.action_Load_Amiibo->setEnabled(false); ui.action_Remove_Amiibo->setEnabled(false); ui.action_Report_Compatibility->setEnabled(false); @@ -1343,6 +1348,8 @@ void GMainWindow::OnStartGame() { ui.action_Stop->setEnabled(true); ui.action_Restart->setEnabled(true); ui.action_Cheats->setEnabled(true); + ui.action_Save->setEnabled(true); + ui.action_Load->setEnabled(true); ui.action_Load_Amiibo->setEnabled(true); ui.action_Report_Compatibility->setEnabled(true); ui.action_Enable_Frame_Advancing->setEnabled(true); @@ -1496,6 +1503,23 @@ void GMainWindow::OnCheats() { cheat_dialog.exec(); } +void GMainWindow::OnSave() { + Core::System& system{Core::System::GetInstance()}; + auto fs = std::ofstream("save0.citrasave"); + emu_thread->SetRunning(false); + Core::System::GetInstance().Save(fs); + emu_thread->SetRunning(true); +} + +void GMainWindow::OnLoad() { + if (QFileInfo("save0.citrasave").exists()) { + auto fs = std::ifstream("save0.citrasave"); + emu_thread->SetRunning(false); + Core::System::GetInstance().Load(fs); + emu_thread->SetRunning(true); + } +} + void GMainWindow::OnConfigure() { ConfigureDialog configureDialog(this, hotkey_registry, !multiplayer_state->IsHostingPublicRoom()); diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h index 91d7eed1b4..1858d5988f 100644 --- a/src/citra_qt/main.h +++ b/src/citra_qt/main.h @@ -163,6 +163,8 @@ private slots: void OnStartGame(); void OnPauseGame(); void OnStopGame(); + void OnSave(); + void OnLoad(); void OnMenuReportCompatibility(); /// Called whenever a user selects a game in the game list widget. void OnGameListLoadFile(QString game_path); diff --git a/src/citra_qt/main.ui b/src/citra_qt/main.ui index 6011b0e7f9..c0c38e4c8b 100644 --- a/src/citra_qt/main.ui +++ b/src/citra_qt/main.ui @@ -88,6 +88,8 @@ + + @@ -217,6 +219,22 @@ &Stop + + + false + + + Save + + + + + false + + + Load + + FAQ diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 39ddffbcc0..c6294c4643 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -86,7 +86,6 @@ add_library(common STATIC misc.cpp param_package.cpp param_package.h - pod.h quaternion.h ring_buffer.h scm_rev.cpp diff --git a/src/core/hle/kernel/config_mem.h b/src/core/hle/kernel/config_mem.h index e4e8955165..ef1c889a04 100644 --- a/src/core/hle/kernel/config_mem.h +++ b/src/core/hle/kernel/config_mem.h @@ -61,8 +61,7 @@ private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int file_version) { - auto o_config_mem = boost::serialization::binary_object(&config_mem, sizeof(config_mem)); - ar& o_config_mem; + ar& boost::serialization::make_binary_object(&config_mem, sizeof(config_mem)); } }; diff --git a/src/core/hle/kernel/ipc.cpp b/src/core/hle/kernel/ipc.cpp index 3dacb98317..e45b87e490 100644 --- a/src/core/hle/kernel/ipc.cpp +++ b/src/core/hle/kernel/ipc.cpp @@ -193,19 +193,19 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy // TODO(Subv): Perform permission checks. // Reserve a page of memory before the mapped buffer - auto reserve_buffer = std::make_unique(Memory::PAGE_SIZE); + auto reserve_buffer = std::vector(Memory::PAGE_SIZE); dst_process->vm_manager.MapBackingMemoryToBase( - Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer.get(), + Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer.data(), Memory::PAGE_SIZE, Kernel::MemoryState::Reserved); - auto buffer = std::make_unique(num_pages * Memory::PAGE_SIZE); - memory.ReadBlock(*src_process, source_address, buffer.get() + page_offset, size); + auto buffer = std::vector(num_pages * Memory::PAGE_SIZE); + memory.ReadBlock(*src_process, source_address, buffer.data() + page_offset, size); // Map the page(s) into the target process' address space. target_address = dst_process->vm_manager .MapBackingMemoryToBase(Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, - buffer.get(), num_pages * Memory::PAGE_SIZE, + buffer.data(), num_pages * Memory::PAGE_SIZE, Kernel::MemoryState::Shared) .Unwrap(); @@ -213,7 +213,7 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy // Reserve a page of memory after the mapped buffer dst_process->vm_manager.MapBackingMemoryToBase( - Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer.get(), + Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer.data(), Memory::PAGE_SIZE, Kernel::MemoryState::Reserved); mapped_buffer_context.push_back({permissions, size, source_address, diff --git a/src/core/hle/kernel/ipc.h b/src/core/hle/kernel/ipc.h index 2c69617d4e..f9fd1a00e5 100644 --- a/src/core/hle/kernel/ipc.h +++ b/src/core/hle/kernel/ipc.h @@ -6,7 +6,7 @@ #include #include -#include +#include #include "common/common_types.h" #include "core/hle/ipc.h" #include "core/hle/kernel/thread.h" @@ -25,8 +25,8 @@ struct MappedBufferContext { VAddr source_address; VAddr target_address; - std::unique_ptr buffer; - std::unique_ptr reserve_buffer; + std::vector buffer; + std::vector reserve_buffer; private: template @@ -35,10 +35,8 @@ private: ar& size; ar& source_address; ar& target_address; - // TODO: Check whether we need these. If we do, add a field for the size and/or change to a - // 'vector' - // ar & buffer; - // ar & reserve_buffer; + ar& buffer; + ar& reserve_buffer; } friend class boost::serialization::access; }; diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 78b695e978..18de2cd917 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -29,7 +29,7 @@ template void Process::serialize(Archive& ar, const unsigned int file_version) { ar& boost::serialization::base_object(*this); ar& handle_table; - ar& codeset; + ar& codeset; // TODO: Replace with apploader reference ar& resource_limit; ar& svc_access_mask; ar& handle_table_size; diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index f9aa76c67a..576cf7e15e 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -133,7 +133,7 @@ private: template void serialize(Archive& ar, const unsigned int file_version) { ar& boost::serialization::base_object(*this); - // TODO: memory reference + ar& memory; ar& segments; ar& entrypoint; ar& name; diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h index fcf7a3137e..9169bf9ae0 100644 --- a/src/core/hw/gpu.h +++ b/src/core/hw/gpu.h @@ -301,8 +301,7 @@ private: template void serialize(Archive& ar, const unsigned int) { - auto obj = boost::serialization::binary_object(this, sizeof(Regs)); - ar& obj; + ar& boost::serialization::make_binary_object(this, sizeof(Regs)); } friend class boost::serialization::access; }; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 6a41ca9572..92bce0b691 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -84,18 +84,15 @@ private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int file_version) { - // TODO: Skip n3ds ram when not used? - auto s_fcram = boost::serialization::binary_object(fcram.get(), Memory::FCRAM_N3DS_SIZE); - auto s_vram = boost::serialization::binary_object(vram.get(), Memory::VRAM_SIZE); - auto s_extra = - boost::serialization::binary_object(n3ds_extra_ram.get(), Memory::N3DS_EXTRA_RAM_SIZE); - ar& s_fcram; - ar& s_vram; - ar& s_extra; + ar& boost::serialization::make_binary_object(fcram.get(), Memory::FCRAM_N3DS_SIZE); + ar& boost::serialization::make_binary_object(vram.get(), Memory::VRAM_SIZE); + // TODO: When n3ds support is added, put this back in + // ar& boost::serialization::make_binary_object(n3ds_extra_ram.get(), + // Memory::N3DS_EXTRA_RAM_SIZE); + ar& current_page_table; ar& cache_marker; - // TODO: How the hell to do page tables.. - // ar & page_table_list; - // ar & current_page_table; + ar& page_table_list; + // dsp is set from Core::System at startup } }; diff --git a/src/core/memory.h b/src/core/memory.h index aac57af26a..564191d895 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -9,7 +9,9 @@ #include #include #include -#include "boost/serialization/access.hpp" +#include +#include +#include #include "common/common_types.h" #include "core/mmio.h" @@ -54,12 +56,14 @@ struct SpecialRegion { u32 size; MMIORegionPointer handler; +private: template void serialize(Archive& ar, const unsigned int file_version) { ar& base; ar& size; ar& handler; } + friend class boost::serialization::access; }; /** @@ -86,6 +90,15 @@ struct PageTable { * the corresponding entry in `pointers` MUST be set to null. */ std::array attributes; + +private: + template + void serialize(Archive& ar, const unsigned int) { + // TODO: Pointers; same as VMA backing regions we need to serialize the u8* + ar& special_regions; + ar& attributes; + } + friend class boost::serialization::access; }; /// Physical memory regions as seen from the ARM11 From cf985631e04bd1363b483f28ac020c2d5b4c8883 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sat, 4 Jan 2020 00:40:32 +0000 Subject: [PATCH 056/129] Minor tidying up --- TODO | 8 ++++---- src/core/core.cpp | 8 ++++++-- src/core/hle/service/cam/cam.h | 3 +-- src/core/hle/service/gsp/gsp.cpp | 6 +++++- src/core/hle/service/gsp/gsp.h | 2 ++ src/core/hle/service/gsp/gsp_gpu.h | 1 + src/core/memory.cpp | 13 ++++++++----- 7 files changed, 27 insertions(+), 14 deletions(-) diff --git a/TODO b/TODO index ad64a00842..d72a797127 100644 --- a/TODO +++ b/TODO @@ -4,8 +4,7 @@ ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) ☐ Page tables - ✘ Skip N3DS RAM if unused @cancelled(20-01-03 15:26) - Since no n3ds support, leave this for now + ✔ Skip N3DS RAM if unused @done(20-01-03 23:26) ✔ DSP @done(19-12-28 16:57) Memory only ✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) @@ -99,7 +98,7 @@ ✔ AM @started(19-12-24 23:17) @done(19-12-24 23:53) @lasted(36m8s) ✔ APT @done(19-12-25 21:41) ✔ BOSS @started(19-12-25 21:48) @done(19-12-25 23:18) @lasted(1h30m14s) - ☐ CAM @started(19-12-26 10:37) + ✔ CAM @started(19-12-26 10:37) @done(20-01-03 23:38) @lasted(1w1d13h1m50s) Need to check capture_result ✔ CECD @done(20-01-01 23:58) ✔ CFG @done(20-01-02 00:44) @@ -111,7 +110,8 @@ ✔ FRD @done(19-12-26 19:09) ✔ FS @done(19-12-27 11:46) ✔ GSP @done(19-12-30 12:45) - ☐ Fix the global weak_ptr to gsp + ✔ Fix the global weak_ptr to gsp @done(20-01-04 00:29) + Didn't quite 'fix' it but worked around it ✔ HID @done(19-12-30 14:46) ✔ HTTP @done(19-12-30 15:18) ✔ IR @done(19-12-30 16:06) diff --git a/src/core/core.cpp b/src/core/core.cpp index 5b9b4fca03..a05e2a6365 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -31,6 +31,7 @@ #include "core/hle/kernel/process.h" #include "core/hle/kernel/thread.h" #include "core/hle/service/fs/archive.h" +#include "core/hle/service/gsp/gsp.h" #include "core/hle/service/service.h" #include "core/hle/service/sm/sm.h" #include "core/hw/gpu.h" @@ -213,8 +214,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo timing = std::make_unique(); - kernel = std::make_unique(*memory, *timing, - [this] { PrepareReschedule(); }, system_mode); + kernel = std::make_unique( + *memory, *timing, [this] { PrepareReschedule(); }, system_mode); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 @@ -413,6 +414,9 @@ void System::serialize(Archive& ar, const unsigned int file_version) { ar & dsp_core->GetDspMemory(); ar&* memory.get(); ar&* kernel.get(); + + // This needs to be set from somewhere - might as well be here! + Service::GSP::SetGlobalModule(*this); } void System::Save(std::ostream& stream) const { diff --git a/src/core/hle/service/cam/cam.h b/src/core/hle/service/cam/cam.h index 876e2e1851..9c56407a33 100644 --- a/src/core/hle/service/cam/cam.h +++ b/src/core/hle/service/cam/cam.h @@ -830,8 +830,7 @@ private: ar& completion_event; ar& buffer_error_interrupt_event; ar& vsync_interrupt_event; - // TODO: Check if this is ever needed: - // ar & capture_result; + // Ignore capture_result. In-progress captures might be affected but this is OK. ar& dest_process; ar& dest; ar& dest_size; diff --git a/src/core/hle/service/gsp/gsp.cpp b/src/core/hle/service/gsp/gsp.cpp index 3d3f497b2b..c360d895c3 100644 --- a/src/core/hle/service/gsp/gsp.cpp +++ b/src/core/hle/service/gsp/gsp.cpp @@ -10,7 +10,7 @@ namespace Service::GSP { -static std::weak_ptr gsp_gpu; // TODO: Fix this for the love of god +static std::weak_ptr gsp_gpu; void SignalInterrupt(InterruptId interrupt_id) { auto gpu = gsp_gpu.lock(); @@ -27,4 +27,8 @@ void InstallInterfaces(Core::System& system) { std::make_shared()->InstallAsService(service_manager); } +void SetGlobalModule(Core::System& system) { + gsp_gpu = system.ServiceManager().GetService("gsp::Gpu"); +} + } // namespace Service::GSP diff --git a/src/core/hle/service/gsp/gsp.h b/src/core/hle/service/gsp/gsp.h index 4cde19e93a..a4dd84f277 100644 --- a/src/core/hle/service/gsp/gsp.h +++ b/src/core/hle/service/gsp/gsp.h @@ -23,4 +23,6 @@ namespace Service::GSP { void SignalInterrupt(InterruptId interrupt_id); void InstallInterfaces(Core::System& system); + +void SetGlobalModule(Core::System& system); } // namespace Service::GSP diff --git a/src/core/hle/service/gsp/gsp_gpu.h b/src/core/hle/service/gsp/gsp_gpu.h index d1f2c0742f..6194f0446f 100644 --- a/src/core/hle/service/gsp/gsp_gpu.h +++ b/src/core/hle/service/gsp/gsp_gpu.h @@ -444,6 +444,7 @@ private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& shared_memory; ar& active_thread_id; ar& first_initialization; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 92bce0b691..cba5867eb9 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -18,6 +18,7 @@ #include "core/hle/kernel/process.h" #include "core/hle/lock.h" #include "core/memory.h" +#include "core/settings.h" #include "video_core/renderer_base.h" #include "video_core/video_core.h" @@ -84,15 +85,17 @@ private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int file_version) { - ar& boost::serialization::make_binary_object(fcram.get(), Memory::FCRAM_N3DS_SIZE); + bool save_n3ds_ram = Settings::values.is_new_3ds; + ar& save_n3ds_ram; ar& boost::serialization::make_binary_object(vram.get(), Memory::VRAM_SIZE); - // TODO: When n3ds support is added, put this back in - // ar& boost::serialization::make_binary_object(n3ds_extra_ram.get(), - // Memory::N3DS_EXTRA_RAM_SIZE); - ar& current_page_table; + ar& boost::serialization::make_binary_object( + fcram.get(), save_n3ds_ram ? Memory::FCRAM_N3DS_SIZE : Memory::FCRAM_SIZE); + ar& boost::serialization::make_binary_object( + n3ds_extra_ram.get(), save_n3ds_ram ? Memory::N3DS_EXTRA_RAM_SIZE : 0); ar& cache_marker; ar& page_table_list; // dsp is set from Core::System at startup + // current page table set from current process? } }; From 65d96bf6c158b9e8a864947a9c60608fc097e078 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sat, 4 Jan 2020 22:39:54 +0000 Subject: [PATCH 057/129] Changed u8* to MemoryRef --- TODO | 11 ++- src/common/CMakeLists.txt | 4 +- src/common/memory_ref.cpp | 4 + src/common/memory_ref.h | 112 +++++++++++++++++++++++ src/core/arm/dynarmic/arm_dynarmic.cpp | 2 +- src/core/hle/kernel/config_mem.h | 11 ++- src/core/hle/kernel/ipc.cpp | 18 ++-- src/core/hle/kernel/ipc.h | 6 +- src/core/hle/kernel/kernel.cpp | 4 +- src/core/hle/kernel/kernel.h | 4 +- src/core/hle/kernel/memory.cpp | 26 +++--- src/core/hle/kernel/process.cpp | 8 +- src/core/hle/kernel/shared_memory.cpp | 4 +- src/core/hle/kernel/shared_memory.h | 5 +- src/core/hle/kernel/shared_page.cpp | 12 +++ src/core/hle/kernel/shared_page.h | 24 ++++- src/core/hle/kernel/thread.cpp | 2 +- src/core/hle/kernel/vm_manager.cpp | 22 ++--- src/core/hle/kernel/vm_manager.h | 46 +++------- src/core/memory.cpp | 122 +++++++++++++++++++++---- src/core/memory.h | 79 ++++++++++++++-- src/tests/core/arm/arm_test_common.cpp | 3 +- src/tests/core/hle/kernel/hle_ipc.cpp | 97 +++++++++++--------- src/tests/core/memory/vm_manager.cpp | 37 ++++---- 24 files changed, 486 insertions(+), 177 deletions(-) create mode 100644 src/common/memory_ref.cpp create mode 100644 src/common/memory_ref.h diff --git a/TODO b/TODO index d72a797127..4bb80f8d53 100644 --- a/TODO +++ b/TODO @@ -4,6 +4,7 @@ ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) ☐ Page tables + Need to change uses to shared_ptr ✔ Skip N3DS RAM if unused @done(20-01-03 23:26) ✔ DSP @done(19-12-28 16:57) Memory only @@ -44,6 +45,7 @@ Doesn't need to be serialized here ✔ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE @started(20-01-03 13:47) @done(20-01-03 13:58) @lasted(11m22s) ☐ Review constructor/initialization code +☐ Review core timing events ✔ Fix CI @done(19-12-31 21:32) ✔ HW @done(19-08-13 15:41) ✔ GPU regs @done(19-08-13 15:41) @@ -60,7 +62,7 @@ ✔ Address arbiter @done(19-08-13 16:40) ✔ Client port @done(19-08-13 16:40) ✔ Client session @done(19-08-13 16:40) - ✔ Config mem @done(19-08-13 16:40) + ✔ Config mem @done(20-01-04 21:09) ✔ Event @done(19-12-22 18:44) ✔ Handle table @done(19-08-13 16:42) ✔ HLE IPC @done(19-12-23 00:36) @@ -80,16 +82,15 @@ This is needed because IPC can take as long as it takes Changed the unique_ptr to vector ✔ Session @done(19-08-13 16:44) - ☐ Shared memory @started(19-12-22 21:20) + ✔ Shared memory @started(19-12-22 21:20) @done(20-01-04 21:09) @lasted(1w5d23h49m26s) Need to figure out backing memory (a u8*) - ✘ Shared page @started(19-08-13 16:44) @cancelled(19-12-22 11:19) - Not needed right now as shared_page is read-only and derived from other data + ✔ Shared page @done(20-01-04 21:09) ✔ SVC @done(19-12-22 21:32) Nothing to do - all data is constant ☐ Thread @started(19-08-13 16:45) This requires refactoring wakeup_callback to be an object ref ✔ Timer @done(19-08-13 16:45) - ☐ VM Manager @started(19-08-13 16:46) + ✔ VM Manager @started(19-08-13 16:46) @done(20-01-04 21:09) @lasted(20w4d5h23m42s) Just need to figure out backing_mem (a u8*) ✔ Wait object @done(19-08-13 16:46) ☐ Service @started(19-12-23 12:49) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index c6294c4643..ea117d4409 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -80,6 +80,8 @@ add_library(common STATIC logging/text_formatter.cpp logging/text_formatter.h math_util.h + memory_ref.h + memory_ref.cpp microprofile.cpp microprofile.h microprofileui.h @@ -127,7 +129,7 @@ endif() create_target_directory_groups(common) -target_link_libraries(common PUBLIC fmt microprofile) +target_link_libraries(common PUBLIC fmt microprofile Boost::boost Boost::serialization) target_link_libraries(common PRIVATE libzstd_static) if (ARCHITECTURE_x86_64) target_link_libraries(common PRIVATE xbyak) diff --git a/src/common/memory_ref.cpp b/src/common/memory_ref.cpp new file mode 100644 index 0000000000..170784ff8d --- /dev/null +++ b/src/common/memory_ref.cpp @@ -0,0 +1,4 @@ +#include "common/archives.h" +#include "common/memory_ref.h" + +SERIALIZE_EXPORT_IMPL(BufferMem) diff --git a/src/common/memory_ref.h b/src/common/memory_ref.h new file mode 100644 index 0000000000..5aaaef468a --- /dev/null +++ b/src/common/memory_ref.h @@ -0,0 +1,112 @@ +#pragma once + +#include +#include +#include +#include +#include +#include "common/assert.h" +#include "common/common_types.h" + +/// Abstract host-side memory - for example a static buffer, or local vector +class BackingMem { +public: + virtual ~BackingMem() = default; + virtual u8* GetPtr() = 0; + virtual u32 GetSize() const = 0; +}; + +/// Backing memory implemented by a local buffer +class BufferMem : public BackingMem { +public: + BufferMem() = default; + BufferMem(u32 size) : data(std::vector(size)) {} + + virtual u8* GetPtr() { + return data.data(); + } + + virtual u32 GetSize() const { + return static_cast(data.size()); + } + + std::vector& Vector() { + return data; + } + +private: + std::vector data; + + template + void serialize(Archive& ar, const unsigned int) { + ar& data; + } + friend class boost::serialization::access; +}; + +BOOST_CLASS_EXPORT_KEY(BufferMem); + +/// A managed reference to host-side memory. Fast enough to be used everywhere instead of u8* +/// Supports serialization. +class MemoryRef { +public: + MemoryRef() = default; + MemoryRef(std::nullptr_t) {} + MemoryRef(std::shared_ptr backing_mem_) + : backing_mem(std::move(backing_mem_)), offset(0) { + Init(); + } + MemoryRef(std::shared_ptr backing_mem_, u32 offset_) + : backing_mem(std::move(backing_mem_)), offset(offset_) { + ASSERT(offset < backing_mem->GetSize()); + Init(); + } + inline operator u8*() { + return cptr; + } + inline u8* GetPtr() { + return cptr; + } + inline operator bool() const { + return cptr != nullptr; + } + inline const u8* GetPtr() const { + return cptr; + } + inline u32 GetSize() const { + return csize; + } + inline void operator+=(u32 offset_by) { + ASSERT(offset_by < csize); + offset += offset_by; + Init(); + } + inline MemoryRef operator+(u32 offset_by) const { + ASSERT(offset_by < csize); + return MemoryRef(backing_mem, offset + offset_by); + } + inline u8* operator+(std::size_t offset_by) const { + ASSERT(offset_by < csize); + return cptr + offset_by; + } + +private: + std::shared_ptr backing_mem; + u32 offset; + // Cached values for speed + u8* cptr; + u32 csize; + + void Init() { + cptr = backing_mem->GetPtr() + offset; + csize = static_cast(backing_mem->GetSize() - offset); + } + + template + void serialize(Archive& ar, const unsigned int) { + ar& backing_mem; + ar& offset; + Init(); + } + friend class boost::serialization::access; +}; diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index a422db6af6..eb3295956e 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -298,7 +298,7 @@ void ARM_Dynarmic::PageTableChanged() { std::unique_ptr ARM_Dynarmic::MakeJit() { Dynarmic::A32::UserConfig config; config.callbacks = cb.get(); - config.page_table = ¤t_page_table->pointers; + config.page_table = ¤t_page_table->GetPointerArray(); config.coprocessors[15] = std::make_shared(interpreter_state); config.define_unpredictable_behaviour = true; return std::make_unique(config); diff --git a/src/core/hle/kernel/config_mem.h b/src/core/hle/kernel/config_mem.h index ef1c889a04..0ec67fb5e8 100644 --- a/src/core/hle/kernel/config_mem.h +++ b/src/core/hle/kernel/config_mem.h @@ -12,6 +12,7 @@ #include #include "common/common_funcs.h" #include "common/common_types.h" +#include "common/memory_ref.h" #include "common/swap.h" #include "core/memory.h" @@ -50,11 +51,19 @@ struct ConfigMemDef { static_assert(sizeof(ConfigMemDef) == Memory::CONFIG_MEMORY_SIZE, "Config Memory structure size is wrong"); -class Handler { +class Handler : public BackingMem { public: Handler(); ConfigMemDef& GetConfigMem(); + virtual u8* GetPtr() { + return static_cast(static_cast(&config_mem)); + } + + virtual u32 GetSize() const { + return sizeof(config_mem); + } + private: ConfigMemDef config_mem; diff --git a/src/core/hle/kernel/ipc.cpp b/src/core/hle/kernel/ipc.cpp index e45b87e490..e39732c149 100644 --- a/src/core/hle/kernel/ipc.cpp +++ b/src/core/hle/kernel/ipc.cpp @@ -4,6 +4,7 @@ #include #include "common/alignment.h" +#include "common/memory_ref.h" #include "core/core.h" #include "core/hle/ipc.h" #include "core/hle/kernel/handle_table.h" @@ -193,28 +194,29 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy // TODO(Subv): Perform permission checks. // Reserve a page of memory before the mapped buffer - auto reserve_buffer = std::vector(Memory::PAGE_SIZE); + std::shared_ptr reserve_buffer = + std::make_shared(Memory::PAGE_SIZE); dst_process->vm_manager.MapBackingMemoryToBase( - Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer.data(), + Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer, Memory::PAGE_SIZE, Kernel::MemoryState::Reserved); - auto buffer = std::vector(num_pages * Memory::PAGE_SIZE); - memory.ReadBlock(*src_process, source_address, buffer.data() + page_offset, size); + std::shared_ptr buffer = + std::make_shared(num_pages * Memory::PAGE_SIZE); + memory.ReadBlock(*src_process, source_address, buffer->GetPtr() + page_offset, size); // Map the page(s) into the target process' address space. target_address = dst_process->vm_manager .MapBackingMemoryToBase(Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, - buffer.data(), num_pages * Memory::PAGE_SIZE, - Kernel::MemoryState::Shared) + buffer, buffer->GetSize(), Kernel::MemoryState::Shared) .Unwrap(); cmd_buf[i++] = target_address + page_offset; // Reserve a page of memory after the mapped buffer dst_process->vm_manager.MapBackingMemoryToBase( - Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer.data(), - Memory::PAGE_SIZE, Kernel::MemoryState::Reserved); + Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer, + reserve_buffer->GetSize(), Kernel::MemoryState::Reserved); mapped_buffer_context.push_back({permissions, size, source_address, target_address + page_offset, std::move(buffer), diff --git a/src/core/hle/kernel/ipc.h b/src/core/hle/kernel/ipc.h index f9fd1a00e5..2a5fcb4b2e 100644 --- a/src/core/hle/kernel/ipc.h +++ b/src/core/hle/kernel/ipc.h @@ -6,7 +6,7 @@ #include #include -#include +#include #include "common/common_types.h" #include "core/hle/ipc.h" #include "core/hle/kernel/thread.h" @@ -25,8 +25,8 @@ struct MappedBufferContext { VAddr source_address; VAddr target_address; - std::vector buffer; - std::vector reserve_buffer; + std::shared_ptr buffer; + std::shared_ptr reserve_buffer; private: template diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 7edef25055..6fef2d4dee 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -116,8 +116,8 @@ void KernelSystem::serialize(Archive& ar, const unsigned int file_version) { ar& process_list; ar& current_process; ar&* thread_manager.get(); - ar&* config_mem_handler.get(); - // Shared page data is read-only at the moment, so doesn't need serializing + ar& config_mem_handler; + ar& shared_page_handler; // Deliberately don't include debugger info to allow debugging through loads } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 6ca3267fb6..0a527d8b42 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -282,8 +282,8 @@ private: std::unique_ptr thread_manager; - std::unique_ptr config_mem_handler; - std::unique_ptr shared_page_handler; + std::shared_ptr config_mem_handler; + std::shared_ptr shared_page_handler; std::unique_ptr ipc_recorder; diff --git a/src/core/hle/kernel/memory.cpp b/src/core/hle/kernel/memory.cpp index e4aae5d139..04d09fa461 100644 --- a/src/core/hle/kernel/memory.cpp +++ b/src/core/hle/kernel/memory.cpp @@ -57,7 +57,7 @@ void KernelSystem::MemoryInit(u32 mem_type) { // We must've allocated the entire FCRAM by the end ASSERT(base == Memory::FCRAM_SIZE); - config_mem_handler = std::make_unique(); + config_mem_handler = std::make_shared(); auto& config_mem = config_mem_handler->GetConfigMem(); config_mem.app_mem_type = mem_type; // app_mem_malloc does not always match the configured size for memory_region[0]: in case the @@ -66,7 +66,7 @@ void KernelSystem::MemoryInit(u32 mem_type) { config_mem.sys_mem_alloc = memory_regions[1].size; config_mem.base_mem_alloc = memory_regions[2].size; - shared_page_handler = std::make_unique(timing); + shared_page_handler = std::make_shared(timing); } MemoryRegionInfo* KernelSystem::GetMemoryRegion(MemoryRegion region) { @@ -127,7 +127,7 @@ void KernelSystem::HandleSpecialMapping(VMManager& address_space, const AddressM return; } - u8* target_pointer = memory.GetPhysicalPointer(area->paddr_base + offset_into_region); + auto target_pointer = memory.GetPhysicalRef(area->paddr_base + offset_into_region); // TODO(yuriks): This flag seems to have some other effect, but it's unknown what MemoryState memory_state = mapping.unk_flag ? MemoryState::Static : MemoryState::IO; @@ -140,20 +140,16 @@ void KernelSystem::HandleSpecialMapping(VMManager& address_space, const AddressM } void KernelSystem::MapSharedPages(VMManager& address_space) { - auto cfg_mem_vma = - address_space - .MapBackingMemory(Memory::CONFIG_MEMORY_VADDR, - reinterpret_cast(&config_mem_handler->GetConfigMem()), - Memory::CONFIG_MEMORY_SIZE, MemoryState::Shared) - .Unwrap(); + auto cfg_mem_vma = address_space + .MapBackingMemory(Memory::CONFIG_MEMORY_VADDR, {config_mem_handler}, + Memory::CONFIG_MEMORY_SIZE, MemoryState::Shared) + .Unwrap(); address_space.Reprotect(cfg_mem_vma, VMAPermission::Read); - auto shared_page_vma = - address_space - .MapBackingMemory(Memory::SHARED_PAGE_VADDR, - reinterpret_cast(&shared_page_handler->GetSharedPage()), - Memory::SHARED_PAGE_SIZE, MemoryState::Shared) - .Unwrap(); + auto shared_page_vma = address_space + .MapBackingMemory(Memory::SHARED_PAGE_VADDR, {shared_page_handler}, + Memory::SHARED_PAGE_SIZE, MemoryState::Shared) + .Unwrap(); address_space.Reprotect(shared_page_vma, VMAPermission::Read); } diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 18de2cd917..c181bd01ad 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -223,7 +223,7 @@ ResultVal Process::HeapAllocate(VAddr target, u32 size, VMAPermission per std::fill(kernel.memory.GetFCRAMPointer(interval.lower()), kernel.memory.GetFCRAMPointer(interval.upper()), 0); auto vma = vm_manager.MapBackingMemory(interval_target, - kernel.memory.GetFCRAMPointer(interval.lower()), + kernel.memory.GetFCRAMRef(interval.lower()), interval_size, memory_state); ASSERT(vma.Succeeded()); vm_manager.Reprotect(vma.Unwrap(), perms); @@ -251,7 +251,7 @@ ResultCode Process::HeapFree(VAddr target, u32 size) { // Free heaps block by block CASCADE_RESULT(auto backing_blocks, vm_manager.GetBackingBlocksForRange(target, size)); for (const auto [backing_memory, block_size] : backing_blocks) { - memory_region->Free(kernel.memory.GetFCRAMOffset(backing_memory), block_size); + memory_region->Free(kernel.memory.GetFCRAMOffset(backing_memory.GetPtr()), block_size); } ResultCode result = vm_manager.UnmapRange(target, size); @@ -295,9 +295,9 @@ ResultVal Process::LinearAllocate(VAddr target, u32 size, VMAPermission p } } - u8* backing_memory = kernel.memory.GetFCRAMPointer(physical_offset); + auto backing_memory = kernel.memory.GetFCRAMRef(physical_offset); - std::fill(backing_memory, backing_memory + size, 0); + std::fill(backing_memory.GetPtr(), backing_memory.GetPtr() + size, 0); auto vma = vm_manager.MapBackingMemory(target, backing_memory, size, MemoryState::Continuous); ASSERT(vma.Succeeded()); vm_manager.Reprotect(vma.Unwrap(), perms); diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 55c374dc56..23f67f7331 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -48,7 +48,7 @@ ResultVal> KernelSystem::CreateSharedMemory( ASSERT_MSG(offset, "Not enough space in region to allocate shared memory!"); std::fill(memory.GetFCRAMPointer(*offset), memory.GetFCRAMPointer(*offset + size), 0); - shared_memory->backing_blocks = {{memory.GetFCRAMPointer(*offset), size}}; + shared_memory->backing_blocks = {{memory.GetFCRAMRef(*offset), size}}; shared_memory->holding_memory += MemoryRegionInfo::Interval(*offset, *offset + size); shared_memory->linear_heap_phys_offset = *offset; @@ -90,7 +90,7 @@ std::shared_ptr KernelSystem::CreateSharedMemoryForApplet( shared_memory->other_permissions = other_permissions; for (const auto& interval : backing_blocks) { shared_memory->backing_blocks.push_back( - {memory.GetFCRAMPointer(interval.lower()), interval.upper() - interval.lower()}); + {memory.GetFCRAMRef(interval.lower()), interval.upper() - interval.lower()}); std::fill(memory.GetFCRAMPointer(interval.lower()), memory.GetFCRAMPointer(interval.upper()), 0); } diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index f2fa1a7286..aa2be05a6d 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -8,6 +8,7 @@ #include #include #include "common/common_types.h" +#include "common/memory_ref.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/process.h" #include "core/hle/result.h" @@ -87,7 +88,7 @@ private: /// during creation. PAddr linear_heap_phys_offset = 0; /// Backing memory for this shared memory block. - std::vector> backing_blocks; + std::vector> backing_blocks; /// Size of the memory block. Page-aligned. u32 size = 0; /// Permission restrictions applied to the process which created the block. @@ -109,7 +110,7 @@ private: template void serialize(Archive& ar, const unsigned int file_version) { ar& linear_heap_phys_offset; - // TODO: backing blocks u8* (this is always FCRAM I think) + ar& backing_blocks; ar& size; ar& permissions; ar& other_permissions; diff --git a/src/core/hle/kernel/shared_page.cpp b/src/core/hle/kernel/shared_page.cpp index 7067aace8b..f7b02993ff 100644 --- a/src/core/hle/kernel/shared_page.cpp +++ b/src/core/hle/kernel/shared_page.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/archives.h" #include "core/core.h" #include "core/core_timing.h" #include "core/hle/kernel/shared_page.h" @@ -13,6 +14,17 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// +namespace boost::serialization { + +template +void load_construct_data(Archive& ar, SharedPage::Handler* t, const unsigned int) { + ::new (t) SharedPage::Handler(Core::System::GetInstance().CoreTiming()); +} +template void load_construct_data(iarchive& ar, SharedPage::Handler* t, + const unsigned int); + +} // namespace boost::serialization + namespace SharedPage { static std::chrono::seconds GetInitTime() { diff --git a/src/core/hle/kernel/shared_page.h b/src/core/hle/kernel/shared_page.h index 45f9cd3489..7b1f7ed164 100644 --- a/src/core/hle/kernel/shared_page.h +++ b/src/core/hle/kernel/shared_page.h @@ -17,6 +17,7 @@ #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" +#include "common/memory_ref.h" #include "common/swap.h" #include "core/memory.h" @@ -83,7 +84,7 @@ struct SharedPageDef { static_assert(sizeof(SharedPageDef) == Memory::SHARED_PAGE_SIZE, "Shared page structure size is wrong"); -class Handler { +class Handler : public BackingMem { public: Handler(Core::Timing& timing); @@ -97,6 +98,14 @@ public: SharedPageDef& GetSharedPage(); + virtual u8* GetPtr() { + return static_cast(static_cast(&shared_page)); + } + + virtual u32 GetSize() const { + return sizeof(shared_page); + } + private: u64 GetSystemTime() const; void UpdateTimeCallback(u64 userdata, int cycles_late); @@ -105,6 +114,19 @@ private: std::chrono::seconds init_time; SharedPageDef shared_page; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::make_binary_object(&shared_page, sizeof(shared_page)); + } + friend class boost::serialization::access; }; } // namespace SharedPage + +namespace boost::serialization { + +template +void load_construct_data(Archive& ar, SharedPage::Handler* t, const unsigned int); + +} // namespace boost::serialization diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index c3c5da7d41..1af2d4f4d6 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -382,7 +382,7 @@ ResultVal> KernelSystem::CreateThread(std::string name, // Map the page to the current process' address space. vm_manager.MapBackingMemory(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE, - memory.GetFCRAMPointer(*offset), Memory::PAGE_SIZE, + memory.GetFCRAMRef(*offset), Memory::PAGE_SIZE, MemoryState::Locked); } diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 3280f99e98..1b9875ee2a 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp @@ -27,7 +27,8 @@ bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const { type != next.type) { return false; } - if (type == VMAType::BackingMemory && backing_memory + size != next.backing_memory) { + if (type == VMAType::BackingMemory && + backing_memory.GetPtr() + size != next.backing_memory.GetPtr()) { return false; } if (type == VMAType::MMIO && paddr + size != next.paddr) { @@ -50,8 +51,7 @@ void VMManager::Reset() { initial_vma.size = MAX_ADDRESS; vma_map.emplace(initial_vma.base, initial_vma); - page_table.pointers.fill(nullptr); - page_table.attributes.fill(Memory::PageType::Unmapped); + page_table.Clear(); UpdatePageTableForVMA(initial_vma); } @@ -64,7 +64,7 @@ VMManager::VMAHandle VMManager::FindVMA(VAddr target) const { } } -ResultVal VMManager::MapBackingMemoryToBase(VAddr base, u32 region_size, u8* memory, +ResultVal VMManager::MapBackingMemoryToBase(VAddr base, u32 region_size, MemoryRef memory, u32 size, MemoryState state) { // Find the first Free VMA. @@ -93,9 +93,9 @@ ResultVal VMManager::MapBackingMemoryToBase(VAddr base, u32 region_size, return MakeResult(target); } -ResultVal VMManager::MapBackingMemory(VAddr target, u8* memory, u32 size, - MemoryState state) { - ASSERT(memory != nullptr); +ResultVal VMManager::MapBackingMemory(VAddr target, MemoryRef memory, + u32 size, MemoryState state) { + ASSERT(memory.GetPtr() != nullptr); // This is the appropriately sized VMA that will turn into our allocation. CASCADE_RESULT(VMAIter vma_handle, CarveVMA(target, size)); @@ -359,9 +359,9 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) { } } -ResultVal>> VMManager::GetBackingBlocksForRange(VAddr address, - u32 size) { - std::vector> backing_blocks; +ResultVal>> VMManager::GetBackingBlocksForRange(VAddr address, + u32 size) { + std::vector> backing_blocks; VAddr interval_target = address; while (interval_target != address + size) { auto vma = FindVMA(interval_target); @@ -372,7 +372,7 @@ ResultVal>> VMManager::GetBackingBlocksForRange( VAddr interval_end = std::min(address + size, vma->second.base + vma->second.size); u32 interval_size = interval_end - interval_target; - u8* backing_memory = vma->second.backing_memory + (interval_target - vma->second.base); + auto backing_memory = vma->second.backing_memory + (interval_target - vma->second.base); backing_blocks.push_back({backing_memory, interval_size}); interval_target += interval_size; diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 5fd6d87402..880d9ec81f 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -11,6 +11,7 @@ #include #include #include "common/common_types.h" +#include "common/memory_ref.h" #include "core/hle/result.h" #include "core/memory.h" #include "core/mmio.h" @@ -73,7 +74,7 @@ struct VirtualMemoryArea { // Settings for type = BackingMemory /// Pointer backing this VMA. It will not be destroyed or freed when the VMA is removed. - u8* backing_memory = nullptr; + MemoryRef backing_memory{}; // Settings for type = MMIO /// Physical address of the register area this VMA maps to. @@ -92,8 +93,7 @@ private: ar& type; ar& permissions; ar& meminfo_state; - // TODO: backing memory ref - // backing memory can be: Physical/FCRAM pointer, config mem, shared page + ar& backing_memory; ar& paddr; ar& mmio_handler; } @@ -151,7 +151,7 @@ public: * @param state MemoryState tag to attach to the VMA. * @returns The address at which the memory was mapped. */ - ResultVal MapBackingMemoryToBase(VAddr base, u32 region_size, u8* memory, u32 size, + ResultVal MapBackingMemoryToBase(VAddr base, u32 region_size, MemoryRef memory, u32 size, MemoryState state); /** * Maps an unmanaged host memory pointer at a given address. @@ -161,7 +161,8 @@ public: * @param size Size of the mapping. * @param state MemoryState tag to attach to the VMA. */ - ResultVal MapBackingMemory(VAddr target, u8* memory, u32 size, MemoryState state); + ResultVal MapBackingMemory(VAddr target, MemoryRef memory, u32 size, + MemoryState state); /** * Maps a memory-mapped IO region at a given address. @@ -203,38 +204,14 @@ public: void LogLayout(Log::Level log_level) const; /// Gets a list of backing memory blocks for the specified range - ResultVal>> GetBackingBlocksForRange(VAddr address, u32 size); + ResultVal>> GetBackingBlocksForRange(VAddr address, + u32 size); /// Each VMManager has its own page table, which is set as the main one when the owning process /// is scheduled. Memory::PageTable page_table; private: - friend class boost::serialization::access; - template - void save(Archive& ar, const unsigned int file_version) const { - ar& vma_map; - for (int i = 0; i < page_table.pointers.size(); i++) { - ar << memory.GetFCRAMOffset(page_table.pointers[i]); - } - ar& page_table.special_regions; - ar& page_table.attributes; - } - - template - void load(Archive& ar, const unsigned int file_version) { - ar& vma_map; - for (int i = 0; i < page_table.pointers.size(); i++) { - u32 offset{}; - ar >> offset; - page_table.pointers[i] = memory.GetFCRAMPointer(offset); - } - ar& page_table.special_regions; - ar& page_table.attributes; - } - - BOOST_SERIALIZATION_SPLIT_MEMBER() - using VMAIter = decltype(vma_map)::iterator; /// Converts a VMAHandle to a mutable VMAIter. @@ -271,5 +248,12 @@ private: void UpdatePageTableForVMA(const VirtualMemoryArea& vma); Memory::MemorySystem& memory; + + template + void serialize(Archive& ar, const unsigned int) { + ar& vma_map; + ar& page_table; + } + friend class boost::serialization::access; }; } // namespace Kernel diff --git a/src/core/memory.cpp b/src/core/memory.cpp index cba5867eb9..9762619f03 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -14,6 +14,7 @@ #include "common/swap.h" #include "core/arm/arm_interface.h" #include "core/core.h" +#include "core/global.h" #include "core/hle/kernel/memory.h" #include "core/hle/kernel/process.h" #include "core/hle/lock.h" @@ -22,8 +23,19 @@ #include "video_core/renderer_base.h" #include "video_core/video_core.h" +SERIALIZE_EXPORT_IMPL(Memory::MemorySystem::BackingMemImpl) +SERIALIZE_EXPORT_IMPL(Memory::MemorySystem::BackingMemImpl) +SERIALIZE_EXPORT_IMPL(Memory::MemorySystem::BackingMemImpl) +SERIALIZE_EXPORT_IMPL(Memory::MemorySystem::BackingMemImpl) + namespace Memory { +void PageTable::Clear() { + pointers.raw.fill(nullptr); + pointers.refs.fill(MemoryRef()); + attributes.fill(PageType::Unmapped); +} + class RasterizerCacheMarker { public: void Mark(VAddr addr, bool cached) { @@ -81,6 +93,43 @@ public: AudioCore::DspInterface* dsp = nullptr; + std::shared_ptr fcram_mem; + std::shared_ptr vram_mem; + std::shared_ptr n3ds_extra_ram_mem; + std::shared_ptr dsp_mem; + + MemorySystem::Impl(); + + virtual u8* GetPtr(Region r) { + switch (r) { + case Region::VRAM: + return vram.get(); + case Region::DSP: + return dsp->GetDspMemory().data(); + case Region::FCRAM: + return fcram.get(); + case Region::N3DS: + return n3ds_extra_ram.get(); + default: + UNREACHABLE(); + } + } + + virtual u32 GetSize(Region r) const { + switch (r) { + case Region::VRAM: + return VRAM_SIZE; + case Region::DSP: + return DSP_RAM_SIZE; + case Region::FCRAM: + return FCRAM_N3DS_SIZE; + case Region::N3DS: + return N3DS_EXTRA_RAM_SIZE; + default: + UNREACHABLE(); + } + } + private: friend class boost::serialization::access; template @@ -95,10 +144,41 @@ private: ar& cache_marker; ar& page_table_list; // dsp is set from Core::System at startup - // current page table set from current process? + // TODO: current_page_table + ar& fcram_mem; + ar& vram_mem; + ar& n3ds_extra_ram_mem; + ar& dsp_mem; } }; +// We use this rather than BufferMem because we don't want new objects to be allocated when +// deserializing. This avoids unnecessary memory thrashing. +template +class MemorySystem::BackingMemImpl : public BackingMem { +public: + BackingMemImpl() : system(Core::Global().Memory()) {} + virtual u8* GetPtr() { + return system.impl->GetPtr(R); + } + virtual u32 GetSize() const { + return system.impl->GetSize(R); + } + +private: + MemorySystem& system; + + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; +}; + +MemorySystem::Impl::Impl() + : fcram_mem(std::make_shared>()), + vram_mem(std::make_shared>()), + n3ds_extra_ram_mem(std::make_shared>()), + dsp_mem(std::make_shared>()) {} + MemorySystem::MemorySystem() : impl(std::make_unique()) {} MemorySystem::~MemorySystem() = default; @@ -117,8 +197,9 @@ PageTable* MemorySystem::GetCurrentPageTable() const { return impl->current_page_table; } -void MemorySystem::MapPages(PageTable& page_table, u32 base, u32 size, u8* memory, PageType type) { - LOG_DEBUG(HW_Memory, "Mapping {} onto {:08X}-{:08X}", (void*)memory, base * PAGE_SIZE, +void MemorySystem::MapPages(PageTable& page_table, u32 base, u32 size, MemoryRef memory, + PageType type) { + LOG_DEBUG(HW_Memory, "Mapping {} onto {:08X}-{:08X}", (void*)memory.GetPtr(), base * PAGE_SIZE, (base + size) * PAGE_SIZE); RasterizerFlushVirtualRegion(base << PAGE_BITS, size * PAGE_SIZE, @@ -143,7 +224,7 @@ void MemorySystem::MapPages(PageTable& page_table, u32 base, u32 size, u8* memor } } -void MemorySystem::MapMemoryRegion(PageTable& page_table, VAddr base, u32 size, u8* target) { +void MemorySystem::MapMemoryRegion(PageTable& page_table, VAddr base, u32 size, MemoryRef target) { ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:08X}", size); ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:08X}", base); MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, PageType::Memory); @@ -164,15 +245,15 @@ void MemorySystem::UnmapRegion(PageTable& page_table, VAddr base, u32 size) { MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, nullptr, PageType::Unmapped); } -u8* MemorySystem::GetPointerForRasterizerCache(VAddr addr) { +MemoryRef MemorySystem::GetPointerForRasterizerCache(VAddr addr) { if (addr >= LINEAR_HEAP_VADDR && addr < LINEAR_HEAP_VADDR_END) { - return impl->fcram.get() + (addr - LINEAR_HEAP_VADDR); + return {impl->fcram_mem, addr - LINEAR_HEAP_VADDR}; } if (addr >= NEW_LINEAR_HEAP_VADDR && addr < NEW_LINEAR_HEAP_VADDR_END) { - return impl->fcram.get() + (addr - NEW_LINEAR_HEAP_VADDR); + return {impl->fcram_mem, addr - NEW_LINEAR_HEAP_VADDR}; } if (addr >= VRAM_VADDR && addr < VRAM_VADDR_END) { - return impl->vram.get() + (addr - VRAM_VADDR); + return {impl->vram_mem, addr - VRAM_VADDR}; } UNREACHABLE(); } @@ -271,7 +352,7 @@ void MemorySystem::Write(const VAddr vaddr, const T data) { bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) { auto& page_table = process.vm_manager.page_table; - const u8* page_pointer = page_table.pointers[vaddr >> PAGE_BITS]; + auto page_pointer = page_table.pointers[vaddr >> PAGE_BITS]; if (page_pointer) return true; @@ -323,6 +404,10 @@ std::string MemorySystem::ReadCString(VAddr vaddr, std::size_t max_length) { } u8* MemorySystem::GetPhysicalPointer(PAddr address) { + return GetPhysicalRef(address); +} + +MemoryRef MemorySystem::GetPhysicalRef(PAddr address) { struct MemoryArea { PAddr paddr_base; u32 size; @@ -349,25 +434,25 @@ u8* MemorySystem::GetPhysicalPointer(PAddr address) { u32 offset_into_region = address - area->paddr_base; - u8* target_pointer = nullptr; + std::shared_ptr target_mem = nullptr; switch (area->paddr_base) { case VRAM_PADDR: - target_pointer = impl->vram.get() + offset_into_region; + target_mem = impl->vram_mem; break; case DSP_RAM_PADDR: - target_pointer = impl->dsp->GetDspMemory().data() + offset_into_region; + target_mem = impl->dsp_mem; break; case FCRAM_PADDR: - target_pointer = impl->fcram.get() + offset_into_region; + target_mem = impl->fcram_mem; break; case N3DS_EXTRA_RAM_PADDR: - target_pointer = impl->n3ds_extra_ram.get() + offset_into_region; + target_mem = impl->n3ds_extra_ram_mem; break; default: UNREACHABLE(); } - return target_pointer; + return {target_mem, offset_into_region}; } /// For a rasterizer-accessible PAddr, gets a list of all possible VAddr @@ -781,7 +866,7 @@ void WriteMMIO(MMIORegionPointer mmio_handler, VAddr addr, const u64 data) mmio_handler->Write64(addr, data); } -u32 MemorySystem::GetFCRAMOffset(u8* pointer) { +u32 MemorySystem::GetFCRAMOffset(const u8* pointer) { ASSERT(pointer >= impl->fcram.get() && pointer <= impl->fcram.get() + Memory::FCRAM_N3DS_SIZE); return pointer - impl->fcram.get(); } @@ -791,6 +876,11 @@ u8* MemorySystem::GetFCRAMPointer(u32 offset) { return impl->fcram.get() + offset; } +MemoryRef MemorySystem::GetFCRAMRef(u32 offset) { + ASSERT(offset <= Memory::FCRAM_N3DS_SIZE); + return MemoryRef(impl->fcram_mem, offset); +} + void MemorySystem::SetDSP(AudioCore::DspInterface& dsp) { impl->dsp = &dsp; } diff --git a/src/core/memory.h b/src/core/memory.h index 564191d895..0dc98a4282 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -13,6 +13,7 @@ #include #include #include "common/common_types.h" +#include "common/memory_ref.h" #include "core/mmio.h" class ARM_Interface; @@ -77,7 +78,48 @@ struct PageTable { * Array of memory pointers backing each page. An entry can only be non-null if the * corresponding entry in the `attributes` array is of type `Memory`. */ - std::array pointers; + + // The reason for this rigmarole is to keep the 'raw' and 'refs' arrays in sync. + // We need 'raw' for dynarmic and 'refs' for serialization + struct Pointers { + + struct Entry { + Entry(Pointers& pointers_, VAddr idx_) : pointers(pointers_), idx(idx_) {} + + inline void operator=(MemoryRef value) { + pointers.refs[idx] = value; + pointers.raw[idx] = value.GetPtr(); + } + + inline operator u8*() { + return pointers.raw[idx]; + } + + private: + Pointers& pointers; + VAddr idx; + }; + + inline Entry operator[](VAddr idx) { + return Entry(*this, idx); + } + + inline u8* operator[](VAddr idx) const { + return raw[idx]; + } + + inline Entry operator[](std::size_t idx) { + return Entry(*this, static_cast(idx)); + } + + private: + std::array raw; + + std::array refs; + + friend struct PageTable; + }; + Pointers pointers; /** * Contains MMIO handlers that back memory regions whose entries in the `attribute` array is of @@ -91,12 +133,21 @@ struct PageTable { */ std::array attributes; + inline std::array& GetPointerArray() { + return pointers.raw; + } + + void Clear(); + private: template void serialize(Archive& ar, const unsigned int) { - // TODO: Pointers; same as VMA backing regions we need to serialize the u8* + ar& pointers.refs; ar& special_regions; ar& attributes; + for (auto i = 0; i < PAGE_TABLE_NUM_ENTRIES; i++) { + pointers.raw[i] = pointers.refs[i].GetPtr(); + } } friend class boost::serialization::access; }; @@ -142,6 +193,8 @@ enum : PAddr { FCRAM_N3DS_PADDR_END = FCRAM_PADDR + FCRAM_N3DS_SIZE, }; +enum class Region { FCRAM, VRAM, DSP, N3DS }; + /// Virtual user-space memory regions enum : VAddr { /// Where the application text, data and bss reside. @@ -249,7 +302,7 @@ public: * @param size The amount of bytes to map. Must be page-aligned. * @param target Buffer with the memory backing the mapping. Must be of length at least `size`. */ - void MapMemoryRegion(PageTable& page_table, VAddr base, u32 size, u8* target); + void MapMemoryRegion(PageTable& page_table, VAddr base, u32 size, MemoryRef target); /** * Maps a region of the emulated process address space as a IO region. @@ -293,16 +346,21 @@ public: */ u8* GetPhysicalPointer(PAddr address); + MemoryRef GetPhysicalRef(PAddr address); + u8* GetPointer(VAddr vaddr); bool IsValidPhysicalAddress(PAddr paddr); /// Gets offset in FCRAM from a pointer inside FCRAM range - u32 GetFCRAMOffset(u8* pointer); + u32 GetFCRAMOffset(const u8* pointer); /// Gets pointer in FCRAM with given offset u8* GetFCRAMPointer(u32 offset); + /// Gets a serializable ref to FCRAM with the given offset + MemoryRef GetFCRAMRef(u32 offset); + /** * Mark each page touching the region as cached. */ @@ -329,9 +387,9 @@ private: * Since the cache only happens on linear heap or VRAM, we know the exact physical address and * pointer of such virtual address */ - u8* GetPointerForRasterizerCache(VAddr addr); + MemoryRef GetPointerForRasterizerCache(VAddr addr); - void MapPages(PageTable& page_table, u32 base, u32 size, u8* memory, PageType type); + void MapPages(PageTable& page_table, u32 base, u32 size, MemoryRef memory, PageType type); class Impl; @@ -340,9 +398,18 @@ private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int file_version); + +public: + template + class BackingMemImpl; }; /// Determines if the given VAddr is valid for the specified process. bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr); } // namespace Memory + +BOOST_CLASS_EXPORT_KEY(Memory::MemorySystem::BackingMemImpl) +BOOST_CLASS_EXPORT_KEY(Memory::MemorySystem::BackingMemImpl) +BOOST_CLASS_EXPORT_KEY(Memory::MemorySystem::BackingMemImpl) +BOOST_CLASS_EXPORT_KEY(Memory::MemorySystem::BackingMemImpl) diff --git a/src/tests/core/arm/arm_test_common.cpp b/src/tests/core/arm/arm_test_common.cpp index dbbc21c8c6..3f90482ec9 100644 --- a/src/tests/core/arm/arm_test_common.cpp +++ b/src/tests/core/arm/arm_test_common.cpp @@ -22,8 +22,7 @@ TestEnvironment::TestEnvironment(bool mutable_memory_) kernel->SetCurrentProcess(kernel->CreateProcess(kernel->CreateCodeSet("", 0))); page_table = &kernel->GetCurrentProcess()->vm_manager.page_table; - page_table->pointers.fill(nullptr); - page_table->attributes.fill(Memory::PageType::Unmapped); + page_table->Clear(); memory->MapIoRegion(*page_table, 0x00000000, 0x80000000, test_memory); memory->MapIoRegion(*page_table, 0x80000000, 0x80000000, test_memory); diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index e405f67290..414d64021f 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -138,67 +138,70 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel } SECTION("translates StaticBuffer descriptors") { - auto buffer = std::make_shared>(Memory::PAGE_SIZE); - std::fill(buffer->begin(), buffer->end(), 0xAB); + auto mem = std::make_shared(Memory::PAGE_SIZE); + MemoryRef buffer{mem}; + std::fill(buffer.GetPtr(), buffer.GetPtr() + buffer.GetSize(), 0xAB); VAddr target_address = 0x10000000; - auto result = process->vm_manager.MapBackingMemory(target_address, buffer->data(), - buffer->size(), MemoryState::Private); + auto result = process->vm_manager.MapBackingMemory(target_address, buffer, buffer.GetSize(), + MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); const u32_le input[]{ IPC::MakeHeader(0, 0, 2), - IPC::StaticBufferDesc(buffer->size(), 0), + IPC::StaticBufferDesc(buffer.GetSize(), 0), target_address, }; context.PopulateFromIncomingCommandBuffer(input, *process); - CHECK(context.GetStaticBuffer(0) == *buffer); + CHECK(context.GetStaticBuffer(0) == mem->Vector()); - REQUIRE(process->vm_manager.UnmapRange(target_address, buffer->size()) == RESULT_SUCCESS); + REQUIRE(process->vm_manager.UnmapRange(target_address, buffer.GetSize()) == RESULT_SUCCESS); } SECTION("translates MappedBuffer descriptors") { - auto buffer = std::make_shared>(Memory::PAGE_SIZE); - std::fill(buffer->begin(), buffer->end(), 0xCD); + auto mem = std::make_shared(Memory::PAGE_SIZE); + MemoryRef buffer{mem}; + std::fill(buffer.GetPtr(), buffer.GetPtr() + buffer.GetSize(), 0xCD); VAddr target_address = 0x10000000; - auto result = process->vm_manager.MapBackingMemory(target_address, buffer->data(), - buffer->size(), MemoryState::Private); + auto result = process->vm_manager.MapBackingMemory(target_address, buffer, buffer.GetSize(), + MemoryState::Private); const u32_le input[]{ IPC::MakeHeader(0, 0, 2), - IPC::MappedBufferDesc(buffer->size(), IPC::R), + IPC::MappedBufferDesc(buffer.GetSize(), IPC::R), target_address, }; context.PopulateFromIncomingCommandBuffer(input, *process); - std::vector other_buffer(buffer->size()); - context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer->size()); + std::vector other_buffer(buffer.GetSize()); + context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer.GetSize()); - CHECK(other_buffer == *buffer); + CHECK(other_buffer == mem->Vector()); - REQUIRE(process->vm_manager.UnmapRange(target_address, buffer->size()) == RESULT_SUCCESS); + REQUIRE(process->vm_manager.UnmapRange(target_address, buffer.GetSize()) == RESULT_SUCCESS); } SECTION("translates mixed params") { - auto buffer_static = std::make_shared>(Memory::PAGE_SIZE); - std::fill(buffer_static->begin(), buffer_static->end(), 0xCE); + auto mem_static = std::make_shared(Memory::PAGE_SIZE); + MemoryRef buffer_static{mem_static}; + std::fill(buffer_static.GetPtr(), buffer_static.GetPtr() + buffer_static.GetSize(), 0xCE); - auto buffer_mapped = std::make_shared>(Memory::PAGE_SIZE); - std::fill(buffer_mapped->begin(), buffer_mapped->end(), 0xDF); + auto mem_mapped = std::make_shared(Memory::PAGE_SIZE); + MemoryRef buffer_mapped{mem_mapped}; + std::fill(buffer_mapped.GetPtr(), buffer_mapped.GetPtr() + buffer_mapped.GetSize(), 0xDF); VAddr target_address_static = 0x10000000; - auto result = - process->vm_manager.MapBackingMemory(target_address_static, buffer_static->data(), - buffer_static->size(), MemoryState::Private); + auto result = process->vm_manager.MapBackingMemory( + target_address_static, buffer_static, buffer_static.GetSize(), MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); VAddr target_address_mapped = 0x20000000; - result = process->vm_manager.MapBackingMemory(target_address_mapped, buffer_mapped->data(), - buffer_mapped->size(), MemoryState::Private); + result = process->vm_manager.MapBackingMemory( + target_address_mapped, buffer_mapped, buffer_mapped.GetSize(), MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); auto a = MakeObject(kernel); @@ -210,9 +213,9 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel process->handle_table.Create(a).Unwrap(), IPC::CallingPidDesc(), 0, - IPC::StaticBufferDesc(buffer_static->size(), 0), + IPC::StaticBufferDesc(buffer_static.GetSize(), 0), target_address_static, - IPC::MappedBufferDesc(buffer_mapped->size(), IPC::R), + IPC::MappedBufferDesc(buffer_mapped.GetSize(), IPC::R), target_address_mapped, }; @@ -223,14 +226,14 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel CHECK(output[2] == 0xABCDEF00); CHECK(context.GetIncomingHandle(output[4]) == a); CHECK(output[6] == process->process_id); - CHECK(context.GetStaticBuffer(0) == *buffer_static); - std::vector other_buffer(buffer_mapped->size()); - context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer_mapped->size()); - CHECK(other_buffer == *buffer_mapped); + CHECK(context.GetStaticBuffer(0) == mem_static->Vector()); + std::vector other_buffer(buffer_mapped.GetSize()); + context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer_mapped.GetSize()); + CHECK(other_buffer == mem_mapped->Vector()); - REQUIRE(process->vm_manager.UnmapRange(target_address_static, buffer_static->size()) == + REQUIRE(process->vm_manager.UnmapRange(target_address_static, buffer_static.GetSize()) == RESULT_SUCCESS); - REQUIRE(process->vm_manager.UnmapRange(target_address_mapped, buffer_mapped->size()) == + REQUIRE(process->vm_manager.UnmapRange(target_address_mapped, buffer_mapped.GetSize()) == RESULT_SUCCESS); } } @@ -317,10 +320,12 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { context.AddStaticBuffer(0, input_buffer); - auto output_buffer = std::make_shared>(Memory::PAGE_SIZE); + auto output_mem = std::make_shared(Memory::PAGE_SIZE); + MemoryRef output_buffer{output_mem}; + VAddr target_address = 0x10000000; auto result = process->vm_manager.MapBackingMemory( - target_address, output_buffer->data(), output_buffer->size(), MemoryState::Private); + target_address, output_buffer, output_buffer.GetSize(), MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); input[0] = IPC::MakeHeader(0, 0, 2); @@ -332,13 +337,13 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { std::array output_cmdbuff; // Set up the output StaticBuffer output_cmdbuff[IPC::COMMAND_BUFFER_LENGTH] = - IPC::StaticBufferDesc(output_buffer->size(), 0); + IPC::StaticBufferDesc(output_buffer.GetSize(), 0); output_cmdbuff[IPC::COMMAND_BUFFER_LENGTH + 1] = target_address; context.WriteToOutgoingCommandBuffer(output_cmdbuff.data(), *process); - CHECK(*output_buffer == input_buffer); - REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer->size()) == + CHECK(output_mem->Vector() == input_buffer); + REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer.GetSize()) == RESULT_SUCCESS); } @@ -346,15 +351,17 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { std::vector input_buffer(Memory::PAGE_SIZE); std::fill(input_buffer.begin(), input_buffer.end(), 0xAB); - auto output_buffer = std::make_shared>(Memory::PAGE_SIZE); + auto output_mem = std::make_shared(Memory::PAGE_SIZE); + MemoryRef output_buffer{output_mem}; + VAddr target_address = 0x10000000; auto result = process->vm_manager.MapBackingMemory( - target_address, output_buffer->data(), output_buffer->size(), MemoryState::Private); + target_address, output_buffer, output_buffer.GetSize(), MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); const u32_le input_cmdbuff[]{ IPC::MakeHeader(0, 0, 2), - IPC::MappedBufferDesc(output_buffer->size(), IPC::W), + IPC::MappedBufferDesc(output_buffer.GetSize(), IPC::W), target_address, }; @@ -363,15 +370,15 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { context.GetMappedBuffer(0).Write(input_buffer.data(), 0, input_buffer.size()); input[0] = IPC::MakeHeader(0, 0, 2); - input[1] = IPC::MappedBufferDesc(output_buffer->size(), IPC::W); + input[1] = IPC::MappedBufferDesc(output_buffer.GetSize(), IPC::W); input[2] = 0; context.WriteToOutgoingCommandBuffer(output, *process); - CHECK(output[1] == IPC::MappedBufferDesc(output_buffer->size(), IPC::W)); + CHECK(output[1] == IPC::MappedBufferDesc(output_buffer.GetSize(), IPC::W)); CHECK(output[2] == target_address); - CHECK(*output_buffer == input_buffer); - REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer->size()) == + CHECK(output_mem->Vector() == input_buffer); + REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer.GetSize()) == RESULT_SUCCESS); } } diff --git a/src/tests/core/memory/vm_manager.cpp b/src/tests/core/memory/vm_manager.cpp index bd510864a5..5a8e8b7884 100644 --- a/src/tests/core/memory/vm_manager.cpp +++ b/src/tests/core/memory/vm_manager.cpp @@ -10,47 +10,48 @@ #include "core/memory.h" TEST_CASE("Memory Basics", "[kernel][memory]") { - auto block = std::make_shared>(Memory::PAGE_SIZE); + auto mem = std::make_shared(Memory::PAGE_SIZE); + MemoryRef block{mem}; Memory::MemorySystem memory; SECTION("mapping memory") { // Because of the PageTable, Kernel::VMManager is too big to be created on the stack. auto manager = std::make_unique(memory); - auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block->data(), block->size(), + auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block, block.GetSize(), Kernel::MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); auto vma = manager->FindVMA(Memory::HEAP_VADDR); CHECK(vma != manager->vma_map.end()); - CHECK(vma->second.size == block->size()); + CHECK(vma->second.size == block.GetSize()); CHECK(vma->second.type == Kernel::VMAType::BackingMemory); - CHECK(vma->second.backing_memory == block->data()); + CHECK(vma->second.backing_memory.GetPtr() == block.GetPtr()); CHECK(vma->second.meminfo_state == Kernel::MemoryState::Private); } SECTION("unmapping memory") { // Because of the PageTable, Kernel::VMManager is too big to be created on the stack. auto manager = std::make_unique(memory); - auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block->data(), block->size(), + auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block, block.GetSize(), Kernel::MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); - ResultCode code = manager->UnmapRange(Memory::HEAP_VADDR, block->size()); + ResultCode code = manager->UnmapRange(Memory::HEAP_VADDR, block.GetSize()); REQUIRE(code == RESULT_SUCCESS); auto vma = manager->FindVMA(Memory::HEAP_VADDR); CHECK(vma != manager->vma_map.end()); CHECK(vma->second.type == Kernel::VMAType::Free); - CHECK(vma->second.backing_memory == nullptr); + CHECK(vma->second.backing_memory.GetPtr() == nullptr); } SECTION("changing memory permissions") { // Because of the PageTable, Kernel::VMManager is too big to be created on the stack. auto manager = std::make_unique(memory); - auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block->data(), block->size(), + auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block, block.GetSize(), Kernel::MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); - ResultCode code = manager->ReprotectRange(Memory::HEAP_VADDR, block->size(), + ResultCode code = manager->ReprotectRange(Memory::HEAP_VADDR, block.GetSize(), Kernel::VMAPermission::Execute); CHECK(code == RESULT_SUCCESS); @@ -58,24 +59,24 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { CHECK(vma != manager->vma_map.end()); CHECK(vma->second.permissions == Kernel::VMAPermission::Execute); - code = manager->UnmapRange(Memory::HEAP_VADDR, block->size()); + code = manager->UnmapRange(Memory::HEAP_VADDR, block.GetSize()); REQUIRE(code == RESULT_SUCCESS); } SECTION("changing memory state") { // Because of the PageTable, Kernel::VMManager is too big to be created on the stack. auto manager = std::make_unique(memory); - auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block->data(), block->size(), + auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block, block.GetSize(), Kernel::MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); - ResultCode code = manager->ReprotectRange(Memory::HEAP_VADDR, block->size(), + ResultCode code = manager->ReprotectRange(Memory::HEAP_VADDR, block.GetSize(), Kernel::VMAPermission::ReadWrite); REQUIRE(code == RESULT_SUCCESS); SECTION("with invalid address") { ResultCode code = manager->ChangeMemoryState( - 0xFFFFFFFF, block->size(), Kernel::MemoryState::Locked, + 0xFFFFFFFF, block.GetSize(), Kernel::MemoryState::Locked, Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased, Kernel::VMAPermission::Execute); CHECK(code == Kernel::ERR_INVALID_ADDRESS); @@ -83,7 +84,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { SECTION("ignoring the original permissions") { ResultCode code = manager->ChangeMemoryState( - Memory::HEAP_VADDR, block->size(), Kernel::MemoryState::Private, + Memory::HEAP_VADDR, block.GetSize(), Kernel::MemoryState::Private, Kernel::VMAPermission::None, Kernel::MemoryState::Locked, Kernel::VMAPermission::Write); CHECK(code == RESULT_SUCCESS); @@ -96,7 +97,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { SECTION("enforcing the original permissions with correct expectations") { ResultCode code = manager->ChangeMemoryState( - Memory::HEAP_VADDR, block->size(), Kernel::MemoryState::Private, + Memory::HEAP_VADDR, block.GetSize(), Kernel::MemoryState::Private, Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased, Kernel::VMAPermission::Execute); CHECK(code == RESULT_SUCCESS); @@ -109,7 +110,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { SECTION("with incorrect permission expectations") { ResultCode code = manager->ChangeMemoryState( - Memory::HEAP_VADDR, block->size(), Kernel::MemoryState::Private, + Memory::HEAP_VADDR, block.GetSize(), Kernel::MemoryState::Private, Kernel::VMAPermission::Execute, Kernel::MemoryState::Aliased, Kernel::VMAPermission::Execute); CHECK(code == Kernel::ERR_INVALID_ADDRESS_STATE); @@ -122,7 +123,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { SECTION("with incorrect state expectations") { ResultCode code = manager->ChangeMemoryState( - Memory::HEAP_VADDR, block->size(), Kernel::MemoryState::Locked, + Memory::HEAP_VADDR, block.GetSize(), Kernel::MemoryState::Locked, Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased, Kernel::VMAPermission::Execute); CHECK(code == Kernel::ERR_INVALID_ADDRESS_STATE); @@ -133,7 +134,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { CHECK(vma->second.meminfo_state == Kernel::MemoryState::Private); } - code = manager->UnmapRange(Memory::HEAP_VADDR, block->size()); + code = manager->UnmapRange(Memory::HEAP_VADDR, block.GetSize()); REQUIRE(code == RESULT_SUCCESS); } } From e4afa8e5124a61c17f171406b2011a1ea8b163ea Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 5 Jan 2020 13:26:16 +0000 Subject: [PATCH 058/129] Make the tests pass --- src/common/memory_ref.h | 17 +++++++++++------ src/core/core.cpp | 4 ++-- src/core/hle/service/cecd/cecd.cpp | 3 +-- src/core/memory.cpp | 21 +++++++++++---------- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/common/memory_ref.h b/src/common/memory_ref.h index 5aaaef468a..05b1c7901f 100644 --- a/src/common/memory_ref.h +++ b/src/common/memory_ref.h @@ -91,15 +91,20 @@ public: } private: - std::shared_ptr backing_mem; - u32 offset; + std::shared_ptr backing_mem = nullptr; + u32 offset = 0; // Cached values for speed - u8* cptr; - u32 csize; + u8* cptr = nullptr; + u32 csize = 0; void Init() { - cptr = backing_mem->GetPtr() + offset; - csize = static_cast(backing_mem->GetSize() - offset); + if (backing_mem) { + cptr = backing_mem->GetPtr() + offset; + csize = static_cast(backing_mem->GetSize() - offset); + } else { + cptr = nullptr; + csize = 0; + } } template diff --git a/src/core/core.cpp b/src/core/core.cpp index a05e2a6365..bada80b55e 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -214,8 +214,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo timing = std::make_unique(); - kernel = std::make_unique( - *memory, *timing, [this] { PrepareReschedule(); }, system_mode); + kernel = std::make_unique(*memory, *timing, + [this] { PrepareReschedule(); }, system_mode); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index 42ac76946a..f13df6926b 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -1352,8 +1352,7 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ case CecDataPathType::MboxData: case CecDataPathType::MboxIcon: case CecDataPathType::MboxTitle: - default: { - } + default: {} } } diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 9762619f03..dd3a078043 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -98,7 +98,7 @@ public: std::shared_ptr n3ds_extra_ram_mem; std::shared_ptr dsp_mem; - MemorySystem::Impl(); + Impl(); virtual u8* GetPtr(Region r) { switch (r) { @@ -157,16 +157,17 @@ private: template class MemorySystem::BackingMemImpl : public BackingMem { public: - BackingMemImpl() : system(Core::Global().Memory()) {} + BackingMemImpl() : impl(*Core::Global().Memory().impl) {} + BackingMemImpl(MemorySystem::Impl& impl_) : impl(impl_) {} virtual u8* GetPtr() { - return system.impl->GetPtr(R); + return impl.GetPtr(R); } virtual u32 GetSize() const { - return system.impl->GetSize(R); + return impl.GetSize(R); } private: - MemorySystem& system; + MemorySystem::Impl& impl; template void serialize(Archive& ar, const unsigned int) {} @@ -174,10 +175,10 @@ private: }; MemorySystem::Impl::Impl() - : fcram_mem(std::make_shared>()), - vram_mem(std::make_shared>()), - n3ds_extra_ram_mem(std::make_shared>()), - dsp_mem(std::make_shared>()) {} + : fcram_mem(std::make_shared>(*this)), + vram_mem(std::make_shared>(*this)), + n3ds_extra_ram_mem(std::make_shared>(*this)), + dsp_mem(std::make_shared>(*this)) {} MemorySystem::MemorySystem() : impl(std::make_unique()) {} MemorySystem::~MemorySystem() = default; @@ -219,7 +220,7 @@ void MemorySystem::MapPages(PageTable& page_table, u32 base, u32 size, MemoryRef } base += 1; - if (memory != nullptr) + if (memory != nullptr && memory.GetSize() > PAGE_SIZE) memory += PAGE_SIZE; } } From 96432589bdeff1ac53ca1e2b7601d9eea1def435 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 5 Jan 2020 16:35:01 +0000 Subject: [PATCH 059/129] Use shared_ptr for PageTable --- TODO | 2 +- src/core/arm/dynarmic/arm_dynarmic.h | 4 ++-- src/core/hle/kernel/kernel.cpp | 4 ++-- src/core/hle/kernel/kernel.h | 2 +- src/core/hle/kernel/process.cpp | 4 ++-- src/core/hle/kernel/vm_manager.cpp | 11 ++++++----- src/core/hle/kernel/vm_manager.h | 2 +- src/core/memory.cpp | 26 +++++++++++++------------- src/core/memory.h | 8 ++++---- src/tests/core/arm/arm_test_common.cpp | 4 ++-- 10 files changed, 34 insertions(+), 33 deletions(-) diff --git a/TODO b/TODO index 4bb80f8d53..9c77cec5b1 100644 --- a/TODO +++ b/TODO @@ -3,7 +3,7 @@ ☐ Multiple slots etc. ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) - ☐ Page tables + ✔ Page tables @done(20-01-05 16:33) Need to change uses to shared_ptr ✔ Skip N3DS RAM if unused @done(20-01-03 23:26) ✔ DSP @done(19-12-28 16:57) diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index ff9a104b5c..690c1aa2e2 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -61,7 +61,7 @@ private: std::unique_ptr MakeJit(); Dynarmic::A32::Jit* jit = nullptr; - Memory::PageTable* current_page_table = nullptr; - std::map> jits; + std::shared_ptr current_page_table = nullptr; + std::map, std::unique_ptr> jits; std::shared_ptr interpreter_state; }; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 6fef2d4dee..968e905ac5 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -52,10 +52,10 @@ std::shared_ptr KernelSystem::GetCurrentProcess() const { void KernelSystem::SetCurrentProcess(std::shared_ptr process) { current_process = process; - SetCurrentMemoryPageTable(&process->vm_manager.page_table); + SetCurrentMemoryPageTable(process->vm_manager.page_table); } -void KernelSystem::SetCurrentMemoryPageTable(Memory::PageTable* page_table) { +void KernelSystem::SetCurrentMemoryPageTable(std::shared_ptr page_table) { memory.SetCurrentPageTable(page_table); if (current_cpu != nullptr) { current_cpu->PageTableChanged(); // notify the CPU the page table in memory has changed diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 0a527d8b42..c07bfdbcaf 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -214,7 +214,7 @@ public: std::shared_ptr GetCurrentProcess() const; void SetCurrentProcess(std::shared_ptr process); - void SetCurrentMemoryPageTable(Memory::PageTable* page_table); + void SetCurrentMemoryPageTable(std::shared_ptr page_table); void SetCPU(std::shared_ptr cpu); diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index c181bd01ad..ea3449c219 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -435,7 +435,7 @@ ResultCode Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission pe Kernel::Process::Process(KernelSystem& kernel) : Object(kernel), handle_table(kernel), vm_manager(kernel.memory), kernel(kernel) { - kernel.memory.RegisterPageTable(&vm_manager.page_table); + kernel.memory.RegisterPageTable(vm_manager.page_table); } Kernel::Process::~Process() { // Release all objects this process owns first so that their potential destructor can do clean @@ -444,7 +444,7 @@ Kernel::Process::~Process() { // memory etc.) even if they are still referenced by other processes. handle_table.Clear(); - kernel.memory.UnregisterPageTable(&vm_manager.page_table); + kernel.memory.UnregisterPageTable(vm_manager.page_table); } std::shared_ptr KernelSystem::GetProcessById(u32 process_id) const { diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 1b9875ee2a..f1408235b2 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp @@ -37,7 +37,8 @@ bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const { return true; } -VMManager::VMManager(Memory::MemorySystem& memory) : memory(memory) { +VMManager::VMManager(Memory::MemorySystem& memory) + : memory(memory), page_table(std::make_shared()) { Reset(); } @@ -51,7 +52,7 @@ void VMManager::Reset() { initial_vma.size = MAX_ADDRESS; vma_map.emplace(initial_vma.base, initial_vma); - page_table.Clear(); + page_table->Clear(); UpdatePageTableForVMA(initial_vma); } @@ -348,13 +349,13 @@ VMManager::VMAIter VMManager::MergeAdjacent(VMAIter iter) { void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) { switch (vma.type) { case VMAType::Free: - memory.UnmapRegion(page_table, vma.base, vma.size); + memory.UnmapRegion(*page_table, vma.base, vma.size); break; case VMAType::BackingMemory: - memory.MapMemoryRegion(page_table, vma.base, vma.size, vma.backing_memory); + memory.MapMemoryRegion(*page_table, vma.base, vma.size, vma.backing_memory); break; case VMAType::MMIO: - memory.MapIoRegion(page_table, vma.base, vma.size, vma.mmio_handler); + memory.MapIoRegion(*page_table, vma.base, vma.size, vma.mmio_handler); break; } } diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 880d9ec81f..3ca46d0691 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -209,7 +209,7 @@ public: /// Each VMManager has its own page table, which is set as the main one when the owning process /// is scheduled. - Memory::PageTable page_table; + std::shared_ptr page_table; private: using VMAIter = decltype(vma_map)::iterator; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index dd3a078043..ceb6aad4e1 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -87,9 +87,9 @@ public: std::unique_ptr vram = std::make_unique(Memory::VRAM_SIZE); std::unique_ptr n3ds_extra_ram = std::make_unique(Memory::N3DS_EXTRA_RAM_SIZE); - PageTable* current_page_table = nullptr; + std::shared_ptr current_page_table = nullptr; RasterizerCacheMarker cache_marker; - std::vector page_table_list; + std::vector> page_table_list; AudioCore::DspInterface* dsp = nullptr; @@ -144,7 +144,7 @@ private: ar& cache_marker; ar& page_table_list; // dsp is set from Core::System at startup - // TODO: current_page_table + ar& current_page_table; ar& fcram_mem; ar& vram_mem; ar& n3ds_extra_ram_mem; @@ -190,11 +190,11 @@ void MemorySystem::serialize(Archive& ar, const unsigned int file_version) { SERIALIZE_IMPL(MemorySystem) -void MemorySystem::SetCurrentPageTable(PageTable* page_table) { +void MemorySystem::SetCurrentPageTable(std::shared_ptr page_table) { impl->current_page_table = page_table; } -PageTable* MemorySystem::GetCurrentPageTable() const { +std::shared_ptr MemorySystem::GetCurrentPageTable() const { return impl->current_page_table; } @@ -259,11 +259,11 @@ MemoryRef MemorySystem::GetPointerForRasterizerCache(VAddr addr) { UNREACHABLE(); } -void MemorySystem::RegisterPageTable(PageTable* page_table) { +void MemorySystem::RegisterPageTable(std::shared_ptr page_table) { impl->page_table_list.push_back(page_table); } -void MemorySystem::UnregisterPageTable(PageTable* page_table) { +void MemorySystem::UnregisterPageTable(std::shared_ptr page_table) { impl->page_table_list.erase( std::find(impl->page_table_list.begin(), impl->page_table_list.end(), page_table)); } @@ -351,7 +351,7 @@ void MemorySystem::Write(const VAddr vaddr, const T data) { } bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) { - auto& page_table = process.vm_manager.page_table; + auto& page_table = *process.vm_manager.page_table; auto page_pointer = page_table.pointers[vaddr >> PAGE_BITS]; if (page_pointer) @@ -486,7 +486,7 @@ void MemorySystem::RasterizerMarkRegionCached(PAddr start, u32 size, bool cached for (unsigned i = 0; i < num_pages; ++i, paddr += PAGE_SIZE) { for (VAddr vaddr : PhysicalToVirtualAddressForRasterizer(paddr)) { impl->cache_marker.Mark(vaddr, cached); - for (PageTable* page_table : impl->page_table_list) { + for (auto page_table : impl->page_table_list) { PageType& page_type = page_table->attributes[vaddr >> PAGE_BITS]; if (cached) { @@ -608,7 +608,7 @@ u64 MemorySystem::Read64(const VAddr addr) { void MemorySystem::ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer, const std::size_t size) { - auto& page_table = process.vm_manager.page_table; + auto& page_table = *process.vm_manager.page_table; std::size_t remaining_size = size; std::size_t page_index = src_addr >> PAGE_BITS; @@ -674,7 +674,7 @@ void MemorySystem::Write64(const VAddr addr, const u64 data) { void MemorySystem::WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer, const std::size_t size) { - auto& page_table = process.vm_manager.page_table; + auto& page_table = *process.vm_manager.page_table; std::size_t remaining_size = size; std::size_t page_index = dest_addr >> PAGE_BITS; std::size_t page_offset = dest_addr & PAGE_MASK; @@ -722,7 +722,7 @@ void MemorySystem::WriteBlock(const Kernel::Process& process, const VAddr dest_a void MemorySystem::ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std::size_t size) { - auto& page_table = process.vm_manager.page_table; + auto& page_table = *process.vm_manager.page_table; std::size_t remaining_size = size; std::size_t page_index = dest_addr >> PAGE_BITS; std::size_t page_offset = dest_addr & PAGE_MASK; @@ -777,7 +777,7 @@ void MemorySystem::CopyBlock(const Kernel::Process& process, VAddr dest_addr, VA void MemorySystem::CopyBlock(const Kernel::Process& dest_process, const Kernel::Process& src_process, VAddr dest_addr, VAddr src_addr, std::size_t size) { - auto& page_table = src_process.vm_manager.page_table; + auto& page_table = *src_process.vm_manager.page_table; std::size_t remaining_size = size; std::size_t page_index = src_addr >> PAGE_BITS; std::size_t page_offset = src_addr & PAGE_MASK; diff --git a/src/core/memory.h b/src/core/memory.h index 0dc98a4282..348fee3c90 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -316,8 +316,8 @@ public: void UnmapRegion(PageTable& page_table, VAddr base, u32 size); /// Currently active page table - void SetCurrentPageTable(PageTable* page_table); - PageTable* GetCurrentPageTable() const; + void SetCurrentPageTable(std::shared_ptr page_table); + std::shared_ptr GetCurrentPageTable() const; u8 Read8(VAddr addr); u16 Read16(VAddr addr); @@ -367,10 +367,10 @@ public: void RasterizerMarkRegionCached(PAddr start, u32 size, bool cached); /// Registers page table for rasterizer cache marking - void RegisterPageTable(PageTable* page_table); + void RegisterPageTable(std::shared_ptr page_table); /// Unregisters page table for rasterizer cache marking - void UnregisterPageTable(PageTable* page_table); + void UnregisterPageTable(std::shared_ptr page_table); void SetDSP(AudioCore::DspInterface& dsp); diff --git a/src/tests/core/arm/arm_test_common.cpp b/src/tests/core/arm/arm_test_common.cpp index 3f90482ec9..cf2ecf0d48 100644 --- a/src/tests/core/arm/arm_test_common.cpp +++ b/src/tests/core/arm/arm_test_common.cpp @@ -10,7 +10,7 @@ namespace ArmTests { -static Memory::PageTable* page_table = nullptr; +static std::shared_ptr page_table = nullptr; TestEnvironment::TestEnvironment(bool mutable_memory_) : mutable_memory(mutable_memory_), test_memory(std::make_shared(this)) { @@ -20,7 +20,7 @@ TestEnvironment::TestEnvironment(bool mutable_memory_) kernel = std::make_unique(*memory, *timing, [] {}, 0); kernel->SetCurrentProcess(kernel->CreateProcess(kernel->CreateCodeSet("", 0))); - page_table = &kernel->GetCurrentProcess()->vm_manager.page_table; + page_table = kernel->GetCurrentProcess()->vm_manager.page_table; page_table->Clear(); From 7019561fd51919ddc21fbc17220d8b2f4bc10461 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 5 Jan 2020 16:42:04 +0000 Subject: [PATCH 060/129] Bind NWM_UDS service in the constructor --- TODO | 4 ++-- src/core/hle/service/nwm/nwm_uds.cpp | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/TODO b/TODO index 9c77cec5b1..c4f46e3126 100644 --- a/TODO +++ b/TODO @@ -93,7 +93,7 @@ ✔ VM Manager @started(19-08-13 16:46) @done(20-01-04 21:09) @lasted(20w4d5h23m42s) Just need to figure out backing_mem (a u8*) ✔ Wait object @done(19-08-13 16:46) - ☐ Service @started(19-12-23 12:49) + ✔ Service @started(19-12-23 12:49) @done(20-01-05 16:41) @lasted(1w6d3h52m17s) ✔ AC @started(19-12-23 12:48) @done(19-12-24 22:38) @lasted(1d9h50m3s) ✔ ACT @done(19-12-24 23:17) ✔ AM @started(19-12-24 23:17) @done(19-12-24 23:53) @lasted(36m8s) @@ -125,7 +125,7 @@ ✔ NIM @done(19-12-31 21:08) ✔ NS @done(20-01-01 00:46) ✔ NWM @done(20-01-01 21:31) - ☐ Fix wifi_packet_received? + ✔ Fix wifi_packet_received @done(20-01-05 16:41) ✔ PM @done(20-01-01 22:14) ✔ PS @done(20-01-01 00:54) ✔ PTM @done(20-01-01 22:36) diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 9a3de82fab..dddf55333e 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -31,7 +31,7 @@ void NWM_UDS::serialize(Archive& ar, const unsigned int) { ar& node_map; ar& connection_event; ar& received_beacons; - // TODO: Fix wifi_packet_received? + // wifi_packet_received set in constructor } SERIALIZE_IMPL(NWM_UDS) @@ -637,13 +637,6 @@ ResultVal> NWM_UDS::Initialize( recv_buffer_memory = std::move(sharedmem); ASSERT_MSG(recv_buffer_memory->GetSize() == sharedmem_size, "Invalid shared memory size."); - if (auto room_member = Network::GetRoomMember().lock()) { - wifi_packet_received = room_member->BindOnWifiPacketReceived( - [this](const Network::WifiPacket& packet) { OnWifiPacketReceived(packet); }); - } else { - LOG_ERROR(Service_NWM, "Network isn't initalized"); - } - { std::lock_guard lock(connection_status_mutex); @@ -1408,6 +1401,13 @@ NWM_UDS::NWM_UDS(Core::System& system) : ServiceFramework("nwm::UDS"), system(sy system.Kernel().GetSharedPageHandler().SetMacAddress(mac); system.Kernel().GetSharedPageHandler().SetWifiLinkLevel(SharedPage::WifiLinkLevel::BEST); + + if (auto room_member = Network::GetRoomMember().lock()) { + wifi_packet_received = room_member->BindOnWifiPacketReceived( + [this](const Network::WifiPacket& packet) { OnWifiPacketReceived(packet); }); + } else { + LOG_ERROR(Service_NWM, "Network isn't initalized"); + } } NWM_UDS::~NWM_UDS() { From 116d22d562b294e95f3e924c00ecc40bbcc28117 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 6 Jan 2020 20:03:40 +0000 Subject: [PATCH 061/129] Refactor out the wakeup_callback function pointer --- TODO | 3 +- src/common/CMakeLists.txt | 1 + .../serialization/boost_small_vector.hpp | 144 +++++++++++++++++ src/common/serialization/boost_vector.hpp | 148 +++++++----------- src/core/hle/kernel/address_arbiter.cpp | 16 +- src/core/hle/kernel/address_arbiter.h | 6 +- src/core/hle/kernel/hle_ipc.cpp | 95 +++++++---- src/core/hle/kernel/hle_ipc.h | 55 +++++-- src/core/hle/kernel/ipc.cpp | 2 +- src/core/hle/kernel/ipc_debugger/recorder.cpp | 4 +- src/core/hle/kernel/kernel.h | 2 +- src/core/hle/kernel/server_session.cpp | 6 +- src/core/hle/kernel/svc.cpp | 139 ++++++++-------- src/core/hle/kernel/svc.h | 7 + src/core/hle/kernel/thread.cpp | 29 ++-- src/core/hle/kernel/thread.h | 15 +- src/core/hle/kernel/wait_object.cpp | 2 +- src/core/hle/service/fs/file.cpp | 7 +- src/core/hle/service/fs/fs_user.cpp | 14 +- src/core/hle/service/nwm/nwm_uds.cpp | 36 +++-- src/core/hle/service/nwm/nwm_uds.h | 4 + src/core/hle/service/sm/srv.cpp | 66 +++++--- src/core/hle/service/sm/srv.h | 5 + src/tests/core/hle/kernel/hle_ipc.cpp | 22 +-- 24 files changed, 533 insertions(+), 295 deletions(-) create mode 100644 src/common/serialization/boost_small_vector.hpp diff --git a/TODO b/TODO index c4f46e3126..097c310a79 100644 --- a/TODO +++ b/TODO @@ -46,6 +46,7 @@ ✔ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE @started(20-01-03 13:47) @done(20-01-03 13:58) @lasted(11m22s) ☐ Review constructor/initialization code ☐ Review core timing events +☐ Review base class serialization everywhere ✔ Fix CI @done(19-12-31 21:32) ✔ HW @done(19-08-13 15:41) ✔ GPU regs @done(19-08-13 15:41) @@ -87,7 +88,7 @@ ✔ Shared page @done(20-01-04 21:09) ✔ SVC @done(19-12-22 21:32) Nothing to do - all data is constant - ☐ Thread @started(19-08-13 16:45) + ✔ Thread @started(19-08-13 16:45) @done(20-01-06 20:01) @lasted(20w6d4h16m22s) This requires refactoring wakeup_callback to be an object ref ✔ Timer @done(19-08-13 16:45) ✔ VM Manager @started(19-08-13 16:46) @done(20-01-04 21:09) @lasted(20w4d5h23m42s) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index ea117d4409..7ab54242d5 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -96,6 +96,7 @@ add_library(common STATIC serialization/atomic.h serialization/boost_discrete_interval.hpp serialization/boost_flat_set.h + serialization/boost_small_vector.hpp serialization/boost_vector.hpp string_util.cpp string_util.h diff --git a/src/common/serialization/boost_small_vector.hpp b/src/common/serialization/boost_small_vector.hpp new file mode 100644 index 0000000000..b4e07a8962 --- /dev/null +++ b/src/common/serialization/boost_small_vector.hpp @@ -0,0 +1,144 @@ +#ifndef BOOST_SERIALIZATION_BOOST_SMALL_VECTOR_HPP +#define BOOST_SERIALIZATION_BOOST_SMALL_VECTOR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +#pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// boost_vector.hpp: serialization for boost vector templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// fast array serialization (C) Copyright 2005 Matthias Troyer +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +// default is being compatible with version 1.34.1 files, not 1.35 files +#ifndef BOOST_SERIALIZATION_VECTOR_VERSIONED +#define BOOST_SERIALIZATION_VECTOR_VERSIONED(V) (V == 4 || V == 5) +#endif + +namespace boost { +namespace serialization { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// vector< T > + +// the default versions + +template +inline void save(Archive& ar, const boost::container::small_vector& t, + const unsigned int /* file_version */, mpl::false_) { + boost::serialization::stl::save_collection>(ar, + t); +} + +template +inline void load(Archive& ar, boost::container::small_vector& t, + const unsigned int /* file_version */, mpl::false_) { + const boost::archive::library_version_type library_version(ar.get_library_version()); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if (boost::archive::library_version_type(3) < library_version) { + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + t.reserve(count); + stl::collection_load_impl(ar, t, count, item_version); +} + +// the optimized versions + +template +inline void save(Archive& ar, const boost::container::small_vector& t, + const unsigned int /* file_version */, mpl::true_) { + const collection_size_type count(t.size()); + ar << BOOST_SERIALIZATION_NVP(count); + if (!t.empty()) + // explict template arguments to pass intel C++ compiler + ar << serialization::make_array(static_cast(&t[0]), + count); +} + +template +inline void load(Archive& ar, boost::container::small_vector& t, + const unsigned int /* file_version */, mpl::true_) { + collection_size_type count(t.size()); + ar >> BOOST_SERIALIZATION_NVP(count); + t.resize(count); + unsigned int item_version = 0; + if (BOOST_SERIALIZATION_VECTOR_VERSIONED(ar.get_library_version())) { + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + if (!t.empty()) + // explict template arguments to pass intel C++ compiler + ar >> serialization::make_array(static_cast(&t[0]), count); +} + +// dispatch to either default or optimized versions + +template +inline void save(Archive& ar, const boost::container::small_vector& t, + const unsigned int file_version) { + typedef typename boost::serialization::use_array_optimization::template apply< + typename remove_const::type>::type use_optimized; + save(ar, t, file_version, use_optimized()); +} + +template +inline void load(Archive& ar, boost::container::small_vector& t, + const unsigned int file_version) { +#ifdef BOOST_SERIALIZATION_VECTOR_135_HPP + if (ar.get_library_version() == boost::archive::library_version_type(5)) { + load(ar, t, file_version, boost::is_arithmetic()); + return; + } +#endif + typedef typename boost::serialization::use_array_optimization::template apply< + typename remove_const::type>::type use_optimized; + load(ar, t, file_version, use_optimized()); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize(Archive& ar, boost::container::small_vector& t, + const unsigned int file_version) { + boost::serialization::split_free(ar, t, file_version); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize(Archive& ar, boost::container::small_vector& t, + const unsigned int file_version) { + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_BOOST_SMALL_VECTOR_HPP diff --git a/src/common/serialization/boost_vector.hpp b/src/common/serialization/boost_vector.hpp index d97ebd2085..55a5b9eaee 100644 --- a/src/common/serialization/boost_vector.hpp +++ b/src/common/serialization/boost_vector.hpp @@ -1,9 +1,9 @@ -#ifndef BOOST_SERIALIZATION_BOOST_VECTOR_HPP +#ifndef BOOST_SERIALIZATION_BOOST_VECTOR_HPP #define BOOST_SERIALIZATION_BOOST_VECTOR_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) -# pragma once +#pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 @@ -24,20 +24,20 @@ #include #include -#include #include #include +#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include // default is being compatible with version 1.34.1 files, not 1.35 files #ifndef BOOST_SERIALIZATION_VECTOR_VERSIONED -#define BOOST_SERIALIZATION_VECTOR_VERSIONED(V) (V==4 || V==5) +#define BOOST_SERIALIZATION_VECTOR_VERSIONED(V) (V == 4 || V == 5) #endif namespace boost { @@ -48,33 +48,23 @@ namespace serialization { // the default versions -template -inline void save( - Archive & ar, - const boost::container::vector &t, - const unsigned int /* file_version */, - mpl::false_ -){ - boost::serialization::stl::save_collection >( - ar, t - ); +template +inline void save(Archive& ar, const boost::container::vector& t, + const unsigned int /* file_version */, mpl::false_) { + boost::serialization::stl::save_collection>(ar, + t); } -template -inline void load( - Archive & ar, - boost::container::vector &t, - const unsigned int /* file_version */, - mpl::false_ -){ - const boost::archive::library_version_type library_version( - ar.get_library_version() - ); +template +inline void load(Archive& ar, boost::container::vector& t, + const unsigned int /* file_version */, mpl::false_) { + const boost::archive::library_version_type library_version(ar.get_library_version()); // retrieve number of elements item_version_type item_version(0); collection_size_type count; ar >> BOOST_SERIALIZATION_NVP(count); - if(boost::archive::library_version_type(3) < library_version){ + if (boost::archive::library_version_type(3) < library_version) { ar >> BOOST_SERIALIZATION_NVP(item_version); } t.reserve(count); @@ -83,107 +73,77 @@ inline void load( // the optimized versions -template -inline void save( - Archive & ar, - const boost::container::vector &t, - const unsigned int /* file_version */, - mpl::true_ -){ +template +inline void save(Archive& ar, const boost::container::vector& t, + const unsigned int /* file_version */, mpl::true_) { const collection_size_type count(t.size()); ar << BOOST_SERIALIZATION_NVP(count); if (!t.empty()) // explict template arguments to pass intel C++ compiler - ar << serialization::make_array( - static_cast(&t[0]), - count - ); + ar << serialization::make_array(static_cast(&t[0]), + count); } -template -inline void load( - Archive & ar, - boost::container::vector &t, - const unsigned int /* file_version */, - mpl::true_ -){ +template +inline void load(Archive& ar, boost::container::vector& t, + const unsigned int /* file_version */, mpl::true_) { collection_size_type count(t.size()); ar >> BOOST_SERIALIZATION_NVP(count); t.resize(count); - unsigned int item_version=0; - if(BOOST_SERIALIZATION_VECTOR_VERSIONED(ar.get_library_version())) { + unsigned int item_version = 0; + if (BOOST_SERIALIZATION_VECTOR_VERSIONED(ar.get_library_version())) { ar >> BOOST_SERIALIZATION_NVP(item_version); } if (!t.empty()) // explict template arguments to pass intel C++ compiler - ar >> serialization::make_array( - static_cast(&t[0]), - count - ); - } + ar >> serialization::make_array(static_cast(&t[0]), count); +} // dispatch to either default or optimized versions -template -inline void save( - Archive & ar, - const boost::container::vector &t, - const unsigned int file_version -){ - typedef typename - boost::serialization::use_array_optimization::template apply< - typename remove_const::type - >::type use_optimized; - save(ar,t,file_version, use_optimized()); +template +inline void save(Archive& ar, const boost::container::vector& t, + const unsigned int file_version) { + typedef typename boost::serialization::use_array_optimization::template apply< + typename remove_const::type>::type use_optimized; + save(ar, t, file_version, use_optimized()); } -template -inline void load( - Archive & ar, - boost::container::vector &t, - const unsigned int file_version -){ +template +inline void load(Archive& ar, boost::container::vector& t, + const unsigned int file_version) { #ifdef BOOST_SERIALIZATION_VECTOR_135_HPP - if (ar.get_library_version()==boost::archive::library_version_type(5)) - { - load(ar,t,file_version, boost::is_arithmetic()); - return; + if (ar.get_library_version() == boost::archive::library_version_type(5)) { + load(ar, t, file_version, boost::is_arithmetic()); + return; } #endif - typedef typename - boost::serialization::use_array_optimization::template apply< - typename remove_const::type - >::type use_optimized; - load(ar,t,file_version, use_optimized()); + typedef typename boost::serialization::use_array_optimization::template apply< + typename remove_const::type>::type use_optimized; + load(ar, t, file_version, use_optimized()); } // split non-intrusive serialization function member into separate // non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - boost::container::vector & t, - const unsigned int file_version -){ +template +inline void serialize(Archive& ar, boost::container::vector& t, + const unsigned int file_version) { boost::serialization::split_free(ar, t, file_version); } // split non-intrusive serialization function member into separate // non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - boost::container::vector & t, - const unsigned int file_version -){ +template +inline void serialize(Archive& ar, boost::container::vector& t, + const unsigned int file_version) { boost::serialization::split_free(ar, t, file_version); } -} // serialization +} // namespace serialization } // namespace boost #include BOOST_SERIALIZATION_COLLECTION_TRAITS(boost::container::vector) -#endif // BOOST_SERIALIZATION_VECTOR_HPP +#endif // BOOST_SERIALIZATION_BOOST_VECTOR_HPP diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 7b8329c4d4..5074e352fc 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -80,16 +80,18 @@ std::shared_ptr KernelSystem::CreateAddressArbiter(std::string n return address_arbiter; } +void AddressArbiter::WakeUp(ThreadWakeupReason reason, std::shared_ptr thread, + std::shared_ptr object) { + ASSERT(reason == ThreadWakeupReason::Timeout); + // Remove the newly-awakened thread from the Arbiter's waiting list. + waiting_threads.erase(std::remove(waiting_threads.begin(), waiting_threads.end(), thread), + waiting_threads.end()); +}; + ResultCode AddressArbiter::ArbitrateAddress(std::shared_ptr thread, ArbitrationType type, VAddr address, s32 value, u64 nanoseconds) { - auto timeout_callback = [this](ThreadWakeupReason reason, std::shared_ptr thread, - std::shared_ptr object) { - ASSERT(reason == ThreadWakeupReason::Timeout); - // Remove the newly-awakened thread from the Arbiter's waiting list. - waiting_threads.erase(std::remove(waiting_threads.begin(), waiting_threads.end(), thread), - waiting_threads.end()); - }; + auto timeout_callback = std::dynamic_pointer_cast(shared_from_this()); switch (type) { diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index 19b80315f8..85a2a065a5 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -12,6 +12,7 @@ #include #include "common/common_types.h" #include "core/hle/kernel/object.h" +#include "core/hle/kernel/thread.h" #include "core/hle/result.h" // Address arbiters are an underlying kernel synchronization object that can be created/used via @@ -34,7 +35,7 @@ enum class ArbitrationType : u32 { DecrementAndWaitIfLessThanWithTimeout, }; -class AddressArbiter final : public Object { +class AddressArbiter final : public Object, public WakeupCallback { public: explicit AddressArbiter(KernelSystem& kernel); ~AddressArbiter() override; @@ -56,6 +57,9 @@ public: ResultCode ArbitrateAddress(std::shared_ptr thread, ArbitrationType type, VAddr address, s32 value, u64 nanoseconds); + void WakeUp(ThreadWakeupReason reason, std::shared_ptr thread, + std::shared_ptr object); + private: KernelSystem& kernel; diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index ab4ecfd059..b1e2f7d8b0 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -16,6 +16,46 @@ namespace Kernel { +class HLERequestContext::ThreadCallback : public Kernel::WakeupCallback { + +public: + ThreadCallback(std::shared_ptr context_, + std::shared_ptr callback_) + : context(context_), callback(callback_) {} + void WakeUp(ThreadWakeupReason reason, std::shared_ptr thread, + std::shared_ptr object) { + ASSERT(thread->status == ThreadStatus::WaitHleEvent); + if (callback) { + callback->WakeUp(thread, *context, reason); + } + + auto& process = thread->owner_process; + // We must copy the entire command buffer *plus* the entire static buffers area, since + // the translation might need to read from it in order to retrieve the StaticBuffer + // target addresses. + std::array cmd_buff; + Memory::MemorySystem& memory = context->kernel.memory; + memory.ReadBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(), + cmd_buff.size() * sizeof(u32)); + context->WriteToOutgoingCommandBuffer(cmd_buff.data(), *process); + // Copy the translated command buffer back into the thread's command buffer area. + memory.WriteBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(), + cmd_buff.size() * sizeof(u32)); + } + +private: + ThreadCallback() = default; + std::shared_ptr callback{}; + std::shared_ptr context{}; + + template + void serialize(Archive& ar, const unsigned int) { + ar& callback; + ar& context; + } + friend class boost::serialization::access; +}; + SessionRequestHandler::SessionInfo::SessionInfo(std::shared_ptr session, std::unique_ptr data) : session(std::move(session)), data(std::move(data)) {} @@ -33,34 +73,16 @@ void SessionRequestHandler::ClientDisconnected(std::shared_ptr se connected_sessions.end()); } -std::shared_ptr HLERequestContext::SleepClientThread(const std::string& reason, - std::chrono::nanoseconds timeout, - WakeupCallback&& callback) { +std::shared_ptr HLERequestContext::SleepClientThread( + const std::string& reason, std::chrono::nanoseconds timeout, + std::shared_ptr callback) { // Put the client thread to sleep until the wait event is signaled or the timeout expires. - thread->wakeup_callback = [context = *this, - callback](ThreadWakeupReason reason, std::shared_ptr thread, - std::shared_ptr object) mutable { - ASSERT(thread->status == ThreadStatus::WaitHleEvent); - callback(thread, context, reason); - - auto& process = thread->owner_process; - // We must copy the entire command buffer *plus* the entire static buffers area, since - // the translation might need to read from it in order to retrieve the StaticBuffer - // target addresses. - std::array cmd_buff; - Memory::MemorySystem& memory = context.kernel.memory; - memory.ReadBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(), - cmd_buff.size() * sizeof(u32)); - context.WriteToOutgoingCommandBuffer(cmd_buff.data(), *process); - // Copy the translated command buffer back into the thread's command buffer area. - memory.WriteBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(), - cmd_buff.size() * sizeof(u32)); - }; + thread->wakeup_callback = std::make_shared(shared_from_this(), callback); auto event = kernel.CreateEvent(Kernel::ResetType::OneShot, "HLE Pause Event: " + reason); thread->status = ThreadStatus::WaitHleEvent; thread->wait_objects = {event}; - event->AddWaitingThread(SharedFrom(thread)); + event->AddWaitingThread(thread); if (timeout.count() > 0) thread->WakeAfterDelay(timeout.count()); @@ -68,8 +90,10 @@ std::shared_ptr HLERequestContext::SleepClientThread(const std::string& r return event; } +HLERequestContext::HLERequestContext() : kernel(Core::Global()) {} + HLERequestContext::HLERequestContext(KernelSystem& kernel, std::shared_ptr session, - Thread* thread) + std::shared_ptr thread) : kernel(kernel), session(std::move(session)), thread(thread) { cmd_buf[0] = 0; } @@ -98,8 +122,9 @@ void HLERequestContext::AddStaticBuffer(u8 buffer_id, std::vector data) { static_buffers[buffer_id] = std::move(data); } -ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf, - Process& src_process) { +ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer( + const u32_le* src_cmdbuf, std::shared_ptr src_process_) { + auto& src_process = *src_process_; IPC::Header header{src_cmdbuf[0]}; std::size_t untranslated_size = 1u + header.normal_params_size; @@ -158,7 +183,7 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr } case IPC::DescriptorType::MappedBuffer: { u32 next_id = static_cast(request_mapped_buffers.size()); - request_mapped_buffers.emplace_back(kernel.memory, src_process, descriptor, + request_mapped_buffers.emplace_back(kernel.memory, src_process_, descriptor, src_cmdbuf[i], next_id); cmd_buf[i++] = next_id; break; @@ -170,7 +195,7 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr if (should_record) { std::vector translated_cmdbuf{cmd_buf.begin(), cmd_buf.begin() + command_size}; - kernel.GetIPCRecorder().SetRequestInfo(SharedFrom(thread), std::move(untranslated_cmdbuf), + kernel.GetIPCRecorder().SetRequestInfo(thread, std::move(untranslated_cmdbuf), std::move(translated_cmdbuf)); } @@ -248,7 +273,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, if (should_record) { std::vector translated_cmdbuf{dst_cmdbuf, dst_cmdbuf + command_size}; - kernel.GetIPCRecorder().SetReplyInfo(SharedFrom(thread), std::move(untranslated_cmdbuf), + kernel.GetIPCRecorder().SetReplyInfo(thread, std::move(untranslated_cmdbuf), std::move(translated_cmdbuf)); } @@ -262,13 +287,15 @@ MappedBuffer& HLERequestContext::GetMappedBuffer(u32 id_from_cmdbuf) { void HLERequestContext::ReportUnimplemented() const { if (kernel.GetIPCRecorder().IsEnabled()) { - kernel.GetIPCRecorder().SetHLEUnimplemented(SharedFrom(thread)); + kernel.GetIPCRecorder().SetHLEUnimplemented(thread); } } -MappedBuffer::MappedBuffer(Memory::MemorySystem& memory, const Process& process, u32 descriptor, - VAddr address, u32 id) - : memory(&memory), id(id), address(address), process(&process) { +MappedBuffer::MappedBuffer() : memory(&Core::Global().Memory()) {} + +MappedBuffer::MappedBuffer(Memory::MemorySystem& memory, std::shared_ptr process, + u32 descriptor, VAddr address, u32 id) + : memory(&memory), id(id), address(address), process(process) { IPC::MappedBufferDescInfo desc{descriptor}; size = desc.size; perms = desc.perms; @@ -287,3 +314,5 @@ void MappedBuffer::Write(const void* src_buffer, std::size_t offset, std::size_t } } // namespace Kernel + +SERIALIZE_EXPORT_IMPL(Kernel::HLERequestContext::ThreadCallback) diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 2177b733ea..56c6d8ce1c 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -16,6 +16,7 @@ #include #include #include "common/common_types.h" +#include "common/serialization/boost_small_vector.hpp" #include "common/swap.h" #include "core/hle/ipc.h" #include "core/hle/kernel/object.h" @@ -127,7 +128,7 @@ private: class MappedBuffer { public: - MappedBuffer(Memory::MemorySystem& memory, const Process& process, u32 descriptor, + MappedBuffer(Memory::MemorySystem& memory, std::shared_ptr process, u32 descriptor, VAddr address, u32 id); // interface for service @@ -151,9 +152,21 @@ private: Memory::MemorySystem* memory; u32 id; VAddr address; - const Process* process; - std::size_t size; + std::shared_ptr process; + u32 size; IPC::MappedBufferPermissions perms; + + MappedBuffer(); + + template + void serialize(Archive& ar, const unsigned int) { + ar& id; + ar& address; + ar& process; + ar& size; + ar& perms; + } + friend class boost::serialization::access; }; /** @@ -185,9 +198,10 @@ private: * id of the memory interface and let kernel convert it back to client vaddr. No real unmapping is * needed in this case, though. */ -class HLERequestContext { +class HLERequestContext : std::enable_shared_from_this { public: - HLERequestContext(KernelSystem& kernel, std::shared_ptr session, Thread* thread); + HLERequestContext(KernelSystem& kernel, std::shared_ptr session, + std::shared_ptr thread); ~HLERequestContext(); /// Returns a pointer to the IPC command buffer for this request. @@ -203,8 +217,12 @@ public: return session; } - using WakeupCallback = std::function thread, HLERequestContext& context, ThreadWakeupReason reason)>; + class WakeupCallback { + public: + virtual ~WakeupCallback() = default; + virtual void WakeUp(std::shared_ptr thread, HLERequestContext& context, + ThreadWakeupReason reason) = 0; + }; /** * Puts the specified guest thread to sleep until the returned event is signaled or until the @@ -219,7 +237,7 @@ public: */ std::shared_ptr SleepClientThread(const std::string& reason, std::chrono::nanoseconds timeout, - WakeupCallback&& callback); + std::shared_ptr callback); /** * Resolves a object id from the request command buffer into a pointer to an object. See the @@ -259,26 +277,43 @@ public: MappedBuffer& GetMappedBuffer(u32 id_from_cmdbuf); /// Populates this context with data from the requesting process/thread. - ResultCode PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf, Process& src_process); + ResultCode PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf, + std::shared_ptr src_process); /// Writes data from this context back to the requesting process/thread. ResultCode WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process) const; /// Reports an unimplemented function. void ReportUnimplemented() const; + class ThreadCallback; + friend class ThreadCallback; + private: KernelSystem& kernel; std::array cmd_buf; std::shared_ptr session; - Thread* thread; + std::shared_ptr thread; // TODO(yuriks): Check common usage of this and optimize size accordingly boost::container::small_vector, 8> request_handles; // The static buffers will be created when the IPC request is translated. std::array, IPC::MAX_STATIC_BUFFERS> static_buffers; // The mapped buffers will be created when the IPC request is translated boost::container::small_vector request_mapped_buffers; + + HLERequestContext(); + template + void serialize(Archive& ar, const unsigned int) { + ar& cmd_buf; + ar& session; + ar& thread; + ar& request_handles; + ar& static_buffers; + ar& request_mapped_buffers; + } + friend class boost::serialization::access; }; } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::SessionRequestHandler::SessionDataBase) +BOOST_CLASS_EXPORT_KEY(Kernel::HLERequestContext::ThreadCallback) diff --git a/src/core/hle/kernel/ipc.cpp b/src/core/hle/kernel/ipc.cpp index e39732c149..eb14888404 100644 --- a/src/core/hle/kernel/ipc.cpp +++ b/src/core/hle/kernel/ipc.cpp @@ -72,7 +72,7 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy if (handle == CurrentThread) { object = src_thread; } else if (handle == CurrentProcess) { - object = SharedFrom(src_process); + object = src_process; } else if (handle != 0) { object = src_process->handle_table.GetGeneric(handle); if (descriptor == IPC::DescriptorType::MoveHandle) { diff --git a/src/core/hle/kernel/ipc_debugger/recorder.cpp b/src/core/hle/kernel/ipc_debugger/recorder.cpp index 968815c5bd..f1e4a09f16 100644 --- a/src/core/hle/kernel/ipc_debugger/recorder.cpp +++ b/src/core/hle/kernel/ipc_debugger/recorder.cpp @@ -52,7 +52,7 @@ void Recorder::RegisterRequest(const std::shared_ptr& cli RequestRecord record = {/* id */ ++record_count, /* status */ RequestStatus::Sent, - /* client_process */ GetObjectInfo(client_thread->owner_process), + /* client_process */ GetObjectInfo(client_thread->owner_process.get()), /* client_thread */ GetObjectInfo(client_thread.get()), /* client_session */ GetObjectInfo(client_session.get()), /* client_port */ GetObjectInfo(client_session->parent->port.get()), @@ -82,7 +82,7 @@ void Recorder::SetRequestInfo(const std::shared_ptr& client_thre record.translated_request_cmdbuf = std::move(translated_cmdbuf); if (server_thread) { - record.server_process = GetObjectInfo(server_thread->owner_process); + record.server_process = GetObjectInfo(server_thread->owner_process.get()); record.server_thread = GetObjectInfo(server_thread.get()); } else { record.is_hle = true; diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index c07bfdbcaf..e7b7314d62 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -134,7 +134,7 @@ public: */ ResultVal> CreateThread(std::string name, VAddr entry_point, u32 priority, u32 arg, s32 processor_id, - VAddr stack_top, Process& owner_process); + VAddr stack_top, std::shared_ptr owner_process); /** * Creates a semaphore. diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 4b393b63d9..8bb82fc839 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -71,12 +71,12 @@ ResultCode ServerSession::HandleSyncRequest(std::shared_ptr thread) { // If this ServerSession has an associated HLE handler, forward the request to it. if (hle_handler != nullptr) { std::array cmd_buf; - Kernel::Process* current_process = thread->owner_process; + auto current_process = thread->owner_process; kernel.memory.ReadBlock(*current_process, thread->GetCommandBufferAddress(), cmd_buf.data(), cmd_buf.size() * sizeof(u32)); - Kernel::HLERequestContext context(kernel, SharedFrom(this), thread.get()); - context.PopulateFromIncomingCommandBuffer(cmd_buf.data(), *current_process); + Kernel::HLERequestContext context(kernel, SharedFrom(this), thread); + context.PopulateFromIncomingCommandBuffer(cmd_buf.data(), current_process); hle_handler->HandleSyncRequest(context); diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index b5ebaf936e..7f7cc12725 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -282,7 +282,7 @@ void SVC::ExitProcess() { // Stop all the process threads that are currently waiting for objects. auto& thread_list = kernel.GetThreadManager().GetThreadList(); for (auto& thread : thread_list) { - if (thread->owner_process != current_process.get()) + if (thread->owner_process != current_process) continue; if (thread.get() == kernel.GetThreadManager().GetCurrentThread()) @@ -403,6 +403,73 @@ ResultCode SVC::CloseHandle(Handle handle) { return kernel.GetCurrentProcess()->handle_table.Close(handle); } +static ResultCode ReceiveIPCRequest(Kernel::KernelSystem& kernel, Memory::MemorySystem& memory, + std::shared_ptr server_session, + std::shared_ptr thread); + +class SVC_SyncCallback : public Kernel::WakeupCallback { +public: + SVC_SyncCallback(bool do_output_) : do_output(do_output_) {} + void WakeUp(ThreadWakeupReason reason, std::shared_ptr thread, + std::shared_ptr object) { + + if (reason == ThreadWakeupReason::Timeout) { + thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); + return; + } + + ASSERT(reason == ThreadWakeupReason::Signal); + + thread->SetWaitSynchronizationResult(RESULT_SUCCESS); + + // The wait_all case does not update the output index. + if (do_output) { + thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(object.get())); + } + } + +private: + bool do_output; + + SVC_SyncCallback() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& do_output; + } + friend class boost::serialization::access; +}; + +class SVC_IPCCallback : public Kernel::WakeupCallback { +public: + SVC_IPCCallback(Core::System& system_) : system(system_) {} + + void WakeUp(ThreadWakeupReason reason, std::shared_ptr thread, + std::shared_ptr object) { + + ASSERT(thread->status == ThreadStatus::WaitSynchAny); + ASSERT(reason == ThreadWakeupReason::Signal); + + ResultCode result = RESULT_SUCCESS; + + if (object->GetHandleType() == HandleType::ServerSession) { + auto server_session = DynamicObjectCast(object); + result = ReceiveIPCRequest(system.Kernel(), system.Memory(), server_session, thread); + } + + thread->SetWaitSynchronizationResult(result); + thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(object.get())); + } + +private: + Core::System& system; + + SVC_IPCCallback() : system(Core::Global()) {} + + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; +}; + /// Wait for a handle to synchronize, timeout after the specified nanoseconds ResultCode SVC::WaitSynchronization1(Handle handle, s64 nano_seconds) { auto object = kernel.GetCurrentProcess()->handle_table.Get(handle); @@ -426,21 +493,7 @@ ResultCode SVC::WaitSynchronization1(Handle handle, s64 nano_seconds) { // Create an event to wake the thread up after the specified nanosecond delay has passed thread->WakeAfterDelay(nano_seconds); - thread->wakeup_callback = [](ThreadWakeupReason reason, std::shared_ptr thread, - std::shared_ptr object) { - ASSERT(thread->status == ThreadStatus::WaitSynchAny); - - if (reason == ThreadWakeupReason::Timeout) { - thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); - return; - } - - ASSERT(reason == ThreadWakeupReason::Signal); - thread->SetWaitSynchronizationResult(RESULT_SUCCESS); - - // WaitSynchronization1 doesn't have an output index like WaitSynchronizationN, so we - // don't have to do anything else here. - }; + thread->wakeup_callback = std::make_shared(false); system.PrepareReschedule(); @@ -515,20 +568,7 @@ ResultCode SVC::WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle // Create an event to wake the thread up after the specified nanosecond delay has passed thread->WakeAfterDelay(nano_seconds); - thread->wakeup_callback = [](ThreadWakeupReason reason, std::shared_ptr thread, - std::shared_ptr object) { - ASSERT(thread->status == ThreadStatus::WaitSynchAll); - - if (reason == ThreadWakeupReason::Timeout) { - thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); - return; - } - - ASSERT(reason == ThreadWakeupReason::Signal); - - thread->SetWaitSynchronizationResult(RESULT_SUCCESS); - // The wait_all case does not update the output index. - }; + thread->wakeup_callback = std::make_shared(false); system.PrepareReschedule(); @@ -575,20 +615,7 @@ ResultCode SVC::WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle // Create an event to wake the thread up after the specified nanosecond delay has passed thread->WakeAfterDelay(nano_seconds); - thread->wakeup_callback = [](ThreadWakeupReason reason, std::shared_ptr thread, - std::shared_ptr object) { - ASSERT(thread->status == ThreadStatus::WaitSynchAny); - - if (reason == ThreadWakeupReason::Timeout) { - thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); - return; - } - - ASSERT(reason == ThreadWakeupReason::Signal); - - thread->SetWaitSynchronizationResult(RESULT_SUCCESS); - thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(object.get())); - }; + thread->wakeup_callback = std::make_shared(true); system.PrepareReschedule(); @@ -730,22 +757,7 @@ ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_co thread->wait_objects = std::move(objects); - thread->wakeup_callback = [& kernel = this->kernel, &memory = this->memory]( - ThreadWakeupReason reason, std::shared_ptr thread, - std::shared_ptr object) { - ASSERT(thread->status == ThreadStatus::WaitSynchAny); - ASSERT(reason == ThreadWakeupReason::Signal); - - ResultCode result = RESULT_SUCCESS; - - if (object->GetHandleType() == HandleType::ServerSession) { - auto server_session = DynamicObjectCast(object); - result = ReceiveIPCRequest(kernel, memory, server_session, thread); - } - - thread->SetWaitSynchronizationResult(result); - thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(object.get())); - }; + thread->wakeup_callback = std::make_shared(system); system.PrepareReschedule(); @@ -911,7 +923,7 @@ ResultCode SVC::CreateThread(Handle* out_handle, u32 entry_point, u32 arg, VAddr CASCADE_RESULT(std::shared_ptr thread, kernel.CreateThread(name, entry_point, priority, arg, processor_id, stack_top, - *current_process)); + current_process)); thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO); // 0x03C00000 @@ -1020,7 +1032,7 @@ ResultCode SVC::GetProcessIdOfThread(u32* process_id, Handle thread_handle) { if (thread == nullptr) return ERR_INVALID_HANDLE; - const std::shared_ptr process = SharedFrom(thread->owner_process); + const std::shared_ptr process = thread->owner_process; ASSERT_MSG(process != nullptr, "Invalid parent process for thread={:#010X}", thread_handle); @@ -1611,3 +1623,6 @@ void SVCContext::CallSVC(u32 immediate) { } } // namespace Kernel + +SERIALIZE_EXPORT_IMPL(Kernel::SVC_SyncCallback) +SERIALIZE_EXPORT_IMPL(Kernel::SVC_IPCCallback) diff --git a/src/core/hle/kernel/svc.h b/src/core/hle/kernel/svc.h index efddff9e88..4cf2654001 100644 --- a/src/core/hle/kernel/svc.h +++ b/src/core/hle/kernel/svc.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include "common/common_types.h" namespace Core { @@ -25,4 +26,10 @@ private: std::unique_ptr impl; }; +class SVC_SyncCallback; +class SVC_IPCCallback; + } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::SVC_SyncCallback) +BOOST_CLASS_EXPORT_KEY(Kernel::SVC_IPCCallback) diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 1af2d4f4d6..13a3017a53 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -48,7 +48,7 @@ void Thread::serialize(Archive& ar, const unsigned int file_version) { ar& wait_objects; ar& wait_address; ar& name; - // TODO: How the hell to do wakeup_callback + ar& wakeup_callback; } SERIALIZE_IMPL(Thread) @@ -138,8 +138,8 @@ void ThreadManager::SwitchContext(Thread* new_thread) { ready_queue.remove(new_thread->current_priority, new_thread); new_thread->status = ThreadStatus::Running; - if (previous_process.get() != current_thread->owner_process) { - kernel.SetCurrentProcess(SharedFrom(current_thread->owner_process)); + if (previous_process != current_thread->owner_process) { + kernel.SetCurrentProcess(current_thread->owner_process); } cpu->LoadContext(new_thread->context); @@ -196,7 +196,7 @@ void ThreadManager::ThreadWakeupCallback(u64 thread_id, s64 cycles_late) { // Invoke the wakeup callback before clearing the wait objects if (thread->wakeup_callback) - thread->wakeup_callback(ThreadWakeupReason::Timeout, thread, nullptr); + thread->wakeup_callback->WakeUp(ThreadWakeupReason::Timeout, thread, nullptr); // Remove the thread from each of its waiting objects' waitlists for (auto& object : thread->wait_objects) @@ -313,10 +313,9 @@ static void ResetThreadContext(const std::unique_ptrSetCpsr(USER32MODE | ((entry_point & 1) << 5)); // Usermode and THUMB mode } -ResultVal> KernelSystem::CreateThread(std::string name, VAddr entry_point, - u32 priority, u32 arg, - s32 processor_id, VAddr stack_top, - Process& owner_process) { +ResultVal> KernelSystem::CreateThread( + std::string name, VAddr entry_point, u32 priority, u32 arg, s32 processor_id, VAddr stack_top, + std::shared_ptr owner_process) { // Check if priority is in ranged. Lowest priority -> highest priority id. if (priority > ThreadPrioLowest) { LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority); @@ -330,7 +329,7 @@ ResultVal> KernelSystem::CreateThread(std::string name, // TODO(yuriks): Other checks, returning 0xD9001BEA - if (!Memory::IsValidVirtualAddress(owner_process, entry_point)) { + if (!Memory::IsValidVirtualAddress(*owner_process, entry_point)) { LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:08x}", name, entry_point); // TODO: Verify error return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, @@ -353,10 +352,10 @@ ResultVal> KernelSystem::CreateThread(std::string name, thread->wait_address = 0; thread->name = std::move(name); thread_manager->wakeup_callback_table[thread->thread_id] = thread.get(); - thread->owner_process = &owner_process; + thread->owner_process = owner_process; // Find the next available TLS index, and mark it as used - auto& tls_slots = owner_process.tls_slots; + auto& tls_slots = owner_process->tls_slots; auto [available_page, available_slot, needs_allocation] = GetFreeThreadLocalSlot(tls_slots); @@ -372,13 +371,13 @@ ResultVal> KernelSystem::CreateThread(std::string name, "Not enough space in region to allocate a new TLS page for thread"); return ERR_OUT_OF_MEMORY; } - owner_process.memory_used += Memory::PAGE_SIZE; + owner_process->memory_used += Memory::PAGE_SIZE; tls_slots.emplace_back(0); // The page is completely available at the start available_page = tls_slots.size() - 1; available_slot = 0; // Use the first slot in the new page - auto& vm_manager = owner_process.vm_manager; + auto& vm_manager = owner_process->vm_manager; // Map the page to the current process' address space. vm_manager.MapBackingMemory(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE, @@ -391,7 +390,7 @@ ResultVal> KernelSystem::CreateThread(std::string name, thread->tls_address = Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE + available_slot * Memory::TLS_ENTRY_SIZE; - memory.ZeroBlock(owner_process, thread->tls_address, Memory::TLS_ENTRY_SIZE); + memory.ZeroBlock(*owner_process, thread->tls_address, Memory::TLS_ENTRY_SIZE); // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used // to initialize the context @@ -438,7 +437,7 @@ std::shared_ptr SetupMainThread(KernelSystem& kernel, u32 entry_point, u // Initialize new "main" thread auto thread_res = kernel.CreateThread("main", entry_point, priority, 0, owner_process->ideal_processor, - Memory::HEAP_VADDR_END, *owner_process); + Memory::HEAP_VADDR_END, owner_process); std::shared_ptr thread = std::move(thread_res).Unwrap(); diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 219db9f2d9..9941c76db5 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -59,6 +59,15 @@ enum class ThreadWakeupReason { Timeout // The thread was woken up due to a wait timeout. }; +class Thread; + +class WakeupCallback { +public: + virtual ~WakeupCallback() = default; + virtual void WakeUp(ThreadWakeupReason reason, std::shared_ptr thread, + std::shared_ptr object) = 0; +}; + class ThreadManager { public: explicit ThreadManager(Kernel::KernelSystem& kernel); @@ -300,7 +309,7 @@ public: /// Mutexes that this thread is currently waiting for. boost::container::flat_set> pending_mutexes; - Process* owner_process; ///< Process that owns this thread + std::shared_ptr owner_process; ///< Process that owns this thread /// Objects that the thread is waiting on, in the same order as they were // passed to WaitSynchronization1/N. @@ -310,12 +319,10 @@ public: std::string name; - using WakeupCallback = void(ThreadWakeupReason reason, std::shared_ptr thread, - std::shared_ptr object); // Callback that will be invoked when the thread is resumed from a waiting state. If the thread // was waiting via WaitSynchronizationN then the object will be the last object that became // available. In case of a timeout, the object will be nullptr. - std::function wakeup_callback; + std::shared_ptr wakeup_callback; private: ThreadManager& thread_manager; diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp index 94ae632cde..6fe75b6d82 100644 --- a/src/core/hle/kernel/wait_object.cpp +++ b/src/core/hle/kernel/wait_object.cpp @@ -80,7 +80,7 @@ void WaitObject::WakeupAllWaitingThreads() { // Invoke the wakeup callback before clearing the wait objects if (thread->wakeup_callback) - thread->wakeup_callback(ThreadWakeupReason::Signal, thread, SharedFrom(this)); + thread->wakeup_callback->WakeUp(ThreadWakeupReason::Signal, thread, SharedFrom(this)); for (auto& object : thread->wait_objects) object->RemoveWaitingThread(thread.get()); diff --git a/src/core/hle/service/fs/file.cpp b/src/core/hle/service/fs/file.cpp index 946e27211c..c8727314b8 100644 --- a/src/core/hle/service/fs/file.cpp +++ b/src/core/hle/service/fs/file.cpp @@ -71,12 +71,7 @@ void File::Read(Kernel::HLERequestContext& ctx) { rb.PushMappedBuffer(buffer); std::chrono::nanoseconds read_timeout_ns{backend->GetReadDelayNs(length)}; - ctx.SleepClientThread("file::read", read_timeout_ns, - [](std::shared_ptr /*thread*/, - Kernel::HLERequestContext& /*ctx*/, - Kernel::ThreadWakeupReason /*reason*/) { - // Nothing to do here - }); + ctx.SleepClientThread("file::read", read_timeout_ns, nullptr); } void File::Write(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index e027e837fe..010600ee2d 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -76,12 +76,7 @@ void FS_USER::OpenFile(Kernel::HLERequestContext& ctx) { LOG_ERROR(Service_FS, "failed to get a handle for file {}", file_path.DebugStr()); } - ctx.SleepClientThread("fs_user::open", open_timeout_ns, - [](std::shared_ptr /*thread*/, - Kernel::HLERequestContext& /*ctx*/, - Kernel::ThreadWakeupReason /*reason*/) { - // Nothing to do here - }); + ctx.SleepClientThread("fs_user::open", open_timeout_ns, nullptr); } void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) { @@ -134,12 +129,7 @@ void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) { file_path.DebugStr(), mode.hex, attributes); } - ctx.SleepClientThread("fs_user::open_directly", open_timeout_ns, - [](std::shared_ptr /*thread*/, - Kernel::HLERequestContext& /*ctx*/, - Kernel::ThreadWakeupReason /*reason*/) { - // Nothing to do here - }); + ctx.SleepClientThread("fs_user::open_directly", open_timeout_ns, nullptr); } void FS_USER::DeleteFile(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index dddf55333e..eef8cbd1d3 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -1170,6 +1170,29 @@ void NWM_UDS::GetChannel(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_NWM, "called"); } +class NWM_UDS::ThreadCallback : public Kernel::HLERequestContext::WakeupCallback { +public: + ThreadCallback(u16 command_id_) : command_id(command_id_) {} + + void WakeUp(std::shared_ptr thread, Kernel::HLERequestContext& ctx, + Kernel::ThreadWakeupReason reason) { + // TODO(B3N30): Add error handling for host full and timeout + IPC::RequestBuilder rb(ctx, command_id, 1, 0); + rb.Push(RESULT_SUCCESS); + LOG_DEBUG(Service_NWM, "connection sequence finished"); + } + +private: + ThreadCallback() = default; + u16 command_id; + + template + void serialize(Archive& ar, const unsigned int) { + ar& command_id; + } + friend class boost::serialization::access; +}; + void NWM_UDS::ConnectToNetwork(Kernel::HLERequestContext& ctx, u16 command_id, const u8* network_info_buffer, std::size_t network_info_size, u8 connection_type, std::vector passphrase) { @@ -1183,15 +1206,8 @@ void NWM_UDS::ConnectToNetwork(Kernel::HLERequestContext& ctx, u16 command_id, // Since this timing is handled by core_timing it could differ from the 'real world' time static constexpr std::chrono::nanoseconds UDSConnectionTimeout{300000000}; - connection_event = ctx.SleepClientThread( - "uds::ConnectToNetwork", UDSConnectionTimeout, - [command_id](std::shared_ptr thread, Kernel::HLERequestContext& ctx, - Kernel::ThreadWakeupReason reason) { - // TODO(B3N30): Add error handling for host full and timeout - IPC::RequestBuilder rb(ctx, command_id, 1, 0); - rb.Push(RESULT_SUCCESS); - LOG_DEBUG(Service_NWM, "connection sequence finished"); - }); + connection_event = ctx.SleepClientThread("uds::ConnectToNetwork", UDSConnectionTimeout, + std::make_shared(command_id)); } void NWM_UDS::ConnectToNetwork(Kernel::HLERequestContext& ctx) { @@ -1418,3 +1434,5 @@ NWM_UDS::~NWM_UDS() { } } // namespace Service::NWM + +SERIALIZE_EXPORT_IMPL(Service::NWM::NWM_UDS::ThreadCallback) diff --git a/src/core/hle/service/nwm/nwm_uds.h b/src/core/hle/service/nwm/nwm_uds.h index 07dd7e9ba1..b2ab1d76a6 100644 --- a/src/core/hle/service/nwm/nwm_uds.h +++ b/src/core/hle/service/nwm/nwm_uds.h @@ -15,6 +15,7 @@ #include #include #include +#include #include "common/common_types.h" #include "common/swap.h" #include "core/hle/service/service.h" @@ -127,6 +128,8 @@ public: explicit NWM_UDS(Core::System& system); ~NWM_UDS(); + class ThreadCallback; + private: Core::System& system; @@ -560,3 +563,4 @@ private: SERVICE_CONSTRUCT(Service::NWM::NWM_UDS) BOOST_CLASS_EXPORT_KEY(Service::NWM::NWM_UDS) +BOOST_CLASS_EXPORT_KEY(Service::NWM::NWM_UDS::ThreadCallback) diff --git a/src/core/hle/service/sm/srv.cpp b/src/core/hle/service/sm/srv.cpp index 396bd3559e..10179f4163 100644 --- a/src/core/hle/service/sm/srv.cpp +++ b/src/core/hle/service/sm/srv.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" #include "core/core.h" @@ -71,6 +72,46 @@ void SRV::EnableNotification(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_SRV, "(STUBBED) called"); } +class SRV::ThreadCallback : public Kernel::HLERequestContext::WakeupCallback { + +public: + ThreadCallback(Core::System& system_, std::string name_) : system(system_), name(name_) {} + + void WakeUp(std::shared_ptr thread, Kernel::HLERequestContext& ctx, + Kernel::ThreadWakeupReason reason) { + LOG_ERROR(Service_SRV, "called service={} wakeup", name); + auto client_port = system.ServiceManager().GetServicePort(name); + + auto session = client_port.Unwrap()->Connect(); + if (session.Succeeded()) { + LOG_DEBUG(Service_SRV, "called service={} -> session={}", name, + (*session)->GetObjectId()); + IPC::RequestBuilder rb(ctx, 0x5, 1, 2); + rb.Push(session.Code()); + rb.PushMoveObjects(std::move(session).Unwrap()); + } else if (session.Code() == Kernel::ERR_MAX_CONNECTIONS_REACHED) { + LOG_ERROR(Service_SRV, "called service={} -> ERR_MAX_CONNECTIONS_REACHED", name); + UNREACHABLE(); + } else { + LOG_ERROR(Service_SRV, "called service={} -> error 0x{:08X}", name, session.Code().raw); + IPC::RequestBuilder rb(ctx, 0x5, 1, 0); + rb.Push(session.Code()); + } + } + +private: + Core::System& system; + std::string name; + + ThreadCallback() : system(Core::Global()) {} + + template + void serialize(Archive& ar, const unsigned int) { + ar& name; + } + friend class boost::serialization::access; +}; + /** * SRV::GetServiceHandle service function * Inputs: @@ -100,28 +141,7 @@ void SRV::GetServiceHandle(Kernel::HLERequestContext& ctx) { // TODO(yuriks): Permission checks go here - auto get_handle = [name, this](std::shared_ptr thread, - Kernel::HLERequestContext& ctx, - Kernel::ThreadWakeupReason reason) { - LOG_ERROR(Service_SRV, "called service={} wakeup", name); - auto client_port = system.ServiceManager().GetServicePort(name); - - auto session = client_port.Unwrap()->Connect(); - if (session.Succeeded()) { - LOG_DEBUG(Service_SRV, "called service={} -> session={}", name, - (*session)->GetObjectId()); - IPC::RequestBuilder rb(ctx, 0x5, 1, 2); - rb.Push(session.Code()); - rb.PushMoveObjects(std::move(session).Unwrap()); - } else if (session.Code() == Kernel::ERR_MAX_CONNECTIONS_REACHED) { - LOG_ERROR(Service_SRV, "called service={} -> ERR_MAX_CONNECTIONS_REACHED", name); - UNREACHABLE(); - } else { - LOG_ERROR(Service_SRV, "called service={} -> error 0x{:08X}", name, session.Code().raw); - IPC::RequestBuilder rb(ctx, 0x5, 1, 0); - rb.Push(session.Code()); - } - }; + auto get_handle = std::make_shared(system, name); auto client_port = system.ServiceManager().GetServicePort(name); if (client_port.Failed()) { @@ -266,3 +286,5 @@ SRV::SRV(Core::System& system) : ServiceFramework("srv:", 4), system(system) { SRV::~SRV() = default; } // namespace Service::SM + +SERIALIZE_EXPORT_IMPL(Service::SM::SRV::ThreadCallback) diff --git a/src/core/hle/service/sm/srv.h b/src/core/hle/service/sm/srv.h index 2382f48425..7d17f87a58 100644 --- a/src/core/hle/service/sm/srv.h +++ b/src/core/hle/service/sm/srv.h @@ -6,6 +6,7 @@ #include #include +#include #include "core/hle/service/service.h" namespace Core { @@ -25,6 +26,8 @@ public: explicit SRV(Core::System& system); ~SRV(); + class ThreadCallback; + private: void RegisterClient(Kernel::HLERequestContext& ctx); void EnableNotification(Kernel::HLERequestContext& ctx); @@ -40,3 +43,5 @@ private: }; } // namespace Service::SM + +BOOST_CLASS_EXPORT_KEY(Service::SM::SRV::ThreadCallback) diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index 414d64021f..a4f7c8062c 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -37,7 +37,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel IPC::MakeHeader(0x1234, 0, 0), }; - context.PopulateFromIncomingCommandBuffer(input, *process); + context.PopulateFromIncomingCommandBuffer(input, process); REQUIRE(context.CommandBuffer()[0] == 0x12340000); } @@ -50,7 +50,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel 0xAABBCCDD, }; - context.PopulateFromIncomingCommandBuffer(input, *process); + context.PopulateFromIncomingCommandBuffer(input, process); auto* output = context.CommandBuffer(); REQUIRE(output[1] == 0x12345678); @@ -67,7 +67,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel a_handle, }; - context.PopulateFromIncomingCommandBuffer(input, *process); + context.PopulateFromIncomingCommandBuffer(input, process); auto* output = context.CommandBuffer(); REQUIRE(context.GetIncomingHandle(output[2]) == a); @@ -83,7 +83,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel a_handle, }; - context.PopulateFromIncomingCommandBuffer(input, *process); + context.PopulateFromIncomingCommandBuffer(input, process); auto* output = context.CommandBuffer(); REQUIRE(context.GetIncomingHandle(output[2]) == a); @@ -103,7 +103,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel process->handle_table.Create(c).Unwrap(), }; - context.PopulateFromIncomingCommandBuffer(input, *process); + context.PopulateFromIncomingCommandBuffer(input, process); auto* output = context.CommandBuffer(); REQUIRE(context.GetIncomingHandle(output[2]) == a); @@ -118,7 +118,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel 0, }; - auto result = context.PopulateFromIncomingCommandBuffer(input, *process); + auto result = context.PopulateFromIncomingCommandBuffer(input, process); REQUIRE(result == RESULT_SUCCESS); auto* output = context.CommandBuffer(); @@ -132,7 +132,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel 0x98989898, }; - context.PopulateFromIncomingCommandBuffer(input, *process); + context.PopulateFromIncomingCommandBuffer(input, process); REQUIRE(context.CommandBuffer()[2] == process->process_id); } @@ -153,7 +153,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel target_address, }; - context.PopulateFromIncomingCommandBuffer(input, *process); + context.PopulateFromIncomingCommandBuffer(input, process); CHECK(context.GetStaticBuffer(0) == mem->Vector()); @@ -175,7 +175,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel target_address, }; - context.PopulateFromIncomingCommandBuffer(input, *process); + context.PopulateFromIncomingCommandBuffer(input, process); std::vector other_buffer(buffer.GetSize()); context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer.GetSize()); @@ -219,7 +219,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel target_address_mapped, }; - context.PopulateFromIncomingCommandBuffer(input, *process); + context.PopulateFromIncomingCommandBuffer(input, process); auto* output = context.CommandBuffer(); CHECK(output[1] == 0x12345678); @@ -365,7 +365,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { target_address, }; - context.PopulateFromIncomingCommandBuffer(input_cmdbuff, *process); + context.PopulateFromIncomingCommandBuffer(input_cmdbuff, process); context.GetMappedBuffer(0).Write(input_buffer.data(), 0, input_buffer.size()); From f2de70c3fbdef9ac16bcbc5c6773c97311bd663b Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 6 Jan 2020 23:20:18 +0000 Subject: [PATCH 062/129] Fix crash bugs --- CMakeLists.txt | 2 +- TODO | 14 +++++++------- save0.citrasave | Bin 0 -> 776 bytes src/common/archives.h | 3 +-- src/core/core.cpp | 20 ++++++++++++++------ src/core/hle/kernel/hle_ipc.h | 2 +- src/core/hle/kernel/server_session.cpp | 9 +++++---- src/core/memory.cpp | 3 +++ 8 files changed, 32 insertions(+), 21 deletions(-) create mode 100644 save0.citrasave diff --git a/CMakeLists.txt b/CMakeLists.txt index f986a39af2..45deee61a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,7 +123,7 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # set up output paths for executable binaries -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}) # System imported libraries diff --git a/TODO b/TODO index 097c310a79..a422fda4d9 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,11 @@ ☐ Save/load UI ✔ Basic version @done(20-01-03 15:27) ☐ Multiple slots etc. +☐ Custom texture cache +☐ Review constructor/initialization code +☐ Review core timing events +☐ Review base class serialization everywhere +☐ Serialize codeset with an apploader reference instead ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) ✔ Page tables @done(20-01-05 16:33) @@ -32,7 +37,6 @@ Not needed as nothing serializes file buffers ✘ Replace delay generator with virtual fns @cancelled(20-01-03 13:16) While they have no state, the extra refactoring here is unneeded -☐ Custom texture cache ✘ MMIO @cancelled(20-01-01 01:06) Seems that this whole subsystem is only used in tests ✘ Movie @cancelled(20-01-01 01:07) @@ -44,9 +48,6 @@ ✘ Telemetry session @cancelled(20-01-01 01:12) Doesn't need to be serialized here ✔ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE @started(20-01-03 13:47) @done(20-01-03 13:58) @lasted(11m22s) -☐ Review constructor/initialization code -☐ Review core timing events -☐ Review base class serialization everywhere ✔ Fix CI @done(19-12-31 21:32) ✔ HW @done(19-08-13 15:41) ✔ GPU regs @done(19-08-13 15:41) @@ -57,8 +58,8 @@ ✔ PICA state @done(19-08-13 15:41) ✔ Primitive assembly @done(19-12-22 16:05) ✔ Shader @done(19-08-13 16:03) -☐ HLE @started(19-08-13 16:43) - ☐ Kernel @started(19-08-13 16:43) +✔ HLE @started(19-08-13 16:43) @done(20-01-06 20:37) @lasted(20w6d4h54m19s) + ✔ Kernel @started(19-08-13 16:43) @done(20-01-06 20:37) @lasted(20w6d4h54m17s) Most of these require adding Core::Global ✔ Address arbiter @done(19-08-13 16:40) ✔ Client port @done(19-08-13 16:40) @@ -74,7 +75,6 @@ ✔ Process @started(19-08-13 16:43) @done(19-12-22 18:41) ✔ Code set @started(19-12-22 18:41) @done(20-01-03 15:15) @lasted(1w4d20h34m2s) Needs a way to reference loaded images (so we don't serialize the entire ROM as well) - ☐ Serialize codeset with an apploader reference instead ✔ Resource limit @done(19-08-13 16:43) ✔ Semaphore @done(19-08-13 16:44) ✔ Server port @done(19-08-13 16:44) diff --git a/save0.citrasave b/save0.citrasave new file mode 100644 index 0000000000000000000000000000000000000000..578174ec6b7489150da4ff634caacf0e34d2ddd8 GIT binary patch literal 776 zcmWe*fPmuEqRhmc%&Nqa%=|nntHh$@jLfoBK?W8U77j+J8VJP9?L0*8h?10RqH1|V?|A17eUl4nX1q zlntb43brUPIsz>Kd4++2my6*Yh!z9_5UsL-A0!C@U@rjWfQ|zq29QTVfSFN%k%^f} zfI&eCB+MWP^p>C^gOH$rlAxiY0HY&Nw8DXvfgdC}gusXY|Nn!WyQGVg;ep2k7Zj)K z{eZ+8iXbT*ADCiTFv9qtbN~VcxmJk<1>lfo1CtP8ILQfOfdU*DXW(!L6CgooJb{=H X09FNMLyV0NPAw`+ErKZk({Muob(AbM literal 0 HcmV?d00001 diff --git a/src/common/archives.h b/src/common/archives.h index 29f23865bb..6000bef2c7 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -11,5 +11,4 @@ using oarchive = boost::archive::binary_oarchive; #define SERIALIZE_EXPORT_IMPL(A) \ BOOST_SERIALIZATION_REGISTER_ARCHIVE(iarchive) \ - BOOST_SERIALIZATION_REGISTER_ARCHIVE(oarchive) \ - BOOST_CLASS_EXPORT_IMPLEMENT(A) + BOOST_SERIALIZATION_REGISTER_ARCHIVE(oarchive) diff --git a/src/core/core.cpp b/src/core/core.cpp index bada80b55e..20a8f32fec 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -44,6 +44,8 @@ #include "network/network.h" #include "video_core/video_core.h" +#include "core/hle/service/pm/pm_app.h" + namespace Core { /*static*/ System System::s_instance; @@ -214,8 +216,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo timing = std::make_unique(); - kernel = std::make_unique(*memory, *timing, - [this] { PrepareReschedule(); }, system_mode); + kernel = std::make_unique( + *memory, *timing, [this] { PrepareReschedule(); }, system_mode); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 @@ -420,11 +422,17 @@ void System::serialize(Archive& ar, const unsigned int file_version) { } void System::Save(std::ostream& stream) const { - { - oarchive oa{stream}; - oa&* this; + try { + + { + oarchive oa{stream}; + oa&* this; + } + VideoCore::Save(stream); + + } catch (const std::exception& e) { + LOG_ERROR(Core, "Error saving: {}", e.what()); } - VideoCore::Save(stream); } void System::Load(std::istream& stream) { diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 56c6d8ce1c..01fec190bc 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -198,7 +198,7 @@ private: * id of the memory interface and let kernel convert it back to client vaddr. No real unmapping is * needed in this case, though. */ -class HLERequestContext : std::enable_shared_from_this { +class HLERequestContext : public std::enable_shared_from_this { public: HLERequestContext(KernelSystem& kernel, std::shared_ptr session, std::shared_ptr thread); diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 8bb82fc839..3dc20e9a73 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -75,10 +75,11 @@ ResultCode ServerSession::HandleSyncRequest(std::shared_ptr thread) { kernel.memory.ReadBlock(*current_process, thread->GetCommandBufferAddress(), cmd_buf.data(), cmd_buf.size() * sizeof(u32)); - Kernel::HLERequestContext context(kernel, SharedFrom(this), thread); - context.PopulateFromIncomingCommandBuffer(cmd_buf.data(), current_process); + auto context = + std::make_shared(kernel, SharedFrom(this), thread); + context->PopulateFromIncomingCommandBuffer(cmd_buf.data(), current_process); - hle_handler->HandleSyncRequest(context); + hle_handler->HandleSyncRequest(*context); ASSERT(thread->status == Kernel::ThreadStatus::Running || thread->status == Kernel::ThreadStatus::WaitHleEvent); @@ -86,7 +87,7 @@ ResultCode ServerSession::HandleSyncRequest(std::shared_ptr thread) { // put the thread to sleep then the writing of the command buffer will be deferred to the // wakeup callback. if (thread->status == Kernel::ThreadStatus::Running) { - context.WriteToOutgoingCommandBuffer(cmd_buf.data(), *current_process); + context->WriteToOutgoingCommandBuffer(cmd_buf.data(), *current_process); kernel.memory.WriteBlock(*current_process, thread->GetCommandBufferAddress(), cmd_buf.data(), cmd_buf.size() * sizeof(u32)); } diff --git a/src/core/memory.cpp b/src/core/memory.cpp index ceb6aad4e1..cd3cf8aed1 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -452,6 +452,9 @@ MemoryRef MemorySystem::GetPhysicalRef(PAddr address) { default: UNREACHABLE(); } + if (offset_into_region >= target_mem->GetSize()) { + return {nullptr}; + } return {target_mem, offset_into_region}; } From 996aba39feda48356cddc61af1242cff7b5551e4 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 8 Jan 2020 22:13:56 +0000 Subject: [PATCH 063/129] Correct exports; add some file serialization; fix service base object serialization --- TODO | 1 + src/common/archives.h | 1 + src/common/file_util.cpp | 8 ++++++ src/common/file_util.h | 29 ++++++++++++++++++++- src/common/memory_ref.h | 6 +++++ src/core/file_sys/archive_extsavedata.cpp | 4 +++ src/core/file_sys/archive_extsavedata.h | 3 +++ src/core/file_sys/archive_sdmc.cpp | 4 +++ src/core/file_sys/archive_sdmc.h | 3 +++ src/core/file_sys/archive_sdmcwriteonly.cpp | 4 +++ src/core/file_sys/archive_sdmcwriteonly.h | 3 +++ src/core/file_sys/delay_generator.h | 12 ++++++++- src/core/file_sys/disk_archive.h | 9 +++++++ src/core/file_sys/file_backend.h | 8 ++++++ src/core/file_sys/savedata_archive.cpp | 5 ++++ src/core/file_sys/savedata_archive.h | 4 +++ src/core/hle/service/cam/cam_q.h | 6 +---- src/core/hle/service/cfg/cfg_nor.h | 3 +++ src/core/hle/service/dlp/dlp_clnt.h | 6 +---- src/core/hle/service/dlp/dlp_fkcl.h | 6 +---- src/core/hle/service/dlp/dlp_srvr.h | 6 +---- src/core/hle/service/err_f.h | 6 +---- src/core/hle/service/fs/file.h | 11 ++++++++ src/core/hle/service/fs/fs_user.h | 2 ++ src/core/hle/service/gsp/gsp_gpu.h | 2 ++ src/core/hle/service/http_c.h | 2 ++ src/core/hle/service/ldr_ro/ldr_ro.h | 2 ++ src/core/hle/service/mic_u.cpp | 1 + src/core/hle/service/mvd/mvd_std.h | 6 +---- src/core/hle/service/news/news_s.h | 2 ++ src/core/hle/service/news/news_u.h | 3 +++ src/core/hle/service/nim/nim_aoc.h | 3 +++ src/core/hle/service/nim/nim_s.h | 3 +++ src/core/hle/service/nwm/nwm_cec.h | 3 +++ src/core/hle/service/nwm/nwm_ext.h | 3 +++ src/core/hle/service/nwm/nwm_inf.h | 3 +++ src/core/hle/service/nwm/nwm_sap.h | 3 +++ src/core/hle/service/nwm/nwm_soc.h | 3 +++ src/core/hle/service/nwm/nwm_tst.h | 3 +++ src/core/hle/service/nwm/nwm_uds.cpp | 1 + src/core/hle/service/pm/pm_app.h | 3 +++ src/core/hle/service/pm/pm_dbg.h | 3 +++ src/core/hle/service/ps/ps_ps.h | 2 ++ src/core/hle/service/pxi/dev.h | 3 +++ src/core/hle/service/qtm/qtm_c.h | 3 +++ src/core/hle/service/qtm/qtm_s.h | 3 +++ src/core/hle/service/qtm/qtm_sp.h | 3 +++ src/core/hle/service/qtm/qtm_u.h | 3 +++ src/core/hle/service/service.h | 7 +++++ src/core/hle/service/ssl_c.h | 2 ++ src/core/hle/service/y2r_u.cpp | 1 + src/core/memory.cpp | 4 ++- 52 files changed, 197 insertions(+), 33 deletions(-) diff --git a/TODO b/TODO index a422fda4d9..def70ac2bd 100644 --- a/TODO +++ b/TODO @@ -5,6 +5,7 @@ ☐ Review constructor/initialization code ☐ Review core timing events ☐ Review base class serialization everywhere + Make sure that all base/derived relationships are registered ☐ Serialize codeset with an apploader reference instead ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) diff --git a/src/common/archives.h b/src/common/archives.h index 6000bef2c7..eef292634b 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -10,5 +10,6 @@ using oarchive = boost::archive::binary_oarchive; template void A::serialize(oarchive & ar, const unsigned int file_version); #define SERIALIZE_EXPORT_IMPL(A) \ + BOOST_CLASS_EXPORT_IMPLEMENT(A) \ BOOST_SERIALIZATION_REGISTER_ARCHIVE(iarchive) \ BOOST_SERIALIZATION_REGISTER_ARCHIVE(oarchive) diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index d59e34daec..ca86f7bfca 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -901,10 +901,18 @@ IOFile& IOFile::operator=(IOFile&& other) { void IOFile::Swap(IOFile& other) { std::swap(m_file, other.m_file); std::swap(m_good, other.m_good); + std::swap(filename, other.filename); + std::swap(openmode, other.openmode); + std::swap(flags, other.flags); } bool IOFile::Open(const std::string& filename, const char openmode[], int flags) { Close(); + + this->filename = filename; + this->openmode = openmode; + this->flags = flags; + #ifdef _WIN32 if (flags != 0) { m_file = _wfsopen(Common::UTF8ToUTF16W(filename).c_str(), diff --git a/src/common/file_util.h b/src/common/file_util.h index 09c3cb6f05..c09aa88d61 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include "common/common_types.h" #ifdef _MSC_VER #include "common/string_util.h" @@ -221,7 +223,6 @@ public: void Swap(IOFile& other); - bool Open(const std::string& filename, const char openmode[], int flags = 0); bool Close(); template @@ -305,8 +306,34 @@ public: } private: + bool Open(const std::string& filename, const char openmode[], int flags = 0); + std::FILE* m_file = nullptr; bool m_good = true; + + std::string filename; + std::string openmode; + u32 flags; + + template + void save(Archive& ar, const unsigned int) const { + ar << filename; + ar << openmode; + ar << flags; + ar << Tell(); + } + + template + void load(Archive& ar, const unsigned int) { + ar >> filename; + ar >> openmode; + ar >> flags; + u64 pos; + ar >> pos; + Seek(pos, SEEK_SET); + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() }; } // namespace FileUtil diff --git a/src/common/memory_ref.h b/src/common/memory_ref.h index 05b1c7901f..ae30b009cd 100644 --- a/src/common/memory_ref.h +++ b/src/common/memory_ref.h @@ -14,6 +14,11 @@ public: virtual ~BackingMem() = default; virtual u8* GetPtr() = 0; virtual u32 GetSize() const = 0; + +private: + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; /// Backing memory implemented by a local buffer @@ -39,6 +44,7 @@ private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& data; } friend class boost::serialization::access; diff --git a/src/core/file_sys/archive_extsavedata.cpp b/src/core/file_sys/archive_extsavedata.cpp index 22084b690c..59973b8c58 100644 --- a/src/core/file_sys/archive_extsavedata.cpp +++ b/src/core/file_sys/archive_extsavedata.cpp @@ -80,6 +80,8 @@ public: static constexpr u64 IPCDelayNanoseconds(3085068); return IPCDelayNanoseconds; } + + SERIALIZE_DELAY_GENERATOR }; /** @@ -300,3 +302,5 @@ void ArchiveFactory_ExtSaveData::WriteIcon(const Path& path, const u8* icon_data } } // namespace FileSys + +SERIALIZE_EXPORT_IMPL(FileSys::ExtSaveDataDelayGenerator) diff --git a/src/core/file_sys/archive_extsavedata.h b/src/core/file_sys/archive_extsavedata.h index b00e1633d6..c9b84c984c 100644 --- a/src/core/file_sys/archive_extsavedata.h +++ b/src/core/file_sys/archive_extsavedata.h @@ -103,6 +103,9 @@ std::string GetExtDataContainerPath(const std::string& mount_point, bool shared) */ Path ConstructExtDataBinaryPath(u32 media_type, u32 high, u32 low); +class ExtSaveDataDelayGenerator; + } // namespace FileSys BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_ExtSaveData) +BOOST_CLASS_EXPORT_KEY(FileSys::ExtSaveDataDelayGenerator) diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp index 1c51183202..4c3ce6d69a 100644 --- a/src/core/file_sys/archive_sdmc.cpp +++ b/src/core/file_sys/archive_sdmc.cpp @@ -41,6 +41,8 @@ public: static constexpr u64 IPCDelayNanoseconds(269082); return IPCDelayNanoseconds; } + + SERIALIZE_DELAY_GENERATOR }; ResultVal> SDMCArchive::OpenFile(const Path& path, @@ -409,3 +411,5 @@ ResultVal ArchiveFactory_SDMC::GetFormatInfo(const Path& path return ResultCode(-1); } } // namespace FileSys + +SERIALIZE_EXPORT_IMPL(FileSys::SDMCDelayGenerator) diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index 2e0abf44b2..6051abef03 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h @@ -86,7 +86,10 @@ private: friend class boost::serialization::access; }; +class SDMCDelayGenerator; + } // namespace FileSys BOOST_CLASS_EXPORT_KEY(FileSys::SDMCArchive) BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SDMC) +BOOST_CLASS_EXPORT_KEY(FileSys::SDMCDelayGenerator) diff --git a/src/core/file_sys/archive_sdmcwriteonly.cpp b/src/core/file_sys/archive_sdmcwriteonly.cpp index ea64dc8645..241e93f0a9 100644 --- a/src/core/file_sys/archive_sdmcwriteonly.cpp +++ b/src/core/file_sys/archive_sdmcwriteonly.cpp @@ -39,6 +39,8 @@ public: static constexpr u64 IPCDelayNanoseconds(269082); return IPCDelayNanoseconds; } + + SERIALIZE_DELAY_GENERATOR }; ResultVal> SDMCWriteOnlyArchive::OpenFile(const Path& path, @@ -100,3 +102,5 @@ ResultVal ArchiveFactory_SDMCWriteOnly::GetFormatInfo(const P } } // namespace FileSys + +SERIALIZE_EXPORT_IMPL(FileSys::SDMCWriteOnlyDelayGenerator) diff --git a/src/core/file_sys/archive_sdmcwriteonly.h b/src/core/file_sys/archive_sdmcwriteonly.h index 2ba504aa70..19982a9dbf 100644 --- a/src/core/file_sys/archive_sdmcwriteonly.h +++ b/src/core/file_sys/archive_sdmcwriteonly.h @@ -72,7 +72,10 @@ private: friend class boost::serialization::access; }; +class SDMCWriteOnlyDelayGenerator; + } // namespace FileSys BOOST_CLASS_EXPORT_KEY(FileSys::SDMCWriteOnlyArchive) BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SDMCWriteOnly) +BOOST_CLASS_EXPORT_KEY(FileSys::SDMCWriteOnlyDelayGenerator) diff --git a/src/core/file_sys/delay_generator.h b/src/core/file_sys/delay_generator.h index 8fa92ac419..6513a730ef 100644 --- a/src/core/file_sys/delay_generator.h +++ b/src/core/file_sys/delay_generator.h @@ -5,10 +5,18 @@ #pragma once #include -#include +#include #include #include "common/common_types.h" +#define SERIALIZE_DELAY_GENERATOR \ +private: \ + template \ + void serialize(Archive& ar, const unsigned int) { \ + ar& boost::serialization::base_object(*this); \ + } \ + friend class boost::serialization::access; + namespace FileSys { class DelayGenerator { @@ -28,6 +36,8 @@ class DefaultDelayGenerator : public DelayGenerator { public: u64 GetReadDelayNs(std::size_t length) override; u64 GetOpenDelayNs() override; + + SERIALIZE_DELAY_GENERATOR }; } // namespace FileSys diff --git a/src/core/file_sys/disk_archive.h b/src/core/file_sys/disk_archive.h index 481aa470a9..9251749ce9 100644 --- a/src/core/file_sys/disk_archive.h +++ b/src/core/file_sys/disk_archive.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include "common/common_types.h" #include "common/file_util.h" #include "core/file_sys/archive_backend.h" @@ -43,6 +45,13 @@ public: protected: Mode mode; std::unique_ptr file; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& mode; + ar& file; + } }; class DiskDirectory : public DirectoryBackend { diff --git a/src/core/file_sys/file_backend.h b/src/core/file_sys/file_backend.h index c865c98e8f..04f03a77d5 100644 --- a/src/core/file_sys/file_backend.h +++ b/src/core/file_sys/file_backend.h @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "common/common_types.h" #include "core/hle/result.h" #include "delay_generator.h" @@ -90,6 +92,12 @@ public: protected: std::unique_ptr delay_generator; + + template + void serialize(Archive& ar, const unsigned int) { + ar& delay_generator; + } + friend class boost::serialization::access; }; } // namespace FileSys diff --git a/src/core/file_sys/savedata_archive.cpp b/src/core/file_sys/savedata_archive.cpp index 8d7830468d..1f22b50ab5 100644 --- a/src/core/file_sys/savedata_archive.cpp +++ b/src/core/file_sys/savedata_archive.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "common/file_util.h" #include "core/file_sys/disk_archive.h" #include "core/file_sys/errors.h" @@ -33,6 +34,8 @@ public: static constexpr u64 IPCDelayNanoseconds(269082); return IPCDelayNanoseconds; } + + SERIALIZE_DELAY_GENERATOR }; ResultVal> SaveDataArchive::OpenFile(const Path& path, @@ -353,3 +356,5 @@ u64 SaveDataArchive::GetFreeBytes() const { } } // namespace FileSys + +SERIALIZE_EXPORT_IMPL(FileSys::SaveDataDelayGenerator) diff --git a/src/core/file_sys/savedata_archive.h b/src/core/file_sys/savedata_archive.h index 176d357106..47f2f75e05 100644 --- a/src/core/file_sys/savedata_archive.h +++ b/src/core/file_sys/savedata_archive.h @@ -40,4 +40,8 @@ protected: std::string mount_point; }; +class SaveDataDelayGenerator; + } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::SaveDataDelayGenerator) diff --git a/src/core/hle/service/cam/cam_q.h b/src/core/hle/service/cam/cam_q.h index ab901cf85c..992b383905 100644 --- a/src/core/hle/service/cam/cam_q.h +++ b/src/core/hle/service/cam/cam_q.h @@ -13,11 +13,7 @@ public: CAM_Q(); private: - template - void serialize(Archive& ar, const unsigned int) { - ar& boost::serialization::base_object(*this); - } - friend class boost::serialization::access; + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::CAM diff --git a/src/core/hle/service/cfg/cfg_nor.h b/src/core/hle/service/cfg/cfg_nor.h index 1eca85a050..7e0a1a2b82 100644 --- a/src/core/hle/service/cfg/cfg_nor.h +++ b/src/core/hle/service/cfg/cfg_nor.h @@ -11,6 +11,9 @@ namespace Service::CFG { class CFG_NOR final : public ServiceFramework { public: CFG_NOR(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::CFG diff --git a/src/core/hle/service/dlp/dlp_clnt.h b/src/core/hle/service/dlp/dlp_clnt.h index 835d017482..ac6933e7ea 100644 --- a/src/core/hle/service/dlp/dlp_clnt.h +++ b/src/core/hle/service/dlp/dlp_clnt.h @@ -14,11 +14,7 @@ public: ~DLP_CLNT() = default; private: - template - void serialize(Archive& ar, const unsigned int) { - ar& boost::serialization::base_object(*this); - } - friend class boost::serialization::access; + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::DLP diff --git a/src/core/hle/service/dlp/dlp_fkcl.h b/src/core/hle/service/dlp/dlp_fkcl.h index d778ace8b6..c05a77b495 100644 --- a/src/core/hle/service/dlp/dlp_fkcl.h +++ b/src/core/hle/service/dlp/dlp_fkcl.h @@ -14,11 +14,7 @@ public: ~DLP_FKCL() = default; private: - template - void serialize(Archive& ar, const unsigned int) { - ar& boost::serialization::base_object(*this); - } - friend class boost::serialization::access; + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::DLP diff --git a/src/core/hle/service/dlp/dlp_srvr.h b/src/core/hle/service/dlp/dlp_srvr.h index 1f171f9506..625740d2f2 100644 --- a/src/core/hle/service/dlp/dlp_srvr.h +++ b/src/core/hle/service/dlp/dlp_srvr.h @@ -16,11 +16,7 @@ public: private: void IsChild(Kernel::HLERequestContext& ctx); - template - void serialize(Archive& ar, const unsigned int) { - ar& boost::serialization::base_object(*this); - } - friend class boost::serialization::access; + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::DLP diff --git a/src/core/hle/service/err_f.h b/src/core/hle/service/err_f.h index de92fed050..1b9fad4526 100644 --- a/src/core/hle/service/err_f.h +++ b/src/core/hle/service/err_f.h @@ -35,11 +35,7 @@ private: Core::System& system; - template - void serialize(Archive& ar, const unsigned int) { - ar& boost::serialization::base_object(*this); - } - friend class boost::serialization::access; + SERVICE_SERIALIZATION_SIMPLE }; void InstallInterfaces(Core::System& system); diff --git a/src/core/hle/service/fs/file.h b/src/core/hle/service/fs/file.h index ff4a5670a3..18317212e2 100644 --- a/src/core/hle/service/fs/file.h +++ b/src/core/hle/service/fs/file.h @@ -19,6 +19,17 @@ struct FileSessionSlot : public Kernel::SessionRequestHandler::SessionDataBase { u64 offset; ///< Offset that this session will start reading from. u64 size; ///< Max size of the file that this session is allowed to access bool subfile; ///< Whether this file was opened via OpenSubFile or not. + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object( + *this); + ar& priority; + ar& offset; + ar& size; + ar& subfile; + } }; // TODO: File is not a real service, but it can still utilize ServiceFramework::RegisterHandlers. diff --git a/src/core/hle/service/fs/fs_user.h b/src/core/hle/service/fs/fs_user.h index 29b47a99c1..83183ecf66 100644 --- a/src/core/hle/service/fs/fs_user.h +++ b/src/core/hle/service/fs/fs_user.h @@ -26,6 +26,8 @@ struct ClientSlot : public Kernel::SessionRequestHandler::SessionDataBase { private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object( + *this); ar& program_id; } friend class boost::serialization::access; diff --git a/src/core/hle/service/gsp/gsp_gpu.h b/src/core/hle/service/gsp/gsp_gpu.h index 6194f0446f..a97aee278d 100644 --- a/src/core/hle/service/gsp/gsp_gpu.h +++ b/src/core/hle/service/gsp/gsp_gpu.h @@ -203,6 +203,8 @@ public: private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object( + *this); ar& gsp; ar& interrupt_event; ar& thread_id; diff --git a/src/core/hle/service/http_c.h b/src/core/hle/service/http_c.h index a3aa62ae0a..641b6b4d1c 100644 --- a/src/core/hle/service/http_c.h +++ b/src/core/hle/service/http_c.h @@ -240,6 +240,8 @@ struct SessionData : public Kernel::SessionRequestHandler::SessionDataBase { private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object( + *this); ar& current_http_context; ar& session_id; ar& num_http_contexts; diff --git a/src/core/hle/service/ldr_ro/ldr_ro.h b/src/core/hle/service/ldr_ro/ldr_ro.h index 2b6f79f032..7581884f61 100644 --- a/src/core/hle/service/ldr_ro/ldr_ro.h +++ b/src/core/hle/service/ldr_ro/ldr_ro.h @@ -18,6 +18,8 @@ struct ClientSlot : public Kernel::SessionRequestHandler::SessionDataBase { private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object( + *this); ar& loaded_crs; } friend class boost::serialization::access; diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index 34b16094a7..478bf110fb 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp @@ -25,6 +25,7 @@ namespace Service::MIC { template void MIC_U::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar&* impl.get(); } SERIALIZE_IMPL(MIC_U) diff --git a/src/core/hle/service/mvd/mvd_std.h b/src/core/hle/service/mvd/mvd_std.h index 6e8312e592..fed41e6f04 100644 --- a/src/core/hle/service/mvd/mvd_std.h +++ b/src/core/hle/service/mvd/mvd_std.h @@ -14,11 +14,7 @@ public: ~MVD_STD() = default; private: - template - void serialize(Archive& ar, const unsigned int) { - ar& boost::serialization::base_object(*this); - } - friend class boost::serialization::access; + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::MVD diff --git a/src/core/hle/service/news/news_s.h b/src/core/hle/service/news/news_s.h index 711a0e99bf..9d1ce829f7 100644 --- a/src/core/hle/service/news/news_s.h +++ b/src/core/hle/service/news/news_s.h @@ -24,6 +24,8 @@ private: * 2 : Number of notifications */ void GetTotalNotifications(Kernel::HLERequestContext& ctx); + + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NEWS diff --git a/src/core/hle/service/news/news_u.h b/src/core/hle/service/news/news_u.h index 472dd579c8..8e672256d4 100644 --- a/src/core/hle/service/news/news_u.h +++ b/src/core/hle/service/news/news_u.h @@ -12,6 +12,9 @@ namespace Service::NEWS { class NEWS_U final : public ServiceFramework { public: NEWS_U(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NEWS diff --git a/src/core/hle/service/nim/nim_aoc.h b/src/core/hle/service/nim/nim_aoc.h index 2d06a9d1ce..003b3fd856 100644 --- a/src/core/hle/service/nim/nim_aoc.h +++ b/src/core/hle/service/nim/nim_aoc.h @@ -12,6 +12,9 @@ class NIM_AOC final : public ServiceFramework { public: NIM_AOC(); ~NIM_AOC(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NIM diff --git a/src/core/hle/service/nim/nim_s.h b/src/core/hle/service/nim/nim_s.h index 6281270f5b..10b041456a 100644 --- a/src/core/hle/service/nim/nim_s.h +++ b/src/core/hle/service/nim/nim_s.h @@ -12,6 +12,9 @@ class NIM_S final : public ServiceFramework { public: NIM_S(); ~NIM_S(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NIM diff --git a/src/core/hle/service/nwm/nwm_cec.h b/src/core/hle/service/nwm/nwm_cec.h index 4f62f32f13..674c98caec 100644 --- a/src/core/hle/service/nwm/nwm_cec.h +++ b/src/core/hle/service/nwm/nwm_cec.h @@ -11,6 +11,9 @@ namespace Service::NWM { class NWM_CEC final : public ServiceFramework { public: NWM_CEC(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NWM diff --git a/src/core/hle/service/nwm/nwm_ext.h b/src/core/hle/service/nwm/nwm_ext.h index a8d43df70d..1e8bcfde3c 100644 --- a/src/core/hle/service/nwm/nwm_ext.h +++ b/src/core/hle/service/nwm/nwm_ext.h @@ -11,6 +11,9 @@ namespace Service::NWM { class NWM_EXT final : public ServiceFramework { public: NWM_EXT(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NWM diff --git a/src/core/hle/service/nwm/nwm_inf.h b/src/core/hle/service/nwm/nwm_inf.h index f13fd41581..9f8c65a2b0 100644 --- a/src/core/hle/service/nwm/nwm_inf.h +++ b/src/core/hle/service/nwm/nwm_inf.h @@ -11,6 +11,9 @@ namespace Service::NWM { class NWM_INF final : public ServiceFramework { public: NWM_INF(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NWM diff --git a/src/core/hle/service/nwm/nwm_sap.h b/src/core/hle/service/nwm/nwm_sap.h index 1a289542cc..0422dc658f 100644 --- a/src/core/hle/service/nwm/nwm_sap.h +++ b/src/core/hle/service/nwm/nwm_sap.h @@ -11,6 +11,9 @@ namespace Service::NWM { class NWM_SAP final : public ServiceFramework { public: NWM_SAP(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NWM diff --git a/src/core/hle/service/nwm/nwm_soc.h b/src/core/hle/service/nwm/nwm_soc.h index 883a20854d..f13490e835 100644 --- a/src/core/hle/service/nwm/nwm_soc.h +++ b/src/core/hle/service/nwm/nwm_soc.h @@ -11,6 +11,9 @@ namespace Service::NWM { class NWM_SOC final : public ServiceFramework { public: NWM_SOC(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NWM diff --git a/src/core/hle/service/nwm/nwm_tst.h b/src/core/hle/service/nwm/nwm_tst.h index e58fa33714..576d4d1244 100644 --- a/src/core/hle/service/nwm/nwm_tst.h +++ b/src/core/hle/service/nwm/nwm_tst.h @@ -11,6 +11,9 @@ namespace Service::NWM { class NWM_TST final : public ServiceFramework { public: NWM_TST(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NWM diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index eef8cbd1d3..2aa64f7fce 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -28,6 +28,7 @@ namespace Service::NWM { template void NWM_UDS::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& node_map; ar& connection_event; ar& received_beacons; diff --git a/src/core/hle/service/pm/pm_app.h b/src/core/hle/service/pm/pm_app.h index 0fb290abae..9aefb0cee1 100644 --- a/src/core/hle/service/pm/pm_app.h +++ b/src/core/hle/service/pm/pm_app.h @@ -12,6 +12,9 @@ class PM_APP final : public ServiceFramework { public: PM_APP(); ~PM_APP() = default; + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::PM diff --git a/src/core/hle/service/pm/pm_dbg.h b/src/core/hle/service/pm/pm_dbg.h index 1cfdea6fe2..3a6e3c5c74 100644 --- a/src/core/hle/service/pm/pm_dbg.h +++ b/src/core/hle/service/pm/pm_dbg.h @@ -12,6 +12,9 @@ class PM_DBG final : public ServiceFramework { public: PM_DBG(); ~PM_DBG() = default; + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::PM diff --git a/src/core/hle/service/ps/ps_ps.h b/src/core/hle/service/ps/ps_ps.h index 39f6d62b28..f5005d4441 100644 --- a/src/core/hle/service/ps/ps_ps.h +++ b/src/core/hle/service/ps/ps_ps.h @@ -18,6 +18,8 @@ public: ~PS_PS() = default; private: + SERVICE_SERIALIZATION_SIMPLE + /** * PS_PS::SignRsaSha256 service function * Inputs: diff --git a/src/core/hle/service/pxi/dev.h b/src/core/hle/service/pxi/dev.h index ed17435b6e..f16491077b 100644 --- a/src/core/hle/service/pxi/dev.h +++ b/src/core/hle/service/pxi/dev.h @@ -13,6 +13,9 @@ class DEV final : public ServiceFramework { public: DEV(); ~DEV(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::PXI diff --git a/src/core/hle/service/qtm/qtm_c.h b/src/core/hle/service/qtm/qtm_c.h index 8ad05b6e18..b601cd9de1 100644 --- a/src/core/hle/service/qtm/qtm_c.h +++ b/src/core/hle/service/qtm/qtm_c.h @@ -12,6 +12,9 @@ class QTM_C final : public ServiceFramework { public: QTM_C(); ~QTM_C() = default; + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::QTM diff --git a/src/core/hle/service/qtm/qtm_s.h b/src/core/hle/service/qtm/qtm_s.h index 51e1a4bc85..b32a497dbd 100644 --- a/src/core/hle/service/qtm/qtm_s.h +++ b/src/core/hle/service/qtm/qtm_s.h @@ -12,6 +12,9 @@ class QTM_S final : public ServiceFramework { public: QTM_S(); ~QTM_S() = default; + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::QTM diff --git a/src/core/hle/service/qtm/qtm_sp.h b/src/core/hle/service/qtm/qtm_sp.h index 3c16dea37c..2f290f1922 100644 --- a/src/core/hle/service/qtm/qtm_sp.h +++ b/src/core/hle/service/qtm/qtm_sp.h @@ -12,6 +12,9 @@ class QTM_SP final : public ServiceFramework { public: QTM_SP(); ~QTM_SP() = default; + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::QTM diff --git a/src/core/hle/service/qtm/qtm_u.h b/src/core/hle/service/qtm/qtm_u.h index f6b54c8af5..d1aee1e971 100644 --- a/src/core/hle/service/qtm/qtm_u.h +++ b/src/core/hle/service/qtm/qtm_u.h @@ -12,6 +12,9 @@ class QTM_U final : public ServiceFramework { public: QTM_U(); ~QTM_U() = default; + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::QTM diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index d39e72aca4..0261d061ff 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -219,6 +219,13 @@ extern const std::array service_module_map; friend class boost::serialization::access; \ friend class ::construct_access; +#define SERVICE_SERIALIZATION_SIMPLE \ + template \ + void serialize(Archive& ar, const unsigned int) { \ + ar& boost::serialization::base_object(*this); \ + } \ + friend class boost::serialization::access; + #define SERVICE_CONSTRUCT(T) \ namespace boost::serialization { \ template \ diff --git a/src/core/hle/service/ssl_c.h b/src/core/hle/service/ssl_c.h index 3984f7ecc9..30b87378a0 100644 --- a/src/core/hle/service/ssl_c.h +++ b/src/core/hle/service/ssl_c.h @@ -23,6 +23,8 @@ private: // TODO: Implement a proper CSPRNG in the future when actual security is needed std::mt19937 rand_gen; + + SERVICE_SERIALIZATION_SIMPLE }; void InstallInterfaces(Core::System& system); diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index 0c981b545e..45e7da13d1 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp @@ -20,6 +20,7 @@ namespace Service::Y2R { template void Y2R_U::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& completion_event; ar& conversion; ar& dithering_weight_params; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index cd3cf8aed1..4c083d8c0f 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -170,7 +170,9 @@ private: MemorySystem::Impl& impl; template - void serialize(Archive& ar, const unsigned int) {} + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + } friend class boost::serialization::access; }; From 9525d81344151d2116665a42a7e06ba98cb8db5d Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 8 Jan 2020 23:19:49 +0000 Subject: [PATCH 064/129] More base-derived fixes --- TODO | 5 +++++ src/core/file_sys/archive_extsavedata.h | 1 + src/core/file_sys/archive_ncch.h | 4 +++- src/core/file_sys/archive_other_savedata.h | 2 ++ src/core/file_sys/archive_savedata.h | 1 + src/core/file_sys/archive_sdmc.h | 1 + src/core/file_sys/archive_sdmcwriteonly.h | 1 + src/core/file_sys/archive_selfncch.h | 6 ++++++ src/core/file_sys/archive_systemsavedata.h | 1 + src/core/file_sys/savedata_archive.cpp | 1 + src/core/file_sys/savedata_archive.h | 11 +++++++++++ src/core/hle/kernel/config_mem.h | 1 + src/core/hle/kernel/hle_ipc.cpp | 1 + src/core/hle/kernel/hle_ipc.h | 5 +++++ src/core/hle/kernel/server_session.h | 2 +- src/core/hle/kernel/shared_memory.h | 1 + src/core/hle/kernel/shared_page.h | 1 + src/core/hle/kernel/svc.cpp | 5 ++++- src/core/hle/kernel/thread.cpp | 1 + src/core/hle/kernel/thread.h | 5 +++++ src/core/hle/service/nwm/nwm_uds.cpp | 1 + src/core/hle/service/sm/srv.cpp | 15 +++++++++++++++ src/core/hle/service/sm/srv.h | 6 ++++++ 23 files changed, 75 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index def70ac2bd..a8efb78eb8 100644 --- a/TODO +++ b/TODO @@ -7,6 +7,11 @@ ☐ Review base class serialization everywhere Make sure that all base/derived relationships are registered ☐ Serialize codeset with an apploader reference instead +☐ Additional stuff to serialize + ☐ Self-NCCH archive + ☐ File backends + ☐ Directory backends + ☐ File/directory 'services' ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) ✔ Page tables @done(20-01-05 16:33) diff --git a/src/core/file_sys/archive_extsavedata.h b/src/core/file_sys/archive_extsavedata.h index c9b84c984c..f33dd1a895 100644 --- a/src/core/file_sys/archive_extsavedata.h +++ b/src/core/file_sys/archive_extsavedata.h @@ -60,6 +60,7 @@ private: ArchiveFactory_ExtSaveData() = default; template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& shared; ar& mount_point; } diff --git a/src/core/file_sys/archive_ncch.h b/src/core/file_sys/archive_ncch.h index 0a3f95b5c9..d17fbc3a2e 100644 --- a/src/core/file_sys/archive_ncch.h +++ b/src/core/file_sys/archive_ncch.h @@ -116,7 +116,9 @@ public: private: template - void serialize(Archive& ar, const unsigned int) {} + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + } friend class boost::serialization::access; }; diff --git a/src/core/file_sys/archive_other_savedata.h b/src/core/file_sys/archive_other_savedata.h index a9deae95a9..c5bf98a683 100644 --- a/src/core/file_sys/archive_other_savedata.h +++ b/src/core/file_sys/archive_other_savedata.h @@ -35,6 +35,7 @@ private: ArchiveFactory_OtherSaveDataPermitted() = default; template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& sd_savedata_source; } friend class boost::serialization::access; @@ -62,6 +63,7 @@ private: ArchiveFactory_OtherSaveDataGeneral() = default; template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& sd_savedata_source; } friend class boost::serialization::access; diff --git a/src/core/file_sys/archive_savedata.h b/src/core/file_sys/archive_savedata.h index 3ebe94a63d..6bb22f7a80 100644 --- a/src/core/file_sys/archive_savedata.h +++ b/src/core/file_sys/archive_savedata.h @@ -34,6 +34,7 @@ private: ArchiveFactory_SaveData() = default; template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& sd_savedata_source; } friend class boost::serialization::access; diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index 6051abef03..265dd7e932 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h @@ -81,6 +81,7 @@ private: ArchiveFactory_SDMC() = default; template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& sdmc_directory; } friend class boost::serialization::access; diff --git a/src/core/file_sys/archive_sdmcwriteonly.h b/src/core/file_sys/archive_sdmcwriteonly.h index 19982a9dbf..f4149961c3 100644 --- a/src/core/file_sys/archive_sdmcwriteonly.h +++ b/src/core/file_sys/archive_sdmcwriteonly.h @@ -67,6 +67,7 @@ private: ArchiveFactory_SDMCWriteOnly() = default; template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& sdmc_directory; } friend class boost::serialization::access; diff --git a/src/core/file_sys/archive_selfncch.h b/src/core/file_sys/archive_selfncch.h index de7fd75e09..571789b9fe 100644 --- a/src/core/file_sys/archive_selfncch.h +++ b/src/core/file_sys/archive_selfncch.h @@ -47,6 +47,12 @@ private: /// Mapping of ProgramId -> NCCHData std::unordered_map ncch_data; // TODO: Remove this, or actually set the values here + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + } + friend class boost::serialization::access; }; } // namespace FileSys diff --git a/src/core/file_sys/archive_systemsavedata.h b/src/core/file_sys/archive_systemsavedata.h index cf18cab899..d4f204a666 100644 --- a/src/core/file_sys/archive_systemsavedata.h +++ b/src/core/file_sys/archive_systemsavedata.h @@ -37,6 +37,7 @@ private: ArchiveFactory_SystemSaveData() = default; template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& base_path; } friend class boost::serialization::access; diff --git a/src/core/file_sys/savedata_archive.cpp b/src/core/file_sys/savedata_archive.cpp index 1f22b50ab5..090dc6fb05 100644 --- a/src/core/file_sys/savedata_archive.cpp +++ b/src/core/file_sys/savedata_archive.cpp @@ -357,4 +357,5 @@ u64 SaveDataArchive::GetFreeBytes() const { } // namespace FileSys +SERIALIZE_EXPORT_IMPL(FileSys::SaveDataArchive) SERIALIZE_EXPORT_IMPL(FileSys::SaveDataDelayGenerator) diff --git a/src/core/file_sys/savedata_archive.h b/src/core/file_sys/savedata_archive.h index 47f2f75e05..c9956e1358 100644 --- a/src/core/file_sys/savedata_archive.h +++ b/src/core/file_sys/savedata_archive.h @@ -38,10 +38,21 @@ public: protected: std::string mount_point; + +private: + SaveDataArchive() = default; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& mount_point; + } + friend class boost::serialization::access; }; class SaveDataDelayGenerator; } // namespace FileSys +BOOST_CLASS_EXPORT_KEY(FileSys::SaveDataArchive) BOOST_CLASS_EXPORT_KEY(FileSys::SaveDataDelayGenerator) diff --git a/src/core/hle/kernel/config_mem.h b/src/core/hle/kernel/config_mem.h index 0ec67fb5e8..46595976ea 100644 --- a/src/core/hle/kernel/config_mem.h +++ b/src/core/hle/kernel/config_mem.h @@ -70,6 +70,7 @@ private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); ar& boost::serialization::make_binary_object(&config_mem, sizeof(config_mem)); } }; diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index b1e2f7d8b0..23f5774902 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -50,6 +50,7 @@ private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& callback; ar& context; } diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 01fec190bc..046a31e2eb 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -222,6 +222,11 @@ public: virtual ~WakeupCallback() = default; virtual void WakeUp(std::shared_ptr thread, HLERequestContext& context, ThreadWakeupReason reason) = 0; + + private: + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; /** diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 331ac83971..74dbef624b 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -111,7 +111,7 @@ private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int file_version) { - ar& boost::serialization::base_object(*this); + ar& boost::serialization::base_object(*this); ar& name; ar& parent; ar& hle_handler; diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index aa2be05a6d..cb2dee685f 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -109,6 +109,7 @@ private: template void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); ar& linear_heap_phys_offset; ar& backing_blocks; ar& size; diff --git a/src/core/hle/kernel/shared_page.h b/src/core/hle/kernel/shared_page.h index 7b1f7ed164..c94cc079e4 100644 --- a/src/core/hle/kernel/shared_page.h +++ b/src/core/hle/kernel/shared_page.h @@ -117,6 +117,7 @@ private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& boost::serialization::make_binary_object(&shared_page, sizeof(shared_page)); } friend class boost::serialization::access; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 7f7cc12725..371bbdfe31 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -434,6 +434,7 @@ private: SVC_SyncCallback() = default; template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& do_output; } friend class boost::serialization::access; @@ -466,7 +467,9 @@ private: SVC_IPCCallback() : system(Core::Global()) {} template - void serialize(Archive& ar, const unsigned int) {} + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + } friend class boost::serialization::access; }; diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 13a3017a53..f7379f50d4 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -32,6 +32,7 @@ namespace Kernel { template void Thread::serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); ar&* context.get(); ar& thread_id; ar& status; diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 9941c76db5..c64e240718 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -66,6 +66,11 @@ public: virtual ~WakeupCallback() = default; virtual void WakeUp(ThreadWakeupReason reason, std::shared_ptr thread, std::shared_ptr object) = 0; + +private: + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; class ThreadManager { diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 2aa64f7fce..01bdd821ed 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -1189,6 +1189,7 @@ private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& command_id; } friend class boost::serialization::access; diff --git a/src/core/hle/service/sm/srv.cpp b/src/core/hle/service/sm/srv.cpp index 10179f4163..91b26b497c 100644 --- a/src/core/hle/service/sm/srv.cpp +++ b/src/core/hle/service/sm/srv.cpp @@ -3,6 +3,9 @@ // Refer to the license.txt file included. #include +#include +#include +#include #include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" @@ -21,8 +24,19 @@ #include "core/hle/service/sm/sm.h" #include "core/hle/service/sm/srv.h" +SERVICE_CONSTRUCT_IMPL(Service::SM::SRV) +SERIALIZE_EXPORT_IMPL(Service::SM::SRV) + namespace Service::SM { +template +void SRV::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& notification_semaphore; + ar& get_service_handle_delayed_map; +} +SERIALIZE_IMPL(SRV) + constexpr int MAX_PENDING_NOTIFICATIONS = 16; /** @@ -107,6 +121,7 @@ private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& name; } friend class boost::serialization::access; diff --git a/src/core/hle/service/sm/srv.h b/src/core/hle/service/sm/srv.h index 7d17f87a58..753218dca5 100644 --- a/src/core/hle/service/sm/srv.h +++ b/src/core/hle/service/sm/srv.h @@ -40,8 +40,14 @@ private: Core::System& system; std::shared_ptr notification_semaphore; std::unordered_map> get_service_handle_delayed_map; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; } // namespace Service::SM +SERVICE_CONSTRUCT(Service::SM::SRV) +BOOST_CLASS_EXPORT_KEY(Service::SM::SRV) BOOST_CLASS_EXPORT_KEY(Service::SM::SRV::ThreadCallback) From ca971ff31f49456e01d5e7f9747327f2ce18133a Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 10 Jan 2020 23:47:39 +0000 Subject: [PATCH 065/129] Serialize file/directory services --- TODO | 4 ++-- src/core/file_sys/archive_backend.h | 30 ++++++++++++++++++++++++++- src/core/file_sys/directory_backend.h | 5 +++++ src/core/hle/service/fs/directory.cpp | 12 +++++++++++ src/core/hle/service/fs/directory.h | 9 ++++++++ src/core/hle/service/fs/file.cpp | 13 ++++++++++++ src/core/hle/service/fs/file.h | 11 ++++++++++ 7 files changed, 81 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index a8efb78eb8..a768901851 100644 --- a/TODO +++ b/TODO @@ -4,14 +4,14 @@ ☐ Custom texture cache ☐ Review constructor/initialization code ☐ Review core timing events -☐ Review base class serialization everywhere +✔ Review base class serialization everywhere @done(20-01-10 23:47) Make sure that all base/derived relationships are registered ☐ Serialize codeset with an apploader reference instead ☐ Additional stuff to serialize ☐ Self-NCCH archive ☐ File backends ☐ Directory backends - ☐ File/directory 'services' + ✔ File/directory 'services' @done(20-01-10 23:46) ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) ✔ Page tables @done(20-01-05 16:33) diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 756613a305..6468c0630e 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include "common/bit_field.h" #include "common/common_types.h" #include "common/swap.h" @@ -63,7 +65,33 @@ private: LowPathType type; std::vector binary; std::string string; - std::u16string u16str; + std::u16string u16str{}; + + template + void serialize(Archive& ar, const unsigned int) { + ar& type; + switch (type) { + case LowPathType::Binary: + ar& binary; + break; + case LowPathType::Char: + ar& string; + break; + case LowPathType::Wchar: + static_assert(sizeof(wchar_t) == sizeof(char16_t)); + { + std::wstring wstring(reinterpret_cast(u16str.data())); + ar& wstring; + if (!Archive::is_saving::value) { + u16str = std::u16string(reinterpret_cast(wstring.data())); + } + } + break; + default: + break; + } + } + friend class boost::serialization::access; }; /// Parameters of the archive, as specified in the Create or Format call. diff --git a/src/core/file_sys/directory_backend.h b/src/core/file_sys/directory_backend.h index e9f124b024..4c9dbb4df3 100644 --- a/src/core/file_sys/directory_backend.h +++ b/src/core/file_sys/directory_backend.h @@ -53,6 +53,11 @@ public: * @return true if the directory closed correctly */ virtual bool Close() const = 0; + +private: + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; } // namespace FileSys diff --git a/src/core/hle/service/fs/directory.cpp b/src/core/hle/service/fs/directory.cpp index a72a9307ad..16b12905c8 100644 --- a/src/core/hle/service/fs/directory.cpp +++ b/src/core/hle/service/fs/directory.cpp @@ -2,13 +2,25 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "common/logging/log.h" #include "core/file_sys/directory_backend.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/fs/directory.h" +SERIALIZE_EXPORT_IMPL(Service::FS::Directory) + namespace Service::FS { +template +void Directory::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& path; + ar& backend; +} + +Directory::Directory() : ServiceFramework("", 1) {} + Directory::Directory(std::unique_ptr&& backend, const FileSys::Path& path) : ServiceFramework("", 1), path(path), backend(std::move(backend)) { diff --git a/src/core/hle/service/fs/directory.h b/src/core/hle/service/fs/directory.h index 890b266488..77956b1661 100644 --- a/src/core/hle/service/fs/directory.h +++ b/src/core/hle/service/fs/directory.h @@ -25,6 +25,15 @@ public: protected: void Read(Kernel::HLERequestContext& ctx); void Close(Kernel::HLERequestContext& ctx); + +private: + Directory(); + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; } // namespace Service::FS + +BOOST_CLASS_EXPORT_KEY(Service::FS::Directory) diff --git a/src/core/hle/service/fs/file.cpp b/src/core/hle/service/fs/file.cpp index c8727314b8..b878197d76 100644 --- a/src/core/hle/service/fs/file.cpp +++ b/src/core/hle/service/fs/file.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "common/logging/log.h" #include "core/core.h" #include "core/file_sys/errors.h" @@ -13,8 +14,20 @@ #include "core/hle/kernel/server_session.h" #include "core/hle/service/fs/file.h" +SERIALIZE_EXPORT_IMPL(Service::FS::File) +SERIALIZE_EXPORT_IMPL(Service::FS::FileSessionSlot) + namespace Service::FS { +template +void File::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& path; + ar& backend; +} + +File::File() : ServiceFramework("", 1), kernel(Core::Global()) {} + File::File(Kernel::KernelSystem& kernel, std::unique_ptr&& backend, const FileSys::Path& path) : ServiceFramework("", 1), path(path), backend(std::move(backend)), kernel(kernel) { diff --git a/src/core/hle/service/fs/file.h b/src/core/hle/service/fs/file.h index 18317212e2..98d4487559 100644 --- a/src/core/hle/service/fs/file.h +++ b/src/core/hle/service/fs/file.h @@ -6,6 +6,7 @@ #include #include "core/file_sys/archive_backend.h" +#include "core/global.h" #include "core/hle/service/service.h" namespace Core { @@ -30,6 +31,7 @@ private: ar& size; ar& subfile; } + friend class boost::serialization::access; }; // TODO: File is not a real service, but it can still utilize ServiceFramework::RegisterHandlers. @@ -71,6 +73,15 @@ private: void OpenSubFile(Kernel::HLERequestContext& ctx); Kernel::KernelSystem& kernel; + + File(); + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; } // namespace Service::FS + +BOOST_CLASS_EXPORT_KEY(Service::FS::FileSessionSlot) +BOOST_CLASS_EXPORT_KEY(Service::FS::File) From e4f05884c3be6249a8ab03e8b2c6bb8cb9caa7ac Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sat, 11 Jan 2020 16:33:48 +0000 Subject: [PATCH 066/129] Fixed serialization runtime exceptions --- TODO | 19 +++++++++---------- src/common/file_util.h | 1 + src/core/file_sys/archive_ncch.cpp | 1 + src/core/file_sys/archive_ncch.h | 14 +++++++++++--- src/core/file_sys/archive_selfncch.cpp | 21 +++++++++++++++++++++ src/core/file_sys/archive_selfncch.h | 18 ++++++++++++++++++ src/core/file_sys/ivfc_archive.cpp | 6 ++++++ src/core/file_sys/ivfc_archive.h | 22 ++++++++++++++++++++++ src/core/file_sys/romfs_reader.h | 21 ++++++++++++++++++--- src/core/hle/kernel/config_mem.cpp | 3 +++ src/core/hle/kernel/config_mem.h | 3 +++ src/core/hle/kernel/shared_page.cpp | 2 ++ src/core/hle/kernel/shared_page.h | 3 +++ src/core/hle/service/gsp/gsp_lcd.h | 3 +++ src/core/hle/service/ir/ir_rst.cpp | 1 - src/core/hle/service/ir/ir_u.h | 3 +++ src/core/hle/service/ir/ir_user.cpp | 11 +++++++++-- src/core/hle/service/ir/ir_user.h | 4 +++- src/core/hle/service/mic_u.cpp | 1 - src/core/hle/service/nwm/nwm_uds.cpp | 4 +++- src/core/hle/service/nwm/nwm_uds.h | 1 + src/core/hle/service/sm/srv.cpp | 1 - src/core/hle/service/y2r_u.cpp | 1 - 23 files changed, 140 insertions(+), 24 deletions(-) diff --git a/TODO b/TODO index a768901851..83603d1c6f 100644 --- a/TODO +++ b/TODO @@ -3,14 +3,15 @@ ☐ Multiple slots etc. ☐ Custom texture cache ☐ Review constructor/initialization code -☐ Review core timing events +☐ Core timing events +☐ Serialize codeset with an apploader reference instead ✔ Review base class serialization everywhere @done(20-01-10 23:47) Make sure that all base/derived relationships are registered -☐ Serialize codeset with an apploader reference instead -☐ Additional stuff to serialize - ☐ Self-NCCH archive - ☐ File backends - ☐ Directory backends +✔ Additional stuff to serialize @done(20-01-11 16:32) + ✔ Self-NCCH archive @done(20-01-11 16:32) + ✔ File backends @done(20-01-11 16:32) + ✘ Directory backends @cancelled(20-01-11 16:32) + Not needed for now ✔ File/directory 'services' @done(20-01-10 23:46) ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) @@ -37,10 +38,8 @@ ✔ SDMC @done(20-01-02 23:34) ✔ Normal @done(20-01-02 23:34) ✔ Write-only @done(20-01-02 23:34) - ✘ IVFC @cancelled(20-01-03 13:22) - Seems IVFCArchive is never used.. which is good because it has a file reference! - ✘ File refs @cancelled(20-01-03 13:22) - Not needed as nothing serializes file buffers + ✔ IVFC @done(20-01-11 16:33) + ✔ File refs @done(20-01-11 16:33) ✘ Replace delay generator with virtual fns @cancelled(20-01-03 13:16) While they have no state, the extra refactoring here is unneeded ✘ MMIO @cancelled(20-01-01 01:06) diff --git a/src/common/file_util.h b/src/common/file_util.h index c09aa88d61..71f943ed30 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -334,6 +334,7 @@ private: } BOOST_SERIALIZATION_SPLIT_MEMBER() + friend class boost::serialization::access; }; } // namespace FileUtil diff --git a/src/core/file_sys/archive_ncch.cpp b/src/core/file_sys/archive_ncch.cpp index 636bb81ed6..789547f0e3 100644 --- a/src/core/file_sys/archive_ncch.cpp +++ b/src/core/file_sys/archive_ncch.cpp @@ -30,6 +30,7 @@ // FileSys namespace SERIALIZE_EXPORT_IMPL(FileSys::NCCHArchive) +SERIALIZE_EXPORT_IMPL(FileSys::NCCHFile) SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_NCCH) namespace FileSys { diff --git a/src/core/file_sys/archive_ncch.h b/src/core/file_sys/archive_ncch.h index d17fbc3a2e..2d38f9a2e2 100644 --- a/src/core/file_sys/archive_ncch.h +++ b/src/core/file_sys/archive_ncch.h @@ -95,9 +95,16 @@ public: void Flush() const override {} private: - NCCHFile() = default; // NOTE: If the public ctor has behaviour, need to replace this with - // *_construct_data - std::vector file_buffer; // TODO: Replace with file ref for serialization + std::vector file_buffer; + + NCCHFile() = default; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& file_buffer; // TODO: See about a more efficient way to do this + } + friend class boost::serialization::access; }; /// File system interface to the NCCH archive @@ -125,4 +132,5 @@ private: } // namespace FileSys BOOST_CLASS_EXPORT_KEY(FileSys::NCCHArchive) +BOOST_CLASS_EXPORT_KEY(FileSys::NCCHFile) BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_NCCH) diff --git a/src/core/file_sys/archive_selfncch.cpp b/src/core/file_sys/archive_selfncch.cpp index 214ad7c084..e866e9bc0a 100644 --- a/src/core/file_sys/archive_selfncch.cpp +++ b/src/core/file_sys/archive_selfncch.cpp @@ -77,6 +77,15 @@ public: private: std::shared_ptr> data; + + ExeFSSectionFile() = default; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& data; + } + friend class boost::serialization::access; }; // SelfNCCHArchive represents the running application itself. From this archive the application can @@ -234,6 +243,15 @@ private: } NCCHData ncch_data; + + SelfNCCHArchive() = default; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& ncch_data; + } + friend class boost::serialization::access; }; void ArchiveFactory_SelfNCCH::Register(Loader::AppLoader& app_loader) { @@ -300,3 +318,6 @@ ResultVal ArchiveFactory_SelfNCCH::GetFormatInfo(const Path&, } } // namespace FileSys + +SERIALIZE_EXPORT_IMPL(FileSys::ExeFSSectionFile) +SERIALIZE_EXPORT_IMPL(FileSys::SelfNCCHArchive) diff --git a/src/core/file_sys/archive_selfncch.h b/src/core/file_sys/archive_selfncch.h index 571789b9fe..d7b1cf301d 100644 --- a/src/core/file_sys/archive_selfncch.h +++ b/src/core/file_sys/archive_selfncch.h @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include "common/common_types.h" #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -25,6 +27,17 @@ struct NCCHData { std::shared_ptr> banner; std::shared_ptr romfs_file; std::shared_ptr update_romfs_file; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& icon; + ar& logo; + ar& banner; + ar& romfs_file; + ar& update_romfs_file; + } + friend class boost::serialization::access; }; /// File system interface to the SelfNCCH archive @@ -55,6 +68,11 @@ private: friend class boost::serialization::access; }; +class ExeFSSectionFile; +class SelfNCCHArchive; + } // namespace FileSys BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SelfNCCH) +BOOST_CLASS_EXPORT_KEY(FileSys::ExeFSSectionFile) +BOOST_CLASS_EXPORT_KEY(FileSys::SelfNCCHArchive) diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp index ba16f8cd86..3dbef7049e 100644 --- a/src/core/file_sys/ivfc_archive.cpp +++ b/src/core/file_sys/ivfc_archive.cpp @@ -5,6 +5,7 @@ #include #include #include +#include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" #include "core/file_sys/ivfc_archive.h" @@ -12,6 +13,11 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::IVFCFile) +SERIALIZE_EXPORT_IMPL(FileSys::IVFCDelayGenerator) +SERIALIZE_EXPORT_IMPL(FileSys::RomFSDelayGenerator) +SERIALIZE_EXPORT_IMPL(FileSys::ExeFSDelayGenerator) + namespace FileSys { IVFCArchive::IVFCArchive(std::shared_ptr file, diff --git a/src/core/file_sys/ivfc_archive.h b/src/core/file_sys/ivfc_archive.h index 8168e04f4a..3926f5229d 100644 --- a/src/core/file_sys/ivfc_archive.h +++ b/src/core/file_sys/ivfc_archive.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include "common/common_types.h" #include "common/file_util.h" #include "core/file_sys/archive_backend.h" @@ -38,6 +40,8 @@ class IVFCDelayGenerator : public DelayGenerator { static constexpr u64 IPCDelayNanoseconds(9438006); return IPCDelayNanoseconds; } + + SERIALIZE_DELAY_GENERATOR }; class RomFSDelayGenerator : public DelayGenerator { @@ -60,6 +64,8 @@ public: static constexpr u64 IPCDelayNanoseconds(9438006); return IPCDelayNanoseconds; } + + SERIALIZE_DELAY_GENERATOR }; class ExeFSDelayGenerator : public DelayGenerator { @@ -82,6 +88,8 @@ public: static constexpr u64 IPCDelayNanoseconds(9438006); return IPCDelayNanoseconds; } + + SERIALIZE_DELAY_GENERATOR }; /** @@ -128,6 +136,15 @@ public: private: std::shared_ptr romfs_file; + + IVFCFile() = default; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& romfs_file; + } + friend class boost::serialization::access; }; class IVFCDirectory : public DirectoryBackend { @@ -162,3 +179,8 @@ private: }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::IVFCFile) +BOOST_CLASS_EXPORT_KEY(FileSys::IVFCDelayGenerator) +BOOST_CLASS_EXPORT_KEY(FileSys::RomFSDelayGenerator) +BOOST_CLASS_EXPORT_KEY(FileSys::ExeFSDelayGenerator) diff --git a/src/core/file_sys/romfs_reader.h b/src/core/file_sys/romfs_reader.h index 72a02cde3d..ab1986fe64 100644 --- a/src/core/file_sys/romfs_reader.h +++ b/src/core/file_sys/romfs_reader.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "common/common_types.h" #include "common/file_util.h" @@ -29,9 +30,23 @@ private: FileUtil::IOFile file; std::array key; std::array ctr; - std::size_t file_offset; - std::size_t crypto_offset; - std::size_t data_size; + u64 file_offset; + u64 crypto_offset; + u64 data_size; + + RomFSReader() = default; + + template + void serialize(Archive& ar, const unsigned int) { + ar& is_encrypted; + ar& file; + ar& key; + ar& ctr; + ar& file_offset; + ar& crypto_offset; + ar& data_size; + } + friend class boost::serialization::access; }; } // namespace FileSys diff --git a/src/core/hle/kernel/config_mem.cpp b/src/core/hle/kernel/config_mem.cpp index 58bef4110b..4b262b5013 100644 --- a/src/core/hle/kernel/config_mem.cpp +++ b/src/core/hle/kernel/config_mem.cpp @@ -3,10 +3,13 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "core/hle/kernel/config_mem.h" //////////////////////////////////////////////////////////////////////////////////////////////////// +SERIALIZE_EXPORT_IMPL(ConfigMem::Handler) + namespace ConfigMem { Handler::Handler() { diff --git a/src/core/hle/kernel/config_mem.h b/src/core/hle/kernel/config_mem.h index 46595976ea..74d934345f 100644 --- a/src/core/hle/kernel/config_mem.h +++ b/src/core/hle/kernel/config_mem.h @@ -10,6 +10,7 @@ // putting this as a subset of HLE for now. #include +#include #include "common/common_funcs.h" #include "common/common_types.h" #include "common/memory_ref.h" @@ -76,3 +77,5 @@ private: }; } // namespace ConfigMem + +BOOST_CLASS_EXPORT_KEY(ConfigMem::Handler) diff --git a/src/core/hle/kernel/shared_page.cpp b/src/core/hle/kernel/shared_page.cpp index f7b02993ff..5456a48e05 100644 --- a/src/core/hle/kernel/shared_page.cpp +++ b/src/core/hle/kernel/shared_page.cpp @@ -14,6 +14,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// +SERIALIZE_EXPORT_IMPL(SharedPage::Handler) + namespace boost::serialization { template diff --git a/src/core/hle/kernel/shared_page.h b/src/core/hle/kernel/shared_page.h index c94cc079e4..b74470b4a3 100644 --- a/src/core/hle/kernel/shared_page.h +++ b/src/core/hle/kernel/shared_page.h @@ -14,6 +14,7 @@ #include #include #include +#include #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" @@ -131,3 +132,5 @@ template void load_construct_data(Archive& ar, SharedPage::Handler* t, const unsigned int); } // namespace boost::serialization + +BOOST_CLASS_EXPORT_KEY(SharedPage::Handler) diff --git a/src/core/hle/service/gsp/gsp_lcd.h b/src/core/hle/service/gsp/gsp_lcd.h index 781d9dba8d..31d17f5400 100644 --- a/src/core/hle/service/gsp/gsp_lcd.h +++ b/src/core/hle/service/gsp/gsp_lcd.h @@ -12,6 +12,9 @@ class GSP_LCD final : public ServiceFramework { public: GSP_LCD(); ~GSP_LCD() = default; + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::GSP diff --git a/src/core/hle/service/ir/ir_rst.cpp b/src/core/hle/service/ir/ir_rst.cpp index dc9612e624..751460a044 100644 --- a/src/core/hle/service/ir/ir_rst.cpp +++ b/src/core/hle/service/ir/ir_rst.cpp @@ -29,7 +29,6 @@ void IR_RST::serialize(Archive& ar, const unsigned int) { // update_callback_id and input devices are set separately ReloadInputDevices(); } -SERIALIZE_IMPL(IR_RST) struct PadDataEntry { PadState current_state; diff --git a/src/core/hle/service/ir/ir_u.h b/src/core/hle/service/ir/ir_u.h index eaa54c6578..ecaf1be285 100644 --- a/src/core/hle/service/ir/ir_u.h +++ b/src/core/hle/service/ir/ir_u.h @@ -12,6 +12,9 @@ namespace Service::IR { class IR_U final : public ServiceFramework { public: IR_U(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::IR diff --git a/src/core/hle/service/ir/ir_user.cpp b/src/core/hle/service/ir/ir_user.cpp index 64a298103e..4bf6e74996 100644 --- a/src/core/hle/service/ir/ir_user.cpp +++ b/src/core/hle/service/ir/ir_user.cpp @@ -4,6 +4,8 @@ #include #include +#include +#include #include "common/string_util.h" #include "common/swap.h" #include "core/core.h" @@ -13,6 +15,9 @@ #include "core/hle/service/ir/extra_hid.h" #include "core/hle/service/ir/ir_user.h" +SERIALIZE_EXPORT_IMPL(Service::IR::IR_USER) +SERVICE_CONSTRUCT_IMPL(Service::IR::IR_USER) + namespace Service::IR { template @@ -23,10 +28,9 @@ void IR_USER::serialize(Archive& ar, const unsigned int) { ar& receive_event; ar& shared_memory; ar& connected_device; - ar&* receive_buffer.get(); + ar& receive_buffer; ar&* extra_hid.get(); } -SERIALIZE_IMPL(IR_USER) // This is a header that will present in the ir:USER shared memory if it is initialized with // InitializeIrNopShared service function. Otherwise the shared memory doesn't have this header if @@ -204,6 +208,8 @@ private: u32 max_data_size; private: + BufferManager() = default; + template void serialize(Archive& ar, const unsigned int) { ar& info; @@ -449,6 +455,7 @@ IR_USER::IR_USER(Core::System& system) : ServiceFramework("ir:USER", 1) { using namespace Kernel; + connected_device = false; conn_status_event = system.Kernel().CreateEvent(ResetType::OneShot, "IR:ConnectionStatusEvent"); send_event = system.Kernel().CreateEvent(ResetType::OneShot, "IR:SendEvent"); receive_event = system.Kernel().CreateEvent(ResetType::OneShot, "IR:ReceiveEvent"); diff --git a/src/core/hle/service/ir/ir_user.h b/src/core/hle/service/ir/ir_user.h index 75bbeb7791..afb9be4f7b 100644 --- a/src/core/hle/service/ir/ir_user.h +++ b/src/core/hle/service/ir/ir_user.h @@ -7,7 +7,6 @@ #include #include #include -#include #include "core/hle/service/service.h" namespace Kernel { @@ -177,3 +176,6 @@ private: }; } // namespace Service::IR + +BOOST_CLASS_EXPORT_KEY(Service::IR::IR_USER) +SERVICE_CONSTRUCT(Service::IR::IR_USER) diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index 478bf110fb..bd324ada25 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp @@ -28,7 +28,6 @@ void MIC_U::serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object(*this); ar&* impl.get(); } -SERIALIZE_IMPL(MIC_U) /// Microphone audio encodings. enum class Encoding : u8 { diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 01bdd821ed..b2793285f2 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -24,6 +24,9 @@ #include "core/hle/service/nwm/uds_data.h" #include "core/memory.h" +SERIALIZE_EXPORT_IMPL(Service::NWM::NWM_UDS) +SERVICE_CONSTRUCT_IMPL(Service::NWM::NWM_UDS) + namespace Service::NWM { template @@ -34,7 +37,6 @@ void NWM_UDS::serialize(Archive& ar, const unsigned int) { ar& received_beacons; // wifi_packet_received set in constructor } -SERIALIZE_IMPL(NWM_UDS) namespace ErrCodes { enum { diff --git a/src/core/hle/service/nwm/nwm_uds.h b/src/core/hle/service/nwm/nwm_uds.h index b2ab1d76a6..7ae471a538 100644 --- a/src/core/hle/service/nwm/nwm_uds.h +++ b/src/core/hle/service/nwm/nwm_uds.h @@ -557,6 +557,7 @@ private: template void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; } // namespace Service::NWM diff --git a/src/core/hle/service/sm/srv.cpp b/src/core/hle/service/sm/srv.cpp index 91b26b497c..f9c62e9ad1 100644 --- a/src/core/hle/service/sm/srv.cpp +++ b/src/core/hle/service/sm/srv.cpp @@ -35,7 +35,6 @@ void SRV::serialize(Archive& ar, const unsigned int) { ar& notification_semaphore; ar& get_service_handle_delayed_map; } -SERIALIZE_IMPL(SRV) constexpr int MAX_PENDING_NOTIFICATIONS = 16; diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index 45e7da13d1..89da8058c4 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp @@ -28,7 +28,6 @@ void Y2R_U::serialize(Archive& ar, const unsigned int) { ar& transfer_end_interrupt_enabled; ar& spacial_dithering_enabled; } -SERIALIZE_IMPL(Y2R_U) static const CoefficientSet standard_coefficients[4] = { {{0x100, 0x166, 0xB6, 0x58, 0x1C5, -0x166F, 0x10EE, -0x1C5B}}, // ITU_Rec601 From 8abc5525be98854abecee14046d8e175a8b68b79 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 12 Jan 2020 00:24:44 +0000 Subject: [PATCH 067/129] Added Signals; more runtime fixes --- src/citra_qt/main.cpp | 11 ++---- src/common/thread_queue_list.h | 30 ++++++++++++---- src/core/arm/arm_interface.h | 2 +- src/core/core.cpp | 50 +++++++++++++++++++++----- src/core/core.h | 11 +++--- src/core/core_timing.cpp | 12 +++---- src/core/file_sys/ivfc_archive.cpp | 1 + src/core/file_sys/ivfc_archive.h | 12 +++++++ src/core/hle/kernel/kernel.cpp | 5 ++- src/core/hle/kernel/kernel.h | 7 ++-- src/core/hle/kernel/memory.cpp | 16 ++++----- src/core/hle/kernel/process.h | 2 +- src/core/hle/kernel/shared_memory.cpp | 4 +-- src/core/hle/kernel/thread.cpp | 4 +-- src/core/hle/service/gsp/gsp_gpu.cpp | 4 --- src/core/hle/service/gsp/gsp_gpu.h | 2 +- src/core/hle/service/ldr_ro/ldr_ro.cpp | 1 + 17 files changed, 118 insertions(+), 56 deletions(-) diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 08e3cac02a..7fe4936f5f 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -1504,19 +1504,12 @@ void GMainWindow::OnCheats() { } void GMainWindow::OnSave() { - Core::System& system{Core::System::GetInstance()}; - auto fs = std::ofstream("save0.citrasave"); - emu_thread->SetRunning(false); - Core::System::GetInstance().Save(fs); - emu_thread->SetRunning(true); + Core::System::GetInstance().SendSignal(Core::System::Signal::Save); } void GMainWindow::OnLoad() { if (QFileInfo("save0.citrasave").exists()) { - auto fs = std::ifstream("save0.citrasave"); - emu_thread->SetRunning(false); - Core::System::GetInstance().Load(fs); - emu_thread->SetRunning(true); + Core::System::GetInstance().SendSignal(Core::System::Signal::Load); } } diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h index 093d867817..f5db59f053 100644 --- a/src/common/thread_queue_list.h +++ b/src/common/thread_queue_list.h @@ -160,15 +160,33 @@ private: // The priority level queues of thread ids. std::array queues; + s32 ToIndex(Queue* q) const { + if (q == nullptr) { + return -2; + } else if (q == UnlinkedTag()) { + return -1; + } else { + return static_cast(q - &queues[0]); + } + } + + Queue* ToPointer(s32 idx) { + if (idx == -1) { + return UnlinkedTag(); + } else if (idx < 0) { + return nullptr; + } else { + return &queues[idx]; + } + } + friend class boost::serialization::access; template void save(Archive& ar, const unsigned int file_version) const { - s32 idx = first == UnlinkedTag() ? -1 : static_cast(first - &queues[0]); + s32 idx = ToIndex(first); ar << idx; for (auto i = 0; i < NUM_QUEUES; i++) { - s32 idx1 = first == UnlinkedTag() - ? -1 - : static_cast(queues[i].next_nonempty - &queues[0]); + s32 idx1 = ToIndex(queues[i].next_nonempty); ar << idx1; ar << queues[i].data; } @@ -178,10 +196,10 @@ private: void load(Archive& ar, const unsigned int file_version) { s32 idx; ar >> idx; - first = idx < 0 ? UnlinkedTag() : &queues[idx]; + first = ToPointer(idx); for (auto i = 0; i < NUM_QUEUES; i++) { ar >> idx; - queues[i].next_nonempty = idx < 0 ? UnlinkedTag() : &queues[idx]; + queues[i].next_nonempty = ToPointer(idx); ar >> queues[i].data; } } diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index be30499d1a..e416a5f4ce 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -264,7 +264,7 @@ private: ar >> r; SetCP15Register(static_cast(i), r); } - // TODO: Clear caches etc? + ClearInstructionCache(); } BOOST_SERIALIZATION_SPLIT_MEMBER() diff --git a/src/core/core.cpp b/src/core/core.cpp index 20a8f32fec..fcd1268da6 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include #include #include @@ -103,15 +104,38 @@ System::ResultStatus System::RunLoop(bool tight_loop) { HW::Update(); Reschedule(); - if (reset_requested.exchange(false)) { + auto signal = current_signal.exchange(Signal::None); + switch (signal) { + case Signal::Reset: Reset(); - } else if (shutdown_requested.exchange(false)) { + break; + case Signal::Shutdown: return ResultStatus::ShutdownRequested; + break; + case Signal::Load: { + auto stream = std::ifstream("save0.citrasave", std::fstream::binary); + System::Load(stream); + } break; + case Signal::Save: { + auto stream = std::ofstream("save0.citrasave", std::fstream::binary); + System::Save(stream); + } break; + default: + break; } return status; } +bool System::SendSignal(System::Signal signal) { + auto prev = System::Signal::None; + if (!current_signal.compare_exchange_strong(prev, signal)) { + LOG_ERROR(Core, "Unable to {} as {} is ongoing", signal, prev); + return false; + } + return true; +} + System::ResultStatus System::SingleStep() { return RunLoop(false); } @@ -216,8 +240,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo timing = std::make_unique(); - kernel = std::make_unique( - *memory, *timing, [this] { PrepareReschedule(); }, system_mode); + kernel = std::make_unique(*memory, *timing, + [this] { PrepareReschedule(); }, system_mode); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 @@ -409,6 +433,7 @@ void System::Reset() { template void System::serialize(Archive& ar, const unsigned int file_version) { + Memory::RasterizerFlushAndInvalidateRegion(0, 0xFFFFFFFF); ar&* cpu_core.get(); ar&* service_manager.get(); ar& GPU::g_regs; @@ -436,11 +461,20 @@ void System::Save(std::ostream& stream) const { } void System::Load(std::istream& stream) { - { - iarchive ia{stream}; - ia&* this; + try { + + { + iarchive ia{stream}; + ia&* this; + } + VideoCore::Load(stream); + + // Flush state through: + Kernel().SetCurrentProcess(Kernel().GetCurrentProcess()); + + } catch (const std::exception& e) { + LOG_ERROR(Core, "Error loading: {}", e.what()); } - VideoCore::Load(stream); } } // namespace Core diff --git a/src/core/core.h b/src/core/core.h index 75e0e1a545..a3b2f5cddb 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -116,14 +116,18 @@ public: /// Shutdown and then load again void Reset(); + enum class Signal : u32 { None, Shutdown, Reset, Save, Load }; + + bool SendSignal(Signal signal); + /// Request reset of the system void RequestReset() { - reset_requested = true; + SendSignal(Signal::Reset); } /// Request shutdown of the system void RequestShutdown() { - shutdown_requested = true; + SendSignal(Signal::Shutdown); } /** @@ -341,8 +345,7 @@ private: Frontend::EmuWindow* m_emu_window; std::string m_filepath; - std::atomic reset_requested; - std::atomic shutdown_requested; + std::atomic current_signal; friend class boost::serialization::access; template diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index df355ab273..976a6f3ba2 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -23,14 +23,10 @@ bool Timing::Event::operator<(const Event& right) const { TimingEventType* Timing::RegisterEvent(const std::string& name, TimedCallback callback) { // check for existing type with same name. // we want event type names to remain unique so that we can use them for serialization. - ASSERT_MSG(event_types.find(name) == event_types.end(), - "CoreTiming Event \"{}\" is already registered. Events should only be registered " - "during Init to avoid breaking save states.", - name); - - auto info = event_types.emplace(name, TimingEventType{callback, nullptr}); + auto info = event_types.emplace(name, TimingEventType{}); TimingEventType* event_type = &info.first->second; event_type->name = &info.first->first; + event_type->callback = callback; return event_type; } @@ -129,6 +125,10 @@ void Timing::Advance() { Event evt = std::move(event_queue.front()); std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>()); event_queue.pop_back(); + if (event_types.find(*evt.type->name) == event_types.end()) { + LOG_ERROR(Core, "Unknown queued event"); + continue; + } evt.type->callback(evt.userdata, global_timer - evt.time); } diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp index 3dbef7049e..10d0851644 100644 --- a/src/core/file_sys/ivfc_archive.cpp +++ b/src/core/file_sys/ivfc_archive.cpp @@ -14,6 +14,7 @@ // FileSys namespace SERIALIZE_EXPORT_IMPL(FileSys::IVFCFile) +SERIALIZE_EXPORT_IMPL(FileSys::IVFCFileInMemory) SERIALIZE_EXPORT_IMPL(FileSys::IVFCDelayGenerator) SERIALIZE_EXPORT_IMPL(FileSys::RomFSDelayGenerator) SERIALIZE_EXPORT_IMPL(FileSys::ExeFSDelayGenerator) diff --git a/src/core/file_sys/ivfc_archive.h b/src/core/file_sys/ivfc_archive.h index 3926f5229d..145fabb986 100644 --- a/src/core/file_sys/ivfc_archive.h +++ b/src/core/file_sys/ivfc_archive.h @@ -176,11 +176,23 @@ private: std::vector romfs_file; u64 data_offset; u64 data_size; + + IVFCFileInMemory() = default; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& romfs_file; + ar& data_offset; + ar& data_size; + } + friend class boost::serialization::access; }; } // namespace FileSys BOOST_CLASS_EXPORT_KEY(FileSys::IVFCFile) +BOOST_CLASS_EXPORT_KEY(FileSys::IVFCFileInMemory) BOOST_CLASS_EXPORT_KEY(FileSys::IVFCDelayGenerator) BOOST_CLASS_EXPORT_KEY(FileSys::RomFSDelayGenerator) BOOST_CLASS_EXPORT_KEY(FileSys::ExeFSDelayGenerator) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 968e905ac5..3c3dfc6c6b 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -23,6 +23,9 @@ KernelSystem::KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing, std::function prepare_reschedule_callback, u32 system_mode) : memory(memory), timing(timing), prepare_reschedule_callback(std::move(prepare_reschedule_callback)) { + for (auto i = 0; i < memory_regions.size(); i++) { + memory_regions[i] = std::make_shared(); + } MemoryInit(system_mode); resource_limits = std::make_unique(*this); @@ -107,7 +110,7 @@ template void KernelSystem::serialize(Archive& ar, const unsigned int file_version) { ar& memory_regions; ar& named_ports; - ar&* current_cpu.get(); + // current_cpu set externally // NB: subsystem references and prepare_reschedule_callback are constant ar&* resource_limits.get(); ar& next_object_id; diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index e7b7314d62..41ef5272b3 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -134,7 +134,8 @@ public: */ ResultVal> CreateThread(std::string name, VAddr entry_point, u32 priority, u32 arg, s32 processor_id, - VAddr stack_top, std::shared_ptr owner_process); + VAddr stack_top, + std::shared_ptr owner_process); /** * Creates a semaphore. @@ -232,11 +233,11 @@ public: IPCDebugger::Recorder& GetIPCRecorder(); const IPCDebugger::Recorder& GetIPCRecorder() const; - MemoryRegionInfo* GetMemoryRegion(MemoryRegion region); + std::shared_ptr GetMemoryRegion(MemoryRegion region); void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping); - std::array memory_regions; + std::array, 3> memory_regions{}; /// Adds a port to the named port table void AddNamedPort(std::string name, std::shared_ptr port); diff --git a/src/core/hle/kernel/memory.cpp b/src/core/hle/kernel/memory.cpp index 04d09fa461..f8db3c31e1 100644 --- a/src/core/hle/kernel/memory.cpp +++ b/src/core/hle/kernel/memory.cpp @@ -49,9 +49,9 @@ void KernelSystem::MemoryInit(u32 mem_type) { // the sizes specified in the memory_region_sizes table. VAddr base = 0; for (int i = 0; i < 3; ++i) { - memory_regions[i].Reset(base, memory_region_sizes[mem_type][i]); + memory_regions[i]->Reset(base, memory_region_sizes[mem_type][i]); - base += memory_regions[i].size; + base += memory_regions[i]->size; } // We must've allocated the entire FCRAM by the end @@ -63,20 +63,20 @@ void KernelSystem::MemoryInit(u32 mem_type) { // app_mem_malloc does not always match the configured size for memory_region[0]: in case the // n3DS type override is in effect it reports the size the game expects, not the real one. config_mem.app_mem_alloc = memory_region_sizes[mem_type][0]; - config_mem.sys_mem_alloc = memory_regions[1].size; - config_mem.base_mem_alloc = memory_regions[2].size; + config_mem.sys_mem_alloc = memory_regions[1]->size; + config_mem.base_mem_alloc = memory_regions[2]->size; shared_page_handler = std::make_shared(timing); } -MemoryRegionInfo* KernelSystem::GetMemoryRegion(MemoryRegion region) { +std::shared_ptr KernelSystem::GetMemoryRegion(MemoryRegion region) { switch (region) { case MemoryRegion::APPLICATION: - return &memory_regions[0]; + return memory_regions[0]; case MemoryRegion::SYSTEM: - return &memory_regions[1]; + return memory_regions[1]; case MemoryRegion::BASE: - return &memory_regions[2]; + return memory_regions[2]; default: UNREACHABLE(); } diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 576cf7e15e..6eb79d2278 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -200,7 +200,7 @@ public: u32 memory_used = 0; - MemoryRegionInfo* memory_region = nullptr; + std::shared_ptr memory_region = nullptr; /// The Thread Local Storage area is allocated as processes create threads, /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 23f67f7331..47c966fec9 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -42,7 +42,7 @@ ResultVal> KernelSystem::CreateSharedMemory( if (address == 0) { // We need to allocate a block from the Linear Heap ourselves. // We'll manually allocate some memory from the linear heap in the specified region. - MemoryRegionInfo* memory_region = GetMemoryRegion(region); + auto memory_region = GetMemoryRegion(region); auto offset = memory_region->LinearAllocate(size); ASSERT_MSG(offset, "Not enough space in region to allocate shared memory!"); @@ -79,7 +79,7 @@ std::shared_ptr KernelSystem::CreateSharedMemoryForApplet( auto shared_memory{std::make_shared(*this)}; // Allocate memory in heap - MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::SYSTEM); + auto memory_region = GetMemoryRegion(MemoryRegion::SYSTEM); auto backing_blocks = memory_region->HeapAllocate(size); ASSERT_MSG(!backing_blocks.empty(), "Not enough space in region to allocate shared memory!"); shared_memory->holding_memory = backing_blocks; diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index f7379f50d4..5382f9ec8a 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -32,7 +32,7 @@ namespace Kernel { template void Thread::serialize(Archive& ar, const unsigned int file_version) { - ar& boost::serialization::base_object(*this); + ar& boost::serialization::base_object(*this); ar&* context.get(); ar& thread_id; ar& status; @@ -363,7 +363,7 @@ ResultVal> KernelSystem::CreateThread( if (needs_allocation) { // There are no already-allocated pages with free slots, lets allocate a new one. // TLS pages are allocated from the BASE region in the linear heap. - MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::BASE); + auto memory_region = GetMemoryRegion(MemoryRegion::BASE); // Allocate some memory from the end of the linear heap for this region. auto offset = memory_region->LinearAllocate(Memory::PAGE_SIZE); diff --git a/src/core/hle/service/gsp/gsp_gpu.cpp b/src/core/hle/service/gsp/gsp_gpu.cpp index 78d84499b9..5a41f5ca0c 100644 --- a/src/core/hle/service/gsp/gsp_gpu.cpp +++ b/src/core/hle/service/gsp/gsp_gpu.cpp @@ -824,10 +824,6 @@ std::unique_ptr GSP_GPU::MakeSes return std::make_unique(this); } -SessionData::SessionData() { - UNREACHABLE(); -} - SessionData::SessionData(GSP_GPU* gsp) : gsp(gsp) { // Assign a new thread id to this session when it connects. Note: In the real GSP service this // is done through a real thread (svcCreateThread) but we have to simulate it since our HLE diff --git a/src/core/hle/service/gsp/gsp_gpu.h b/src/core/hle/service/gsp/gsp_gpu.h index a97aee278d..82ecf2480b 100644 --- a/src/core/hle/service/gsp/gsp_gpu.h +++ b/src/core/hle/service/gsp/gsp_gpu.h @@ -187,7 +187,7 @@ class GSP_GPU; class SessionData : public Kernel::SessionRequestHandler::SessionDataBase { public: - SessionData(); + SessionData() = default; SessionData(GSP_GPU* gsp); ~SessionData(); diff --git a/src/core/hle/service/ldr_ro/ldr_ro.cpp b/src/core/hle/service/ldr_ro/ldr_ro.cpp index 0a61f4c23c..8ac6f10685 100644 --- a/src/core/hle/service/ldr_ro/ldr_ro.cpp +++ b/src/core/hle/service/ldr_ro/ldr_ro.cpp @@ -15,6 +15,7 @@ SERVICE_CONSTRUCT_IMPL(Service::LDR::RO) SERIALIZE_EXPORT_IMPL(Service::LDR::RO) +SERIALIZE_EXPORT_IMPL(Service::LDR::ClientSlot) namespace Service::LDR { From c24ea0f0eea2d263cf3cd9bb616332fed3085c5f Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 12 Jan 2020 20:01:29 +0000 Subject: [PATCH 068/129] Serialize core timing --- TODO | 3 ++- src/core/core.cpp | 1 + src/core/core_timing.cpp | 10 +++++++-- src/core/core_timing.h | 42 ++++++++++++++++++++++++++++++++++++ src/core/hle/kernel/thread.h | 1 + 5 files changed, 54 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 83603d1c6f..9cc333d46b 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,10 @@ ☐ Save/load UI ✔ Basic version @done(20-01-03 15:27) ☐ Multiple slots etc. +☐ Add 'force flush all' to Rasterizer interface + impls ☐ Custom texture cache ☐ Review constructor/initialization code -☐ Core timing events +✔ Core timing events @done(20-01-12 15:14) ☐ Serialize codeset with an apploader reference instead ✔ Review base class serialization everywhere @done(20-01-10 23:47) Make sure that all base/derived relationships are registered diff --git a/src/core/core.cpp b/src/core/core.cpp index fcd1268da6..fa60035dc1 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -434,6 +434,7 @@ void System::Reset() { template void System::serialize(Archive& ar, const unsigned int file_version) { Memory::RasterizerFlushAndInvalidateRegion(0, 0xFFFFFFFF); + ar&* timing.get(); ar&* cpu_core.get(); ar&* service_manager.get(); ar& GPU::g_regs; diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 976a6f3ba2..4b2729a769 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -11,6 +11,8 @@ namespace Core { +Timing* Timing::deserializing = nullptr; + // Sort by time, unless the times are the same, in which case sort by the order added to the queue bool Timing::Event::operator>(const Event& right) const { return std::tie(time, fifo_order) > std::tie(right.time, right.fifo_order); @@ -26,7 +28,9 @@ TimingEventType* Timing::RegisterEvent(const std::string& name, TimedCallback ca auto info = event_types.emplace(name, TimingEventType{}); TimingEventType* event_type = &info.first->second; event_type->name = &info.first->first; - event_type->callback = callback; + if (callback != nullptr) { + event_type->callback = callback; + } return event_type; } @@ -129,7 +133,9 @@ void Timing::Advance() { LOG_ERROR(Core, "Unknown queued event"); continue; } - evt.type->callback(evt.userdata, global_timer - evt.time); + if (evt.type->callback != nullptr) { + evt.type->callback(evt.userdata, global_timer - evt.time); + } } is_global_timer_sane = false; diff --git a/src/core/core_timing.h b/src/core/core_timing.h index 229fc37f41..1e6a3b0213 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "common/common_types.h" #include "common/logging/log.h" #include "common/threadsafe_queue.h" @@ -190,6 +192,8 @@ public: s64 GetDowncount() const; private: + static Timing* deserializing; + struct Event { s64 time; u64 fifo_order; @@ -198,6 +202,29 @@ private: bool operator>(const Event& right) const; bool operator<(const Event& right) const; + + private: + template + void save(Archive& ar, const unsigned int) const { + ar& time; + ar& fifo_order; + ar& userdata; + std::string name = *(type->name); + ar << name; + } + + template + void load(Archive& ar, const unsigned int) { + ar& time; + ar& fifo_order; + ar& userdata; + std::string name; + ar >> name; + type = Timing::deserializing->RegisterEvent(name, nullptr); + } + friend class boost::serialization::access; + + BOOST_SERIALIZATION_SPLIT_MEMBER() }; static constexpr int MAX_SLICE_LENGTH = 20000; @@ -229,6 +256,21 @@ private: // executing the first cycle of each slice to prepare the slice length and downcount for // that slice. bool is_global_timer_sane = true; + + template + void serialize(Archive& ar, const unsigned int) { + // event_types set during initialization of other things + deserializing = this; + MoveEvents(); + ar& global_timer; + ar& slice_length; + ar& downcount; + ar& event_queue; + ar& event_fifo_id; + ar& idled_cycles; + deserializing = nullptr; + } + friend class boost::serialization::access; }; } // namespace Core diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index c64e240718..0286e210d6 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -172,6 +172,7 @@ private: ar& ready_queue; ar& wakeup_callback_table; ar& thread_list; + SwitchContext(current_thread.get()); } }; From 2217b3558d98dfcc8a40d901a643c2fb72a9c476 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 16 Jan 2020 00:53:20 +0000 Subject: [PATCH 069/129] Fixed file services serialization --- src/common/file_util.cpp | 13 +++++-------- src/common/file_util.h | 3 ++- src/core/core.cpp | 4 ++++ src/core/hle/service/fs/directory.cpp | 9 ++++++--- src/core/hle/service/fs/file.cpp | 10 ++++++++-- src/core/hle/service/fs/file.h | 1 + 6 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index ca86f7bfca..c5da82973c 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -881,8 +881,9 @@ std::string SanitizePath(std::string_view path_, DirectorySeparator directory_se IOFile::IOFile() {} -IOFile::IOFile(const std::string& filename, const char openmode[], int flags) { - Open(filename, openmode, flags); +IOFile::IOFile(const std::string& filename, const char openmode[], int flags) + : filename(filename), openmode(openmode), flags(flags) { + Open(); } IOFile::~IOFile() { @@ -906,13 +907,9 @@ void IOFile::Swap(IOFile& other) { std::swap(flags, other.flags); } -bool IOFile::Open(const std::string& filename, const char openmode[], int flags) { +bool IOFile::Open() { Close(); - this->filename = filename; - this->openmode = openmode; - this->flags = flags; - #ifdef _WIN32 if (flags != 0) { m_file = _wfsopen(Common::UTF8ToUTF16W(filename).c_str(), @@ -922,7 +919,7 @@ bool IOFile::Open(const std::string& filename, const char openmode[], int flags) Common::UTF8ToUTF16W(openmode).c_str()); } #else - m_file = fopen(filename.c_str(), openmode); + m_file = fopen(filename.c_str(), openmode.c_str()); #endif m_good = IsOpen(); diff --git a/src/common/file_util.h b/src/common/file_util.h index 71f943ed30..0368d36658 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -306,7 +306,7 @@ public: } private: - bool Open(const std::string& filename, const char openmode[], int flags = 0); + bool Open(); std::FILE* m_file = nullptr; bool m_good = true; @@ -330,6 +330,7 @@ private: ar >> flags; u64 pos; ar >> pos; + Open(); Seek(pos, SEEK_SET); } diff --git a/src/core/core.cpp b/src/core/core.cpp index fa60035dc1..985d37291d 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -113,12 +113,16 @@ System::ResultStatus System::RunLoop(bool tight_loop) { return ResultStatus::ShutdownRequested; break; case Signal::Load: { + LOG_INFO(Core, "Begin load"); auto stream = std::ifstream("save0.citrasave", std::fstream::binary); System::Load(stream); + LOG_INFO(Core, "Load completed"); } break; case Signal::Save: { + LOG_INFO(Core, "Begin save"); auto stream = std::ofstream("save0.citrasave", std::fstream::binary); System::Save(stream); + LOG_INFO(Core, "Save completed"); } break; default: break; diff --git a/src/core/hle/service/fs/directory.cpp b/src/core/hle/service/fs/directory.cpp index 16b12905c8..c7fb085ea1 100644 --- a/src/core/hle/service/fs/directory.cpp +++ b/src/core/hle/service/fs/directory.cpp @@ -19,11 +19,14 @@ void Directory::serialize(Archive& ar, const unsigned int) { ar& backend; } -Directory::Directory() : ServiceFramework("", 1) {} - Directory::Directory(std::unique_ptr&& backend, const FileSys::Path& path) - : ServiceFramework("", 1), path(path), backend(std::move(backend)) { + : Directory() { + this->backend = std::move(backend); + this->path = path; +} + +Directory::Directory() : ServiceFramework("", 1), path(""), backend(nullptr) { static const FunctionInfo functions[] = { // clang-format off {0x08010042, &Directory::Read, "Read"}, diff --git a/src/core/hle/service/fs/file.cpp b/src/core/hle/service/fs/file.cpp index b878197d76..e86d937239 100644 --- a/src/core/hle/service/fs/file.cpp +++ b/src/core/hle/service/fs/file.cpp @@ -26,11 +26,17 @@ void File::serialize(Archive& ar, const unsigned int) { ar& backend; } -File::File() : ServiceFramework("", 1), kernel(Core::Global()) {} +File::File() : File(Core::Global()) {} File::File(Kernel::KernelSystem& kernel, std::unique_ptr&& backend, const FileSys::Path& path) - : ServiceFramework("", 1), path(path), backend(std::move(backend)), kernel(kernel) { + : File(kernel) { + this->backend = std::move(backend); + this->path = path; +} + +File::File(Kernel::KernelSystem& kernel) + : ServiceFramework("", 1), path(""), backend(nullptr), kernel(kernel) { static const FunctionInfo functions[] = { {0x08010100, &File::OpenSubFile, "OpenSubFile"}, {0x080200C2, &File::Read, "Read"}, diff --git a/src/core/hle/service/fs/file.h b/src/core/hle/service/fs/file.h index 98d4487559..6aa301a7bf 100644 --- a/src/core/hle/service/fs/file.h +++ b/src/core/hle/service/fs/file.h @@ -74,6 +74,7 @@ private: Kernel::KernelSystem& kernel; + File(Kernel::KernelSystem& kernel); File(); template From b2370ea35317040ca1159e46ec5c2653898a36ad Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 17 Jan 2020 01:01:18 +0000 Subject: [PATCH 070/129] Fixed setting the right DSP service on deserialization --- src/core/core.cpp | 5 ++++- src/core/core_timing.cpp | 5 +++-- src/video_core/geometry_pipeline.h | 8 ++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 985d37291d..d199b16e2d 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -448,7 +448,10 @@ void System::serialize(Archive& ar, const unsigned int file_version) { ar&* kernel.get(); // This needs to be set from somewhere - might as well be here! - Service::GSP::SetGlobalModule(*this); + if (Archive::is_loading::value) { + Service::GSP::SetGlobalModule(*this); + DSP().SetServiceToInterrupt(ServiceManager().GetService("dsp::DSP")); + } } void System::Save(std::ostream& stream) const { diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 4b2729a769..116ba3a40e 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -130,8 +130,9 @@ void Timing::Advance() { std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>()); event_queue.pop_back(); if (event_types.find(*evt.type->name) == event_types.end()) { - LOG_ERROR(Core, "Unknown queued event"); - continue; + LOG_ERROR(Core, "Unknown queued event {}", *evt.type->name); + } else if (evt.type->callback == nullptr) { + LOG_ERROR(Core, "Event '{}' has no callback", *evt.type->name); } if (evt.type->callback != nullptr) { evt.type->callback(evt.userdata, global_timer - evt.time); diff --git a/src/video_core/geometry_pipeline.h b/src/video_core/geometry_pipeline.h index 1ca2d00c4e..1a903b1e0e 100644 --- a/src/video_core/geometry_pipeline.h +++ b/src/video_core/geometry_pipeline.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include "video_core/shader/shader.h" namespace Pica { @@ -12,6 +13,9 @@ namespace Pica { struct State; class GeometryPipelineBackend; +class GeometryPipeline_Point; +class GeometryPipeline_VariablePrimitive; +class GeometryPipeline_FixedPrimitive; /// A pipeline receiving from vertex shader and sending to geometry shader and primitive assembler class GeometryPipeline { @@ -52,3 +56,7 @@ private: friend class boost::serialization::access; }; } // namespace Pica + +BOOST_CLASS_EXPORT_KEY(Pica::GeometryPipeline_Point) +BOOST_CLASS_EXPORT_KEY(Pica::GeometryPipeline_VariablePrimitive) +BOOST_CLASS_EXPORT_KEY(Pica::GeometryPipeline_FixedPrimitive) From 35c3ca995cd68f6c827599146c42c7aebfac1567 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 17 Jan 2020 01:34:03 +0000 Subject: [PATCH 071/129] Fixed a bug (??) in arm_dynarmic where PageTableChanged could reset the CPU context --- src/core/arm/dynarmic/arm_dynarmic.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index eb3295956e..b6494d40eb 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -283,15 +283,21 @@ void ARM_Dynarmic::InvalidateCacheRange(u32 start_address, std::size_t length) { void ARM_Dynarmic::PageTableChanged() { current_page_table = memory.GetCurrentPageTable(); + Dynarmic::A32::Context ctx{}; + if (jit) { + jit->SaveContext(ctx); + } auto iter = jits.find(current_page_table); if (iter != jits.end()) { jit = iter->second.get(); + jit->LoadContext(ctx); return; } auto new_jit = MakeJit(); jit = new_jit.get(); + jit->LoadContext(ctx); jits.emplace(current_page_table, std::move(new_jit)); } From 0effb229cd754640def04b7d9f9dd3187137aa43 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 17 Jan 2020 07:58:40 +0000 Subject: [PATCH 072/129] Fix geometry pipeline; attempt to fix motion controls --- src/core/hle/service/hid/hid.cpp | 4 +++- src/video_core/geometry_pipeline.cpp | 20 ++++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index f20cebca7d..012a37e6bc 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -40,7 +40,9 @@ void Module::serialize(Archive& ar, const unsigned int) { ar& next_gyroscope_index; ar& enable_accelerometer_count; ar& enable_gyroscope_count; - ReloadInputDevices(); + if (Archive::is_loading::value) { + LoadInputDevices(); + } // Pad state not needed as it's always updated // Update events are set in the constructor // Devices are set from the implementation (and are stateless afaik) diff --git a/src/video_core/geometry_pipeline.cpp b/src/video_core/geometry_pipeline.cpp index 159f1df0b2..7e002d55d2 100644 --- a/src/video_core/geometry_pipeline.cpp +++ b/src/video_core/geometry_pipeline.cpp @@ -49,7 +49,7 @@ private: // TODO: what happens when the input size is not divisible by the output size? class GeometryPipeline_Point : public GeometryPipelineBackend { public: - GeometryPipeline_Point() : regs(g_state.regs), unit(g_state.gs_unit) { + GeometryPipeline_Point(const Regs& regs, Shader::GSUnitState& unit) : regs(regs), unit(unit) { ASSERT(regs.pipeline.variable_primitive == 0); ASSERT(regs.gs.input_to_uniform == 0); vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1; @@ -89,6 +89,8 @@ private: Common::Vec4* buffer_end; unsigned int vs_output_num; + GeometryPipeline_Point() : regs(g_state.regs), unit(g_state.gs_unit) {} + template static void serialize_common(Class* self, Archive& ar, const unsigned int version) { ar& boost::serialization::base_object(*self); @@ -125,7 +127,8 @@ private: // value in the batch. This mode is usually used for subdivision. class GeometryPipeline_VariablePrimitive : public GeometryPipelineBackend { public: - GeometryPipeline_VariablePrimitive() : regs(g_state.regs), setup(g_state.gs) { + GeometryPipeline_VariablePrimitive(const Regs& regs, Shader::ShaderSetup& setup) + : regs(regs), setup(setup) { ASSERT(regs.pipeline.variable_primitive == 1); ASSERT(regs.gs.input_to_uniform == 1); vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1; @@ -183,6 +186,8 @@ private: Common::Vec4* buffer_cur; unsigned int vs_output_num; + GeometryPipeline_VariablePrimitive() : regs(g_state.regs), setup(g_state.gs) {} + template static void serialize_common(Class* self, Archive& ar, const unsigned int version) { ar& boost::serialization::base_object(*self); @@ -217,7 +222,8 @@ private: // particle system. class GeometryPipeline_FixedPrimitive : public GeometryPipelineBackend { public: - GeometryPipeline_FixedPrimitive() : regs(g_state.regs), setup(g_state.gs) { + GeometryPipeline_FixedPrimitive(const Regs& regs, Shader::ShaderSetup& setup) + : regs(regs), setup(setup) { ASSERT(regs.pipeline.variable_primitive == 0); ASSERT(regs.gs.input_to_uniform == 1); vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1; @@ -256,6 +262,8 @@ private: Common::Vec4* buffer_end; unsigned int vs_output_num; + GeometryPipeline_FixedPrimitive() : regs(g_state.regs), setup(g_state.gs) {} + template static void serialize_common(Class* self, Archive& ar, const unsigned int version) { ar& boost::serialization::base_object(*self); @@ -329,13 +337,13 @@ void GeometryPipeline::Reconfigure() { switch (state.regs.pipeline.gs_config.mode) { case PipelineRegs::GSMode::Point: - backend = std::make_unique(); + backend = std::make_unique(state.regs, state.gs_unit); break; case PipelineRegs::GSMode::VariablePrimitive: - backend = std::make_unique(); + backend = std::make_unique(state.regs, state.gs); break; case PipelineRegs::GSMode::FixedPrimitive: - backend = std::make_unique(); + backend = std::make_unique(state.regs, state.gs); break; default: UNREACHABLE(); From 3e34ad6890a08bc2572da52a6b4fc2f967b4681d Mon Sep 17 00:00:00 2001 From: James Rowe Date: Thu, 16 Jan 2020 23:17:07 -0700 Subject: [PATCH 073/129] Hack: Workaround crash when loading state and gyro is used --- src/core/hle/service/hid/hid.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 012a37e6bc..6898c1024e 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -207,6 +207,10 @@ void Module::UpdateAccelerometerCallback(u64 userdata, s64 cycles_late) { next_accelerometer_index = (next_accelerometer_index + 1) % mem->accelerometer.entries.size(); Common::Vec3 accel; + if (!motion_device) { + is_device_reload_pending.exchange(true); + return; + } std::tie(accel, std::ignore) = motion_device->GetStatus(); accel *= accelerometer_coef; // TODO(wwylele): do a time stretch like the one in UpdateGyroscopeCallback @@ -254,6 +258,10 @@ void Module::UpdateGyroscopeCallback(u64 userdata, s64 cycles_late) { GyroscopeDataEntry& gyroscope_entry = mem->gyroscope.entries[mem->gyroscope.index]; Common::Vec3 gyro; + if (!motion_device) { + is_device_reload_pending.exchange(true); + return; + } std::tie(std::ignore, gyro) = motion_device->GetStatus(); double stretch = system.perf_stats->GetLastFrameTimeScale(); gyro *= gyroscope_coef * static_cast(stretch); From 55c75b5e3e3be6e4baa34aaab4520d3c49d9645c Mon Sep 17 00:00:00 2001 From: James Rowe Date: Thu, 16 Jan 2020 23:17:55 -0700 Subject: [PATCH 074/129] Add ClearAll to rasterizer cache for fully wiping the cache on save/load --- src/core/core.cpp | 4 ++- src/core/memory.cpp | 10 +++++++ src/core/memory.h | 6 ++++ src/video_core/rasterizer_interface.h | 3 ++ .../renderer_opengl/gl_rasterizer.cpp | 4 +++ .../renderer_opengl/gl_rasterizer.h | 1 + .../renderer_opengl/gl_rasterizer_cache.cpp | 29 +++++++++++++++++-- .../renderer_opengl/gl_rasterizer_cache.h | 3 ++ src/video_core/swrasterizer/swrasterizer.h | 1 + 9 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index d199b16e2d..aeab0d2b5b 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -437,7 +437,9 @@ void System::Reset() { template void System::serialize(Archive& ar, const unsigned int file_version) { - Memory::RasterizerFlushAndInvalidateRegion(0, 0xFFFFFFFF); + // flush on save, don't flush on load + bool should_flush = !Archive::is_loading::value; + Memory::RasterizerClearAll(should_flush); ar&* timing.get(); ar&* cpu_core.get(); ar&* service_manager.get(); diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 4c083d8c0f..a0fa2a7382 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -556,6 +556,16 @@ void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size) { VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(start, size); } +void RasterizerClearAll(bool flush) { + // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be + // null here + if (VideoCore::g_renderer == nullptr) { + return; + } + + VideoCore::g_renderer->Rasterizer()->ClearAll(flush); +} + void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode) { // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be // null here diff --git a/src/core/memory.h b/src/core/memory.h index 348fee3c90..eb5b6d69ce 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -283,6 +283,12 @@ enum class FlushMode { FlushAndInvalidate, }; +/** + * Flushes and invalidates all memory in the rasterizer cache and removes any leftover state + * If flush is true, the rasterizer should flush any cached resources to RAM before clearing + */ +void RasterizerClearAll(bool flush); + /** * Flushes and invalidates any externally cached rasterizer resources touching the given virtual * address region. diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index 468d84084a..a2510292e9 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h @@ -55,6 +55,9 @@ public: /// and invalidated virtual void FlushAndInvalidateRegion(PAddr addr, u32 size) = 0; + /// Removes as much state as possible from the rasterizer in preparation for a save/load state + virtual void ClearAll(bool flush) = 0; + /// Attempt to use a faster method to perform a display transfer with is_texture_copy = 0 virtual bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) { return false; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 862dcac00a..34bac4f879 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1367,6 +1367,10 @@ void RasterizerOpenGL::FlushAndInvalidateRegion(PAddr addr, u32 size) { res_cache.InvalidateRegion(addr, size, nullptr); } +void RasterizerOpenGL::ClearAll(bool flush) { + res_cache.ClearAll(flush); +} + bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) { MICROPROFILE_SCOPE(OpenGL_Blits); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index b3356a69b6..92cca2e4e4 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -53,6 +53,7 @@ public: void FlushRegion(PAddr addr, u32 size) override; void InvalidateRegion(PAddr addr, u32 size) override; void FlushAndInvalidateRegion(PAddr addr, u32 size) override; + void ClearAll(bool flush) override; bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) override; bool AccelerateTextureCopy(const GPU::Regs::DisplayTransferConfig& config) override; bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config) override; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index af2a918a6f..4dcc64832e 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -1276,9 +1276,7 @@ void main() { } RasterizerCacheOpenGL::~RasterizerCacheOpenGL() { - FlushAll(); - while (!surface_cache.empty()) - UnregisterSurface(*surface_cache.begin()->second.begin()); + ClearAll(false); } MICROPROFILE_DEFINE(OpenGL_BlitSurface, "OpenGL", "BlitSurface", MP_RGB(128, 192, 64)); @@ -1927,6 +1925,31 @@ void RasterizerCacheOpenGL::ValidateSurface(const Surface& surface, PAddr addr, } } +void RasterizerCacheOpenGL::ClearAll(bool flush) { + const SurfaceInterval flush_interval(0x0, 0xFFFFFFFF); + // Force flush all surfaces from the cache + if (flush) { + FlushRegion(0x0, 0xFFFFFFFF); + } + // Unmark all of the marked pages + for (auto& pair : RangeFromInterval(cached_pages, flush_interval)) { + const auto interval = pair.first & flush_interval; + const int count = pair.second; + + const PAddr interval_start_addr = boost::icl::first(interval) << Memory::PAGE_BITS; + const PAddr interval_end_addr = boost::icl::last_next(interval) << Memory::PAGE_BITS; + const u32 interval_size = interval_end_addr - interval_start_addr; + + VideoCore::g_memory->RasterizerMarkRegionCached(interval_start_addr, interval_size, false); + } + + // Remove the whole cache without really looking at it. + cached_pages -= flush_interval; + dirty_regions -= flush_interval; + surface_cache -= flush_interval; + remove_surfaces.clear(); +} + void RasterizerCacheOpenGL::FlushRegion(PAddr addr, u32 size, Surface flush_surface) { if (size == 0) return; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index cd601ef29a..69322f7136 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -482,6 +482,9 @@ public: /// Flush all cached resources tracked by this cache manager void FlushAll(); + /// Clear all cached resources tracked by this cache manager + void ClearAll(bool flush); + private: void DuplicateSurface(const Surface& src_surface, const Surface& dest_surface); diff --git a/src/video_core/swrasterizer/swrasterizer.h b/src/video_core/swrasterizer/swrasterizer.h index e2292f4a4c..9e7a140f1d 100644 --- a/src/video_core/swrasterizer/swrasterizer.h +++ b/src/video_core/swrasterizer/swrasterizer.h @@ -22,6 +22,7 @@ class SWRasterizer : public RasterizerInterface { void FlushRegion(PAddr addr, u32 size) override {} void InvalidateRegion(PAddr addr, u32 size) override {} void FlushAndInvalidateRegion(PAddr addr, u32 size) override {} + void ClearAll(bool flush) override {} }; } // namespace VideoCore From c983528862987d248c6dcf0db83ed08f3c8dae76 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 19 Jan 2020 22:49:22 +0000 Subject: [PATCH 075/129] Reworked DSP serialization --- externals/boost | 2 +- src/audio_core/dsp_interface.h | 5 +++ src/audio_core/hle/hle.cpp | 37 +++++++++++++++++--- src/audio_core/hle/hle.h | 9 +++++ src/audio_core/hle/mixers.h | 12 +++++++ src/audio_core/hle/shared_memory.h | 7 ++++ src/audio_core/hle/source.h | 54 ++++++++++++++++++++++++++++-- src/core/core.cpp | 15 ++++++--- 8 files changed, 128 insertions(+), 13 deletions(-) diff --git a/externals/boost b/externals/boost index 6d7edc593b..eb10fac1e1 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit 6d7edc593be8e47c8de7bc5f7d6b32971fad0c24 +Subproject commit eb10fac1e1dfa4881c273d87e23d41509017223a diff --git a/src/audio_core/dsp_interface.h b/src/audio_core/dsp_interface.h index fc3d7cab2d..00adfa3ead 100644 --- a/src/audio_core/dsp_interface.h +++ b/src/audio_core/dsp_interface.h @@ -6,6 +6,7 @@ #include #include +#include #include "audio_core/audio_types.h" #include "audio_core/time_stretch.h" #include "common/common_types.h" @@ -113,6 +114,10 @@ private: Common::RingBuffer fifo; std::array last_frame{}; TimeStretcher time_stretcher; + + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; } // namespace AudioCore diff --git a/src/audio_core/hle/hle.cpp b/src/audio_core/hle/hle.cpp index 873d6a72e7..f96e2b642d 100644 --- a/src/audio_core/hle/hle.cpp +++ b/src/audio_core/hle/hle.cpp @@ -1,7 +1,13 @@ +#pragma optimize("", off) // Copyright 2017 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include +#include +#include +#include +#include #include "audio_core/audio_types.h" #ifdef HAVE_MF #include "audio_core/hle/wmf_decoder.h" @@ -22,11 +28,21 @@ #include "core/core.h" #include "core/core_timing.h" +SERIALIZE_EXPORT_IMPL(AudioCore::DspHle) + using InterruptType = Service::DSP::DSP_DSP::InterruptType; using Service::DSP::DSP_DSP; namespace AudioCore { +DspHle::DspHle() : DspHle(Core::System::GetInstance().Memory()) {} + +template +void DspHle::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar&* impl.get(); +} + static constexpr u64 audio_frame_ticks = 1310252ull; ///< Units: ARM11 cycles struct DspHle::Impl final { @@ -60,7 +76,7 @@ private: void AudioTickCallback(s64 cycles_late); DspState dsp_state = DspState::Off; - std::array, num_dsp_pipe> pipe_data; + std::array, num_dsp_pipe> pipe_data{}; HLE::DspMemory dsp_memory; std::array sources{{ @@ -70,14 +86,25 @@ private: HLE::Source(15), HLE::Source(16), HLE::Source(17), HLE::Source(18), HLE::Source(19), HLE::Source(20), HLE::Source(21), HLE::Source(22), HLE::Source(23), }}; - HLE::Mixers mixers; + HLE::Mixers mixers{}; DspHle& parent; - Core::TimingEventType* tick_event; + Core::TimingEventType* tick_event{}; - std::unique_ptr decoder; + std::unique_ptr decoder{}; - std::weak_ptr dsp_dsp; + std::weak_ptr dsp_dsp{}; + + template + void serialize(Archive& ar, const unsigned int) { + ar& dsp_state; + ar& pipe_data; + ar& dsp_memory.raw_memory; + ar& sources; + ar& mixers; + ar& dsp_dsp; + } + friend class boost::serialization::access; }; DspHle::Impl::Impl(DspHle& parent_, Memory::MemorySystem& memory) : parent(parent_) { diff --git a/src/audio_core/hle/hle.h b/src/audio_core/hle/hle.h index 4ab468331d..11ec2820a6 100644 --- a/src/audio_core/hle/hle.h +++ b/src/audio_core/hle/hle.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "audio_core/audio_types.h" #include "audio_core/dsp_interface.h" #include "common/common_types.h" @@ -42,6 +43,14 @@ private: struct Impl; friend struct Impl; std::unique_ptr impl; + + DspHle(); + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; } // namespace AudioCore + +BOOST_CLASS_EXPORT_KEY(AudioCore::DspHle) diff --git a/src/audio_core/hle/mixers.h b/src/audio_core/hle/mixers.h index c5bfd512f2..5043be38ce 100644 --- a/src/audio_core/hle/mixers.h +++ b/src/audio_core/hle/mixers.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include "audio_core/audio_types.h" #include "audio_core/hle/shared_memory.h" @@ -54,6 +55,17 @@ private: void DownmixAndMixIntoCurrentFrame(float gain, const QuadFrame32& samples); /// INTERNAL: Generate DspStatus based on internal state. DspStatus GetCurrentStatus() const; + + template + void serialize(Archive& ar, const unsigned int) { + ar& current_frame; + ar& state.intermediate_mixer_volume; + ar& state.mixer1_enabled; + ar& state.mixer2_enabled; + ar& state.intermediate_mix_buffer; + ar& state.output_format; + } + friend class boost::serialization::access; }; } // namespace AudioCore::HLE diff --git a/src/audio_core/hle/shared_memory.h b/src/audio_core/hle/shared_memory.h index 8ab9aa88e9..43bf1df694 100644 --- a/src/audio_core/hle/shared_memory.h +++ b/src/audio_core/hle/shared_memory.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "audio_core/audio_types.h" #include "audio_core/hle/common.h" #include "common/bit_field.h" @@ -56,6 +57,12 @@ private: return (value << 16) | (value >> 16); } u32_le storage; + + template + void serialize(Archive& ar, const unsigned int) { + ar& storage; + } + friend class boost::serialization::access; }; static_assert(std::is_trivially_copyable::value, "u32_dsp isn't trivially copyable"); diff --git a/src/audio_core/hle/source.h b/src/audio_core/hle/source.h index b0db4a5d32..17c31672bc 100644 --- a/src/audio_core/hle/source.h +++ b/src/audio_core/hle/source.h @@ -6,6 +6,10 @@ #include #include +#include +#include +#include +#include #include #include "audio_core/audio_types.h" #include "audio_core/codec.h" @@ -85,6 +89,24 @@ private: bool from_queue; u32_dsp play_position; // = 0; bool has_played; // = false; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& physical_address; + ar& length; + ar& adpcm_ps; + ar& adpcm_yn; + ar& adpcm_dirty; + ar& is_looping; + ar& buffer_id; + ar& mono_or_stereo; + ar& format; + ar& from_queue; + ar& play_position; + ar& has_played; + } + friend class boost::serialization::access; }; struct BufferOrder { @@ -107,7 +129,7 @@ private: // Buffer queue - std::priority_queue, BufferOrder> input_queue; + std::priority_queue, BufferOrder> input_queue = {}; MonoOrStereo mono_or_stereo = MonoOrStereo::Mono; Format format = Format::ADPCM; @@ -115,7 +137,7 @@ private: u32 current_sample_number = 0; u32 next_sample_number = 0; - AudioInterp::StereoBuffer16 current_buffer; + AudioInterp::StereoBuffer16 current_buffer = {}; // buffer_id state @@ -135,7 +157,27 @@ private: // Filter state - SourceFilters filters; + SourceFilters filters = {}; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& enabled; + ar& sync; + ar& gain; + ar& input_queue; + ar& mono_or_stereo; + ar& format; + ar& current_sample_number; + ar& next_sample_number; + ar& current_buffer; + ar& buffer_update; + ar& current_buffer_id; + ar& adpcm_coeffs; + ar& rate_multiplier; + ar& interpolation_mode; + } + friend class boost::serialization::access; } state; @@ -150,6 +192,12 @@ private: bool DequeueBuffer(); /// INTERNAL: Generates a SourceStatus::Status based on our internal state. SourceStatus::Status GetCurrentStatus(); + + template + void serialize(Archive& ar, const unsigned int) { + ar& state; + } + friend class boost::serialization::access; }; } // namespace AudioCore::HLE diff --git a/src/core/core.cpp b/src/core/core.cpp index aeab0d2b5b..03b64b04e1 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -1,3 +1,4 @@ +#pragma optimize("", off) // Copyright 2014 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -244,8 +245,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo timing = std::make_unique(); - kernel = std::make_unique(*memory, *timing, - [this] { PrepareReschedule(); }, system_mode); + kernel = std::make_unique( + *memory, *timing, [this] { PrepareReschedule(); }, system_mode); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 @@ -445,14 +446,20 @@ void System::serialize(Archive& ar, const unsigned int file_version) { ar&* service_manager.get(); ar& GPU::g_regs; ar& LCD::g_regs; - ar & dsp_core->GetDspMemory(); + if (Archive::is_loading::value) { + dsp_core.reset(); + } + ar& dsp_core; ar&* memory.get(); ar&* kernel.get(); // This needs to be set from somewhere - might as well be here! if (Archive::is_loading::value) { Service::GSP::SetGlobalModule(*this); - DSP().SetServiceToInterrupt(ServiceManager().GetService("dsp::DSP")); + + memory->SetDSP(*dsp_core); + dsp_core->SetSink(Settings::values.sink_id, Settings::values.audio_device_id); + dsp_core->EnableStretching(Settings::values.enable_audio_stretching); } } From 246ae84a521fa286b21beca30638f2150f52f5d9 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 20 Jan 2020 21:32:38 +0000 Subject: [PATCH 076/129] Pretty sure ARM/Thread serialization works now --- src/core/arm/arm_interface.h | 17 +++++++++++++++-- src/core/arm/dynarmic/arm_dynarmic.cpp | 14 +++++++++++--- src/core/arm/dynarmic/arm_dynarmic.h | 4 +++- src/core/arm/dyncom/arm_dyncom.cpp | 8 +++++++- src/core/arm/dyncom/arm_dyncom.h | 4 +++- src/core/core.cpp | 3 --- src/core/hle/kernel/kernel.cpp | 2 +- src/core/hle/kernel/thread.h | 1 - 8 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index e416a5f4ce..8ef51519b8 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -11,6 +11,10 @@ #include "core/arm/skyeye_common/arm_regformat.h" #include "core/arm/skyeye_common/vfp/asm_vfp.h" +namespace Memory { +struct PageTable; +} + /// Generic ARM11 CPU interface class ARM_Interface : NonCopyable { public: @@ -111,7 +115,9 @@ public: virtual void InvalidateCacheRange(u32 start_address, std::size_t length) = 0; /// Notify CPU emulation that page tables have changed - virtual void PageTableChanged() = 0; + virtual void SetPageTable(const std::shared_ptr& page_table) = 0; + + virtual std::shared_ptr GetPageTable() const = 0; /** * Set the Program Counter to an address @@ -214,11 +220,15 @@ public: /// Prepare core for thread reschedule (if needed to correctly handle state) virtual void PrepareReschedule() = 0; + virtual void PurgeState() = 0; + private: friend class boost::serialization::access; template void save(Archive& ar, const unsigned int file_version) const { + auto page_table = GetPageTable(); + ar << page_table; for (auto i = 0; i < 15; i++) { auto r = GetReg(i); ar << r; @@ -243,6 +253,10 @@ private: template void load(Archive& ar, const unsigned int file_version) { + PurgeState(); + std::shared_ptr page_table = nullptr; + ar >> page_table; + SetPageTable(page_table); u32 r; for (auto i = 0; i < 15; i++) { ar >> r; @@ -264,7 +278,6 @@ private: ar >> r; SetCP15Register(static_cast(i), r); } - ClearInstructionCache(); } BOOST_SERIALIZATION_SPLIT_MEMBER() diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index b6494d40eb..33bc03a4f8 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -167,7 +167,7 @@ ARM_Dynarmic::ARM_Dynarmic(Core::System* system, Memory::MemorySystem& memory, PrivilegeMode initial_mode) : system(*system), memory(memory), cb(std::make_unique(*this)) { interpreter_state = std::make_shared(system, memory, initial_mode); - PageTableChanged(); + SetPageTable(memory.GetCurrentPageTable()); } ARM_Dynarmic::~ARM_Dynarmic() = default; @@ -281,8 +281,12 @@ void ARM_Dynarmic::InvalidateCacheRange(u32 start_address, std::size_t length) { jit->InvalidateCacheRange(start_address, length); } -void ARM_Dynarmic::PageTableChanged() { - current_page_table = memory.GetCurrentPageTable(); +std::shared_ptr ARM_Dynarmic::GetPageTable() const { + return current_page_table; +} + +void ARM_Dynarmic::SetPageTable(const std::shared_ptr& page_table) { + current_page_table = page_table; Dynarmic::A32::Context ctx{}; if (jit) { jit->SaveContext(ctx); @@ -309,3 +313,7 @@ std::unique_ptr ARM_Dynarmic::MakeJit() { config.define_unpredictable_behaviour = true; return std::make_unique(config); } + +void ARM_Dynarmic::PurgeState() { + ClearInstructionCache(); +} diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index 690c1aa2e2..c4d01835da 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -51,7 +51,9 @@ public: void ClearInstructionCache() override; void InvalidateCacheRange(u32 start_address, std::size_t length) override; - void PageTableChanged() override; + void SetPageTable(const std::shared_ptr& page_table) override; + std::shared_ptr GetPageTable() const override; + void PurgeState() override; private: friend class DynarmicUserCallbacks; diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index 6b67644e79..c069b428e4 100644 --- a/src/core/arm/dyncom/arm_dyncom.cpp +++ b/src/core/arm/dyncom/arm_dyncom.cpp @@ -94,10 +94,16 @@ void ARM_DynCom::InvalidateCacheRange(u32, std::size_t) { ClearInstructionCache(); } -void ARM_DynCom::PageTableChanged() { +void ARM_DynCom::SetPageTable(const std::shared_ptr& page_table) { ClearInstructionCache(); } +std::shared_ptr ARM_DynCom::GetPageTable() const { + return nullptr; +} + +void ARM_DynCom::PurgeState() {} + void ARM_DynCom::SetPC(u32 pc) { state->Reg[15] = pc; } diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h index 7497b765fb..39d55a62aa 100644 --- a/src/core/arm/dyncom/arm_dyncom.h +++ b/src/core/arm/dyncom/arm_dyncom.h @@ -29,7 +29,6 @@ public: void ClearInstructionCache() override; void InvalidateCacheRange(u32 start_address, std::size_t length) override; - void PageTableChanged() override; void SetPC(u32 pc) override; u32 GetPC() const override; @@ -48,7 +47,10 @@ public: void SaveContext(const std::unique_ptr& arg) override; void LoadContext(const std::unique_ptr& arg) override; + void SetPageTable(const std::shared_ptr& page_table) override; + std::shared_ptr GetPageTable() const override; void PrepareReschedule() override; + void PurgeState() override; private: void ExecuteInstructions(u64 num_instructions); diff --git a/src/core/core.cpp b/src/core/core.cpp index 03b64b04e1..18c2e77e11 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -486,9 +486,6 @@ void System::Load(std::istream& stream) { } VideoCore::Load(stream); - // Flush state through: - Kernel().SetCurrentProcess(Kernel().GetCurrentProcess()); - } catch (const std::exception& e) { LOG_ERROR(Core, "Error loading: {}", e.what()); } diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 3c3dfc6c6b..ea3da508e1 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -61,7 +61,7 @@ void KernelSystem::SetCurrentProcess(std::shared_ptr process) { void KernelSystem::SetCurrentMemoryPageTable(std::shared_ptr page_table) { memory.SetCurrentPageTable(page_table); if (current_cpu != nullptr) { - current_cpu->PageTableChanged(); // notify the CPU the page table in memory has changed + current_cpu->SetPageTable(page_table); } } diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 0286e210d6..c64e240718 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -172,7 +172,6 @@ private: ar& ready_queue; ar& wakeup_callback_table; ar& thread_list; - SwitchContext(current_thread.get()); } }; From 5aa5cd60641401878158644a40007f9040732bae Mon Sep 17 00:00:00 2001 From: zhupengfei Date: Thu, 13 Feb 2020 17:26:21 +0800 Subject: [PATCH 077/129] Fix externals/boost spec --- externals/boost | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/boost b/externals/boost index eb10fac1e1..6d7edc593b 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit eb10fac1e1dfa4881c273d87e23d41509017223a +Subproject commit 6d7edc593be8e47c8de7bc5f7d6b32971fad0c24 From 7e8041df28252b0c974741ffecc87dcf87a7c406 Mon Sep 17 00:00:00 2001 From: zhupengfei Date: Fri, 14 Feb 2020 17:13:53 +0800 Subject: [PATCH 078/129] kernel/timer: Add missing base object --- src/core/hle/kernel/timer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index d2c513024d..b591c1b03f 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h @@ -115,6 +115,7 @@ private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); ar& reset_type; ar& initial_delay; ar& interval_delay; From 57efc419734aa8b9f187de2c610548061acef74b Mon Sep 17 00:00:00 2001 From: zhupengfei Date: Fri, 14 Feb 2020 17:15:08 +0800 Subject: [PATCH 079/129] service/cecd: Add missing SessionData serialization --- src/core/hle/service/cecd/cecd.cpp | 1 + src/core/hle/service/cecd/cecd.h | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index f13df6926b..36263f6222 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -27,6 +27,7 @@ SERVICE_CONSTRUCT_IMPL(Service::CECD::Module) SERIALIZE_EXPORT_IMPL(Service::CECD::Module) +SERIALIZE_EXPORT_IMPL(Service::CECD::Module::SessionData) namespace Service::CECD { diff --git a/src/core/hle/service/cecd/cecd.h b/src/core/hle/service/cecd/cecd.h index dd7fff7cb9..0870f31bf9 100644 --- a/src/core/hle/service/cecd/cecd.h +++ b/src/core/hle/service/cecd/cecd.h @@ -248,6 +248,19 @@ public: FileSys::Path path; std::unique_ptr file; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object( + *this); + ar& ncch_program_id; + ar& data_path_type; + ar& open_mode.raw; + ar& path; + ar& file; + } + friend class boost::serialization::access; }; class Interface : public ServiceFramework { @@ -626,3 +639,4 @@ void InstallInterfaces(Core::System& system); SERVICE_CONSTRUCT(Service::CECD::Module) BOOST_CLASS_EXPORT_KEY(Service::CECD::Module) +BOOST_CLASS_EXPORT_KEY(Service::CECD::Module::SessionData) From 7d880f94db5485fdda342cf72cedf0e7901a2293 Mon Sep 17 00:00:00 2001 From: zhupengfei Date: Sun, 16 Feb 2020 23:25:30 +0800 Subject: [PATCH 080/129] Add simple zstd compression Just a simple default compression is able to shrink savestate file size from ~160MB to ~20MB. --- src/core/core.cpp | 29 +++++++++++++++++++++++------ src/core/core.h | 2 +- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 18c2e77e11..0bbb79aead 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -13,6 +13,7 @@ #include "common/archives.h" #include "common/logging/log.h" #include "common/texture.h" +#include "common/zstd_compression.h" #include "core/arm/arm_interface.h" #ifdef ARCHITECTURE_x86_64 #include "core/arm/dynarmic/arm_dynarmic.h" @@ -116,7 +117,7 @@ System::ResultStatus System::RunLoop(bool tight_loop) { case Signal::Load: { LOG_INFO(Core, "Begin load"); auto stream = std::ifstream("save0.citrasave", std::fstream::binary); - System::Load(stream); + System::Load(stream, FileUtil::GetSize("save0.citrasave")); LOG_INFO(Core, "Load completed"); } break; case Signal::Save: { @@ -464,27 +465,43 @@ void System::serialize(Archive& ar, const unsigned int file_version) { } void System::Save(std::ostream& stream) const { + std::ostringstream sstream{std::ios_base::binary}; try { { - oarchive oa{stream}; + oarchive oa{sstream}; oa&* this; } - VideoCore::Save(stream); + VideoCore::Save(sstream); } catch (const std::exception& e) { LOG_ERROR(Core, "Error saving: {}", e.what()); } + const std::string& str{sstream.str()}; + auto buffer = Common::Compression::CompressDataZSTDDefault( + reinterpret_cast(str.data()), str.size()); + stream.write(reinterpret_cast(buffer.data()), buffer.size()); } -void System::Load(std::istream& stream) { +void System::Load(std::istream& stream, std::size_t size) { + std::vector decompressed; + { + std::vector buffer(size); + stream.read(reinterpret_cast(buffer.data()), size); + decompressed = Common::Compression::DecompressDataZSTD(buffer); + } + std::istringstream sstream{ + std::string{reinterpret_cast(decompressed.data()), decompressed.size()}, + std::ios_base::binary}; + decompressed.clear(); + try { { - iarchive ia{stream}; + iarchive ia{sstream}; ia&* this; } - VideoCore::Load(stream); + VideoCore::Load(sstream); } catch (const std::exception& e) { LOG_ERROR(Core, "Error loading: {}", e.what()); diff --git a/src/core/core.h b/src/core/core.h index a3b2f5cddb..80c1505b5d 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -278,7 +278,7 @@ public: void Save(std::ostream& stream) const; - void Load(std::istream& stream); + void Load(std::istream& stream, std::size_t size); private: /** From a487016cb42d0d36ed8706909f4423571141fcaf Mon Sep 17 00:00:00 2001 From: zhupengfei Date: Tue, 18 Feb 2020 13:19:52 +0800 Subject: [PATCH 081/129] core, citra_qt: Implement a save states file format and slot UI 10 slots are offered along with 'Save to Oldest Slot' and 'Load from Newest Slot'. The savestate format is similar to the movie file format. It is called CST (Citra SavesTate), and is basically a 0x100 byte header (consisting of magic, revision, creation time and title ID) followed by Zstd compressed raw savestate data. The savestate files are saved to the `states` folder in Citra's user folder. The files are named like `.<Slot ID>.cst`. --- src/citra_qt/main.cpp | 111 +++++++++++++++++++++--- src/citra_qt/main.h | 16 +++- src/citra_qt/main.ui | 29 ++++++- src/common/common_paths.h | 1 + src/common/file_util.cpp | 1 + src/common/file_util.h | 1 + src/core/CMakeLists.txt | 2 + src/core/core.cpp | 85 ++++++------------- src/core/core.h | 14 ++- src/core/savestate.cpp | 174 ++++++++++++++++++++++++++++++++++++++ src/core/savestate.h | 27 ++++++ 11 files changed, 384 insertions(+), 77 deletions(-) create mode 100644 src/core/savestate.cpp create mode 100644 src/core/savestate.h diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 7fe4936f5f..de66e14ac0 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -79,6 +79,7 @@ #include "core/hle/service/nfc/nfc.h" #include "core/loader/loader.h" #include "core/movie.h" +#include "core/savestate.h" #include "core/settings.h" #include "game_list_p.h" #include "video_core/renderer_base.h" @@ -166,6 +167,7 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) { InitializeWidgets(); InitializeDebugWidgets(); InitializeRecentFileMenuActions(); + InitializeSaveStateMenuActions(); InitializeHotkeys(); ShowUpdaterWidgets(); @@ -383,6 +385,32 @@ void GMainWindow::InitializeRecentFileMenuActions() { UpdateRecentFiles(); } +void GMainWindow::InitializeSaveStateMenuActions() { + for (u32 i = 0; i < Core::SaveStateSlotCount; ++i) { + actions_load_state[i] = new QAction(this); + actions_load_state[i]->setData(i + 1); + connect(actions_load_state[i], &QAction::triggered, this, &GMainWindow::OnLoadState); + ui.menu_Load_State->addAction(actions_load_state[i]); + + actions_save_state[i] = new QAction(this); + actions_save_state[i]->setData(i + 1); + connect(actions_save_state[i], &QAction::triggered, this, &GMainWindow::OnSaveState); + ui.menu_Save_State->addAction(actions_save_state[i]); + } + + connect(ui.action_Load_from_Newest_Slot, &QAction::triggered, + [this] { actions_load_state[newest_slot - 1]->trigger(); }); + connect(ui.action_Save_to_Oldest_Slot, &QAction::triggered, + [this] { actions_save_state[oldest_slot - 1]->trigger(); }); + + connect(ui.menu_Load_State->menuAction(), &QAction::hovered, this, + &GMainWindow::UpdateSaveStates); + connect(ui.menu_Save_State->menuAction(), &QAction::hovered, this, + &GMainWindow::UpdateSaveStates); + + UpdateSaveStates(); +} + void GMainWindow::InitializeHotkeys() { hotkey_registry.LoadHotkeys(); @@ -607,8 +635,6 @@ void GMainWindow::ConnectMenuEvents() { &GMainWindow::OnMenuReportCompatibility); connect(ui.action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure); connect(ui.action_Cheats, &QAction::triggered, this, &GMainWindow::OnCheats); - connect(ui.action_Save, &QAction::triggered, this, &GMainWindow::OnSave); - connect(ui.action_Load, &QAction::triggered, this, &GMainWindow::OnLoad); // View connect(ui.action_Single_Window_Mode, &QAction::triggered, this, @@ -1036,8 +1062,6 @@ void GMainWindow::ShutdownGame() { ui.action_Stop->setEnabled(false); ui.action_Restart->setEnabled(false); ui.action_Cheats->setEnabled(false); - ui.action_Save->setEnabled(false); - ui.action_Load->setEnabled(false); ui.action_Load_Amiibo->setEnabled(false); ui.action_Remove_Amiibo->setEnabled(false); ui.action_Report_Compatibility->setEnabled(false); @@ -1061,6 +1085,8 @@ void GMainWindow::ShutdownGame() { game_fps_label->setVisible(false); emu_frametime_label->setVisible(false); + UpdateSaveStates(); + emulation_running = false; if (defer_update_prompt) { @@ -1107,6 +1133,62 @@ void GMainWindow::UpdateRecentFiles() { ui.menu_recent_files->setEnabled(num_recent_files != 0); } +void GMainWindow::UpdateSaveStates() { + if (!Core::System::GetInstance().IsPoweredOn()) { + ui.menu_Load_State->setEnabled(false); + ui.menu_Save_State->setEnabled(false); + return; + } + + ui.menu_Load_State->setEnabled(true); + ui.menu_Save_State->setEnabled(true); + ui.action_Load_from_Newest_Slot->setEnabled(false); + + oldest_slot = newest_slot = 0; + oldest_slot_time = std::numeric_limits<u64>::max(); + newest_slot_time = 0; + + u64 title_id; + if (Core::System::GetInstance().GetAppLoader().ReadProgramId(title_id) != + Loader::ResultStatus::Success) { + return; + } + auto savestates = Core::ListSaveStates(title_id); + for (u32 i = 0; i < Core::SaveStateSlotCount; ++i) { + actions_load_state[i]->setEnabled(false); + actions_load_state[i]->setText(tr("Slot %1").arg(i + 1)); + actions_save_state[i]->setText(tr("Slot %1").arg(i + 1)); + } + for (const auto& savestate : savestates) { + const auto text = tr("Slot %1 - %2") + .arg(savestate.slot) + .arg(QDateTime::fromSecsSinceEpoch(savestate.time) + .toString(QStringLiteral("yyyy-MM-dd hh:mm:ss"))); + actions_load_state[savestate.slot - 1]->setEnabled(true); + actions_load_state[savestate.slot - 1]->setText(text); + actions_save_state[savestate.slot - 1]->setText(text); + + ui.action_Load_from_Newest_Slot->setEnabled(true); + + if (savestate.time > newest_slot_time) { + newest_slot = savestate.slot; + newest_slot_time = savestate.time; + } + if (savestate.time < oldest_slot_time) { + oldest_slot = savestate.slot; + oldest_slot_time = savestate.time; + } + } + for (u32 i = 0; i < Core::SaveStateSlotCount; ++i) { + if (!actions_load_state[i]->isEnabled()) { + // Prefer empty slot + oldest_slot = i + 1; + oldest_slot_time = 0; + break; + } + } +} + void GMainWindow::OnGameListLoadFile(QString game_path) { BootGame(game_path); } @@ -1348,14 +1430,14 @@ void GMainWindow::OnStartGame() { ui.action_Stop->setEnabled(true); ui.action_Restart->setEnabled(true); ui.action_Cheats->setEnabled(true); - ui.action_Save->setEnabled(true); - ui.action_Load->setEnabled(true); ui.action_Load_Amiibo->setEnabled(true); ui.action_Report_Compatibility->setEnabled(true); ui.action_Enable_Frame_Advancing->setEnabled(true); ui.action_Capture_Screenshot->setEnabled(true); discord_rpc->Update(); + + UpdateSaveStates(); } void GMainWindow::OnPauseGame() { @@ -1503,14 +1585,19 @@ void GMainWindow::OnCheats() { cheat_dialog.exec(); } -void GMainWindow::OnSave() { - Core::System::GetInstance().SendSignal(Core::System::Signal::Save); +void GMainWindow::OnSaveState() { + QAction* action = qobject_cast<QAction*>(sender()); + assert(action); + + Core::System::GetInstance().SendSignal(Core::System::Signal::Save, action->data().toUInt()); + UpdateSaveStates(); } -void GMainWindow::OnLoad() { - if (QFileInfo("save0.citrasave").exists()) { - Core::System::GetInstance().SendSignal(Core::System::Signal::Load); - } +void GMainWindow::OnLoadState() { + QAction* action = qobject_cast<QAction*>(sender()); + assert(action); + + Core::System::GetInstance().SendSignal(Core::System::Signal::Load, action->data().toUInt()); } void GMainWindow::OnConfigure() { diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h index 1858d5988f..ebe1a013af 100644 --- a/src/citra_qt/main.h +++ b/src/citra_qt/main.h @@ -4,6 +4,7 @@ #pragma once +#include <array> #include <memory> #include <QLabel> #include <QMainWindow> @@ -14,6 +15,7 @@ #include "common/announce_multiplayer_room.h" #include "core/core.h" #include "core/hle/service/am/am.h" +#include "core/savestate.h" #include "ui_main.h" class AboutDialog; @@ -106,6 +108,7 @@ private: void InitializeWidgets(); void InitializeDebugWidgets(); void InitializeRecentFileMenuActions(); + void InitializeSaveStateMenuActions(); void SetDefaultUIGeometry(); void SyncMenuUISettings(); @@ -149,6 +152,8 @@ private: */ void UpdateRecentFiles(); + void UpdateSaveStates(); + /** * If the emulation is running, * asks the user if he really want to close the emulator @@ -163,8 +168,8 @@ private slots: void OnStartGame(); void OnPauseGame(); void OnStopGame(); - void OnSave(); - void OnLoad(); + void OnSaveState(); + void OnLoadState(); void OnMenuReportCompatibility(); /// Called whenever a user selects a game in the game list widget. void OnGameListLoadFile(QString game_path); @@ -276,6 +281,13 @@ private: bool defer_update_prompt = false; QAction* actions_recent_files[max_recent_files_item]; + std::array<QAction*, Core::SaveStateSlotCount> actions_load_state; + std::array<QAction*, Core::SaveStateSlotCount> actions_save_state; + + u32 oldest_slot; + u64 oldest_slot_time; + u32 newest_slot; + u64 newest_slot_time; QTranslator translator; diff --git a/src/citra_qt/main.ui b/src/citra_qt/main.ui index c0c38e4c8b..2eff98083b 100644 --- a/src/citra_qt/main.ui +++ b/src/citra_qt/main.ui @@ -79,17 +79,32 @@ <property name="title"> <string>&Emulation</string> </property> + <widget class="QMenu" name="menu_Save_State"> + <property name="title"> + <string>Save State</string> + </property> + <addaction name="action_Save_to_Oldest_Slot"/> + <addaction name="separator"/> + </widget> + <widget class="QMenu" name="menu_Load_State"> + <property name="title"> + <string>Load State</string> + </property> + <addaction name="action_Load_from_Newest_Slot"/> + <addaction name="separator"/> + </widget> <addaction name="action_Start"/> <addaction name="action_Pause"/> <addaction name="action_Stop"/> <addaction name="action_Restart"/> <addaction name="separator"/> + <addaction name="menu_Load_State"/> + <addaction name="menu_Save_State"/> + <addaction name="separator"/> <addaction name="action_Report_Compatibility"/> <addaction name="separator"/> <addaction name="action_Configure"/> <addaction name="action_Cheats"/> - <addaction name="action_Save"/> - <addaction name="action_Load"/> </widget> <widget class="QMenu" name="menu_View"> <property name="title"> @@ -253,6 +268,16 @@ <string>Single Window Mode</string> </property> </action> + <action name="action_Save_to_Oldest_Slot"> + <property name="text"> + <string>Save to Oldest Slot</string> + </property> + </action> + <action name="action_Load_from_Newest_Slot"> + <property name="text"> + <string>Load from Newest Slot</string> + </property> + </action> <action name="action_Configure"> <property name="text"> <string>Configure...</string> diff --git a/src/common/common_paths.h b/src/common/common_paths.h index 13e71615e6..eec4dde9c6 100644 --- a/src/common/common_paths.h +++ b/src/common/common_paths.h @@ -47,6 +47,7 @@ #define DUMP_DIR "dump" #define LOAD_DIR "load" #define SHADER_DIR "shaders" +#define STATES_DIR "states" // Filenames // Files in the directory returned by GetUserPath(UserPath::LogDir) diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index c5da82973c..cd3f4e1027 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -725,6 +725,7 @@ void SetUserPath(const std::string& path) { g_paths.emplace(UserPath::ShaderDir, user_path + SHADER_DIR DIR_SEP); g_paths.emplace(UserPath::DumpDir, user_path + DUMP_DIR DIR_SEP); g_paths.emplace(UserPath::LoadDir, user_path + LOAD_DIR DIR_SEP); + g_paths.emplace(UserPath::StatesDir, user_path + STATES_DIR DIR_SEP); } const std::string& GetUserPath(UserPath path) { diff --git a/src/common/file_util.h b/src/common/file_util.h index 0368d36658..8af5a2a613 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -36,6 +36,7 @@ enum class UserPath { RootDir, SDMCDir, ShaderDir, + StatesDir, SysDataDir, UserDir, }; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index c6908c59a6..2b02ffc416 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -447,6 +447,8 @@ add_library(core STATIC rpc/server.h rpc/udp_server.cpp rpc/udp_server.h + savestate.cpp + savestate.h settings.cpp settings.h telemetry_session.cpp diff --git a/src/core/core.cpp b/src/core/core.cpp index 0bbb79aead..f17474a85e 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -10,10 +10,8 @@ #include "audio_core/dsp_interface.h" #include "audio_core/hle/hle.h" #include "audio_core/lle/lle.h" -#include "common/archives.h" #include "common/logging/log.h" #include "common/texture.h" -#include "common/zstd_compression.h" #include "core/arm/arm_interface.h" #ifdef ARCHITECTURE_x86_64 #include "core/arm/dynarmic/arm_dynarmic.h" @@ -63,6 +61,8 @@ Kernel::KernelSystem& Global() { return System::GetInstance().Kernel(); } +System::~System() = default; + System::ResultStatus System::RunLoop(bool tight_loop) { status = ResultStatus::Success; if (!cpu_core) { @@ -106,7 +106,16 @@ System::ResultStatus System::RunLoop(bool tight_loop) { HW::Update(); Reschedule(); - auto signal = current_signal.exchange(Signal::None); + Signal signal{Signal::None}; + u32 param{}; + { + std::lock_guard lock{signal_mutex}; + if (current_signal != Signal::None) { + signal = current_signal; + param = signal_param; + current_signal = Signal::None; + } + } switch (signal) { case Signal::Reset: Reset(); @@ -116,14 +125,16 @@ System::ResultStatus System::RunLoop(bool tight_loop) { break; case Signal::Load: { LOG_INFO(Core, "Begin load"); - auto stream = std::ifstream("save0.citrasave", std::fstream::binary); - System::Load(stream, FileUtil::GetSize("save0.citrasave")); + System::LoadState(param); + // auto stream = std::ifstream("save0.citrasave", std::fstream::binary); + // System::Load(stream, FileUtil::GetSize("save0.citrasave")); LOG_INFO(Core, "Load completed"); } break; case Signal::Save: { LOG_INFO(Core, "Begin save"); - auto stream = std::ofstream("save0.citrasave", std::fstream::binary); - System::Save(stream); + System::SaveState(param); + // auto stream = std::ofstream("save0.citrasave", std::fstream::binary); + // System::Save(stream); LOG_INFO(Core, "Save completed"); } break; default: @@ -133,12 +144,14 @@ System::ResultStatus System::RunLoop(bool tight_loop) { return status; } -bool System::SendSignal(System::Signal signal) { - auto prev = System::Signal::None; - if (!current_signal.compare_exchange_strong(prev, signal)) { - LOG_ERROR(Core, "Unable to {} as {} is ongoing", signal, prev); +bool System::SendSignal(System::Signal signal, u32 param) { + std::lock_guard lock{signal_mutex}; + if (current_signal != signal && current_signal != Signal::None) { + LOG_ERROR(Core, "Unable to {} as {} is ongoing", signal, current_signal); return false; } + current_signal = signal; + signal_param = param; return true; } @@ -196,7 +209,7 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st } } cheat_engine = std::make_unique<Cheats::CheatEngine>(*this); - u64 title_id{0}; + title_id = 0; if (app_loader->ReadProgramId(title_id) != Loader::ResultStatus::Success) { LOG_ERROR(Core, "Failed to find title id for ROM (Error {})", static_cast<u32>(load_result)); @@ -246,8 +259,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo timing = std::make_unique<Timing>(); - kernel = std::make_unique<Kernel::KernelSystem>( - *memory, *timing, [this] { PrepareReschedule(); }, system_mode); + kernel = std::make_unique<Kernel::KernelSystem>(*memory, *timing, + [this] { PrepareReschedule(); }, system_mode); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 @@ -464,48 +477,6 @@ void System::serialize(Archive& ar, const unsigned int file_version) { } } -void System::Save(std::ostream& stream) const { - std::ostringstream sstream{std::ios_base::binary}; - try { - - { - oarchive oa{sstream}; - oa&* this; - } - VideoCore::Save(sstream); - - } catch (const std::exception& e) { - LOG_ERROR(Core, "Error saving: {}", e.what()); - } - const std::string& str{sstream.str()}; - auto buffer = Common::Compression::CompressDataZSTDDefault( - reinterpret_cast<const u8*>(str.data()), str.size()); - stream.write(reinterpret_cast<const char*>(buffer.data()), buffer.size()); -} - -void System::Load(std::istream& stream, std::size_t size) { - std::vector<u8> decompressed; - { - std::vector<u8> buffer(size); - stream.read(reinterpret_cast<char*>(buffer.data()), size); - decompressed = Common::Compression::DecompressDataZSTD(buffer); - } - std::istringstream sstream{ - std::string{reinterpret_cast<char*>(decompressed.data()), decompressed.size()}, - std::ios_base::binary}; - decompressed.clear(); - - try { - - { - iarchive ia{sstream}; - ia&* this; - } - VideoCore::Load(sstream); - - } catch (const std::exception& e) { - LOG_ERROR(Core, "Error loading: {}", e.what()); - } -} +SERIALIZE_IMPL(System) } // namespace Core diff --git a/src/core/core.h b/src/core/core.h index 80c1505b5d..0ce6924cd0 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -5,6 +5,7 @@ #pragma once #include <memory> +#include <mutex> #include <string> #include "boost/serialization/access.hpp" #include "common/common_types.h" @@ -92,6 +93,8 @@ public: ErrorUnknown ///< Any other error }; + ~System(); + /** * Run the core CPU loop * This function runs the core for the specified number of CPU instructions before trying to @@ -118,7 +121,7 @@ public: enum class Signal : u32 { None, Shutdown, Reset, Save, Load }; - bool SendSignal(Signal signal); + bool SendSignal(Signal signal, u32 param = 0); /// Request reset of the system void RequestReset() { @@ -276,9 +279,9 @@ public: return registered_image_interface; } - void Save(std::ostream& stream) const; + void SaveState(u32 slot) const; - void Load(std::istream& stream, std::size_t size); + void LoadState(u32 slot); private: /** @@ -344,8 +347,11 @@ private: /// Saved variables for reset Frontend::EmuWindow* m_emu_window; std::string m_filepath; + u64 title_id; - std::atomic<Signal> current_signal; + std::mutex signal_mutex; + Signal current_signal; + u32 signal_param; friend class boost::serialization::access; template <typename Archive> diff --git a/src/core/savestate.cpp b/src/core/savestate.cpp new file mode 100644 index 0000000000..d52789b2c2 --- /dev/null +++ b/src/core/savestate.cpp @@ -0,0 +1,174 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <chrono> +#include <cryptopp/hex.h> +#include "common/archives.h" +#include "common/logging/log.h" +#include "common/scm_rev.h" +#include "common/zstd_compression.h" +#include "core/core.h" +#include "core/savestate.h" +#include "video_core/video_core.h" + +namespace Core { + +#pragma pack(push, 1) +struct CSTHeader { + std::array<u8, 4> filetype; /// Unique Identifier to check the file type (always "CST"0x1B) + u64_le program_id; /// ID of the ROM being executed. Also called title_id + std::array<u8, 20> revision; /// Git hash of the revision this savestate was created with + u64_le time; /// The time when this save state was created + + std::array<u8, 216> reserved; /// Make heading 256 bytes so it has consistent size +}; +static_assert(sizeof(CSTHeader) == 256, "CSTHeader should be 256 bytes"); +#pragma pack(pop) + +constexpr std::array<u8, 4> header_magic_bytes{{'C', 'S', 'T', 0x1B}}; + +std::string GetSaveStatePath(u64 program_id, u32 slot) { + return fmt::format("{}{:016X}.{:02d}.cst", FileUtil::GetUserPath(FileUtil::UserPath::StatesDir), + program_id, slot); +} + +std::vector<SaveStateInfo> ListSaveStates(u64 program_id) { + std::vector<SaveStateInfo> result; + for (u32 slot = 1; slot <= SaveStateSlotCount; ++slot) { + const auto path = GetSaveStatePath(program_id, slot); + if (!FileUtil::Exists(path)) { + continue; + } + + SaveStateInfo info; + info.slot = slot; + + FileUtil::IOFile file(path, "rb"); + if (!file) { + LOG_ERROR(Core, "Could not open file {}", path); + continue; + } + CSTHeader header; + if (file.GetSize() < sizeof(header)) { + LOG_ERROR(Core, "File too small {}", path); + continue; + } + if (file.ReadBytes(&header, sizeof(header)) != sizeof(header)) { + LOG_ERROR(Core, "Could not read from file {}", path); + continue; + } + if (header.filetype != header_magic_bytes) { + LOG_WARNING(Core, "Invalid save state file {}", path); + continue; + } + info.time = header.time; + + if (header.program_id != program_id) { + LOG_WARNING(Core, "Save state file isn't for the current game {}", path); + continue; + } + std::string revision = fmt::format("{:02x}", fmt::join(header.revision, "")); + if (revision == Common::g_scm_rev) { + info.status = SaveStateInfo::ValidationStatus::OK; + } else { + LOG_WARNING(Core, "Save state file created from a different revision {}", path); + info.status = SaveStateInfo::ValidationStatus::RevisionDismatch; + } + result.emplace_back(std::move(info)); + } + return result; +} + +void System::SaveState(u32 slot) const { + std::ostringstream sstream{std::ios_base::binary}; + try { + + { + oarchive oa{sstream}; + oa&* this; + } + VideoCore::Save(sstream); + + } catch (const std::exception& e) { + LOG_ERROR(Core, "Error saving: {}", e.what()); + } + const std::string& str{sstream.str()}; + auto buffer = Common::Compression::CompressDataZSTDDefault( + reinterpret_cast<const u8*>(str.data()), str.size()); + + const auto path = GetSaveStatePath(title_id, slot); + if (!FileUtil::CreateFullPath(path)) { + LOG_ERROR(Core, "Could not create path {}", path); + return; + } + + FileUtil::IOFile file(path, "wb"); + if (!file) { + LOG_ERROR(Core, "Could not open file {}", path); + return; + } + + CSTHeader header{}; + header.filetype = header_magic_bytes; + header.program_id = title_id; + std::string rev_bytes; + CryptoPP::StringSource(Common::g_scm_rev, true, + new CryptoPP::HexDecoder(new CryptoPP::StringSink(rev_bytes))); + std::memcpy(header.revision.data(), rev_bytes.data(), sizeof(header.revision)); + header.time = std::chrono::duration_cast<std::chrono::seconds>( + std::chrono::system_clock::now().time_since_epoch()) + .count(); + + if (file.WriteBytes(&header, sizeof(header)) != sizeof(header)) { + LOG_ERROR(Core, "Could not write to file {}", path); + return; + } + if (file.WriteBytes(buffer.data(), buffer.size()) != buffer.size()) { + LOG_ERROR(Core, "Could not write to file {}", path); + return; + } +} + +void System::LoadState(u32 slot) { + const auto path = GetSaveStatePath(title_id, slot); + if (!FileUtil::Exists(path)) { + LOG_ERROR(Core, "File not exist {}", path); + return; + } + + std::vector<u8> decompressed; + { + std::vector<u8> buffer(FileUtil::GetSize(path) - sizeof(CSTHeader)); + + FileUtil::IOFile file(path, "rb"); + if (!file) { + LOG_ERROR(Core, "Could not open file {}", path); + return; + } + file.Seek(sizeof(CSTHeader), SEEK_SET); // Skip header + if (file.ReadBytes(buffer.data(), buffer.size()) != buffer.size()) { + LOG_ERROR(Core, "Could not read from file {}", path); + return; + } + decompressed = Common::Compression::DecompressDataZSTD(buffer); + } + std::istringstream sstream{ + std::string{reinterpret_cast<char*>(decompressed.data()), decompressed.size()}, + std::ios_base::binary}; + decompressed.clear(); + + try { + + { + iarchive ia{sstream}; + ia&* this; + } + VideoCore::Load(sstream); + + } catch (const std::exception& e) { + LOG_ERROR(Core, "Error loading: {}", e.what()); + } +} + +} // namespace Core diff --git a/src/core/savestate.h b/src/core/savestate.h new file mode 100644 index 0000000000..f67bee22f8 --- /dev/null +++ b/src/core/savestate.h @@ -0,0 +1,27 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <vector> +#include "common/common_types.h" + +namespace Core { + +struct CSTHeader; + +struct SaveStateInfo { + u32 slot; + u64 time; + enum class ValidationStatus { + OK, + RevisionDismatch, + } status; +}; + +constexpr u32 SaveStateSlotCount = 10; // Maximum count of savestate slots + +std::vector<SaveStateInfo> ListSaveStates(u64 program_id); + +} // namespace Core From 56046136424be85c625cd622506c2aefee38d915 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Fri, 27 Mar 2020 21:48:58 +0000 Subject: [PATCH 082/129] More merge fixes --- TODO | 2 +- save0.citrasave | Bin 776 -> 0 bytes src/core/core.cpp | 6 ++++++ src/core/core_timing.h | 7 ++++--- src/core/file_sys/layered_fs.cpp | 16 +++++++++++---- src/core/file_sys/layered_fs.h | 32 +++++++++++++++++++++++++++++ src/core/file_sys/romfs_reader.cpp | 3 +++ src/core/file_sys/romfs_reader.h | 10 +++++++++ src/core/hle/service/cecd/cecd.h | 2 +- 9 files changed, 69 insertions(+), 9 deletions(-) delete mode 100644 save0.citrasave diff --git a/TODO b/TODO index 9cc333d46b..41fa8503a7 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,7 @@ ☐ Save/load UI ✔ Basic version @done(20-01-03 15:27) ☐ Multiple slots etc. -☐ Add 'force flush all' to Rasterizer interface + impls +✔ Add 'force flush all' to Rasterizer interface + impls @done(20-03-07 21:54) ☐ Custom texture cache ☐ Review constructor/initialization code ✔ Core timing events @done(20-01-12 15:14) diff --git a/save0.citrasave b/save0.citrasave deleted file mode 100644 index 578174ec6b7489150da4ff634caacf0e34d2ddd8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 776 zcmWe*fPmuEqRhmc%&Nqa%=|nntHh$@jLfoBK?W8U77j+J8VJP<q}YHMBnrX-WeOZj zK>9?L0*8h?10RqH1|V?|<IY3{4i2FBml@d%1~ao61Q-|^UU$fY)qu>A17eUl4nX1q zlntb43brUPIsz>Kd4++2my6*Yh!z9_5UsL-A0!C@U@rjWfQ|zq29QTVfSFN%k%^f} zfI&eCB+MWP^p>C^gOH$rlAxiY0HY&Nw8DXvfgdC}gusXY|Nn!WyQGVg;ep2k7Zj)K z{eZ+8iXbT*ADCiTFv9qtbN~VcxmJk<1>lfo1CtP8ILQfOfdU*DXW(!L6CgooJb{=H X09FNMLyV0NPAw`+ErKZk({Muob(AbM diff --git a/src/core/core.cpp b/src/core/core.cpp index fea1705ed8..ca22999203 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -530,6 +530,9 @@ void System::Reset() { template <class Archive> void System::serialize(Archive& ar, const unsigned int file_version) { u32 num_cores; + if (Archive::is_saving::value) { + num_cores = this->GetNumCores(); + } ar& num_cores; if (num_cores != this->GetNumCores()) { throw std::runtime_error("Wrong N3DS mode"); @@ -547,6 +550,9 @@ void System::serialize(Archive& ar, const unsigned int file_version) { if (Archive::is_loading::value) { dsp_core.reset(); } + if (dsp_core) { + throw "BLEH"; + } ar& dsp_core; ar&* memory.get(); ar&* kernel.get(); diff --git a/src/core/core_timing.h b/src/core/core_timing.h index a56a9097dd..4e11b7bd22 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -223,10 +223,12 @@ public: template <class Archive> void serialize(Archive& ar, const unsigned int) { MoveEvents(); - ar& slice_length; - ar& downcount; + // NOTE: ts_queue should be empty now ar& event_queue; ar& event_fifo_id; + ar& slice_length; + ar& downcount; + ar& executed_ticks; ar& idled_cycles; } friend class boost::serialization::access; @@ -283,7 +285,6 @@ private: deserializing = nullptr; } friend class boost::serialization::access; - }; } // namespace Core diff --git a/src/core/file_sys/layered_fs.cpp b/src/core/file_sys/layered_fs.cpp index 9d5fbf7c21..c8af6b5b09 100644 --- a/src/core/file_sys/layered_fs.cpp +++ b/src/core/file_sys/layered_fs.cpp @@ -5,6 +5,7 @@ #include <algorithm> #include <cstring> #include "common/alignment.h" +#include "common/archives.h" #include "common/assert.h" #include "common/common_paths.h" #include "common/file_util.h" @@ -13,6 +14,8 @@ #include "core/file_sys/layered_fs.h" #include "core/file_sys/patch.h" +SERIALIZE_EXPORT_IMPL(FileSys::LayeredFS) + namespace FileSys { struct FileRelocationInfo { @@ -51,11 +54,16 @@ struct FileMetadata { }; static_assert(sizeof(FileMetadata) == 0x20, "Size of FileMetadata is not correct"); -LayeredFS::LayeredFS(std::shared_ptr<RomFSReader> romfs_, std::string patch_path_, - std::string patch_ext_path_, bool load_relocations) - : romfs(std::move(romfs_)), patch_path(std::move(patch_path_)), - patch_ext_path(std::move(patch_ext_path_)) { +LayeredFS::LayeredFS() = default; +LayeredFS::LayeredFS(std::shared_ptr<RomFSReader> romfs_, std::string patch_path_, + std::string patch_ext_path_, bool load_relocations_) + : romfs(std::move(romfs_)), patch_path(std::move(patch_path_)), + patch_ext_path(std::move(patch_ext_path_)), load_relocations(load_relocations_) { + Load(); +} + +void LayeredFS::Load() { romfs->ReadFile(0, sizeof(header), reinterpret_cast<u8*>(&header)); ASSERT_MSG(header.header_length == sizeof(header), "Header size is incorrect"); diff --git a/src/core/file_sys/layered_fs.h b/src/core/file_sys/layered_fs.h index 956eedcfa7..dc71d052fd 100644 --- a/src/core/file_sys/layered_fs.h +++ b/src/core/file_sys/layered_fs.h @@ -9,6 +9,10 @@ #include <string> #include <unordered_map> #include <vector> +#include <boost/serialization/base_object.hpp> +#include <boost/serialization/export.hpp> +#include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/string.hpp> #include "common/common_types.h" #include "common/swap.h" #include "core/file_sys/romfs_reader.h" @@ -19,6 +23,14 @@ struct RomFSHeader { struct Descriptor { u32_le offset; u32_le length; + + private: + template <class Archive> + void serialize(Archive& ar, const unsigned int) { + ar& offset; + ar& length; + } + friend class boost::serialization::access; }; u32_le header_length; Descriptor directory_hash_table; @@ -92,9 +104,12 @@ private: void RebuildMetadata(); + void Load(); + std::shared_ptr<RomFSReader> romfs; std::string patch_path; std::string patch_ext_path; + bool load_relocations; RomFSHeader header; Directory root; @@ -118,6 +133,23 @@ private: u64 current_file_offset{}; // current file metadata offset std::vector<u8> file_metadata_table; // rebuilt file metadata table u64 current_data_offset{}; // current assigned data offset + + LayeredFS(); + + template <class Archive> + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object<RomFSReader>(*this); + ar& romfs; + ar& patch_path; + ar& patch_ext_path; + ar& load_relocations; + if (Archive::is_loading::value) { + Load(); + } + } + friend class boost::serialization::access; }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::LayeredFS) diff --git a/src/core/file_sys/romfs_reader.cpp b/src/core/file_sys/romfs_reader.cpp index 64374684a1..a1ff389453 100644 --- a/src/core/file_sys/romfs_reader.cpp +++ b/src/core/file_sys/romfs_reader.cpp @@ -1,8 +1,11 @@ #include <algorithm> #include <cryptopp/aes.h> #include <cryptopp/modes.h> +#include "common/archives.h" #include "core/file_sys/romfs_reader.h" +SERIALIZE_EXPORT_IMPL(FileSys::DirectRomFSReader) + namespace FileSys { std::size_t DirectRomFSReader::ReadFile(std::size_t offset, std::size_t length, u8* buffer) { diff --git a/src/core/file_sys/romfs_reader.h b/src/core/file_sys/romfs_reader.h index 1cfaa3b4fb..26dcb98579 100644 --- a/src/core/file_sys/romfs_reader.h +++ b/src/core/file_sys/romfs_reader.h @@ -2,6 +2,8 @@ #include <array> #include <boost/serialization/array.hpp> +#include <boost/serialization/base_object.hpp> +#include <boost/serialization/export.hpp> #include "common/common_types.h" #include "common/file_util.h" @@ -16,6 +18,11 @@ public: virtual std::size_t GetSize() const = 0; virtual std::size_t ReadFile(std::size_t offset, std::size_t length, u8* buffer) = 0; + +private: + template <class Archive> + void serialize(Archive& ar, const unsigned int file_version) {} + friend class boost::serialization::access; }; /** @@ -54,6 +61,7 @@ private: template <class Archive> void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object<RomFSReader>(*this); ar& is_encrypted; ar& file; ar& key; @@ -66,3 +74,5 @@ private: }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::DirectRomFSReader) diff --git a/src/core/hle/service/cecd/cecd.h b/src/core/hle/service/cecd/cecd.h index 0870f31bf9..b752701fe5 100644 --- a/src/core/hle/service/cecd/cecd.h +++ b/src/core/hle/service/cecd/cecd.h @@ -258,7 +258,7 @@ public: ar& data_path_type; ar& open_mode.raw; ar& path; - ar& file; + // ar& file; } friend class boost::serialization::access; }; From 3d1180ee21603392c32b4d610b6e866a1af0d262 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Fri, 27 Mar 2020 22:19:29 +0000 Subject: [PATCH 083/129] DSP now works... committing this!! --- src/audio_core/dsp_interface.cpp | 7 ++++++- src/audio_core/hle/hle.cpp | 11 ++++++++++- src/core/core.cpp | 11 ++++------- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/audio_core/dsp_interface.cpp b/src/audio_core/dsp_interface.cpp index b6e74b82cd..fc2e231f24 100644 --- a/src/audio_core/dsp_interface.cpp +++ b/src/audio_core/dsp_interface.cpp @@ -1,3 +1,4 @@ +#pragma optimize("", off) // Copyright 2017 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -14,7 +15,11 @@ namespace AudioCore { DspInterface::DspInterface() = default; -DspInterface::~DspInterface() = default; +DspInterface::~DspInterface() { + LOG_WARNING(Audio_DSP, "c1"); + sink.reset(); + LOG_WARNING(Audio_DSP, "c2"); +} void DspInterface::SetSink(const std::string& sink_id, const std::string& audio_device) { sink = CreateSinkFromID(Settings::values.sink_id, Settings::values.audio_device_id); diff --git a/src/audio_core/hle/hle.cpp b/src/audio_core/hle/hle.cpp index 87af17ba79..cac8a7df5e 100644 --- a/src/audio_core/hle/hle.cpp +++ b/src/audio_core/hle/hle.cpp @@ -16,6 +16,7 @@ #elif HAVE_FDK #include "audio_core/hle/fdk_decoder.h" #endif +#include <iostream> #include "audio_core/hle/common.h" #include "audio_core/hle/decoder.h" #include "audio_core/hle/hle.h" @@ -148,8 +149,11 @@ DspHle::Impl::Impl(DspHle& parent_, Memory::MemorySystem& memory) : parent(paren } DspHle::Impl::~Impl() { + LOG_WARNING(Audio_DSP, "b1"); Core::Timing& timing = Core::System::GetInstance().CoreTiming(); + LOG_WARNING(Audio_DSP, "b2"); timing.UnscheduleEvent(tick_event, 0); + LOG_WARNING(Audio_DSP, "b3"); } DspState DspHle::Impl::GetDspState() const { @@ -448,7 +452,12 @@ void DspHle::Impl::AudioTickCallback(s64 cycles_late) { } DspHle::DspHle(Memory::MemorySystem& memory) : impl(std::make_unique<Impl>(*this, memory)) {} -DspHle::~DspHle() = default; +DspHle::~DspHle() { + + LOG_WARNING(Audio_DSP, "a1"); + impl.reset(); + LOG_WARNING(Audio_DSP, "a2"); +} u16 DspHle::RecvData(u32 register_number) { return impl->RecvData(register_number); diff --git a/src/core/core.cpp b/src/core/core.cpp index ca22999203..1c18af2027 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -547,13 +547,10 @@ void System::serialize(Archive& ar, const unsigned int file_version) { ar&* service_manager.get(); ar& GPU::g_regs; ar& LCD::g_regs; - if (Archive::is_loading::value) { - dsp_core.reset(); + if (!dynamic_cast<AudioCore::DspHle*>(dsp_core.get())) { + throw std::runtime_error("Only HLE audio supported"); } - if (dsp_core) { - throw "BLEH"; - } - ar& dsp_core; + ar&* dynamic_cast<AudioCore::DspHle*>(dsp_core.get()); ar&* memory.get(); ar&* kernel.get(); @@ -562,7 +559,7 @@ void System::serialize(Archive& ar, const unsigned int file_version) { Service::GSP::SetGlobalModule(*this); memory->SetDSP(*dsp_core); - dsp_core->SetSink(Settings::values.sink_id, Settings::values.audio_device_id); + // dsp_core->SetSink(Settings::values.sink_id, Settings::values.audio_device_id); dsp_core->EnableStretching(Settings::values.enable_audio_stretching); } } From 232b52a27d6d633f8cbed7111310d7aeb82469af Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 09:59:45 +0000 Subject: [PATCH 084/129] Minor cleanup --- src/audio_core/dsp_interface.cpp | 7 +------ src/audio_core/hle/hle.cpp | 11 +--------- src/core/core.cpp | 35 ++++++++++++++++++++------------ src/core/file_sys/layered_fs.cpp | 8 ++++---- 4 files changed, 28 insertions(+), 33 deletions(-) diff --git a/src/audio_core/dsp_interface.cpp b/src/audio_core/dsp_interface.cpp index fc2e231f24..b6e74b82cd 100644 --- a/src/audio_core/dsp_interface.cpp +++ b/src/audio_core/dsp_interface.cpp @@ -1,4 +1,3 @@ -#pragma optimize("", off) // Copyright 2017 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -15,11 +14,7 @@ namespace AudioCore { DspInterface::DspInterface() = default; -DspInterface::~DspInterface() { - LOG_WARNING(Audio_DSP, "c1"); - sink.reset(); - LOG_WARNING(Audio_DSP, "c2"); -} +DspInterface::~DspInterface() = default; void DspInterface::SetSink(const std::string& sink_id, const std::string& audio_device) { sink = CreateSinkFromID(Settings::values.sink_id, Settings::values.audio_device_id); diff --git a/src/audio_core/hle/hle.cpp b/src/audio_core/hle/hle.cpp index cac8a7df5e..6f54b75e6a 100644 --- a/src/audio_core/hle/hle.cpp +++ b/src/audio_core/hle/hle.cpp @@ -1,4 +1,3 @@ -#pragma optimize("", off) // Copyright 2017 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -149,11 +148,8 @@ DspHle::Impl::Impl(DspHle& parent_, Memory::MemorySystem& memory) : parent(paren } DspHle::Impl::~Impl() { - LOG_WARNING(Audio_DSP, "b1"); Core::Timing& timing = Core::System::GetInstance().CoreTiming(); - LOG_WARNING(Audio_DSP, "b2"); timing.UnscheduleEvent(tick_event, 0); - LOG_WARNING(Audio_DSP, "b3"); } DspState DspHle::Impl::GetDspState() const { @@ -452,12 +448,7 @@ void DspHle::Impl::AudioTickCallback(s64 cycles_late) { } DspHle::DspHle(Memory::MemorySystem& memory) : impl(std::make_unique<Impl>(*this, memory)) {} -DspHle::~DspHle() { - - LOG_WARNING(Audio_DSP, "a1"); - impl.reset(); - LOG_WARNING(Audio_DSP, "a2"); -} +DspHle::~DspHle() = default; u16 DspHle::RecvData(u32 register_number) { return impl->RecvData(register_number); diff --git a/src/core/core.cpp b/src/core/core.cpp index 1c18af2027..db9fa83c7e 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -1,4 +1,3 @@ -#pragma optimize("", off) // Copyright 2014 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -313,7 +312,7 @@ void System::Reschedule() { System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mode, u8 n3ds_mode) { LOG_DEBUG(HW_Memory, "initialized OK"); - std::size_t num_cores = 2; + u32 num_cores = 2; if (Settings::values.is_new_3ds) { num_cores = 4; } @@ -327,19 +326,19 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 - for (std::size_t i = 0; i < num_cores; ++i) { + for (u32 i = 0; i < num_cores; ++i) { cpu_cores.push_back( std::make_shared<ARM_Dynarmic>(this, *memory, USER32MODE, i, timing->GetTimer(i))); } #else - for (std::size_t i = 0; i < num_cores; ++i) { + for (u32 i = 0; i < num_cores; ++i) { cpu_cores.push_back( std::make_shared<ARM_DynCom>(this, *memory, USER32MODE, i, timing->GetTimer(i))); } LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available"); #endif } else { - for (std::size_t i = 0; i < num_cores; ++i) { + for (u32 i = 0; i < num_cores; ++i) { cpu_cores.push_back( std::make_shared<ARM_DynCom>(this, *memory, USER32MODE, i, timing->GetTimer(i))); } @@ -541,26 +540,36 @@ void System::serialize(Archive& ar, const unsigned int file_version) { bool should_flush = !Archive::is_loading::value; Memory::RasterizerClearAll(should_flush); ar&* timing.get(); - for (int i = 0; i < num_cores; i++) { + for (u32 i = 0; i < num_cores; i++) { ar&* cpu_cores[i].get(); } ar&* service_manager.get(); ar& GPU::g_regs; ar& LCD::g_regs; - if (!dynamic_cast<AudioCore::DspHle*>(dsp_core.get())) { - throw std::runtime_error("Only HLE audio supported"); + + // NOTE: DSP doesn't like being destroyed and recreated. So instead we do an inline + // serialization; this means that the DSP Settings need to match for loading to work. + bool dsp_type = Settings::values.enable_dsp_lle; + ar& dsp_type; + if (dsp_type != Settings::values.enable_dsp_lle) { + throw std::runtime_error( + "Incorrect DSP type - please change this in Settings before loading"); } - ar&* dynamic_cast<AudioCore::DspHle*>(dsp_core.get()); + auto dsp_hle = dynamic_cast<AudioCore::DspHle*>(dsp_core.get()); + if (dsp_hle) { + ar&* dsp_hle; + } + auto dsp_lle = dynamic_cast<AudioCore::DspLle*>(dsp_core.get()); + if (dsp_lle) { + ar&* dsp_lle; + } + ar&* memory.get(); ar&* kernel.get(); // This needs to be set from somewhere - might as well be here! if (Archive::is_loading::value) { Service::GSP::SetGlobalModule(*this); - - memory->SetDSP(*dsp_core); - // dsp_core->SetSink(Settings::values.sink_id, Settings::values.audio_device_id); - dsp_core->EnableStretching(Settings::values.enable_audio_stretching); } } diff --git a/src/core/file_sys/layered_fs.cpp b/src/core/file_sys/layered_fs.cpp index c8af6b5b09..a4ef57baf2 100644 --- a/src/core/file_sys/layered_fs.cpp +++ b/src/core/file_sys/layered_fs.cpp @@ -281,7 +281,7 @@ std::size_t GetNameSize(const std::string& name) { } void LayeredFS::PrepareBuildDirectory(Directory& current) { - directory_metadata_offset_map.emplace(¤t, current_directory_offset); + directory_metadata_offset_map.emplace(¤t, static_cast<u32>(current_directory_offset)); directory_list.emplace_back(¤t); current_directory_offset += sizeof(DirectoryMetadata) + GetNameSize(current.name); } @@ -290,7 +290,7 @@ void LayeredFS::PrepareBuildFile(File& current) { if (current.relocation.type == 3) { // Deleted files are not counted return; } - file_metadata_offset_map.emplace(¤t, current_file_offset); + file_metadata_offset_map.emplace(¤t, static_cast<u32>(current_file_offset)); file_list.emplace_back(¤t); current_file_offset += sizeof(FileMetadata) + GetNameSize(current.name); } @@ -369,7 +369,7 @@ void LayeredFS::BuildDirectories() { // Write metadata and name std::u16string u16name = Common::UTF8ToUTF16(directory->name); - metadata.name_length = u16name.size() * 2; + metadata.name_length = static_cast<u32_le>(u16name.size() * 2); std::memcpy(directory_metadata_table.data() + written, &metadata, sizeof(metadata)); written += sizeof(metadata); @@ -418,7 +418,7 @@ void LayeredFS::BuildFiles() { // Write metadata and name std::u16string u16name = Common::UTF8ToUTF16(file->name); - metadata.name_length = u16name.size() * 2; + metadata.name_length = static_cast<u32_le>(u16name.size() * 2); std::memcpy(file_metadata_table.data() + written, &metadata, sizeof(metadata)); written += sizeof(metadata); From 5a6093843e63fb9a271b8f04ca5be9e95ab92ee3 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 12:04:00 +0000 Subject: [PATCH 085/129] Remove the TODO (since it's all done now!) --- TODO | 143 ----------------------------------------------------------- 1 file changed, 143 deletions(-) delete mode 100644 TODO diff --git a/TODO b/TODO deleted file mode 100644 index 41fa8503a7..0000000000 --- a/TODO +++ /dev/null @@ -1,143 +0,0 @@ -☐ Save/load UI - ✔ Basic version @done(20-01-03 15:27) - ☐ Multiple slots etc. -✔ Add 'force flush all' to Rasterizer interface + impls @done(20-03-07 21:54) -☐ Custom texture cache -☐ Review constructor/initialization code -✔ Core timing events @done(20-01-12 15:14) -☐ Serialize codeset with an apploader reference instead -✔ Review base class serialization everywhere @done(20-01-10 23:47) - Make sure that all base/derived relationships are registered -✔ Additional stuff to serialize @done(20-01-11 16:32) - ✔ Self-NCCH archive @done(20-01-11 16:32) - ✔ File backends @done(20-01-11 16:32) - ✘ Directory backends @cancelled(20-01-11 16:32) - Not needed for now - ✔ File/directory 'services' @done(20-01-10 23:46) -✔ CPU @done(19-08-13 15:41) -✔ Memory @done(19-08-13 15:41) - ✔ Page tables @done(20-01-05 16:33) - Need to change uses to shared_ptr - ✔ Skip N3DS RAM if unused @done(20-01-03 23:26) -✔ DSP @done(19-12-28 16:57) - Memory only -✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) - ✔ Fix or ignore inverse map @done(19-12-23 12:46) -✘ App loader @cancelled(20-01-01 22:59) - No relevant state -✔ Archive manager @started(20-01-01 23:03) @done(20-01-03 13:23) @lasted(1d14h20m40s) - NB that 'FileBackend' classes are not persistent - ✔ NCCH @started(20-01-02 22:50) @done(20-01-03 12:35) @lasted(13h45m50s) - ✔ Normal @done(20-01-02 22:50) - ✔ Self @done(20-01-03 12:35) - ✔ SaveData @started(20-01-02 23:03) @done(20-01-02 23:27) @lasted(25m) - ✔ Normal @done(20-01-02 23:03) - ✔ Ext @done(20-01-02 23:26) - ✔ Other @done(20-01-02 23:21) - ✔ Source SD @done(20-01-02 23:03) - ✔ System @done(20-01-02 23:13) - ✔ SDMC @done(20-01-02 23:34) - ✔ Normal @done(20-01-02 23:34) - ✔ Write-only @done(20-01-02 23:34) - ✔ IVFC @done(20-01-11 16:33) - ✔ File refs @done(20-01-11 16:33) - ✘ Replace delay generator with virtual fns @cancelled(20-01-03 13:16) - While they have no state, the extra refactoring here is unneeded -✘ MMIO @cancelled(20-01-01 01:06) - Seems that this whole subsystem is only used in tests -✘ Movie @cancelled(20-01-01 01:07) - Doesn't need to be serialized here -✘ Perf stats @cancelled(20-01-01 01:09) - Doesn't need to be serialized here -✘ Settings @cancelled(20-01-01 01:11) - For now, let the settings just be whatever they are -✘ Telemetry session @cancelled(20-01-01 01:12) - Doesn't need to be serialized here -✔ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE @started(20-01-03 13:47) @done(20-01-03 13:58) @lasted(11m22s) -✔ Fix CI @done(19-12-31 21:32) -✔ HW @done(19-08-13 15:41) - ✔ GPU regs @done(19-08-13 15:41) - ✔ LCD regs @done(19-08-13 15:41) -✔ Video core @started(19-08-13 16:43) @done(19-12-22 16:06) - ✔ Geometry pipeline @done(19-12-22 15:52) - Required more use of g_state - ✔ PICA state @done(19-08-13 15:41) - ✔ Primitive assembly @done(19-12-22 16:05) - ✔ Shader @done(19-08-13 16:03) -✔ HLE @started(19-08-13 16:43) @done(20-01-06 20:37) @lasted(20w6d4h54m19s) - ✔ Kernel @started(19-08-13 16:43) @done(20-01-06 20:37) @lasted(20w6d4h54m17s) - Most of these require adding Core::Global - ✔ Address arbiter @done(19-08-13 16:40) - ✔ Client port @done(19-08-13 16:40) - ✔ Client session @done(19-08-13 16:40) - ✔ Config mem @done(20-01-04 21:09) - ✔ Event @done(19-12-22 18:44) - ✔ Handle table @done(19-08-13 16:42) - ✔ HLE IPC @done(19-12-23 00:36) - ✔ IPC @done(19-12-23 00:36) - ✔ Memory @started(19-08-13 16:43) @done(19-12-22 18:34) - ✔ Mutex @done(19-08-13 16:43) - ✔ Object @done(19-08-13 15:41) - ✔ Process @started(19-08-13 16:43) @done(19-12-22 18:41) - ✔ Code set @started(19-12-22 18:41) @done(20-01-03 15:15) @lasted(1w4d20h34m2s) - Needs a way to reference loaded images (so we don't serialize the entire ROM as well) - ✔ Resource limit @done(19-08-13 16:43) - ✔ Semaphore @done(19-08-13 16:44) - ✔ Server port @done(19-08-13 16:44) - ✔ Server session @done(19-08-13 16:44) - ✔ Mapped buffer context @done(20-01-03 15:25) - This is needed because IPC can take as long as it takes - Changed the unique_ptr<u8[]> to vector<u8> - ✔ Session @done(19-08-13 16:44) - ✔ Shared memory @started(19-12-22 21:20) @done(20-01-04 21:09) @lasted(1w5d23h49m26s) - Need to figure out backing memory (a u8*) - ✔ Shared page @done(20-01-04 21:09) - ✔ SVC @done(19-12-22 21:32) - Nothing to do - all data is constant - ✔ Thread @started(19-08-13 16:45) @done(20-01-06 20:01) @lasted(20w6d4h16m22s) - This requires refactoring wakeup_callback to be an object ref - ✔ Timer @done(19-08-13 16:45) - ✔ VM Manager @started(19-08-13 16:46) @done(20-01-04 21:09) @lasted(20w4d5h23m42s) - Just need to figure out backing_mem (a u8*) - ✔ Wait object @done(19-08-13 16:46) - ✔ Service @started(19-12-23 12:49) @done(20-01-05 16:41) @lasted(1w6d3h52m17s) - ✔ AC @started(19-12-23 12:48) @done(19-12-24 22:38) @lasted(1d9h50m3s) - ✔ ACT @done(19-12-24 23:17) - ✔ AM @started(19-12-24 23:17) @done(19-12-24 23:53) @lasted(36m8s) - ✔ APT @done(19-12-25 21:41) - ✔ BOSS @started(19-12-25 21:48) @done(19-12-25 23:18) @lasted(1h30m14s) - ✔ CAM @started(19-12-26 10:37) @done(20-01-03 23:38) @lasted(1w1d13h1m50s) - Need to check capture_result - ✔ CECD @done(20-01-01 23:58) - ✔ CFG @done(20-01-02 00:44) - Also needs archive backend.. - ✔ CSND @started(19-12-26 17:51) @done(19-12-26 17:56) @lasted(5m30s) - ✔ DLP @done(19-12-26 18:02) - ✔ DSP @done(19-12-26 18:10) - ✔ ERR @done(19-12-26 18:14) - ✔ FRD @done(19-12-26 19:09) - ✔ FS @done(19-12-27 11:46) - ✔ GSP @done(19-12-30 12:45) - ✔ Fix the global weak_ptr to gsp @done(20-01-04 00:29) - Didn't quite 'fix' it but worked around it - ✔ HID @done(19-12-30 14:46) - ✔ HTTP @done(19-12-30 15:18) - ✔ IR @done(19-12-30 16:06) - ✔ LDR_RO @done(19-12-30 16:25) - ✔ MIC @done(19-12-30 16:53) - ✔ MVD @done(19-12-31 18:26) - ✔ NDM @done(19-12-31 18:26) - ✔ NEWS @done(19-12-31 18:29) - ✔ NFC @done(19-12-31 20:35) - ✔ NIM @done(19-12-31 21:08) - ✔ NS @done(20-01-01 00:46) - ✔ NWM @done(20-01-01 21:31) - ✔ Fix wifi_packet_received @done(20-01-05 16:41) - ✔ PM @done(20-01-01 22:14) - ✔ PS @done(20-01-01 00:54) - ✔ PTM @done(20-01-01 22:36) - ✔ PXI @done(20-01-01 00:53) - ✔ QTM @done(20-01-01 22:41) - ✔ SOC @done(20-01-01 00:51) - ✔ SSL @done(20-01-01 00:48) - ✔ Y2R @done(20-01-01 22:56) \ No newline at end of file From 025960bcdd486f9747dd25cefa89ff014b414b27 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 15:10:35 +0000 Subject: [PATCH 086/129] Attempt to fix flatpak CI --- .travis/linux-flatpak/generate-data.sh | 2 +- externals/boost | 2 +- src/audio_core/hle/hle.cpp | 1 - src/core/hle/kernel/process.cpp | 5 ++--- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.travis/linux-flatpak/generate-data.sh b/.travis/linux-flatpak/generate-data.sh index aaecd05009..799f0f1b80 100644 --- a/.travis/linux-flatpak/generate-data.sh +++ b/.travis/linux-flatpak/generate-data.sh @@ -43,7 +43,7 @@ cat > /tmp/org.citra.$REPO_NAME.json <<EOF { "app-id": "org.citra.$REPO_NAME", "runtime": "org.kde.Platform", - "runtime-version": "5.12", + "runtime-version": "5.13", "sdk": "org.kde.Sdk", "command": "citra-qt", "rename-desktop-file": "citra.desktop", diff --git a/externals/boost b/externals/boost index 727f616b6e..a37867de91 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit 727f616b6e5cafaba072131c077a3b8fea87b8be +Subproject commit a37867de91767e3289068997bc004f842894ce1f diff --git a/src/audio_core/hle/hle.cpp b/src/audio_core/hle/hle.cpp index 6ced774811..f4e372f85d 100644 --- a/src/audio_core/hle/hle.cpp +++ b/src/audio_core/hle/hle.cpp @@ -17,7 +17,6 @@ #elif HAVE_FDK #include "audio_core/hle/fdk_decoder.h" #endif -#include <iostream> #include "audio_core/hle/common.h" #include "audio_core/hle/decoder.h" #include "audio_core/hle/hle.h" diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index ea3449c219..b72081ad5c 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -33,9 +33,8 @@ void Process::serialize(Archive& ar, const unsigned int file_version) { ar& resource_limit; ar& svc_access_mask; ar& handle_table_size; - ar&(boost::container::vector< - AddressMapping, boost::container::dtl::static_storage_allocator<AddressMapping, 8>>&) - address_mappings; + ar&(boost::container::vector<AddressMapping, boost::container::dtl::static_storage_allocator< + AddressMapping, 8, 0, true>>&)address_mappings; ar& flags.raw; ar& kernel_version; ar& ideal_processor; From 917d651a3c1be4b99a20ad1a2ad193d2ba1251c7 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 15:21:10 +0000 Subject: [PATCH 087/129] Added copyright notices on new files --- src/common/archives.h | 6 ++++++ src/common/construct.h | 5 +++++ src/common/memory_ref.cpp | 4 ++++ src/common/memory_ref.h | 4 ++++ src/core/global.h | 6 ++++++ 5 files changed, 25 insertions(+) diff --git a/src/common/archives.h b/src/common/archives.h index eef292634b..993128197d 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -1,3 +1,9 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + #include "boost/archive/binary_iarchive.hpp" #include "boost/archive/binary_oarchive.hpp" #include "boost/serialization/export.hpp" diff --git a/src/common/construct.h b/src/common/construct.h index aba4c7e892..4e48ee60d1 100644 --- a/src/common/construct.h +++ b/src/common/construct.h @@ -1,4 +1,9 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #pragma once + #include <boost/serialization/serialization.hpp> class construct_access { diff --git a/src/common/memory_ref.cpp b/src/common/memory_ref.cpp index 170784ff8d..300f87d581 100644 --- a/src/common/memory_ref.cpp +++ b/src/common/memory_ref.cpp @@ -1,3 +1,7 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include "common/archives.h" #include "common/memory_ref.h" diff --git a/src/common/memory_ref.h b/src/common/memory_ref.h index ae30b009cd..c11beb04d6 100644 --- a/src/common/memory_ref.h +++ b/src/common/memory_ref.h @@ -1,3 +1,7 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #pragma once #include <memory> diff --git a/src/core/global.h b/src/core/global.h index d2e1cd97d6..83bd4fc802 100644 --- a/src/core/global.h +++ b/src/core/global.h @@ -1,3 +1,9 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + namespace Core { template <class T> From 4aab38f133c2a039eb1d619b896c5eaff76cf939 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 15:47:36 +0000 Subject: [PATCH 088/129] Refactored out the horrible static var in CoreTiming --- src/core/core.cpp | 5 +++++ src/core/core_timing.cpp | 2 -- src/core/core_timing.h | 7 ++----- src/core/file_sys/archive_backend.h | 2 +- src/core/file_sys/archive_ncch.h | 4 ++-- src/core/global.h | 6 +++++- 6 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 65c73f03b9..ff6da91e75 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -61,6 +61,11 @@ Kernel::KernelSystem& Global() { return System::GetInstance().Kernel(); } +template <> +Core::Timing& Global() { + return System::GetInstance().CoreTiming(); +} + System::~System() = default; System::ResultStatus System::RunLoop(bool tight_loop) { diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 67fab0daef..493bb63448 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -11,8 +11,6 @@ namespace Core { -Timing* Timing::deserializing = nullptr; - // Sort by time, unless the times are the same, in which case sort by the order added to the queue bool Timing::Event::operator>(const Timing::Event& right) const { return std::tie(time, fifo_order) > std::tie(right.time, right.fifo_order); diff --git a/src/core/core_timing.h b/src/core/core_timing.h index cbe17b36be..bb34c79b02 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -28,6 +28,7 @@ #include "common/common_types.h" #include "common/logging/log.h" #include "common/threadsafe_queue.h" +#include "core/global.h" // The timing we get from the assembly is 268,111,855.956 Hz // It is possible that this number isn't just an integer because the compiler could have @@ -135,8 +136,6 @@ struct TimingEventType { }; class Timing { -private: - static Timing* deserializing; public: struct Event { @@ -165,7 +164,7 @@ public: ar& userdata; std::string name; ar >> name; - type = Timing::deserializing->RegisterEvent(name, nullptr); + type = Global<Timing>().RegisterEvent(name, nullptr); } friend class boost::serialization::access; @@ -291,11 +290,9 @@ private: template <class Archive> void serialize(Archive& ar, const unsigned int) { // event_types set during initialization of other things - deserializing = this; ar& global_timer; ar& timers; ar& current_timer; - deserializing = nullptr; } friend class boost::serialization::access; }; diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 6468c0630e..658e6f20ca 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -196,7 +196,7 @@ public: } protected: - std::unique_ptr<DelayGenerator> delay_generator; // TODO: Replace with virtual GetOpenDelayNs + std::unique_ptr<DelayGenerator> delay_generator; private: template <class Archive> diff --git a/src/core/file_sys/archive_ncch.h b/src/core/file_sys/archive_ncch.h index 2d38f9a2e2..76b8d46554 100644 --- a/src/core/file_sys/archive_ncch.h +++ b/src/core/file_sys/archive_ncch.h @@ -68,8 +68,8 @@ protected: Service::FS::MediaType media_type; private: - NCCHArchive() = default; // NOTE: If the public ctor has behaviour, need to replace this with - // *_construct_data + NCCHArchive() = default; + template <class Archive> void serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object<ArchiveBackend>(*this); diff --git a/src/core/global.h b/src/core/global.h index 83bd4fc802..794d71f942 100644 --- a/src/core/global.h +++ b/src/core/global.h @@ -9,9 +9,13 @@ namespace Core { template <class T> T& Global(); -// Declare explicit specialisation to prevent im +// Declare explicit specialisation to prevent automatic instantiation class System; template <> System& Global(); +class Timing; +template <> +Timing& Global(); + } // namespace Core From bbf8e876ab9dfed345968c550ca44cf39237f2c1 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 16:26:24 +0000 Subject: [PATCH 089/129] Apply suggestions from code review Co-Authored-By: Pengfei Zhu <zhupf321@gmail.com> --- src/video_core/pica_state.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 4e5a5f16b9..1879528cb8 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -5,7 +5,7 @@ #pragma once #include <array> -#include "boost/serialization/split_member.hpp" +#include <boost/serialization/split_member.hpp> #include "common/bit_field.h" #include "common/common_types.h" #include "common/vector_math.h" @@ -239,7 +239,7 @@ private: void load(Archive& ar, const unsigned int file_version) { u32 offset{}; ar >> offset; - cmd_list.head_ptr = (u32*)VideoCore::g_memory->GetPhysicalPointer(cmd_list.addr); + cmd_list.head_ptr = reinterpret_cast<u32*>(VideoCore::g_memory->GetPhysicalPointer(cmd_list.addr)); cmd_list.current_ptr = cmd_list.head_ptr + offset; } }; From 26f936406235c3b215512f4eabf31465f5fe8e9b Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 16:28:07 +0000 Subject: [PATCH 090/129] Apply suggestions from code review Co-Authored-By: Ben <bene_thomas@web.de> --- src/common/memory_ref.h | 4 ++-- src/video_core/shader/shader.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/common/memory_ref.h b/src/common/memory_ref.h index c11beb04d6..f1a3286aba 100644 --- a/src/common/memory_ref.h +++ b/src/common/memory_ref.h @@ -31,11 +31,11 @@ public: BufferMem() = default; BufferMem(u32 size) : data(std::vector<u8>(size)) {} - virtual u8* GetPtr() { + u8* GetPtr() override { return data.data(); } - virtual u32 GetSize() const { + u32 GetSize() const override { return static_cast<u32>(data.size()); } diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index 6a5a334193..05a1e8b80a 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -70,6 +70,7 @@ private: void serialize(Archive& ar, const unsigned int) { ar& pos; ar& quat; + ar& color; ar& tc0; ar& tc1; ar& tc0_w; From d92b3e9754f635ed956fa11a769f29dab704a388 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 16:29:15 +0000 Subject: [PATCH 091/129] Code review changes - clarified HTTP serialization --- src/core/hle/service/http_c.h | 27 +++++++++------------------ src/core/hle/service/mic_u.cpp | 2 ++ src/video_core/primitive_assembly.h | 4 +--- 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/src/core/hle/service/http_c.h b/src/core/hle/service/http_c.h index d94b47a45e..490e066481 100644 --- a/src/core/hle/service/http_c.h +++ b/src/core/hle/service/http_c.h @@ -6,6 +6,7 @@ #include <future> #include <memory> +#include <optional> #include <string> #include <unordered_map> #include <vector> @@ -215,24 +216,6 @@ public: #ifdef ENABLE_WEB_SERVICE httplib::Response response; #endif - -private: - template <class Archive> - void serialize(Archive& ar, const unsigned int) { - ar& handle; - ar& session_id; - ar& url; - ar& method; - ar& state; - ar& proxy; - ar& basic_auth; - ar& ssl_config; - ar& socket_buffer_size; - ar& headers; - ar& post_data; - } - friend class boost::serialization::access; - }; struct SessionData : public Kernel::SessionRequestHandler::SessionDataBase { @@ -453,10 +436,18 @@ private: private: template <class Archive> void serialize(Archive& ar, const unsigned int) { + // NOTE: Serialization of the HTTP service is on a 'best effort' basis. + // There is a very good chance that saving/loading during a network connection will break, + // regardless! ar& boost::serialization::base_object<Kernel::SessionRequestHandler>(*this); ar& ClCertA.certificate; ar& ClCertA.private_key; ar& ClCertA.init; + ar& context_counter; + ar& client_certs_counter; + ar& client_certs; + // NOTE: `contexts` is not serialized because it contains non-serializable data. (i.e. + // handles to ongoing HTTP requests.) Serializing across HTTP contexts will break. } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index bd324ada25..08ef5473f4 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp @@ -110,6 +110,7 @@ struct State { private: template <class Archive> void serialize(Archive& ar, const unsigned int) { + ar& memory_ref; ar& sharedmem_size; ar& size; ar& offset; @@ -139,6 +140,7 @@ struct MIC_U::Impl { if (shared_memory) { shared_memory->SetName("MIC_U:shared_memory"); + state.memory_ref = shared_memory; state.sharedmem_buffer = shared_memory->GetPointer(); state.sharedmem_size = size; } diff --git a/src/video_core/primitive_assembly.h b/src/video_core/primitive_assembly.h index d6547dddd4..404bc5316c 100644 --- a/src/video_core/primitive_assembly.h +++ b/src/video_core/primitive_assembly.h @@ -5,10 +5,8 @@ #pragma once #include <functional> +#include <boost/serialization/access.hpp> #include "video_core/regs_pipeline.h" -namespace boost::serialization { -class access; -} namespace Pica { From 8f164a16ce9c7b2def438bf998e631c035679f2a Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 17:08:27 +0000 Subject: [PATCH 092/129] Review changes --- CMakeLists.txt | 1 + externals/CMakeLists.txt | 2 +- src/CMakeLists.txt | 2 +- src/citra_qt/main.cpp | 2 +- src/core/core.cpp | 7 +------ src/core/file_sys/archive_ncch.h | 2 +- src/core/file_sys/archive_other_savedata.h | 2 -- src/core/file_sys/archive_savedata.h | 1 - src/core/file_sys/archive_selfncch.h | 4 ++-- src/core/hle/kernel/config_mem.h | 4 ++-- src/core/hle/kernel/hle_ipc.h | 2 +- src/core/hle/service/err_f.cpp | 3 ++- 12 files changed, 13 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index faa41ea54b..315bc237d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ # CMake 3.8 required for 17 to be a valid value for CXX_STANDARD cmake_minimum_required(VERSION 3.8) if (${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.15) + # Don't override the warning flags in MSVC: cmake_policy(SET CMP0092 NEW) endif () list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules") diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 49cca86a1e..7d687a4dc5 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -1,7 +1,7 @@ # Definitions for all external bundled libraries # Suppress warnings from external libraries -if (CMAKE_C_COMPILER_ID MATCHES "MSVC") +if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") add_compile_options(/W0) endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d466415701..38cd0be79f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -42,7 +42,7 @@ if (MSVC) /Zc:externConstexpr /Zc:inline ) - if (CMAKE_C_COMPILER_ID MATCHES "MSVC") + if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") add_compile_options( /MP /Zc:throwingNew diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 6ceaea57d3..a583e903a9 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -1438,7 +1438,7 @@ void GMainWindow::OnCIAInstallFinished() { void GMainWindow::OnMenuRecentFile() { QAction* action = qobject_cast<QAction*>(sender()); - assert(action); + ASSERT(action); const QString filename = action->data().toString(); if (QFileInfo::exists(filename)) { diff --git a/src/core/core.cpp b/src/core/core.cpp index ff6da91e75..5897443676 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -33,6 +33,7 @@ #include "core/hle/kernel/thread.h" #include "core/hle/service/fs/archive.h" #include "core/hle/service/gsp/gsp.h" +#include "core/hle/service/pm/pm_app.h" #include "core/hle/service/service.h" #include "core/hle/service/sm/sm.h" #include "core/hw/gpu.h" @@ -45,8 +46,6 @@ #include "network/network.h" #include "video_core/video_core.h" -#include "core/hle/service/pm/pm_app.h" - namespace Core { /*static*/ System System::s_instance; @@ -183,15 +182,11 @@ System::ResultStatus System::RunLoop(bool tight_loop) { case Signal::Load: { LOG_INFO(Core, "Begin load"); System::LoadState(param); - // auto stream = std::ifstream("save0.citrasave", std::fstream::binary); - // System::Load(stream, FileUtil::GetSize("save0.citrasave")); LOG_INFO(Core, "Load completed"); } break; case Signal::Save: { LOG_INFO(Core, "Begin save"); System::SaveState(param); - // auto stream = std::ofstream("save0.citrasave", std::fstream::binary); - // System::Save(stream); LOG_INFO(Core, "Save completed"); } break; default: diff --git a/src/core/file_sys/archive_ncch.h b/src/core/file_sys/archive_ncch.h index 76b8d46554..95fe889ea5 100644 --- a/src/core/file_sys/archive_ncch.h +++ b/src/core/file_sys/archive_ncch.h @@ -102,7 +102,7 @@ private: template <class Archive> void serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object<FileBackend>(*this); - ar& file_buffer; // TODO: See about a more efficient way to do this + ar& file_buffer; } friend class boost::serialization::access; }; diff --git a/src/core/file_sys/archive_other_savedata.h b/src/core/file_sys/archive_other_savedata.h index c5bf98a683..cc0cfe404d 100644 --- a/src/core/file_sys/archive_other_savedata.h +++ b/src/core/file_sys/archive_other_savedata.h @@ -29,7 +29,6 @@ public: ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override; private: - std::string mount_point; // TODO: Remove, unused? std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata_source; ArchiveFactory_OtherSaveDataPermitted() = default; @@ -57,7 +56,6 @@ public: ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override; private: - std::string mount_point; // TODO: Remove, unused? std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata_source; ArchiveFactory_OtherSaveDataGeneral() = default; diff --git a/src/core/file_sys/archive_savedata.h b/src/core/file_sys/archive_savedata.h index 6bb22f7a80..3f73adba31 100644 --- a/src/core/file_sys/archive_savedata.h +++ b/src/core/file_sys/archive_savedata.h @@ -28,7 +28,6 @@ public: ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override; private: - std::string mount_point; // TODO: Remove this? seems unused std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata_source; ArchiveFactory_SaveData() = default; diff --git a/src/core/file_sys/archive_selfncch.h b/src/core/file_sys/archive_selfncch.h index d7b1cf301d..68b48074f4 100644 --- a/src/core/file_sys/archive_selfncch.h +++ b/src/core/file_sys/archive_selfncch.h @@ -58,12 +58,12 @@ public: private: /// Mapping of ProgramId -> NCCHData - std::unordered_map<u64, NCCHData> - ncch_data; // TODO: Remove this, or actually set the values here + std::unordered_map<u64, NCCHData> ncch_data; template <class Archive> void serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object<ArchiveFactory>(*this); + // NOTE: ncch_data is never written to, so we don't serialize it here } friend class boost::serialization::access; }; diff --git a/src/core/hle/kernel/config_mem.h b/src/core/hle/kernel/config_mem.h index 74d934345f..c466345ece 100644 --- a/src/core/hle/kernel/config_mem.h +++ b/src/core/hle/kernel/config_mem.h @@ -57,11 +57,11 @@ public: Handler(); ConfigMemDef& GetConfigMem(); - virtual u8* GetPtr() { + u8* GetPtr() override { return static_cast<u8*>(static_cast<void*>(&config_mem)); } - virtual u32 GetSize() const { + u32 GetSize() const override { return sizeof(config_mem); } diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 046a31e2eb..0004868259 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -99,12 +99,12 @@ protected: struct SessionInfo { SessionInfo(std::shared_ptr<ServerSession> session, std::unique_ptr<SessionDataBase> data); - SessionInfo() = default; std::shared_ptr<ServerSession> session; std::unique_ptr<SessionDataBase> data; private: + SessionInfo() = default; template <class Archive> void serialize(Archive& ar, const unsigned int file_version) { ar& session; diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp index f88ffef192..85759f9d20 100644 --- a/src/core/hle/service/err_f.cpp +++ b/src/core/hle/service/err_f.cpp @@ -15,7 +15,8 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/result.h" #include "core/hle/service/err_f.h" -#undef exception_info +#undef exception_info // We use 'exception_info' as a plain identifier, but MSVC defines this in one + // of its many headers. SERIALIZE_EXPORT_IMPL(Service::ERR::ERR_F) From 570fc45d03173c4ad6217c817fd2e259ab756896 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 17:11:35 +0000 Subject: [PATCH 093/129] Change boost submodule --- .gitmodules | 2 +- externals/boost | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index b0bfcaee88..b247ccdbe0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "boost"] path = externals/boost - url = https://github.com/hamish-milne/ext-boost.git + url = https://github.com/citra-emu/ext-boost.git [submodule "nihstro"] path = externals/nihstro url = https://github.com/neobrain/nihstro.git diff --git a/externals/boost b/externals/boost index a37867de91..36603a1e66 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit a37867de91767e3289068997bc004f842894ce1f +Subproject commit 36603a1e665e849d29b1735a12c0a51284a10dd0 From 38e9eb379d97f8ba0914949a2e8c10b24c077840 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 17:23:54 +0000 Subject: [PATCH 094/129] Update src/CMakeLists.txt --- src/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 38cd0be79f..96c7f35cdc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,7 +37,6 @@ if (MSVC) /Zo /permissive- /EHsc - /std:c++17 /volatile:iso /Zc:externConstexpr /Zc:inline From de9ae140593a67523c71fa3d66bfd02a89d532fb Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 19:29:29 +0000 Subject: [PATCH 095/129] Only serialize wchar paths on windows --- src/core/file_sys/archive_backend.h | 2 ++ src/core/hle/kernel/thread.cpp | 3 +-- src/video_core/pica_state.h | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 658e6f20ca..87a42b028d 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -77,6 +77,7 @@ private: case LowPathType::Char: ar& string; break; +#ifdef _WIN32 case LowPathType::Wchar: static_assert(sizeof(wchar_t) == sizeof(char16_t)); { @@ -87,6 +88,7 @@ private: } } break; +#endif default: break; } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 465ba46f5b..0567ef325b 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -63,8 +63,7 @@ void Thread::Acquire(Thread* thread) { } Thread::Thread(KernelSystem& kernel, u32 core_id) - : WaitObject(kernel), context(kernel.GetThreadManager(core_id).NewContext()), - core_id(core_id), + : WaitObject(kernel), context(kernel.GetThreadManager(core_id).NewContext()), core_id(core_id), thread_manager(kernel.GetThreadManager(core_id)) {} Thread::~Thread() {} diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 1879528cb8..3a9ec79c52 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -239,7 +239,8 @@ private: void load(Archive& ar, const unsigned int file_version) { u32 offset{}; ar >> offset; - cmd_list.head_ptr = reinterpret_cast<u32*>(VideoCore::g_memory->GetPhysicalPointer(cmd_list.addr)); + cmd_list.head_ptr = + reinterpret_cast<u32*>(VideoCore::g_memory->GetPhysicalPointer(cmd_list.addr)); cmd_list.current_ptr = cmd_list.head_ptr + offset; } }; From 841255cd16f0a9578cd90a860232e34c209c3c3a Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 21:40:18 +0000 Subject: [PATCH 096/129] Attempt to fix the linux builds --- src/audio_core/CMakeLists.txt | 2 +- src/core/file_sys/romfs_reader.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index 3cb9b538d6..63a5665967 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -35,7 +35,7 @@ add_library(audio_core STATIC create_target_directory_groups(audio_core) -target_link_libraries(audio_core PUBLIC common core) +target_link_libraries(audio_core PUBLIC common) target_link_libraries(audio_core PRIVATE SoundTouch teakra) if(ENABLE_MF) diff --git a/src/core/file_sys/romfs_reader.cpp b/src/core/file_sys/romfs_reader.cpp index a1ff389453..4c83515b37 100644 --- a/src/core/file_sys/romfs_reader.cpp +++ b/src/core/file_sys/romfs_reader.cpp @@ -12,7 +12,7 @@ std::size_t DirectRomFSReader::ReadFile(std::size_t offset, std::size_t length, if (length == 0) return 0; // Crypto++ does not like zero size buffer file.Seek(file_offset + offset, SEEK_SET); - std::size_t read_length = std::min(length, data_size - offset); + std::size_t read_length = std::min(length, static_cast<std::size_t>(data_size) - offset); read_length = file.ReadBytes(buffer, read_length); if (is_encrypted) { CryptoPP::CTR_Mode<CryptoPP::AES>::Decryption d(key.data(), key.size(), ctr.data()); From 8f059ae3982c5b6a1ae9d313ea4229563328423c Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sun, 29 Mar 2020 11:39:46 +0100 Subject: [PATCH 097/129] Apply suggestions from code review Co-Authored-By: Mat M. <mathew1800@gmail.com> --- src/common/archives.h | 2 +- src/common/memory_ref.h | 4 ++-- src/common/serialization/boost_flat_set.h | 2 +- src/common/thread_queue_list.h | 6 +++--- src/core/arm/arm_interface.h | 18 +++++++++--------- src/core/hle/kernel/config_mem.h | 2 +- src/core/hle/kernel/hle_ipc.cpp | 4 ++-- src/core/hle/kernel/kernel.cpp | 3 ++- src/core/hle/kernel/svc.cpp | 4 ++-- 9 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/common/archives.h b/src/common/archives.h index 993128197d..4f8b735d39 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -4,7 +4,7 @@ #pragma once -#include "boost/archive/binary_iarchive.hpp" +#include <boost/archive/binary_iarchive.hpp> #include "boost/archive/binary_oarchive.hpp" #include "boost/serialization/export.hpp" diff --git a/src/common/memory_ref.h b/src/common/memory_ref.h index f1a3286aba..65946fc582 100644 --- a/src/common/memory_ref.h +++ b/src/common/memory_ref.h @@ -29,7 +29,7 @@ private: class BufferMem : public BackingMem { public: BufferMem() = default; - BufferMem(u32 size) : data(std::vector<u8>(size)) {} + explicit BufferMem(std::size_t size) : data(size) {} u8* GetPtr() override { return data.data(); @@ -77,7 +77,7 @@ public: inline u8* GetPtr() { return cptr; } - inline operator bool() const { + explicit operator bool() const { return cptr != nullptr; } inline const u8* GetPtr() const { diff --git a/src/common/serialization/boost_flat_set.h b/src/common/serialization/boost_flat_set.h index 7fe0fe0977..c47e8c1a7c 100644 --- a/src/common/serialization/boost_flat_set.h +++ b/src/common/serialization/boost_flat_set.h @@ -19,7 +19,7 @@ void load(Archive& ar, boost::container::flat_set<T>& set, const unsigned int fi u64 count{}; ar >> count; set.clear(); - for (auto i = 0; i < count; i++) { + for (u64 i = 0; i < count; i++) { T value{}; ar >> value; set.insert(value); diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h index c25bbe5853..abeb465ada 100644 --- a/src/common/thread_queue_list.h +++ b/src/common/thread_queue_list.h @@ -167,7 +167,7 @@ private: } else if (q == UnlinkedTag()) { return -1; } else { - return static_cast<s32>(q - &queues[0]); + return q - queues.data(); } } @@ -186,8 +186,8 @@ private: void save(Archive& ar, const unsigned int file_version) const { s32 idx = ToIndex(first); ar << idx; - for (auto i = 0; i < NUM_QUEUES; i++) { - s32 idx1 = ToIndex(queues[i].next_nonempty); + for (size_t i = 0; i < NUM_QUEUES; i++) { + const s32 idx1 = ToIndex(queues[i].next_nonempty); ar << idx1; ar << queues[i].data; } diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index b02e3941fa..e39e1b9fac 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -28,12 +28,12 @@ public: template <class Archive> void save(Archive& ar, const unsigned int file_version) const { - for (auto i = 0; i < 16; i++) { - auto r = GetCpuRegister(i); + for (size_t i = 0; i < 16; i++) { + const auto r = GetCpuRegister(i); ar << r; } - for (auto i = 0; i < 16; i++) { - auto r = GetFpuRegister(i); + for (size_t i = 0; i < 16; i++) { + const auto r = GetFpuRegister(i); ar << r; } auto r1 = GetCpsr(); @@ -47,11 +47,11 @@ public: template <class Archive> void load(Archive& ar, const unsigned int file_version) { u32 r; - for (auto i = 0; i < 16; i++) { + for (size_t i = 0; i < 16; i++) { ar >> r; SetCpuRegister(i, r); } - for (auto i = 0; i < 16; i++) { + for (size_t i = 0; i < 16; i++) { ar >> r; SetFpuRegister(i, r); } @@ -247,7 +247,7 @@ private: ar << id; auto page_table = GetPageTable(); ar << page_table; - for (auto i = 0; i < 15; i++) { + for (size_t i = 0; i < 15; i++) { auto r = GetReg(i); ar << r; } @@ -255,7 +255,7 @@ private: ar << pc; auto cpsr = GetCPSR(); ar << cpsr; - for (auto i = 0; i < 32; i++) { + for (size_t i = 0; i < 32; i++) { auto r = GetVFPReg(i); ar << r; } @@ -278,7 +278,7 @@ private: ar >> page_table; SetPageTable(page_table); u32 r; - for (auto i = 0; i < 15; i++) { + for (size_t = 0; i < 15; i++) { ar >> r; SetReg(i, r); } diff --git a/src/core/hle/kernel/config_mem.h b/src/core/hle/kernel/config_mem.h index c466345ece..a81a5d2917 100644 --- a/src/core/hle/kernel/config_mem.h +++ b/src/core/hle/kernel/config_mem.h @@ -58,7 +58,7 @@ public: ConfigMemDef& GetConfigMem(); u8* GetPtr() override { - return static_cast<u8*>(static_cast<void*>(&config_mem)); + return reinterpret_cast<u8*>(&config_mem)); } u32 GetSize() const override { diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 23f5774902..88bd6b71bb 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -21,7 +21,7 @@ class HLERequestContext::ThreadCallback : public Kernel::WakeupCallback { public: ThreadCallback(std::shared_ptr<HLERequestContext> context_, std::shared_ptr<HLERequestContext::WakeupCallback> callback_) - : context(context_), callback(callback_) {} + : context(std::move(context_)), callback(std::move(callback_)) {} void WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, std::shared_ptr<WaitObject> object) { ASSERT(thread->status == ThreadStatus::WaitHleEvent); @@ -296,7 +296,7 @@ MappedBuffer::MappedBuffer() : memory(&Core::Global<Core::System>().Memory()) {} MappedBuffer::MappedBuffer(Memory::MemorySystem& memory, std::shared_ptr<Process> process, u32 descriptor, VAddr address, u32 id) - : memory(&memory), id(id), address(address), process(process) { + : memory(&memory), id(id), address(address), process(std::move(process)) { IPC::MappedBufferDescInfo desc{descriptor}; size = desc.size; perms = desc.perms; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 8afddb4999..11ef90771c 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -24,7 +24,8 @@ KernelSystem::KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing, u32 num_cores, u8 n3ds_mode) : memory(memory), timing(timing), prepare_reschedule_callback(std::move(prepare_reschedule_callback)) { - for (auto i = 0; i < memory_regions.size(); i++) { +std::generate(memory_regions.begin(), memory_regions.end(), + [] { return std::make_shared<MemoryRegionInfo>(); }); memory_regions[i] = std::make_shared<MemoryRegionInfo>(); } MemoryInit(system_mode, n3ds_mode); diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 9aeeea236f..8f1ba5e011 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -409,7 +409,7 @@ static ResultCode ReceiveIPCRequest(Kernel::KernelSystem& kernel, Memory::Memory class SVC_SyncCallback : public Kernel::WakeupCallback { public: - SVC_SyncCallback(bool do_output_) : do_output(do_output_) {} + explicit SVC_SyncCallback(bool do_output_) : do_output(do_output_) {} void WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, std::shared_ptr<WaitObject> object) { @@ -442,7 +442,7 @@ private: class SVC_IPCCallback : public Kernel::WakeupCallback { public: - SVC_IPCCallback(Core::System& system_) : system(system_) {} + explicit SVC_IPCCallback(Core::System& system_) : system(system_) {} void WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, std::shared_ptr<WaitObject> object) { From 04aa351c40a19c67382da5470a37b79df477367a Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sun, 29 Mar 2020 16:14:36 +0100 Subject: [PATCH 098/129] Code review - general gardening --- src/common/construct.h | 15 ++++----- src/common/memory_ref.h | 49 ++++++++++++++++-------------- src/common/thread_queue_list.h | 10 +++--- src/core/arm/arm_interface.h | 38 +++++++++++------------ src/core/hle/kernel/config_mem.h | 8 +++-- src/core/hle/kernel/kernel.cpp | 6 ++-- src/core/hle/kernel/shared_page.h | 10 ++++-- src/core/hle/service/cecd/cecd.cpp | 43 +++++++++++++++----------- src/core/hle/service/http_c.cpp | 4 +-- src/core/memory.cpp | 30 ++++++++++++++---- 10 files changed, 125 insertions(+), 88 deletions(-) diff --git a/src/common/construct.h b/src/common/construct.h index 4e48ee60d1..cb47bb46ea 100644 --- a/src/common/construct.h +++ b/src/common/construct.h @@ -6,28 +6,29 @@ #include <boost/serialization/serialization.hpp> +/// Allows classes to define `save_construct` and `load_construct` methods for serialization +/// This is used where we don't call the default constructor during deserialization, as a shortcut +/// instead of using load_construct_data directly class construct_access { public: template <class Archive, class T> - static inline void save_construct(Archive& ar, const T* t, const unsigned int file_version) { + static void save_construct(Archive& ar, const T* t, const unsigned int file_version) { t->save_construct(ar, file_version); } template <class Archive, class T> - static inline void load_construct(Archive& ar, T* t, const unsigned int file_version) { + static 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 { \ + namespace boost::serialization { \ template <class Archive> \ - inline void save_construct_data(Archive& ar, const T* t, const unsigned int file_version) { \ + void save_construct_data(Archive& ar, const T* t, const unsigned int file_version) { \ construct_access::save_construct(ar, t, file_version); \ } \ template <class Archive> \ - inline void load_construct_data(Archive& ar, T* t, const unsigned int file_version) { \ + 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/common/memory_ref.h b/src/common/memory_ref.h index 65946fc582..30eabbaee9 100644 --- a/src/common/memory_ref.h +++ b/src/common/memory_ref.h @@ -17,7 +17,8 @@ class BackingMem { public: virtual ~BackingMem() = default; virtual u8* GetPtr() = 0; - virtual u32 GetSize() const = 0; + virtual const u8* GetPtr() const = 0; + virtual std::size_t GetSize() const = 0; private: template <class Archive> @@ -35,7 +36,11 @@ public: return data.data(); } - u32 GetSize() const override { + const u8* GetPtr() const override { + return data.data(); + } + + std::size_t GetSize() const override { return static_cast<u32>(data.size()); } @@ -66,51 +71,51 @@ public: : backing_mem(std::move(backing_mem_)), offset(0) { Init(); } - MemoryRef(std::shared_ptr<BackingMem> backing_mem_, u32 offset_) + MemoryRef(std::shared_ptr<BackingMem> backing_mem_, u64 offset_) : backing_mem(std::move(backing_mem_)), offset(offset_) { ASSERT(offset < backing_mem->GetSize()); Init(); } - inline operator u8*() { - return cptr; - } - inline u8* GetPtr() { - return cptr; - } explicit operator bool() const { return cptr != nullptr; } - inline const u8* GetPtr() const { + operator u8*() { return cptr; } - inline u32 GetSize() const { + u8* GetPtr() { + return cptr; + } + operator const u8*() const { + return cptr; + } + const u8* GetPtr() const { + return cptr; + } + std::size_t GetSize() const { return csize; } - inline void operator+=(u32 offset_by) { + MemoryRef& operator+=(u32 offset_by) { ASSERT(offset_by < csize); offset += offset_by; Init(); + return *this; } - inline MemoryRef operator+(u32 offset_by) const { + MemoryRef operator+(u32 offset_by) const { ASSERT(offset_by < csize); return MemoryRef(backing_mem, offset + offset_by); } - inline u8* operator+(std::size_t offset_by) const { - ASSERT(offset_by < csize); - return cptr + offset_by; - } private: - std::shared_ptr<BackingMem> backing_mem = nullptr; - u32 offset = 0; + std::shared_ptr<BackingMem> backing_mem{}; + u64 offset{}; // Cached values for speed - u8* cptr = nullptr; - u32 csize = 0; + u8* cptr{}; + std::size_t csize{}; void Init() { if (backing_mem) { cptr = backing_mem->GetPtr() + offset; - csize = static_cast<u32>(backing_mem->GetSize() - offset); + csize = static_cast<std::size_t>(backing_mem->GetSize() - offset); } else { cptr = nullptr; csize = 0; diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h index abeb465ada..1ba68e1e4e 100644 --- a/src/common/thread_queue_list.h +++ b/src/common/thread_queue_list.h @@ -161,7 +161,7 @@ private: // The priority level queues of thread ids. std::array<Queue, NUM_QUEUES> queues; - s32 ToIndex(Queue* q) const { + s64 ToIndex(const Queue* q) const { if (q == nullptr) { return -2; } else if (q == UnlinkedTag()) { @@ -171,7 +171,7 @@ private: } } - Queue* ToPointer(s32 idx) { + Queue* ToPointer(s64 idx) { if (idx == -1) { return UnlinkedTag(); } else if (idx < 0) { @@ -184,10 +184,10 @@ private: friend class boost::serialization::access; template <class Archive> void save(Archive& ar, const unsigned int file_version) const { - s32 idx = ToIndex(first); + const s64 idx = ToIndex(first); ar << idx; for (size_t i = 0; i < NUM_QUEUES; i++) { - const s32 idx1 = ToIndex(queues[i].next_nonempty); + const s64 idx1 = ToIndex(queues[i].next_nonempty); ar << idx1; ar << queues[i].data; } @@ -195,7 +195,7 @@ private: template <class Archive> void load(Archive& ar, const unsigned int file_version) { - s32 idx; + s64 idx; ar >> idx; first = ToPointer(idx); for (auto i = 0; i < NUM_QUEUES; i++) { diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index e39e1b9fac..fca4885869 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -36,11 +36,11 @@ public: const auto r = GetFpuRegister(i); ar << r; } - auto r1 = GetCpsr(); + const auto r1 = GetCpsr(); ar << r1; - auto r2 = GetFpscr(); + const auto r2 = GetFpscr(); ar << r2; - auto r3 = GetFpexc(); + const auto r3 = GetFpexc(); ar << r3; } @@ -245,26 +245,26 @@ private: void save(Archive& ar, const unsigned int file_version) const { ar << timer; ar << id; - auto page_table = GetPageTable(); + const auto page_table = GetPageTable(); ar << page_table; - for (size_t i = 0; i < 15; i++) { - auto r = GetReg(i); + for (int i = 0; i < 15; i++) { + const auto r = GetReg(i); ar << r; } - auto pc = GetPC(); + const auto pc = GetPC(); ar << pc; - auto cpsr = GetCPSR(); + const auto cpsr = GetCPSR(); ar << cpsr; - for (size_t i = 0; i < 32; i++) { - auto r = GetVFPReg(i); + for (int i = 0; i < 32; i++) { + const auto r = GetVFPReg(i); ar << r; } - for (auto i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { - auto r = GetVFPSystemReg(static_cast<VFPSystemRegister>(i)); + for (size_t i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { + const auto r = GetVFPSystemReg(static_cast<VFPSystemRegister>(i)); ar << r; } - for (auto i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { - auto r = GetCP15Register(static_cast<CP15Register>(i)); + for (size_t i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { + const auto r = GetCP15Register(static_cast<CP15Register>(i)); ar << r; } } @@ -274,11 +274,11 @@ private: PurgeState(); ar >> timer; ar >> id; - std::shared_ptr<Memory::PageTable> page_table = nullptr; + std::shared_ptr<Memory::PageTable> page_table{}; ar >> page_table; SetPageTable(page_table); u32 r; - for (size_t = 0; i < 15; i++) { + for (int i = 0; i < 15; i++) { ar >> r; SetReg(i, r); } @@ -286,15 +286,15 @@ private: SetPC(r); ar >> r; SetCPSR(r); - for (auto i = 0; i < 32; i++) { + for (int i = 0; i < 32; i++) { ar >> r; SetVFPReg(i, r); } - for (auto i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { + for (size_t i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { ar >> r; SetVFPSystemReg(static_cast<VFPSystemRegister>(i), r); } - for (auto i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { + for (size_t i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { ar >> r; SetCP15Register(static_cast<CP15Register>(i), r); } diff --git a/src/core/hle/kernel/config_mem.h b/src/core/hle/kernel/config_mem.h index a81a5d2917..b592aff7aa 100644 --- a/src/core/hle/kernel/config_mem.h +++ b/src/core/hle/kernel/config_mem.h @@ -58,10 +58,14 @@ public: ConfigMemDef& GetConfigMem(); u8* GetPtr() override { - return reinterpret_cast<u8*>(&config_mem)); + return reinterpret_cast<u8*>(&config_mem); } - u32 GetSize() const override { + const u8* GetPtr() const override { + return reinterpret_cast<const u8*>(&config_mem); + } + + std::size_t GetSize() const override { return sizeof(config_mem); } diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 11ef90771c..f0974f88ac 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -24,10 +24,8 @@ KernelSystem::KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing, u32 num_cores, u8 n3ds_mode) : memory(memory), timing(timing), prepare_reschedule_callback(std::move(prepare_reschedule_callback)) { -std::generate(memory_regions.begin(), memory_regions.end(), - [] { return std::make_shared<MemoryRegionInfo>(); }); - memory_regions[i] = std::make_shared<MemoryRegionInfo>(); - } + std::generate(memory_regions.begin(), memory_regions.end(), + [] { return std::make_shared<MemoryRegionInfo>(); }); MemoryInit(system_mode, n3ds_mode); resource_limits = std::make_unique<ResourceLimitList>(*this); diff --git a/src/core/hle/kernel/shared_page.h b/src/core/hle/kernel/shared_page.h index b74470b4a3..c4b174db4b 100644 --- a/src/core/hle/kernel/shared_page.h +++ b/src/core/hle/kernel/shared_page.h @@ -99,11 +99,15 @@ public: SharedPageDef& GetSharedPage(); - virtual u8* GetPtr() { - return static_cast<u8*>(static_cast<void*>(&shared_page)); + u8* GetPtr() override { + return reinterpret_cast<u8*>(&shared_page); } - virtual u32 GetSize() const { + const u8* GetPtr() const override { + return reinterpret_cast<const u8*>(&shared_page); + } + + std::size_t GetSize() const override { return sizeof(shared_page); } diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index 36263f6222..8db49fc82c 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -106,7 +106,7 @@ void Module::Interface::Open(Kernel::HLERequestContext& ctx) { } else { session_data->file = std::move(file_result).Unwrap(); rb.Push(RESULT_SUCCESS); - rb.Push<u32>(session_data->file->GetSize()); // Return file size + rb.Push<u32>(static_cast<u32>(session_data->file->GetSize())); // Return file size } if (path_type == CecDataPathType::MboxProgramId) { @@ -154,8 +154,8 @@ void Module::Interface::Read(Kernel::HLERequestContext& ctx) { break; default: // If not directory, then it is a file std::vector<u8> buffer(write_buffer_size); - const u32 bytes_read = - session_data->file->Read(0, write_buffer_size, buffer.data()).Unwrap(); + const u32 bytes_read = static_cast<u32>( + session_data->file->Read(0, write_buffer_size, buffer.data()).Unwrap()); write_buffer.Write(buffer.data(), 0, write_buffer_size); session_data->file->Close(); @@ -197,7 +197,8 @@ void Module::Interface::ReadMessage(Kernel::HLERequestContext& ctx) { auto message = std::move(message_result).Unwrap(); std::vector<u8> buffer(buffer_size); - const u32 bytes_read = message->Read(0, buffer_size, buffer.data()).Unwrap(); + const u32 bytes_read = + static_cast<u32>(message->Read(0, buffer_size, buffer.data()).Unwrap()); write_buffer.Write(buffer.data(), 0, buffer_size); message->Close(); @@ -266,7 +267,8 @@ void Module::Interface::ReadMessageWithHMAC(Kernel::HLERequestContext& ctx) { auto message = std::move(message_result).Unwrap(); std::vector<u8> buffer(buffer_size); - const u32 bytes_read = message->Read(0, buffer_size, buffer.data()).Unwrap(); + const u32 bytes_read = + static_cast<u32>(message->Read(0, buffer_size, buffer.data()).Unwrap()); write_buffer.Write(buffer.data(), 0, buffer_size); message->Close(); @@ -367,8 +369,8 @@ void Module::Interface::Write(Kernel::HLERequestContext& ctx) { buffer); } - const u32 bytes_written = - session_data->file->Write(0, buffer.size(), true, buffer.data()).Unwrap(); + const u32 bytes_written = static_cast<u32>( + session_data->file->Write(0, buffer.size(), true, buffer.data()).Unwrap()); session_data->file->Close(); rb.Push(RESULT_SUCCESS); @@ -429,7 +431,8 @@ void Module::Interface::WriteMessage(Kernel::HLERequestContext& ctx) { msg_header.sender_id, msg_header.sender_id2, msg_header.send_count, msg_header.forward_count, msg_header.user_data); - const u32 bytes_written = message->Write(0, buffer_size, true, buffer.data()).Unwrap(); + const u32 bytes_written = + static_cast<u32>(message->Write(0, buffer_size, true, buffer.data()).Unwrap()); message->Close(); rb.Push(RESULT_SUCCESS); @@ -515,7 +518,8 @@ void Module::Interface::WriteMessageWithHMAC(Kernel::HLERequestContext& ctx) { hmac.CalculateDigest(hmac_digest.data(), message_body.data(), msg_header.body_size); std::memcpy(buffer.data() + hmac_offset, hmac_digest.data(), hmac_size); - const u32 bytes_written = message->Write(0, buffer_size, true, buffer.data()).Unwrap(); + const u32 bytes_written = + static_cast<u32>(message->Write(0, buffer_size, true, buffer.data()).Unwrap()); message->Close(); rb.Push(RESULT_SUCCESS); @@ -757,7 +761,8 @@ void Module::Interface::OpenAndWrite(Kernel::HLERequestContext& ctx) { cecd->CheckAndUpdateFile(path_type, ncch_program_id, buffer); } - const u32 bytes_written = file->Write(0, buffer.size(), true, buffer.data()).Unwrap(); + const u32 bytes_written = + static_cast<u32>(file->Write(0, buffer.size(), true, buffer.data()).Unwrap()); file->Close(); rb.Push(RESULT_SUCCESS); @@ -806,7 +811,8 @@ void Module::Interface::OpenAndRead(Kernel::HLERequestContext& ctx) { auto file = std::move(file_result).Unwrap(); std::vector<u8> buffer(buffer_size); - const u32 bytes_read = file->Read(0, buffer_size, buffer.data()).Unwrap(); + const u32 bytes_read = + static_cast<u32>(file->Read(0, buffer_size, buffer.data()).Unwrap()); write_buffer.Write(buffer.data(), 0, buffer_size); file->Close(); @@ -937,7 +943,7 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ constexpr u32 max_num_boxes = 24; constexpr u32 name_size = 16; // fixed size 16 characters long constexpr u32 valid_name_size = 8; // 8 characters are valid, the rest are null - const u32 file_size = file_buffer.size(); + const u32 file_size = static_cast<u32>(file_buffer.size()); switch (path_type) { case CecDataPathType::MboxList: { @@ -1021,7 +1027,7 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ std::u16string u16_filename; // Loop through entries but don't add mboxlist____ to itself. - for (auto i = 0; i < entry_count; i++) { + for (u32 i = 0; i < entry_count; i++) { u16_filename = std::u16string(entries[i].filename); file_name = Common::UTF16ToUTF8(u16_filename); @@ -1212,7 +1218,7 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ std::string file_name; std::u16string u16_filename; - for (auto i = 0; i < entry_count; i++) { + for (u32 i = 0; i < entry_count; i++) { u16_filename = std::u16string(entries[i].filename); file_name = Common::UTF16ToUTF8(u16_filename); @@ -1230,7 +1236,7 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ auto message_result = cecd_system_save_data_archive->OpenFile(message_path, mode); auto message = std::move(message_result).Unwrap(); - const u32 message_size = message->GetSize(); + const u32 message_size = static_cast<u32>(message->GetSize()); std::vector<u8> buffer(message_size); message->Read(0, message_size, buffer.data()).Unwrap(); @@ -1304,7 +1310,7 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ std::string file_name; std::u16string u16_filename; - for (auto i = 0; i < entry_count; i++) { + for (u32 i = 0; i < entry_count; i++) { u16_filename = std::u16string(entries[i].filename); file_name = Common::UTF16ToUTF8(u16_filename); @@ -1320,7 +1326,7 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ auto message_result = cecd_system_save_data_archive->OpenFile(message_path, mode); auto message = std::move(message_result).Unwrap(); - const u32 message_size = message->GetSize(); + const u32 message_size = static_cast<u32>(message->GetSize()); std::vector<u8> buffer(message_size); message->Read(0, message_size, buffer.data()).Unwrap(); @@ -1353,7 +1359,8 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ case CecDataPathType::MboxData: case CecDataPathType::MboxIcon: case CecDataPathType::MboxTitle: - default: {} + default: { + } } } diff --git a/src/core/hle/service/http_c.cpp b/src/core/hle/service/http_c.cpp index af639e4936..4879ab3716 100644 --- a/src/core/hle/service/http_c.cpp +++ b/src/core/hle/service/http_c.cpp @@ -83,10 +83,10 @@ void Context::MakeRequest() { client = std::move(ssl_client); if (auto client_cert = ssl_config.client_cert_ctx.lock()) { - SSL_CTX_use_certificate_ASN1(ctx, client_cert->certificate.size(), + SSL_CTX_use_certificate_ASN1(ctx, static_cast<int>(client_cert->certificate.size()), client_cert->certificate.data()); SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA, ctx, client_cert->private_key.data(), - client_cert->private_key.size()); + static_cast<long>(client_cert->private_key.size())); } // TODO(B3N30): Check for SSLOptions-Bits and set the verify method accordingly diff --git a/src/core/memory.cpp b/src/core/memory.cpp index a0fa2a7382..c0c030de1a 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -100,7 +100,7 @@ public: Impl(); - virtual u8* GetPtr(Region r) { + const u8* GetPtr(Region r) const { switch (r) { case Region::VRAM: return vram.get(); @@ -115,7 +115,22 @@ public: } } - virtual u32 GetSize(Region r) const { + u8* GetPtr(Region r) { + switch (r) { + case Region::VRAM: + return vram.get(); + case Region::DSP: + return dsp->GetDspMemory().data(); + case Region::FCRAM: + return fcram.get(); + case Region::N3DS: + return n3ds_extra_ram.get(); + default: + UNREACHABLE(); + } + } + + u32 GetSize(Region r) const { switch (r) { case Region::VRAM: return VRAM_SIZE; @@ -158,11 +173,14 @@ template <Region R> class MemorySystem::BackingMemImpl : public BackingMem { public: BackingMemImpl() : impl(*Core::Global<Core::System>().Memory().impl) {} - BackingMemImpl(MemorySystem::Impl& impl_) : impl(impl_) {} - virtual u8* GetPtr() { + explicit BackingMemImpl(MemorySystem::Impl& impl_) : impl(impl_) {} + u8* GetPtr() override { return impl.GetPtr(R); } - virtual u32 GetSize() const { + const u8* GetPtr() const override { + return impl.GetPtr(R); + } + std::size_t GetSize() const override { return impl.GetSize(R); } @@ -884,7 +902,7 @@ void WriteMMIO<u64>(MMIORegionPointer mmio_handler, VAddr addr, const u64 data) u32 MemorySystem::GetFCRAMOffset(const u8* pointer) { ASSERT(pointer >= impl->fcram.get() && pointer <= impl->fcram.get() + Memory::FCRAM_N3DS_SIZE); - return pointer - impl->fcram.get(); + return static_cast<u32>(pointer - impl->fcram.get()); } u8* MemorySystem::GetFCRAMPointer(u32 offset) { From 6760ea18b6a63ae9e0afecffcecd081890991b88 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sun, 29 Mar 2020 18:56:25 +0100 Subject: [PATCH 099/129] Serialize ArchiveManager and other code review actions --- src/core/core.cpp | 2 ++ src/core/file_sys/archive_backend.h | 22 ++++++++++------------ src/core/file_sys/archive_extsavedata.cpp | 9 +++++++++ src/core/file_sys/archive_other_savedata.h | 1 + src/core/file_sys/archive_savedata.h | 1 + src/core/file_sys/archive_selfncch.h | 3 ++- src/core/file_sys/file_backend.h | 1 - src/core/file_sys/layered_fs.h | 9 +-------- src/core/file_sys/savedata_archive.h | 5 +++-- src/core/hle/kernel/hle_ipc.h | 3 --- src/core/hle/kernel/process.cpp | 2 +- src/core/hle/kernel/process.h | 1 + src/core/hle/service/ac/ac.h | 2 -- src/core/hle/service/act/act.h | 2 +- src/core/hle/service/am/am.h | 21 ++++++++++++++------- src/core/hle/service/apt/applet_manager.h | 1 + src/core/hle/service/apt/apt.cpp | 2 ++ src/core/hle/service/apt/apt.h | 7 +------ src/core/hle/service/boss/boss.h | 2 +- src/core/hle/service/cam/cam.h | 7 ++++++- src/core/hle/service/cecd/cecd.cpp | 2 ++ src/core/hle/service/cecd/cecd.h | 2 +- src/core/hle/service/cfg/cfg.cpp | 2 ++ src/core/hle/service/csnd/csnd_snd.h | 6 +----- src/core/hle/service/dsp/dsp_dsp.h | 9 ++++----- src/core/hle/service/fs/archive.h | 6 ++++-- src/core/hle/service/fs/directory.cpp | 2 ++ src/core/hle/service/fs/file.cpp | 1 + src/core/hle/service/fs/file.h | 1 + src/core/hle/service/fs/fs_user.h | 1 + src/core/hle/service/gsp/gsp_gpu.h | 2 ++ src/core/hle/service/hid/hid.cpp | 7 +++++-- src/core/hle/service/ir/extra_hid.h | 1 - src/core/hle/service/ir/ir_rst.cpp | 2 ++ src/core/hle/service/ir/ir_user.cpp | 1 + src/core/hle/service/ndm/ndm_u.h | 1 + src/core/hle/service/nfc/nfc.cpp | 2 ++ src/core/hle/service/nfc/nfc.h | 8 ++++++++ src/core/hle/service/nwm/nwm_uds.cpp | 2 +- src/core/hle/service/service.h | 1 - src/core/hle/service/sm/srv.cpp | 3 ++- src/network/CMakeLists.txt | 2 +- src/network/room_member.h | 2 +- 43 files changed, 102 insertions(+), 67 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 5897443676..2928d50e7f 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -1,3 +1,4 @@ +#pragma optimize("", off) // Copyright 2014 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -544,6 +545,7 @@ void System::serialize(Archive& ar, const unsigned int file_version) { ar&* cpu_cores[i].get(); } ar&* service_manager.get(); + ar&* archive_manager.get(); ar& GPU::g_regs; ar& LCD::g_regs; diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 87a42b028d..0c5b14dc52 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -65,7 +65,7 @@ private: LowPathType type; std::vector<u8> binary; std::string string; - std::u16string u16str{}; + std::u16string u16str; template <class Archive> void serialize(Archive& ar, const unsigned int) { @@ -77,18 +77,16 @@ private: case LowPathType::Char: ar& string; break; -#ifdef _WIN32 - case LowPathType::Wchar: - static_assert(sizeof(wchar_t) == sizeof(char16_t)); - { - std::wstring wstring(reinterpret_cast<wchar_t*>(u16str.data())); - ar& wstring; - if (!Archive::is_saving::value) { - u16str = std::u16string(reinterpret_cast<char16_t*>(wstring.data())); - } + case LowPathType::Wchar: { + std::vector<char16_t> data; + if (Archive::is_saving::value) { + std::copy(u16str.begin(), u16str.end(), std::back_inserter(data)); } - break; -#endif + ar& data; + if (Archive::is_loading::value) { + u16str = std::u16string(data.data(), data.size()); + } + } break; default: break; } diff --git a/src/core/file_sys/archive_extsavedata.cpp b/src/core/file_sys/archive_extsavedata.cpp index 59973b8c58..8326122f54 100644 --- a/src/core/file_sys/archive_extsavedata.cpp +++ b/src/core/file_sys/archive_extsavedata.cpp @@ -167,6 +167,14 @@ public: } return SaveDataArchive::CreateFile(path, size); } + +private: + ExtSaveDataArchive() = default; + template <class Archive> + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object<SaveDataArchive>(*this); + } + friend class boost::serialization::access; }; struct ExtSaveDataArchivePath { @@ -304,3 +312,4 @@ void ArchiveFactory_ExtSaveData::WriteIcon(const Path& path, const u8* icon_data } // namespace FileSys SERIALIZE_EXPORT_IMPL(FileSys::ExtSaveDataDelayGenerator) +SERIALIZE_EXPORT_IMPL(FileSys::ExtSaveDataArchive) diff --git a/src/core/file_sys/archive_other_savedata.h b/src/core/file_sys/archive_other_savedata.h index cc0cfe404d..f002fec7f0 100644 --- a/src/core/file_sys/archive_other_savedata.h +++ b/src/core/file_sys/archive_other_savedata.h @@ -4,6 +4,7 @@ #pragma once +#include <boost/serialization/base_object.hpp> #include <boost/serialization/export.hpp> #include <boost/serialization/shared_ptr.hpp> #include "core/file_sys/archive_source_sd_savedata.h" diff --git a/src/core/file_sys/archive_savedata.h b/src/core/file_sys/archive_savedata.h index 3f73adba31..5bc4b8ecdc 100644 --- a/src/core/file_sys/archive_savedata.h +++ b/src/core/file_sys/archive_savedata.h @@ -4,6 +4,7 @@ #pragma once +#include <boost/serialization/base_object.hpp> #include <boost/serialization/shared_ptr.hpp> #include "core/file_sys/archive_source_sd_savedata.h" diff --git a/src/core/file_sys/archive_selfncch.h b/src/core/file_sys/archive_selfncch.h index 68b48074f4..9f5b353b36 100644 --- a/src/core/file_sys/archive_selfncch.h +++ b/src/core/file_sys/archive_selfncch.h @@ -10,6 +10,7 @@ #include <vector> #include <boost/serialization/export.hpp> #include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/unordered_map.hpp> #include <boost/serialization/vector.hpp> #include "common/common_types.h" #include "core/file_sys/archive_backend.h" @@ -63,7 +64,7 @@ private: template <class Archive> void serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object<ArchiveFactory>(*this); - // NOTE: ncch_data is never written to, so we don't serialize it here + ar& ncch_data; } friend class boost::serialization::access; }; diff --git a/src/core/file_sys/file_backend.h b/src/core/file_sys/file_backend.h index 04f03a77d5..d56fc4c1ca 100644 --- a/src/core/file_sys/file_backend.h +++ b/src/core/file_sys/file_backend.h @@ -7,7 +7,6 @@ #include <algorithm> #include <cstddef> #include <memory> -#include <boost/serialization/base_object.hpp> #include <boost/serialization/unique_ptr.hpp> #include "common/common_types.h" #include "core/hle/result.h" diff --git a/src/core/file_sys/layered_fs.h b/src/core/file_sys/layered_fs.h index dc71d052fd..2a494bd8e2 100644 --- a/src/core/file_sys/layered_fs.h +++ b/src/core/file_sys/layered_fs.h @@ -23,14 +23,6 @@ struct RomFSHeader { struct Descriptor { u32_le offset; u32_le length; - - private: - template <class Archive> - void serialize(Archive& ar, const unsigned int) { - ar& offset; - ar& length; - } - friend class boost::serialization::access; }; u32_le header_length; Descriptor directory_hash_table; @@ -146,6 +138,7 @@ private: if (Archive::is_loading::value) { Load(); } + // NOTE: Everything else is essentially cached, updated when we call Load } friend class boost::serialization::access; }; diff --git a/src/core/file_sys/savedata_archive.h b/src/core/file_sys/savedata_archive.h index c9956e1358..38b9653d7d 100644 --- a/src/core/file_sys/savedata_archive.h +++ b/src/core/file_sys/savedata_archive.h @@ -38,10 +38,9 @@ public: protected: std::string mount_point; - -private: SaveDataArchive() = default; +private: template <class Archive> void serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object<ArchiveBackend>(*this); @@ -51,8 +50,10 @@ private: }; class SaveDataDelayGenerator; +class ExtSaveDataArchive; } // namespace FileSys BOOST_CLASS_EXPORT_KEY(FileSys::SaveDataArchive) BOOST_CLASS_EXPORT_KEY(FileSys::SaveDataDelayGenerator) +BOOST_CLASS_EXPORT_KEY(FileSys::ExtSaveDataArchive) diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 0004868259..47d98af2cd 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -22,8 +22,6 @@ #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_session.h" -BOOST_SERIALIZATION_ASSUME_ABSTRACT(Kernel::SessionRequestHandler) - namespace Service { class ServiceFrameworkBase; } @@ -320,5 +318,4 @@ private: } // namespace Kernel -BOOST_CLASS_EXPORT_KEY(Kernel::SessionRequestHandler::SessionDataBase) BOOST_CLASS_EXPORT_KEY(Kernel::HLERequestContext::ThreadCallback) diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index b72081ad5c..9b03f30f97 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -6,12 +6,12 @@ #include <memory> #include <boost/serialization/array.hpp> #include <boost/serialization/bitset.hpp> +#include <boost/serialization/shared_ptr.hpp> #include "common/archives.h" #include "common/assert.h" #include "common/common_funcs.h" #include "common/logging/log.h" #include "common/serialization/boost_vector.hpp" -#include "core/global.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/memory.h" #include "core/hle/kernel/process.h" diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 6eb79d2278..d9af80cd00 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -13,6 +13,7 @@ #include <boost/container/static_vector.hpp> #include <boost/serialization/base_object.hpp> #include <boost/serialization/vector.hpp> +#include <boost/serialization/string.hpp> #include "common/bit_field.h" #include "common/common_types.h" #include "core/hle/kernel/handle_table.h" diff --git a/src/core/hle/service/ac/ac.h b/src/core/hle/service/ac/ac.h index 0f31ca1b4b..e4342bde93 100644 --- a/src/core/hle/service/ac/ac.h +++ b/src/core/hle/service/ac/ac.h @@ -16,8 +16,6 @@ namespace Kernel { class Event; } -BOOST_SERIALIZATION_ASSUME_ABSTRACT(Service::AC::Module::Interface) - namespace Service::AC { class Module final { public: diff --git a/src/core/hle/service/act/act.h b/src/core/hle/service/act/act.h index 11812bcfe5..e5c2cf7aed 100644 --- a/src/core/hle/service/act/act.h +++ b/src/core/hle/service/act/act.h @@ -26,7 +26,7 @@ public: private: template <class Archive> - inline void serialize(Archive& ar, const unsigned int file_version) {} + void serialize(Archive& ar, const unsigned int file_version) {} friend class boost::serialization::access; }; diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 22481179ea..deff326b70 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -13,6 +13,7 @@ #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/vector.hpp> #include "common/common_types.h" +#include "common/construct.h" #include "core/file_sys/cia_container.h" #include "core/file_sys/file_backend.h" #include "core/global.h" @@ -154,7 +155,6 @@ std::string GetMediaTitlePath(Service::FS::MediaType media_type); class Module final { public: explicit Module(Core::System& system); - explicit Module(Kernel::KernelSystem& kernel); Module() = default; ~Module(); @@ -568,6 +568,8 @@ public: }; private: + explicit Module(Kernel::KernelSystem& kernel); + /** * Scans the for titles in a storage medium for listing. * @param media_type the storage medium to scan @@ -590,6 +592,16 @@ private: ar& am_title_list; ar& system_updater_mutex; } + + template <class Archive> + static void load_construct(Archive& ar, Module* t, const unsigned int file_version) { + ::new (t) Module(Core::Global<Kernel::KernelSystem>()); + } + + template <class Archive> + void save_construct(Archive& ar, const unsigned int file_version) const {} + + friend class ::construct_access; friend class boost::serialization::access; }; @@ -597,9 +609,4 @@ void InstallInterfaces(Core::System& system); } // namespace Service::AM -namespace boost::serialization { -template <class Archive> -inline void load_construct_data(Archive& ar, Service::AM::Module* t, const unsigned int) { - ::new (t) Service::AM::Module(Core::Global<Kernel::KernelSystem>()); -} -} // namespace boost::serialization +BOOST_SERIALIZATION_CONSTRUCT(Service::AM::Module); diff --git a/src/core/hle/service/apt/applet_manager.h b/src/core/hle/service/apt/applet_manager.h index 7260fb2d30..0f1a46a8b9 100644 --- a/src/core/hle/service/apt/applet_manager.h +++ b/src/core/hle/service/apt/applet_manager.h @@ -10,6 +10,7 @@ #include <boost/serialization/array.hpp> #include <boost/serialization/optional.hpp> #include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/vector.hpp> #include "core/global.h" #include "core/hle/kernel/event.h" #include "core/hle/result.h" diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 8780f67e06..d93b4bcb25 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/vector.hpp> #include "common/archives.h" #include "common/common_paths.h" #include "common/file_util.h" diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index aa480331c2..8b01d3b8eb 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -6,8 +6,6 @@ #include <memory> #include <vector> -#include <boost/serialization/shared_ptr.hpp> -#include <boost/serialization/vector.hpp> #include "common/archives.h" #include "common/common_funcs.h" #include "common/common_types.h" @@ -651,7 +649,4 @@ void InstallInterfaces(Core::System& system); } // namespace Service::APT -namespace boost::serialization { -template <class Archive> -void load_construct_data(Archive& ar, Service::APT::Module* t, const unsigned int); -} +SERVICE_CONSTRUCT(Service::APT::Module) diff --git a/src/core/hle/service/boss/boss.h b/src/core/hle/service/boss/boss.h index 4dae148f9e..e4000e8515 100644 --- a/src/core/hle/service/boss/boss.h +++ b/src/core/hle/service/boss/boss.h @@ -989,7 +989,7 @@ void InstallInterfaces(Core::System& system); namespace boost::serialization { template <class Archive> -inline void load_construct_data(Archive& ar, Service::BOSS::Module* t, const unsigned int) { +void load_construct_data(Archive& ar, Service::BOSS::Module* t, const unsigned int) { ::new (t) Service::BOSS::Module(Core::Global<Core::System>()); } } // namespace boost::serialization diff --git a/src/core/hle/service/cam/cam.h b/src/core/hle/service/cam/cam.h index 85501e8def..375df2b20a 100644 --- a/src/core/hle/service/cam/cam.h +++ b/src/core/hle/service/cam/cam.h @@ -9,6 +9,10 @@ #include <future> #include <memory> #include <vector> +#include <boost/serialization/array.hpp> +#include <boost/serialization/deque.hpp> +#include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/unique_ptr.hpp> #include "common/common_types.h" #include "common/swap.h" #include "core/global.h" @@ -849,6 +853,7 @@ private: ar& completion_event; ar& buffer_error_interrupt_event; ar& vsync_interrupt_event; + ar& vsync_timings; // Ignore capture_result. In-progress captures might be affected but this is OK. ar& dest_process; ar& dest; @@ -879,7 +884,7 @@ void InstallInterfaces(Core::System& system); namespace boost::serialization { template <class Archive> -inline void load_construct_data(Archive& ar, Service::CAM::Module* t, const unsigned int) { +void load_construct_data(Archive& ar, Service::CAM::Module* t, const unsigned int) { ::new (t) Service::CAM::Module(Core::Global<Core::System>()); } } // namespace boost::serialization diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index 8db49fc82c..31ecd990b1 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <boost/serialization/unique_ptr.hpp> +#include <boost/serialization/shared_ptr.hpp> #include <cryptopp/base64.h> #include <cryptopp/hmac.h> #include <cryptopp/sha.h> diff --git a/src/core/hle/service/cecd/cecd.h b/src/core/hle/service/cecd/cecd.h index b752701fe5..0870f31bf9 100644 --- a/src/core/hle/service/cecd/cecd.h +++ b/src/core/hle/service/cecd/cecd.h @@ -258,7 +258,7 @@ public: ar& data_path_type; ar& open_mode.raw; ar& path; - // ar& file; + ar& file; } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index 98feea8f73..fc285f6625 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp @@ -4,6 +4,8 @@ #include <algorithm> #include <tuple> +#include <boost/serialization/array.hpp> +#include <boost/serialization/unique_ptr.hpp> #include <cryptopp/osrng.h> #include <cryptopp/sha.h> #include "common/archives.h" diff --git a/src/core/hle/service/csnd/csnd_snd.h b/src/core/hle/service/csnd/csnd_snd.h index 6ac5d68766..0b4cd4331d 100644 --- a/src/core/hle/service/csnd/csnd_snd.h +++ b/src/core/hle/service/csnd/csnd_snd.h @@ -277,8 +277,4 @@ void InstallInterfaces(Core::System& system); } // namespace Service::CSND BOOST_CLASS_EXPORT_KEY(Service::CSND::CSND_SND) - -namespace boost::serialization { -template <class Archive> -void load_construct_data(Archive& ar, Service::CSND::CSND_SND* t, const unsigned int); -} +SERVICE_CONSTRUCT(Service::CSND::CSND_SND) diff --git a/src/core/hle/service/dsp/dsp_dsp.h b/src/core/hle/service/dsp/dsp_dsp.h index 90dd17f653..d580b3d00d 100644 --- a/src/core/hle/service/dsp/dsp_dsp.h +++ b/src/core/hle/service/dsp/dsp_dsp.h @@ -5,6 +5,9 @@ #pragma once #include <memory> +#include <boost/serialization/array.hpp> +#include <boost/serialization/base_object.hpp> +#include <boost/serialization/shared_ptr.hpp> #include "audio_core/dsp_interface.h" #include "core/hle/kernel/event.h" #include "core/hle/result.h" @@ -282,8 +285,4 @@ void InstallInterfaces(Core::System& system); } // namespace Service::DSP BOOST_CLASS_EXPORT_KEY(Service::DSP::DSP_DSP) - -namespace boost::serialization { -template <class Archive> -void load_construct_data(Archive& ar, Service::DSP::DSP_DSP* t, const unsigned int); -} +SERVICE_CONSTRUCT(Service::DSP::DSP_DSP) diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index 29965491b9..aba06ac6fe 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -8,7 +8,8 @@ #include <string> #include <unordered_map> #include <vector> -#include <boost/container/flat_map.hpp> +#include <boost/serialization/unique_ptr.hpp> +#include <boost/serialization/unordered_map.hpp> #include "common/common_types.h" #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -253,7 +254,7 @@ private: * Map of registered archives, identified by id code. Once an archive is registered here, it is * never removed until UnregisterArchiveTypes is called. */ - boost::container::flat_map<ArchiveIdCode, std::unique_ptr<ArchiveFactory>> id_code_map; + std::unordered_map<ArchiveIdCode, std::unique_ptr<ArchiveFactory>> id_code_map; /** * Map of active archive handles to archive objects @@ -267,6 +268,7 @@ private: ar& handle_map; ar& next_handle; } + friend class boost::serialization::access; }; } // namespace Service::FS diff --git a/src/core/hle/service/fs/directory.cpp b/src/core/hle/service/fs/directory.cpp index c7fb085ea1..655c5602ea 100644 --- a/src/core/hle/service/fs/directory.cpp +++ b/src/core/hle/service/fs/directory.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <boost/serialization/base_object.hpp> +#include <boost/serialization/unique_ptr.hpp> #include "common/archives.h" #include "common/logging/log.h" #include "core/file_sys/directory_backend.h" diff --git a/src/core/hle/service/fs/file.cpp b/src/core/hle/service/fs/file.cpp index 3664f238db..3d9eee5949 100644 --- a/src/core/hle/service/fs/file.cpp +++ b/src/core/hle/service/fs/file.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <boost/serialization/unique_ptr.hpp> #include "common/archives.h" #include "common/logging/log.h" #include "core/core.h" diff --git a/src/core/hle/service/fs/file.h b/src/core/hle/service/fs/file.h index 6aa301a7bf..a6ef693042 100644 --- a/src/core/hle/service/fs/file.h +++ b/src/core/hle/service/fs/file.h @@ -5,6 +5,7 @@ #pragma once #include <memory> +#include <boost/serialization/base_object.hpp> #include "core/file_sys/archive_backend.h" #include "core/global.h" #include "core/hle/service/service.h" diff --git a/src/core/hle/service/fs/fs_user.h b/src/core/hle/service/fs/fs_user.h index 83183ecf66..e972d0dae6 100644 --- a/src/core/hle/service/fs/fs_user.h +++ b/src/core/hle/service/fs/fs_user.h @@ -4,6 +4,7 @@ #pragma once +#include <boost/serialization/base_object.hpp> #include "common/common_types.h" #include "core/hle/service/service.h" diff --git a/src/core/hle/service/gsp/gsp_gpu.h b/src/core/hle/service/gsp/gsp_gpu.h index 82ecf2480b..c8914ef72f 100644 --- a/src/core/hle/service/gsp/gsp_gpu.h +++ b/src/core/hle/service/gsp/gsp_gpu.h @@ -7,6 +7,8 @@ #include <cstddef> #include <memory> #include <string> +#include <boost/serialization/base_object.hpp> +#include <boost/serialization/shared_ptr.hpp> #include "common/bit_field.h" #include "common/common_types.h" #include "core/hle/kernel/event.h" diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 6898c1024e..845319f628 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -4,6 +4,9 @@ #include <algorithm> #include <cmath> +#include <boost/serialization/array.hpp> +#include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/unique_ptr.hpp> #include "common/archives.h" #include "common/logging/log.h" #include "core/3ds.h" @@ -208,7 +211,7 @@ void Module::UpdateAccelerometerCallback(u64 userdata, s64 cycles_late) { Common::Vec3<float> accel; if (!motion_device) { - is_device_reload_pending.exchange(true); + is_device_reload_pending.store(true); return; } std::tie(accel, std::ignore) = motion_device->GetStatus(); @@ -259,7 +262,7 @@ void Module::UpdateGyroscopeCallback(u64 userdata, s64 cycles_late) { Common::Vec3<float> gyro; if (!motion_device) { - is_device_reload_pending.exchange(true); + is_device_reload_pending.store(true); return; } std::tie(std::ignore, gyro) = motion_device->GetStatus(); diff --git a/src/core/hle/service/ir/extra_hid.h b/src/core/hle/service/ir/extra_hid.h index 1be403167d..46c0fdca4a 100644 --- a/src/core/hle/service/ir/extra_hid.h +++ b/src/core/hle/service/ir/extra_hid.h @@ -7,7 +7,6 @@ #include <array> #include <atomic> #include <boost/serialization/array.hpp> -#include <boost/serialization/export.hpp> #include "common/bit_field.h" #include "common/swap.h" #include "core/frontend/input.h" diff --git a/src/core/hle/service/ir/ir_rst.cpp b/src/core/hle/service/ir/ir_rst.cpp index 751460a044..bd6c64af37 100644 --- a/src/core/hle/service/ir/ir_rst.cpp +++ b/src/core/hle/service/ir/ir_rst.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <boost/serialization/base_object.hpp> +#include <boost/serialization/shared_ptr.hpp> #include "common/archives.h" #include "core/core.h" #include "core/core_timing.h" diff --git a/src/core/hle/service/ir/ir_user.cpp b/src/core/hle/service/ir/ir_user.cpp index 4bf6e74996..0cc77c928f 100644 --- a/src/core/hle/service/ir/ir_user.cpp +++ b/src/core/hle/service/ir/ir_user.cpp @@ -4,6 +4,7 @@ #include <memory> #include <boost/crc.hpp> +#include <boost/serialization/base_object.hpp> #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/unique_ptr.hpp> #include "common/string_util.h" diff --git a/src/core/hle/service/ndm/ndm_u.h b/src/core/hle/service/ndm/ndm_u.h index 3339478d1f..aebc6fa8b8 100644 --- a/src/core/hle/service/ndm/ndm_u.h +++ b/src/core/hle/service/ndm/ndm_u.h @@ -5,6 +5,7 @@ #pragma once #include <array> +#include <boost/serialization/array.hpp> #include "core/hle/service/service.h" namespace Core { diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp index 0bd6121a22..7213b79a72 100644 --- a/src/core/hle/service/nfc/nfc.cpp +++ b/src/core/hle/service/nfc/nfc.cpp @@ -22,6 +22,8 @@ void Module::serialize(Archive& ar, const unsigned int) { ar& tag_out_of_range_event; ar& nfc_tag_state; ar& nfc_status; + ar& amiibo_data; + ar& amiibo_in_range; } SERIALIZE_IMPL(Module) diff --git a/src/core/hle/service/nfc/nfc.h b/src/core/hle/service/nfc/nfc.h index 2d6b26d832..51fe20b76a 100644 --- a/src/core/hle/service/nfc/nfc.h +++ b/src/core/hle/service/nfc/nfc.h @@ -6,6 +6,7 @@ #include <atomic> #include <memory> +#include <boost/serialization/binary_object.hpp> #include "common/common_types.h" #include "core/hle/service/service.h" @@ -35,6 +36,13 @@ struct AmiiboData { u16_be model_number; u8 series; INSERT_PADDING_BYTES(0x1C1); + +private: + template <class Archive> + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::make_binary_object(this, sizeof(AmiiboData)); + } + friend class boost::serialization::access; }; static_assert(sizeof(AmiiboData) == 0x21C, "AmiiboData is an invalid size"); diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index b2793285f2..1a95d2295b 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -1175,7 +1175,7 @@ void NWM_UDS::GetChannel(Kernel::HLERequestContext& ctx) { class NWM_UDS::ThreadCallback : public Kernel::HLERequestContext::WakeupCallback { public: - ThreadCallback(u16 command_id_) : command_id(command_id_) {} + explicit ThreadCallback(u16 command_id_) : command_id(command_id_) {} void WakeUp(std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, Kernel::ThreadWakeupReason reason) { diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 0261d061ff..83b0a5fb1e 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -10,7 +10,6 @@ #include <memory> #include <string> #include <boost/container/flat_map.hpp> -#include <boost/serialization/assume_abstract.hpp> #include <boost/serialization/base_object.hpp> #include <boost/serialization/shared_ptr.hpp> #include "common/common_types.h" diff --git a/src/core/hle/service/sm/srv.cpp b/src/core/hle/service/sm/srv.cpp index f9c62e9ad1..da6d57df7f 100644 --- a/src/core/hle/service/sm/srv.cpp +++ b/src/core/hle/service/sm/srv.cpp @@ -88,7 +88,8 @@ void SRV::EnableNotification(Kernel::HLERequestContext& ctx) { class SRV::ThreadCallback : public Kernel::HLERequestContext::WakeupCallback { public: - ThreadCallback(Core::System& system_, std::string name_) : system(system_), name(name_) {} + explicit ThreadCallback(Core::System& system_, std::string name_) + : system(system_), name(name_) {} void WakeUp(std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, Kernel::ThreadWakeupReason reason) { diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 382a69e2f7..1e0eb4bc9b 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -13,4 +13,4 @@ add_library(network STATIC create_target_directory_groups(network) -target_link_libraries(network PRIVATE common enet Boost::boost) +target_link_libraries(network PRIVATE common enet Boost::serialization) diff --git a/src/network/room_member.h b/src/network/room_member.h index d582a8552f..ee1c921d46 100644 --- a/src/network/room_member.h +++ b/src/network/room_member.h @@ -8,7 +8,7 @@ #include <memory> #include <string> #include <vector> -#include <boost/serialization/access.hpp> +#include <boost/serialization/vector.hpp> #include "common/common_types.h" #include "network/room.h" From 9bd189a1550a94b30faa72416a8e1a72edfdeae2 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sun, 29 Mar 2020 19:07:56 +0100 Subject: [PATCH 100/129] More cleaning up --- src/core/hle/kernel/process.h | 3 ++- src/core/hle/service/am/am.h | 1 - src/core/hle/service/cam/cam.cpp | 2 ++ src/core/hle/service/cam/cam.h | 7 +------ src/tests/core/hle/kernel/hle_ipc.cpp | 8 ++++---- 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index d9af80cd00..4eca568d90 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -11,9 +11,10 @@ #include <string> #include <vector> #include <boost/container/static_vector.hpp> +#include <boost/serialization/array.hpp> #include <boost/serialization/base_object.hpp> -#include <boost/serialization/vector.hpp> #include <boost/serialization/string.hpp> +#include <boost/serialization/vector.hpp> #include "common/bit_field.h" #include "common/common_types.h" #include "core/hle/kernel/handle_table.h" diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index deff326b70..25bd582650 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -155,7 +155,6 @@ std::string GetMediaTitlePath(Service::FS::MediaType media_type); class Module final { public: explicit Module(Core::System& system); - Module() = default; ~Module(); class Interface : public ServiceFramework<Interface> { diff --git a/src/core/hle/service/cam/cam.cpp b/src/core/hle/service/cam/cam.cpp index bf4bdd9c5c..e247d998fd 100644 --- a/src/core/hle/service/cam/cam.cpp +++ b/src/core/hle/service/cam/cam.cpp @@ -21,6 +21,8 @@ #include "core/memory.h" #include "core/settings.h" +SERVICE_CONSTRUCT_IMPL(Service::CAM::Module) + namespace Service::CAM { template <class Archive> diff --git a/src/core/hle/service/cam/cam.h b/src/core/hle/service/cam/cam.h index 375df2b20a..04dc0e2ea5 100644 --- a/src/core/hle/service/cam/cam.h +++ b/src/core/hle/service/cam/cam.h @@ -882,9 +882,4 @@ void InstallInterfaces(Core::System& system); } // namespace Service::CAM -namespace boost::serialization { -template <class Archive> -void load_construct_data(Archive& ar, Service::CAM::Module* t, const unsigned int) { - ::new (t) Service::CAM::Module(Core::Global<Core::System>()); -} -} // namespace boost::serialization +SERVICE_CONSTRUCT(Service::CAM::Module) diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index 6c2a493bbe..890343cd85 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -15,8 +15,6 @@ #include "core/hle/kernel/process.h" #include "core/hle/kernel/server_session.h" -SERIALIZE_EXPORT_IMPL(Kernel::SessionRequestHandler::SessionDataBase) - namespace Kernel { static std::shared_ptr<Object> MakeObject(Kernel::KernelSystem& kernel) { @@ -26,7 +24,8 @@ static std::shared_ptr<Object> MakeObject(Kernel::KernelSystem& kernel) { TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") { Core::Timing timing(1, 100); Memory::MemorySystem memory; - Kernel::KernelSystem kernel(memory, timing, [] {}, 0, 1, 0); + Kernel::KernelSystem kernel( + memory, timing, [] {}, 0, 1, 0); auto [server, client] = kernel.CreateSessionPair(); HLERequestContext context(kernel, std::move(server), nullptr); @@ -241,7 +240,8 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { Core::Timing timing(1, 100); Memory::MemorySystem memory; - Kernel::KernelSystem kernel(memory, timing, [] {}, 0, 1, 0); + Kernel::KernelSystem kernel( + memory, timing, [] {}, 0, 1, 0); auto [server, client] = kernel.CreateSessionPair(); HLERequestContext context(kernel, std::move(server), nullptr); From 92640fc29c6fee66b6c110ce7631f8e5b3e74e72 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Tue, 31 Mar 2020 17:54:28 +0100 Subject: [PATCH 101/129] Code review actions (plus hopefully fix the linux CI) --- src/CMakeLists.txt | 17 +++++------- src/audio_core/hle/hle.cpp | 1 + src/common/archives.h | 4 +-- src/common/memory_ref.h | 6 ++++- src/common/serialization/atomic.h | 4 +++ .../serialization/boost_discrete_interval.hpp | 22 ++++++++------- src/common/serialization/boost_flat_set.h | 4 +++ .../serialization/boost_interval_set.hpp | 20 ++++++++++++++ src/common/thread_queue_list.h | 4 +-- src/core/arm/arm_interface.h | 27 +++++++++---------- src/core/arm/dynarmic/arm_dynarmic.h | 4 ++- src/core/arm/dyncom/arm_dyncom.h | 4 ++- src/core/core.cpp | 19 +++++-------- src/core/core.h | 1 - src/core/core_timing.cpp | 5 ++-- src/core/hle/kernel/address_arbiter.h | 1 + src/core/hle/kernel/client_port.h | 2 ++ src/core/hle/kernel/client_session.h | 1 + src/core/hle/kernel/event.h | 2 ++ src/core/hle/kernel/kernel.cpp | 3 +++ src/core/hle/kernel/kernel.h | 3 --- src/core/hle/kernel/memory.h | 6 ++--- src/core/hle/kernel/mutex.h | 3 +++ src/core/hle/kernel/object.h | 2 +- src/core/hle/kernel/resource_limit.h | 2 ++ src/core/hle/kernel/semaphore.h | 2 ++ src/core/hle/kernel/server_port.cpp | 4 +++ src/core/hle/kernel/server_port.h | 3 --- src/core/hle/kernel/server_session.cpp | 16 ++++++++++- src/core/hle/kernel/server_session.h | 12 +-------- src/core/hle/kernel/session.cpp | 1 - src/core/hle/kernel/shared_memory.cpp | 1 - src/core/hle/kernel/shared_memory.h | 4 ++- src/core/hle/kernel/shared_page.h | 1 + src/core/hle/kernel/thread.cpp | 2 +- src/core/hle/kernel/timer.cpp | 1 - src/core/hle/kernel/timer.h | 1 + src/core/hle/kernel/vm_manager.h | 1 + src/core/hle/kernel/wait_object.cpp | 10 +++++++ src/core/hle/kernel/wait_object.h | 7 +---- src/core/hle/service/hid/hid.cpp | 8 ------ src/core/hle/service/ir/extra_hid.h | 4 ++- src/core/memory.cpp | 4 +-- src/core/memory.h | 13 +++++---- src/video_core/geometry_pipeline.cpp | 1 - src/video_core/pica_state.h | 1 + 46 files changed, 155 insertions(+), 109 deletions(-) create mode 100644 src/common/serialization/boost_interval_set.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 96c7f35cdc..1ada1b3ebc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,8 +31,10 @@ if (MSVC) # /Zc:externConstexpr - Allow extern constexpr variables to have external linkage, like the standard mandates # /Zc:inline - Let codegen omit inline functions in object files # /Zc:throwingNew - Let codegen assume `operator new` (without std::nothrow) will never return null + # /external:* - Suppress warnings from external headers add_compile_options( /W3 + /MP /Zi /Zo /permissive- @@ -40,17 +42,12 @@ if (MSVC) /volatile:iso /Zc:externConstexpr /Zc:inline + /Zc:throwingNew + /experimental:external + /external:I "${CMAKE_SOURCE_DIR}/externals" + /external:anglebrackets + /external:W0 ) - if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") - add_compile_options( - /MP - /Zc:throwingNew - /experimental:external - /external:I "${CMAKE_SOURCE_DIR}/externals" - /external:anglebrackets - /external:W0 - ) - endif() # /GS- - No stack buffer overflow checks add_compile_options("$<$<CONFIG:Release>:/GS->") diff --git a/src/audio_core/hle/hle.cpp b/src/audio_core/hle/hle.cpp index f4e372f85d..3a761dcfaf 100644 --- a/src/audio_core/hle/hle.cpp +++ b/src/audio_core/hle/hle.cpp @@ -45,6 +45,7 @@ void DspHle::serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object<DspInterface>(*this); ar&* impl.get(); } +SERIALIZE_IMPL(DspHle) static constexpr u64 audio_frame_ticks = 1310252ull; ///< Units: ARM11 cycles diff --git a/src/common/archives.h b/src/common/archives.h index 4f8b735d39..b9f4330bde 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -5,8 +5,8 @@ #pragma once #include <boost/archive/binary_iarchive.hpp> -#include "boost/archive/binary_oarchive.hpp" -#include "boost/serialization/export.hpp" +#include <boost/archive/binary_oarchive.hpp> +#include <boost/serialization/export.hpp> using iarchive = boost::archive::binary_iarchive; using oarchive = boost::archive::binary_oarchive; diff --git a/src/common/memory_ref.h b/src/common/memory_ref.h index 30eabbaee9..0a50c7be9c 100644 --- a/src/common/memory_ref.h +++ b/src/common/memory_ref.h @@ -41,13 +41,17 @@ public: } std::size_t GetSize() const override { - return static_cast<u32>(data.size()); + return data.size(); } std::vector<u8>& Vector() { return data; } + const std::vector<u8>& Vector() const { + return data; + } + private: std::vector<u8> data; diff --git a/src/common/serialization/atomic.h b/src/common/serialization/atomic.h index dbc4c0dece..0cf0f20bc4 100644 --- a/src/common/serialization/atomic.h +++ b/src/common/serialization/atomic.h @@ -1,3 +1,7 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #pragma once #include <atomic> diff --git a/src/common/serialization/boost_discrete_interval.hpp b/src/common/serialization/boost_discrete_interval.hpp index dc920e439f..961a9a7ef7 100644 --- a/src/common/serialization/boost_discrete_interval.hpp +++ b/src/common/serialization/boost_discrete_interval.hpp @@ -1,33 +1,37 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #pragma once -#include "common/common_types.h" #include <boost/icl/discrete_interval.hpp> +#include "common/common_types.h" namespace boost::serialization { template <class Archive, class DomainT, ICL_COMPARE Compare> -void save(Archive& ar, const boost::icl::discrete_interval<DomainT, Compare>& obj, const unsigned int file_version) -{ +void save(Archive& ar, const boost::icl::discrete_interval<DomainT, Compare>& obj, + const unsigned int file_version) { ar << obj.lower(); ar << obj.upper(); ar << obj.bounds()._bits; } template <class Archive, class DomainT, ICL_COMPARE Compare> -void load(Archive& ar, boost::icl::discrete_interval<DomainT, Compare>& obj, const unsigned int file_version) -{ +void load(Archive& ar, boost::icl::discrete_interval<DomainT, Compare>& obj, + const unsigned int file_version) { DomainT upper, lower; boost::icl::bound_type bounds; - ar >> upper; ar >> lower; + ar >> upper; ar >> bounds; obj = boost::icl::discrete_interval(upper, lower, boost::icl::interval_bounds(bounds)); } template <class Archive, class DomainT, ICL_COMPARE Compare> -void serialize(Archive& ar, boost::icl::discrete_interval<DomainT, Compare>& obj, const unsigned int file_version) -{ +void serialize(Archive& ar, boost::icl::discrete_interval<DomainT, Compare>& obj, + const unsigned int file_version) { boost::serialization::split_free(ar, obj, file_version); } -} +} // namespace boost::serialization diff --git a/src/common/serialization/boost_flat_set.h b/src/common/serialization/boost_flat_set.h index c47e8c1a7c..703bd28b3d 100644 --- a/src/common/serialization/boost_flat_set.h +++ b/src/common/serialization/boost_flat_set.h @@ -1,3 +1,7 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #pragma once #include <boost/container/flat_set.hpp> diff --git a/src/common/serialization/boost_interval_set.hpp b/src/common/serialization/boost_interval_set.hpp new file mode 100644 index 0000000000..08e6a14f18 --- /dev/null +++ b/src/common/serialization/boost_interval_set.hpp @@ -0,0 +1,20 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <boost/icl/interval_set.hpp> +#include "common/serialization/boost_discrete_interval.hpp" + +namespace boost::serialization { + +template <class Archive, class T> +void serialize(Archive& ar, boost::icl::interval_set<T>& obj, const unsigned int file_version) { + using IntervalSet = boost::icl::interval_set<T>; + // This works because interval_set has exactly one member of type ImplSetT + static_assert(std::is_standard_layout_v<IntervalSet>); + ar&*(reinterpret_cast<typename IntervalSet::ImplSetT*>(&obj)); +} + +} // namespace boost::serialization diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h index 1ba68e1e4e..af40bf09be 100644 --- a/src/common/thread_queue_list.h +++ b/src/common/thread_queue_list.h @@ -186,7 +186,7 @@ private: void save(Archive& ar, const unsigned int file_version) const { const s64 idx = ToIndex(first); ar << idx; - for (size_t i = 0; i < NUM_QUEUES; i++) { + for (std::size_t i = 0; i < NUM_QUEUES; i++) { const s64 idx1 = ToIndex(queues[i].next_nonempty); ar << idx1; ar << queues[i].data; @@ -198,7 +198,7 @@ private: s64 idx; ar >> idx; first = ToPointer(idx); - for (auto i = 0; i < NUM_QUEUES; i++) { + for (std::size_t i = 0; i < NUM_QUEUES; i++) { ar >> idx; queues[i].next_nonempty = ToPointer(idx); ar >> queues[i].data; diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index fca4885869..a6b8a279a5 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -6,15 +6,13 @@ #include <cstddef> #include <memory> +#include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/split_member.hpp> #include "common/common_types.h" #include "core/arm/skyeye_common/arm_regformat.h" #include "core/arm/skyeye_common/vfp/asm_vfp.h" #include "core/core_timing.h" - -namespace Memory { -struct PageTable; -} +#include "core/memory.h" /// Generic ARM11 CPU interface class ARM_Interface : NonCopyable { @@ -28,11 +26,11 @@ public: template <class Archive> void save(Archive& ar, const unsigned int file_version) const { - for (size_t i = 0; i < 16; i++) { + for (std::size_t i = 0; i < 16; i++) { const auto r = GetCpuRegister(i); ar << r; } - for (size_t i = 0; i < 16; i++) { + for (std::size_t i = 0; i < 16; i++) { const auto r = GetFpuRegister(i); ar << r; } @@ -47,11 +45,11 @@ public: template <class Archive> void load(Archive& ar, const unsigned int file_version) { u32 r; - for (size_t i = 0; i < 16; i++) { + for (std::size_t i = 0; i < 16; i++) { ar >> r; SetCpuRegister(i, r); } - for (size_t i = 0; i < 16; i++) { + for (std::size_t i = 0; i < 16; i++) { ar >> r; SetFpuRegister(i, r); } @@ -120,8 +118,6 @@ public: /// Notify CPU emulation that page tables have changed virtual void SetPageTable(const std::shared_ptr<Memory::PageTable>& page_table) = 0; - virtual std::shared_ptr<Memory::PageTable> GetPageTable() const = 0; - /** * Set the Program Counter to an address * @param addr Address to set PC to @@ -234,6 +230,9 @@ public: } protected: + // This us used for serialization. Returning nullptr is valid if page tables are not used. + virtual std::shared_ptr<Memory::PageTable> GetPageTable() const = 0; + std::shared_ptr<Core::Timing::Timer> timer; private: @@ -259,11 +258,11 @@ private: const auto r = GetVFPReg(i); ar << r; } - for (size_t i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { + for (std::size_t i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { const auto r = GetVFPSystemReg(static_cast<VFPSystemRegister>(i)); ar << r; } - for (size_t i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { + for (std::size_t i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { const auto r = GetCP15Register(static_cast<CP15Register>(i)); ar << r; } @@ -290,11 +289,11 @@ private: ar >> r; SetVFPReg(i, r); } - for (size_t i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { + for (std::size_t i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { ar >> r; SetVFPSystemReg(static_cast<VFPSystemRegister>(i), r); } - for (size_t i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { + for (std::size_t i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { ar >> r; SetCP15Register(static_cast<CP15Register>(i), r); } diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index a8f224083e..a5b4893a6b 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -53,9 +53,11 @@ public: void ClearInstructionCache() override; void InvalidateCacheRange(u32 start_address, std::size_t length) override; void SetPageTable(const std::shared_ptr<Memory::PageTable>& page_table) override; - std::shared_ptr<Memory::PageTable> GetPageTable() const override; void PurgeState() override; +protected: + std::shared_ptr<Memory::PageTable> GetPageTable() const override; + private: friend class DynarmicUserCallbacks; Core::System& system; diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h index 91cbcded0e..1452216c2c 100644 --- a/src/core/arm/dyncom/arm_dyncom.h +++ b/src/core/arm/dyncom/arm_dyncom.h @@ -49,10 +49,12 @@ public: void LoadContext(const std::unique_ptr<ThreadContext>& arg) override; void SetPageTable(const std::shared_ptr<Memory::PageTable>& page_table) override; - std::shared_ptr<Memory::PageTable> GetPageTable() const override; void PrepareReschedule() override; void PurgeState() override; +protected: + std::shared_ptr<Memory::PageTable> GetPageTable() const override; + private: void ExecuteInstructions(u64 num_instructions); diff --git a/src/core/core.cpp b/src/core/core.cpp index 2928d50e7f..69223a05e3 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -1,4 +1,3 @@ -#pragma optimize("", off) // Copyright 2014 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -184,12 +183,14 @@ System::ResultStatus System::RunLoop(bool tight_loop) { LOG_INFO(Core, "Begin load"); System::LoadState(param); LOG_INFO(Core, "Load completed"); - } break; + break; + } case Signal::Save: { LOG_INFO(Core, "Begin save"); System::SaveState(param); LOG_INFO(Core, "Save completed"); - } break; + break; + } default: break; } @@ -551,19 +552,11 @@ void System::serialize(Archive& ar, const unsigned int file_version) { // NOTE: DSP doesn't like being destroyed and recreated. So instead we do an inline // serialization; this means that the DSP Settings need to match for loading to work. - bool dsp_type = Settings::values.enable_dsp_lle; - ar& dsp_type; - if (dsp_type != Settings::values.enable_dsp_lle) { - throw std::runtime_error( - "Incorrect DSP type - please change this in Settings before loading"); - } auto dsp_hle = dynamic_cast<AudioCore::DspHle*>(dsp_core.get()); if (dsp_hle) { ar&* dsp_hle; - } - auto dsp_lle = dynamic_cast<AudioCore::DspLle*>(dsp_core.get()); - if (dsp_lle) { - ar&* dsp_lle; + } else { + throw std::runtime_error("LLE audio not supported for save states"); } ar&* memory.get(); diff --git a/src/core/core.h b/src/core/core.h index 66e880fd19..dfb6aee3e6 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -7,7 +7,6 @@ #include <memory> #include <mutex> #include <string> -#include "boost/serialization/access.hpp" #include "common/common_types.h" #include "core/custom_tex_cache.h" #include "core/frontend/applets/mii_selector.h" diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 493bb63448..9639265965 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -183,11 +183,10 @@ void Timing::Timer::Advance(s64 max_slice_length) { Event evt = std::move(event_queue.front()); std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>()); event_queue.pop_back(); - if (evt.type->callback == nullptr) { - LOG_ERROR(Core, "Event '{}' has no callback", *evt.type->name); - } if (evt.type->callback != nullptr) { evt.type->callback(evt.userdata, executed_ticks - evt.time); + } else { + LOG_ERROR(Core, "Event '{}' has no callback", *evt.type->name); } } diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index 85a2a065a5..059ff14003 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -9,6 +9,7 @@ #include <boost/serialization/base_object.hpp> #include <boost/serialization/export.hpp> #include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/string.hpp> #include <boost/serialization/vector.hpp> #include "common/common_types.h" #include "core/hle/kernel/object.h" diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h index 1d0f5c0249..8d0f505201 100644 --- a/src/core/hle/kernel/client_port.h +++ b/src/core/hle/kernel/client_port.h @@ -7,6 +7,8 @@ #include <memory> #include <string> #include <boost/serialization/export.hpp> +#include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/string.hpp> #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_port.h" diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h index 38f39c2991..1943db8e64 100644 --- a/src/core/hle/kernel/client_session.h +++ b/src/core/hle/kernel/client_session.h @@ -9,6 +9,7 @@ #include <boost/serialization/base_object.hpp> #include <boost/serialization/export.hpp> #include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/string.hpp> #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/result.h" diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index 892718533b..02eabd750b 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h @@ -4,7 +4,9 @@ #pragma once +#include <boost/serialization/base_object.hpp> #include <boost/serialization/export.hpp> +#include <boost/serialization/string.hpp> #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/wait_object.h" diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index f0974f88ac..ef9856363c 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -2,6 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/unordered_map.hpp> +#include <boost/serialization/vector.hpp> #include "common/archives.h" #include "common/serialization/atomic.h" #include "core/hle/kernel/client_port.h" diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 828843afcd..f0a8368d91 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -11,9 +11,6 @@ #include <string> #include <unordered_map> #include <vector> -#include <boost/serialization/shared_ptr.hpp> -#include <boost/serialization/unordered_map.hpp> -#include <boost/serialization/vector.hpp> #include "common/common_types.h" #include "core/hle/kernel/memory.h" #include "core/hle/result.h" diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h index f4b0a6d98e..0560b0bec2 100644 --- a/src/core/hle/kernel/memory.h +++ b/src/core/hle/kernel/memory.h @@ -5,10 +5,11 @@ #pragma once #include <optional> +#include <type_traits> #include <boost/icl/interval_set.hpp> #include <boost/serialization/set.hpp> #include "common/common_types.h" -#include "common/serialization/boost_discrete_interval.hpp" +#include "common/serialization/boost_interval_set.hpp" namespace Kernel { @@ -70,8 +71,7 @@ private: ar& base; ar& size; ar& used; - // This works because interval_set has exactly one member of type ImplSetT - ar&*(reinterpret_cast<IntervalSet::ImplSetT*>(&free_blocks)); + ar& free_blocks; } }; diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 4adf674c33..73ee2a0e6b 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -7,6 +7,9 @@ #include <memory> #include <string> #include <boost/serialization/export.hpp> +#include <boost/serialization/base_object.hpp> +#include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/string.hpp> #include "common/common_types.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/wait_object.h" diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index 57b208dc14..b272366d74 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h @@ -104,7 +104,7 @@ BOOST_SERIALIZATION_ASSUME_ABSTRACT(Kernel::Object) #define CONSTRUCT_KERNEL_OBJECT(T) \ namespace boost::serialization { \ template <class Archive> \ - inline void load_construct_data(Archive& ar, T* t, const unsigned int file_version) { \ + void load_construct_data(Archive& ar, T* t, const unsigned int file_version) { \ ::new (t) T(Core::Global<Kernel::KernelSystem>()); \ } \ } diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h index 8593a03a34..cb1c8c78e4 100644 --- a/src/core/hle/kernel/resource_limit.h +++ b/src/core/hle/kernel/resource_limit.h @@ -7,7 +7,9 @@ #include <array> #include <memory> #include <boost/serialization/array.hpp> +#include <boost/serialization/base_object.hpp> #include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/string.hpp> #include "common/common_types.h" #include "core/hle/kernel/object.h" diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h index a7ab192a6c..b9863a838a 100644 --- a/src/core/hle/kernel/semaphore.h +++ b/src/core/hle/kernel/semaphore.h @@ -5,7 +5,9 @@ #pragma once #include <string> +#include <boost/serialization/base_object.hpp> #include <boost/serialization/export.hpp> +#include <boost/serialization/string.hpp> #include <queue> #include "common/common_types.h" #include "core/hle/kernel/object.h" diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index 0771502225..4d293be340 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -3,6 +3,10 @@ // Refer to the license.txt file included. #include <tuple> +#include <boost/serialization/base_object.hpp> +#include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/vector.hpp> +#include <boost/serialization/string.hpp> #include "common/archives.h" #include "common/assert.h" #include "core/hle/kernel/client_port.h" diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h index 2f00e586ea..00eb101005 100644 --- a/src/core/hle/kernel/server_port.h +++ b/src/core/hle/kernel/server_port.h @@ -7,10 +7,7 @@ #include <memory> #include <string> #include <tuple> -#include <boost/serialization/base_object.hpp> #include <boost/serialization/export.hpp> -#include <boost/serialization/shared_ptr.hpp> -#include <boost/serialization/vector.hpp> #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_session.h" diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 3dc20e9a73..61ade5b70a 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -3,8 +3,10 @@ // Refer to the license.txt file included. #include <tuple> +#include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/string.hpp> +#include <boost/serialization/vector.hpp> #include "common/archives.h" -#include "core/global.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/hle_ipc.h" @@ -16,6 +18,18 @@ SERIALIZE_EXPORT_IMPL(Kernel::ServerSession) namespace Kernel { +template <class Archive> +void ServerSession::serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object<WaitObject>(*this); + ar& name; + ar& parent; + ar& hle_handler; + ar& pending_requesting_threads; + ar& currently_handling; + ar& mapped_buffer_context; +} +SERIALIZE_IMPL(ServerSession) + ServerSession::ServerSession(KernelSystem& kernel) : WaitObject(kernel), kernel(kernel) {} ServerSession::~ServerSession() { // This destructor will be called automatically when the last ServerSession handle is closed by diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 74dbef624b..b91accce5b 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -7,8 +7,6 @@ #include <memory> #include <string> #include <boost/serialization/export.hpp> -#include <boost/serialization/shared_ptr.hpp> -#include <boost/serialization/vector.hpp> #include "common/assert.h" #include "common/common_types.h" #include "core/hle/kernel/ipc.h" @@ -110,15 +108,7 @@ private: friend class boost::serialization::access; template <class Archive> - void serialize(Archive& ar, const unsigned int file_version) { - ar& boost::serialization::base_object<WaitObject>(*this); - ar& name; - ar& parent; - ar& hle_handler; - ar& pending_requesting_threads; - ar& currently_handling; - ar& mapped_buffer_context; - } + void serialize(Archive& ar, const unsigned int file_version); }; } // namespace Kernel diff --git a/src/core/hle/kernel/session.cpp b/src/core/hle/kernel/session.cpp index 1ec1039dcc..8bb846c525 100644 --- a/src/core/hle/kernel/session.cpp +++ b/src/core/hle/kernel/session.cpp @@ -6,7 +6,6 @@ #include "common/archives.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" -#include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/server_session.h" #include "core/hle/kernel/session.h" diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 47c966fec9..e8f792ee8c 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -5,7 +5,6 @@ #include <cstring> #include "common/archives.h" #include "common/logging/log.h" -#include "core/global.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/memory.h" #include "core/hle/kernel/shared_memory.h" diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index cb2dee685f..0e500a1ddf 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -6,7 +6,9 @@ #include <string> #include <utility> +#include <boost/serialization/base_object.hpp> #include <boost/serialization/export.hpp> +#include <boost/serialization/string.hpp> #include "common/common_types.h" #include "common/memory_ref.h" #include "core/hle/kernel/object.h" @@ -118,7 +120,7 @@ private: ar& owner_process; ar& base_address; ar& name; - ar&*(reinterpret_cast<MemoryRegionInfo::IntervalSet::ImplSetT*>(&holding_memory)); + ar& holding_memory; } friend class boost::serialization::access; }; diff --git a/src/core/hle/kernel/shared_page.h b/src/core/hle/kernel/shared_page.h index c4b174db4b..9cd579d523 100644 --- a/src/core/hle/kernel/shared_page.h +++ b/src/core/hle/kernel/shared_page.h @@ -13,6 +13,7 @@ #include <chrono> #include <ctime> #include <memory> +#include <boost/serialization/base_object.hpp> #include <boost/serialization/binary_object.hpp> #include <boost/serialization/export.hpp> #include "common/bit_field.h" diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 0567ef325b..cdd908b4e4 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -6,6 +6,7 @@ #include <list> #include <unordered_map> #include <vector> +#include <boost/serialization/string.hpp> #include "common/archives.h" #include "common/assert.h" #include "common/common_types.h" @@ -15,7 +16,6 @@ #include "core/arm/arm_interface.h" #include "core/arm/skyeye_common/armstate.h" #include "core/core.h" -#include "core/global.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/kernel.h" diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index d29b259861..d2a12ade1d 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -8,7 +8,6 @@ #include "common/assert.h" #include "common/logging/log.h" #include "core/core.h" -#include "core/global.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/thread.h" diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index b591c1b03f..d5af5e654d 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h @@ -4,6 +4,7 @@ #pragma once +#include <boost/serialization/string.hpp> #include <boost/serialization/unordered_map.hpp> #include "common/common_types.h" #include "core/core_timing.h" diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 3ca46d0691..06fbb8672b 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -9,6 +9,7 @@ #include <utility> #include <vector> #include <boost/serialization/map.hpp> +#include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/split_member.hpp> #include "common/common_types.h" #include "common/memory_ref.h" diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp index 6fe75b6d82..2cd4331c5d 100644 --- a/src/core/hle/kernel/wait_object.cpp +++ b/src/core/hle/kernel/wait_object.cpp @@ -4,6 +4,7 @@ #include <algorithm> #include <utility> +#include "common/archives.h" #include "common/assert.h" #include "common/logging/log.h" #include "core/hle/kernel/errors.h" @@ -16,6 +17,15 @@ namespace Kernel { +template <class Archive> +void WaitObject::serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object<Object>(*this); + ar& waiting_threads; + // NB: hle_notifier *not* serialized since it's a callback! + // Fortunately it's only used in one place (DSP) so we can reconstruct it there +} +SERIALIZE_IMPL(WaitObject) + void WaitObject::AddWaitingThread(std::shared_ptr<Thread> thread) { auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread); if (itr == waiting_threads.end()) diff --git a/src/core/hle/kernel/wait_object.h b/src/core/hle/kernel/wait_object.h index c07290e8ad..7f73eab9f5 100644 --- a/src/core/hle/kernel/wait_object.h +++ b/src/core/hle/kernel/wait_object.h @@ -69,12 +69,7 @@ private: private: friend class boost::serialization::access; template <class Archive> - void serialize(Archive& ar, const unsigned int file_version) { - ar& boost::serialization::base_object<Object>(*this); - ar& waiting_threads; - // NB: hle_notifier *not* serialized since it's a callback! - // Fortunately it's only used in one place (DSP) so we can reconstruct it there - } + void serialize(Archive& ar, const unsigned int file_version); }; // Specialization of DynamicObjectCast for WaitObjects diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 845319f628..981a4aa63b 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -210,10 +210,6 @@ void Module::UpdateAccelerometerCallback(u64 userdata, s64 cycles_late) { next_accelerometer_index = (next_accelerometer_index + 1) % mem->accelerometer.entries.size(); Common::Vec3<float> accel; - if (!motion_device) { - is_device_reload_pending.store(true); - return; - } std::tie(accel, std::ignore) = motion_device->GetStatus(); accel *= accelerometer_coef; // TODO(wwylele): do a time stretch like the one in UpdateGyroscopeCallback @@ -261,10 +257,6 @@ void Module::UpdateGyroscopeCallback(u64 userdata, s64 cycles_late) { GyroscopeDataEntry& gyroscope_entry = mem->gyroscope.entries[mem->gyroscope.index]; Common::Vec3<float> gyro; - if (!motion_device) { - is_device_reload_pending.store(true); - return; - } std::tie(std::ignore, gyro) = motion_device->GetStatus(); double stretch = system.perf_stats->GetLastFrameTimeScale(); gyro *= gyroscope_coef * static_cast<float>(stretch); diff --git a/src/core/hle/service/ir/extra_hid.h b/src/core/hle/service/ir/extra_hid.h index 46c0fdca4a..4b27fba9bf 100644 --- a/src/core/hle/service/ir/extra_hid.h +++ b/src/core/hle/service/ir/extra_hid.h @@ -71,7 +71,9 @@ private: void serialize(Archive& ar, const unsigned int) { ar& hid_period; ar& calibration_data; // This isn't writeable for now, but might be in future - RequestInputDevicesReload(); // zl, zr, c_stick are loaded here + if (Archive::is_loading::value) { + LoadInputDevices(); // zl, zr, c_stick are loaded here + } } friend class boost::serialization::access; }; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index c0c030de1a..184b7f9bd8 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -4,9 +4,9 @@ #include <array> #include <cstring> +#include <boost/serialization/array.hpp> +#include <boost/serialization/binary_object.hpp> #include "audio_core/dsp_interface.h" -#include "boost/serialization/array.hpp" -#include "boost/serialization/binary_object.hpp" #include "common/archives.h" #include "common/assert.h" #include "common/common_types.h" diff --git a/src/core/memory.h b/src/core/memory.h index eb5b6d69ce..66b28d87d7 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -9,7 +9,6 @@ #include <memory> #include <string> #include <vector> -#include <boost/serialization/access.hpp> #include <boost/serialization/array.hpp> #include <boost/serialization/vector.hpp> #include "common/common_types.h" @@ -86,12 +85,12 @@ struct PageTable { struct Entry { Entry(Pointers& pointers_, VAddr idx_) : pointers(pointers_), idx(idx_) {} - inline void operator=(MemoryRef value) { + void operator=(MemoryRef value) { pointers.refs[idx] = value; pointers.raw[idx] = value.GetPtr(); } - inline operator u8*() { + operator u8*() { return pointers.raw[idx]; } @@ -100,15 +99,15 @@ struct PageTable { VAddr idx; }; - inline Entry operator[](VAddr idx) { + Entry operator[](VAddr idx) { return Entry(*this, idx); } - inline u8* operator[](VAddr idx) const { + u8* operator[](VAddr idx) const { return raw[idx]; } - inline Entry operator[](std::size_t idx) { + Entry operator[](std::size_t idx) { return Entry(*this, static_cast<VAddr>(idx)); } @@ -133,7 +132,7 @@ struct PageTable { */ std::array<PageType, PAGE_TABLE_NUM_ENTRIES> attributes; - inline std::array<u8*, PAGE_TABLE_NUM_ENTRIES>& GetPointerArray() { + std::array<u8*, PAGE_TABLE_NUM_ENTRIES>& GetPointerArray() { return pointers.raw; } diff --git a/src/video_core/geometry_pipeline.cpp b/src/video_core/geometry_pipeline.cpp index 7e002d55d2..0ddbda9436 100644 --- a/src/video_core/geometry_pipeline.cpp +++ b/src/video_core/geometry_pipeline.cpp @@ -385,7 +385,6 @@ void GeometryPipeline::serialize(Archive& ar, const unsigned int version) { } // namespace Pica -BOOST_SERIALIZATION_ASSUME_ABSTRACT(Pica::GeometryPipelineBackend) SERIALIZE_EXPORT_IMPL(Pica::GeometryPipeline_Point) SERIALIZE_EXPORT_IMPL(Pica::GeometryPipeline_VariablePrimitive) SERIALIZE_EXPORT_IMPL(Pica::GeometryPipeline_FixedPrimitive) diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 3a9ec79c52..3c29ff84ea 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -5,6 +5,7 @@ #pragma once #include <array> +#include <boost/serialization/array.hpp> #include <boost/serialization/split_member.hpp> #include "common/bit_field.h" #include "common/common_types.h" From f156fdd332f7f1089ec827e5ed756ae6b6e5548a Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Tue, 31 Mar 2020 18:27:33 +0100 Subject: [PATCH 102/129] clang format fixes etc. --- .../serialization/boost_interval_set.hpp | 28 +++++++++++++++---- src/core/hle/kernel/memory.h | 1 - src/core/hle/kernel/mutex.h | 2 +- src/core/hle/kernel/server_port.cpp | 2 +- src/core/hle/service/cecd/cecd.cpp | 5 ++-- src/core/hle/service/ir/extra_hid.h | 2 +- src/tests/core/hle/kernel/hle_ipc.cpp | 6 ++-- 7 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/common/serialization/boost_interval_set.hpp b/src/common/serialization/boost_interval_set.hpp index 08e6a14f18..905e3f145d 100644 --- a/src/common/serialization/boost_interval_set.hpp +++ b/src/common/serialization/boost_interval_set.hpp @@ -5,16 +5,34 @@ #pragma once #include <boost/icl/interval_set.hpp> +#include <boost/serialization/split_free.hpp> #include "common/serialization/boost_discrete_interval.hpp" namespace boost::serialization { template <class Archive, class T> -void serialize(Archive& ar, boost::icl::interval_set<T>& obj, const unsigned int file_version) { - using IntervalSet = boost::icl::interval_set<T>; - // This works because interval_set has exactly one member of type ImplSetT - static_assert(std::is_standard_layout_v<IntervalSet>); - ar&*(reinterpret_cast<typename IntervalSet::ImplSetT*>(&obj)); +void save(Archive& ar, const boost::icl::interval_set<T>& set, const unsigned int file_version) { + ar << static_cast<u64>(set.size()); + for (auto& v : set) { + ar << v; + } +} + +template <class Archive, class T> +void load(Archive& ar, boost::icl::interval_set<T>& set, const unsigned int file_version) { + u64 count{}; + ar >> count; + set.clear(); + for (u64 i = 0; i < count; i++) { + T value{}; + ar >> value; + set.insert(value); + } +} + +template <class Archive, class T> +void serialize(Archive& ar, boost::icl::interval_set<T>& set, const unsigned int file_version) { + boost::serialization::split_free(ar, set, file_version); } } // namespace boost::serialization diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h index 0560b0bec2..739369a9c6 100644 --- a/src/core/hle/kernel/memory.h +++ b/src/core/hle/kernel/memory.h @@ -5,7 +5,6 @@ #pragma once #include <optional> -#include <type_traits> #include <boost/icl/interval_set.hpp> #include <boost/serialization/set.hpp> #include "common/common_types.h" diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 73ee2a0e6b..db98aa8c96 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -6,8 +6,8 @@ #include <memory> #include <string> -#include <boost/serialization/export.hpp> #include <boost/serialization/base_object.hpp> +#include <boost/serialization/export.hpp> #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/string.hpp> #include "common/common_types.h" diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index 4d293be340..006403925d 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -5,8 +5,8 @@ #include <tuple> #include <boost/serialization/base_object.hpp> #include <boost/serialization/shared_ptr.hpp> -#include <boost/serialization/vector.hpp> #include <boost/serialization/string.hpp> +#include <boost/serialization/vector.hpp> #include "common/archives.h" #include "common/assert.h" #include "core/hle/kernel/client_port.h" diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index 31ecd990b1..977a478421 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include <boost/serialization/unique_ptr.hpp> #include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/unique_ptr.hpp> #include <cryptopp/base64.h> #include <cryptopp/hmac.h> #include <cryptopp/sha.h> @@ -1361,8 +1361,7 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ case CecDataPathType::MboxData: case CecDataPathType::MboxIcon: case CecDataPathType::MboxTitle: - default: { - } + default: {} } } diff --git a/src/core/hle/service/ir/extra_hid.h b/src/core/hle/service/ir/extra_hid.h index 4b27fba9bf..d498c471f1 100644 --- a/src/core/hle/service/ir/extra_hid.h +++ b/src/core/hle/service/ir/extra_hid.h @@ -70,7 +70,7 @@ private: template <class Archive> void serialize(Archive& ar, const unsigned int) { ar& hid_period; - ar& calibration_data; // This isn't writeable for now, but might be in future + ar& calibration_data; // This isn't writeable for now, but might be in future if (Archive::is_loading::value) { LoadInputDevices(); // zl, zr, c_stick are loaded here } diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index 890343cd85..f5623c8c16 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -24,8 +24,7 @@ static std::shared_ptr<Object> MakeObject(Kernel::KernelSystem& kernel) { TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") { Core::Timing timing(1, 100); Memory::MemorySystem memory; - Kernel::KernelSystem kernel( - memory, timing, [] {}, 0, 1, 0); + Kernel::KernelSystem kernel(memory, timing, [] {}, 0, 1, 0); auto [server, client] = kernel.CreateSessionPair(); HLERequestContext context(kernel, std::move(server), nullptr); @@ -240,8 +239,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { Core::Timing timing(1, 100); Memory::MemorySystem memory; - Kernel::KernelSystem kernel( - memory, timing, [] {}, 0, 1, 0); + Kernel::KernelSystem kernel(memory, timing, [] {}, 0, 1, 0); auto [server, client] = kernel.CreateSessionPair(); HLERequestContext context(kernel, std::move(server), nullptr); From 5b6ee9a6abdf5546ad8d3a92101c8ee1059e5018 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Wed, 1 Apr 2020 22:06:22 +0100 Subject: [PATCH 103/129] Clear out state before deserialization - fixes many crashes. --- src/citra_qt/bootmanager.cpp | 4 +++- src/common/serialization/boost_interval_set.hpp | 6 +++--- src/core/core.cpp | 11 +++++++---- src/core/core.h | 2 +- src/core/savestate.cpp | 10 ++++++++++ 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 78541e880c..feab649064 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -132,7 +132,9 @@ void OpenGLWindow::Present() { return; context->makeCurrent(this); - VideoCore::g_renderer->TryPresent(100); + if (VideoCore::g_renderer) { + VideoCore::g_renderer->TryPresent(100); + } context->swapBuffers(this); auto f = context->versionFunctions<QOpenGLFunctions_3_3_Core>(); f->glFinish(); diff --git a/src/common/serialization/boost_interval_set.hpp b/src/common/serialization/boost_interval_set.hpp index 905e3f145d..d4e48e62a7 100644 --- a/src/common/serialization/boost_interval_set.hpp +++ b/src/common/serialization/boost_interval_set.hpp @@ -12,7 +12,7 @@ namespace boost::serialization { template <class Archive, class T> void save(Archive& ar, const boost::icl::interval_set<T>& set, const unsigned int file_version) { - ar << static_cast<u64>(set.size()); + ar << static_cast<u64>(set.iterative_size()); for (auto& v : set) { ar << v; } @@ -24,9 +24,9 @@ void load(Archive& ar, boost::icl::interval_set<T>& set, const unsigned int file ar >> count; set.clear(); for (u64 i = 0; i < count; i++) { - T value{}; + typename boost::icl::interval_set<T>::interval_type value{}; ar >> value; - set.insert(value); + set.add(value); } } diff --git a/src/core/core.cpp b/src/core/core.cpp index 69223a05e3..1e48c0c620 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -478,7 +478,7 @@ void System::RegisterImageInterface(std::shared_ptr<Frontend::ImageInterface> im registered_image_interface = std::move(image_interface); } -void System::Shutdown() { +void System::Shutdown(bool is_deserializing) { // Log last frame performance stats const auto perf_results = GetAndResetPerfStats(); telemetry_session->AddField(Telemetry::FieldType::Performance, "Shutdown_EmulationSpeed", @@ -494,17 +494,19 @@ void System::Shutdown() { GDBStub::Shutdown(); VideoCore::Shutdown(); HW::Shutdown(); + if (!is_deserializing) { + perf_stats.reset(); + cheat_engine.reset(); + app_loader.reset(); + } telemetry_session.reset(); - perf_stats.reset(); rpc_server.reset(); - cheat_engine.reset(); archive_manager.reset(); service_manager.reset(); dsp_core.reset(); cpu_cores.clear(); kernel.reset(); timing.reset(); - app_loader.reset(); if (video_dumper->IsDumping()) { video_dumper->StopDumping(); @@ -565,6 +567,7 @@ void System::serialize(Archive& ar, const unsigned int file_version) { // This needs to be set from somewhere - might as well be here! if (Archive::is_loading::value) { Service::GSP::SetGlobalModule(*this); + memory->SetDSP(*dsp_core); } } diff --git a/src/core/core.h b/src/core/core.h index dfb6aee3e6..9fe98f7232 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -113,7 +113,7 @@ public: ResultStatus SingleStep(); /// Shutdown the emulated system. - void Shutdown(); + void Shutdown(bool is_deserializing = false); /// Shutdown and then load again void Reset(); diff --git a/src/core/savestate.cpp b/src/core/savestate.cpp index d52789b2c2..ae5ba11a81 100644 --- a/src/core/savestate.cpp +++ b/src/core/savestate.cpp @@ -8,6 +8,7 @@ #include "common/logging/log.h" #include "common/scm_rev.h" #include "common/zstd_compression.h" +#include "core/cheats/cheats.h" #include "core/core.h" #include "core/savestate.h" #include "video_core/video_core.h" @@ -158,6 +159,15 @@ void System::LoadState(u32 slot) { std::ios_base::binary}; decompressed.clear(); + // When loading, we want to make sure any lingering state gets cleared out before we begin. + // Shutdown, but persist a few things between loads... + Shutdown(true); + + // Re-initialize everything like it was before + auto system_mode = this->app_loader->LoadKernelSystemMode(); + auto n3ds_mode = this->app_loader->LoadKernelN3dsMode(); + Init(*m_emu_window, *system_mode.first, *n3ds_mode.first); + try { { From 714a85119dbfb4858fd8138ca4b8506c5807fe1b Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Wed, 1 Apr 2020 22:50:19 +0100 Subject: [PATCH 104/129] Don't crash when getting perf stats --- src/core/core.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 1e48c0c620..2a99d3ccc2 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -296,7 +296,8 @@ void System::PrepareReschedule() { } PerfStats::Results System::GetAndResetPerfStats() { - return perf_stats->GetAndResetStats(timing->GetGlobalTimeUs()); + return (perf_stats && timing) ? perf_stats->GetAndResetStats(timing->GetGlobalTimeUs()) + : PerfStats::Results{}; } void System::Reschedule() { From d4ccce13657da93eee49cb125766f368f3e9e266 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Thu, 2 Apr 2020 00:14:00 +0100 Subject: [PATCH 105/129] Add some member initializers in thread --- src/core/hle/kernel/thread.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 09179c0e9b..233381f67f 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -303,25 +303,25 @@ public: VAddr tls_address; ///< Virtual address of the Thread Local Storage of the thread /// Mutexes currently held by this thread, which will be released when it exits. - boost::container::flat_set<std::shared_ptr<Mutex>> held_mutexes; + boost::container::flat_set<std::shared_ptr<Mutex>> held_mutexes{}; /// Mutexes that this thread is currently waiting for. - boost::container::flat_set<std::shared_ptr<Mutex>> pending_mutexes; + boost::container::flat_set<std::shared_ptr<Mutex>> pending_mutexes{}; - std::shared_ptr<Process> owner_process; ///< Process that owns this thread + std::shared_ptr<Process> owner_process{}; ///< Process that owns this thread /// Objects that the thread is waiting on, in the same order as they were // passed to WaitSynchronization1/N. - std::vector<std::shared_ptr<WaitObject>> wait_objects; + std::vector<std::shared_ptr<WaitObject>> wait_objects{}; VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address - std::string name; + std::string name{}; // Callback that will be invoked when the thread is resumed from a waiting state. If the thread // was waiting via WaitSynchronizationN then the object will be the last object that became // available. In case of a timeout, the object will be nullptr. - std::shared_ptr<WakeupCallback> wakeup_callback; + std::shared_ptr<WakeupCallback> wakeup_callback{}; const u32 core_id; From 74c06bd13e8e2bb11a26ec224b5fb5f3d1193b5c Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Thu, 2 Apr 2020 01:43:27 +0100 Subject: [PATCH 106/129] Attempt to fix crashes with LLE applets --- src/core/memory.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 184b7f9bd8..c6a213ff06 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -284,8 +284,10 @@ void MemorySystem::RegisterPageTable(std::shared_ptr<PageTable> page_table) { } void MemorySystem::UnregisterPageTable(std::shared_ptr<PageTable> page_table) { - impl->page_table_list.erase( - std::find(impl->page_table_list.begin(), impl->page_table_list.end(), page_table)); + auto it = std::find(impl->page_table_list.begin(), impl->page_table_list.end(), page_table); + if (it != impl->page_table_list.end()) { + impl->page_table_list.erase(it); + } } /** From b5f394dd129e67058c87d86bc7fb33fa63356a1b Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sun, 5 Apr 2020 00:20:59 +0100 Subject: [PATCH 107/129] Use placeholders for serialized paths --- src/common/file_util.cpp | 27 +++++++++++++++++++++++++++ src/common/file_util.h | 9 ++++++++- src/core/core.cpp | 1 + 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index af4d182883..fd1a3fd309 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -729,6 +729,33 @@ void SetUserPath(const std::string& path) { g_paths.emplace(UserPath::StatesDir, user_path + STATES_DIR DIR_SEP); } +std::string g_currentRomPath{}; + +void SetCurrentRomPath(const std::string& path) { + g_currentRomPath = path; +} + +bool StringReplace(std::string& haystack, const std::string& a, const std::string& b, bool swap) { + const auto& needle = swap ? b : a; + const auto& replacement = swap ? a : b; + if (needle.empty()) { + return false; + } + auto index = haystack.find(needle, 0); + if (index == std::string::npos) { + return false; + } + haystack.replace(index, needle.size(), replacement); + return true; +} + +std::string SerializePath(const std::string& input, bool is_saving) { + auto result = input; + StringReplace(result, "%CITRA_ROM_FILE%", g_currentRomPath, is_saving); + StringReplace(result, "%CITRA_USER_DIR%", GetUserPath(UserPath::UserDir), is_saving); + return result; +} + const std::string& GetUserPath(UserPath path) { // Set up all paths and files on the first run if (g_paths.empty()) diff --git a/src/common/file_util.h b/src/common/file_util.h index 1b1e656098..9eafa24164 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -140,10 +140,15 @@ bool SetCurrentDir(const std::string& directory); void SetUserPath(const std::string& path = ""); +void SetCurrentRomPath(const std::string& path); + // Returns a pointer to a string with a Citra data dir in the user's home // directory. To be used in "multi-user" mode (that is, installed). const std::string& GetUserPath(UserPath path); +// Replaces install-specific paths with standard placeholders, and back again +std::string SerializePath(const std::string& input, bool is_saving); + // Returns the path to where the sys file are std::string GetSysDirectory(); @@ -318,7 +323,8 @@ private: template <class Archive> void save(Archive& ar, const unsigned int) const { - ar << filename; + auto s_filename = SerializePath(filename, true); + ar << s_filename; ar << openmode; ar << flags; ar << Tell(); @@ -327,6 +333,7 @@ private: template <class Archive> void load(Archive& ar, const unsigned int) { ar >> filename; + filename = SerializePath(filename, false); ar >> openmode; ar >> flags; u64 pos; diff --git a/src/core/core.cpp b/src/core/core.cpp index 2a99d3ccc2..41fcb6855c 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -214,6 +214,7 @@ System::ResultStatus System::SingleStep() { } System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath) { + FileUtil::SetCurrentRomPath(filepath); app_loader = Loader::GetLoader(filepath); if (!app_loader) { LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); From ac37de10fc63a93838be270ec09e0e4c6df460ce Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Mon, 6 Apr 2020 20:26:41 +0100 Subject: [PATCH 108/129] Reconnect cheat_engine during load --- src/core/cheats/cheats.cpp | 4 ++++ src/core/cheats/cheats.h | 1 + src/core/savestate.cpp | 1 + 3 files changed, 6 insertions(+) diff --git a/src/core/cheats/cheats.cpp b/src/core/cheats/cheats.cpp index 8b4a30ca63..9053b5ca68 100644 --- a/src/core/cheats/cheats.cpp +++ b/src/core/cheats/cheats.cpp @@ -18,6 +18,10 @@ constexpr u64 run_interval_ticks = BASE_CLOCK_RATE_ARM11 / 60; CheatEngine::CheatEngine(Core::System& system_) : system(system_) { LoadCheatFile(); + Connect(); +} + +void CheatEngine::Connect() { event = system.CoreTiming().RegisterEvent( "CheatCore::run_event", [this](u64 thread_id, s64 cycle_late) { RunCallback(thread_id, cycle_late); }); diff --git a/src/core/cheats/cheats.h b/src/core/cheats/cheats.h index a8d3730383..1dfed7ab81 100644 --- a/src/core/cheats/cheats.h +++ b/src/core/cheats/cheats.h @@ -26,6 +26,7 @@ class CheatEngine { public: explicit CheatEngine(Core::System& system); ~CheatEngine(); + void Connect(); std::vector<std::shared_ptr<CheatBase>> GetCheats() const; void AddCheat(const std::shared_ptr<CheatBase>& cheat); void RemoveCheat(int index); diff --git a/src/core/savestate.cpp b/src/core/savestate.cpp index ae5ba11a81..6a87569c79 100644 --- a/src/core/savestate.cpp +++ b/src/core/savestate.cpp @@ -167,6 +167,7 @@ void System::LoadState(u32 slot) { auto system_mode = this->app_loader->LoadKernelSystemMode(); auto n3ds_mode = this->app_loader->LoadKernelN3dsMode(); Init(*m_emu_window, *system_mode.first, *n3ds_mode.first); + cheat_engine->Connect(); try { From 7ff985cef9602f85af170095d9ce69b662dd71a7 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Mon, 6 Apr 2020 21:23:39 +0100 Subject: [PATCH 109/129] Fixed TAS movie serialization --- src/core/core.cpp | 14 ++++++++++++++ src/core/movie.h | 16 ++++++++++++++-- src/core/savestate.cpp | 28 ++++------------------------ src/video_core/video_core.cpp | 14 +++++--------- src/video_core/video_core.h | 4 ++-- 5 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 41fcb6855c..fa6d0c30d7 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -534,6 +534,17 @@ void System::Reset() { template <class Archive> void System::serialize(Archive& ar, const unsigned int file_version) { + if (Archive::is_loading::value) { + // When loading, we want to make sure any lingering state gets cleared out before we begin. + // Shutdown, but persist a few things between loads... + Shutdown(true); + + // Re-initialize everything like it was before + auto system_mode = this->app_loader->LoadKernelSystemMode(); + auto n3ds_mode = this->app_loader->LoadKernelN3dsMode(); + Init(*m_emu_window, *system_mode.first, *n3ds_mode.first); + } + u32 num_cores; if (Archive::is_saving::value) { num_cores = this->GetNumCores(); @@ -565,11 +576,14 @@ void System::serialize(Archive& ar, const unsigned int file_version) { ar&* memory.get(); ar&* kernel.get(); + VideoCore::serialize(ar, file_version); + ar& Movie::GetInstance(); // This needs to be set from somewhere - might as well be here! if (Archive::is_loading::value) { Service::GSP::SetGlobalModule(*this); memory->SetDSP(*dsp_core); + cheat_engine->Connect(); } } diff --git a/src/core/movie.h b/src/core/movie.h index f1be869462..e578b909cd 100644 --- a/src/core/movie.h +++ b/src/core/movie.h @@ -5,6 +5,7 @@ #pragma once #include <functional> +#include <boost/serialization/vector.hpp> #include "common/common_types.h" namespace Service { @@ -41,8 +42,8 @@ public: return s_instance; } - void StartPlayback(const std::string& movie_file, - std::function<void()> completion_callback = [] {}); + void StartPlayback( + const std::string& movie_file, std::function<void()> completion_callback = [] {}); void StartRecording(const std::string& movie_file); /// Prepare to override the clock before playing back movies @@ -132,5 +133,16 @@ private: u64 init_time; std::function<void()> playback_completion_callback; std::size_t current_byte = 0; + + template <class Archive> + void serialize(Archive& ar, const unsigned int) { + // Only serialize what's needed to make savestates useful for TAS: + u64 _current_byte = static_cast<u64>(current_byte); + ar& _current_byte; + current_byte = static_cast<std::size_t>(_current_byte); + ar& recorded_input; + ar& init_time; + } + friend class boost::serialization::access; }; } // namespace Core \ No newline at end of file diff --git a/src/core/savestate.cpp b/src/core/savestate.cpp index 6a87569c79..ece6406a14 100644 --- a/src/core/savestate.cpp +++ b/src/core/savestate.cpp @@ -84,13 +84,8 @@ std::vector<SaveStateInfo> ListSaveStates(u64 program_id) { void System::SaveState(u32 slot) const { std::ostringstream sstream{std::ios_base::binary}; try { - - { - oarchive oa{sstream}; - oa&* this; - } - VideoCore::Save(sstream); - + oarchive oa{sstream}; + oa&* this; } catch (const std::exception& e) { LOG_ERROR(Core, "Error saving: {}", e.what()); } @@ -159,24 +154,9 @@ void System::LoadState(u32 slot) { std::ios_base::binary}; decompressed.clear(); - // When loading, we want to make sure any lingering state gets cleared out before we begin. - // Shutdown, but persist a few things between loads... - Shutdown(true); - - // Re-initialize everything like it was before - auto system_mode = this->app_loader->LoadKernelSystemMode(); - auto n3ds_mode = this->app_loader->LoadKernelN3dsMode(); - Init(*m_emu_window, *system_mode.first, *n3ds_mode.first); - cheat_engine->Connect(); - try { - - { - iarchive ia{sstream}; - ia&* this; - } - VideoCore::Load(sstream); - + iarchive ia{sstream}; + ia&* this; } catch (const std::exception& e) { LOG_ERROR(Core, "Error loading: {}", e.what()); } diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index 5eccd8c7e2..f33ec7d57f 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp @@ -88,15 +88,11 @@ u16 GetResolutionScaleFactor() { } } -void Save(std::ostream& stream) { - oarchive oa{stream}; - oa& Pica::g_state; -} - -void Load(std::istream& stream) { - iarchive ia{stream}; - ia& Pica::g_state; - // TODO: Flush/reset things +template <class Archive> +void serialize(Archive& ar, const unsigned int) { + ar& Pica::g_state; } } // namespace VideoCore + +SERIALIZE_IMPL(VideoCore) diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h index 10b0d39b6f..46cf1e86d6 100644 --- a/src/video_core/video_core.h +++ b/src/video_core/video_core.h @@ -62,7 +62,7 @@ void RequestScreenshot(void* data, std::function<void()> callback, u16 GetResolutionScaleFactor(); -void Save(std::ostream& stream); -void Load(std::istream& stream); +template <class Archive> +void serialize(Archive& ar, const unsigned int file_version); } // namespace VideoCore From e74b44042b0af4b130d016f8c2023719fa08ba4a Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Mon, 6 Apr 2020 22:47:52 +0100 Subject: [PATCH 110/129] Added save + load hotkeys --- src/citra_qt/configuration/config.cpp | 4 +++- src/citra_qt/main.cpp | 6 +++++- src/core/core.cpp | 4 +++- src/core/core.h | 3 +++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp index d139a89e98..d815c99f57 100644 --- a/src/citra_qt/configuration/config.cpp +++ b/src/citra_qt/configuration/config.cpp @@ -57,7 +57,7 @@ const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> Config: // This must be in alphabetical order according to action name as it must have the same order as // UISetting::values.shortcuts, which is alphabetically ordered. // clang-format off -const std::array<UISettings::Shortcut, 21> default_hotkeys{ +const std::array<UISettings::Shortcut, 23> default_hotkeys{ {{QStringLiteral("Advance Frame"), QStringLiteral("Main Window"), {QStringLiteral("\\"), Qt::ApplicationShortcut}}, {QStringLiteral("Capture Screenshot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+P"), Qt::ApplicationShortcut}}, {QStringLiteral("Continue/Pause Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F4"), Qt::WindowShortcut}}, @@ -73,6 +73,8 @@ const std::array<UISettings::Shortcut, 21> default_hotkeys{ {QStringLiteral("Rotate Screens Upright"), QStringLiteral("Main Window"), {QStringLiteral("F8"), Qt::WindowShortcut}}, {QStringLiteral("Stop Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F5"), Qt::WindowShortcut}}, {QStringLiteral("Swap Screens"), QStringLiteral("Main Window"), {QStringLiteral("F9"), Qt::WindowShortcut}}, + {QStringLiteral("Save to Oldest Slot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+C"), Qt::WindowShortcut}}, + {QStringLiteral("Load from Newest Slot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+V"), Qt::WindowShortcut}}, {QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}}, {QStringLiteral("Toggle Frame Advancing"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+A"), Qt::ApplicationShortcut}}, {QStringLiteral("Toggle Screen Layout"), QStringLiteral("Main Window"), {QStringLiteral("F10"), Qt::WindowShortcut}}, diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index a583e903a9..0ef1e5bb19 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -524,6 +524,10 @@ void GMainWindow::InitializeHotkeys() { OnCaptureScreenshot(); } }); + connect(hotkey_registry.GetHotkey(main_window, ui.action_Load_from_Newest_Slot->text(), this), + &QShortcut::activated, ui.action_Load_from_Newest_Slot, &QAction::trigger); + connect(hotkey_registry.GetHotkey(main_window, ui.action_Save_to_Oldest_Slot->text(), this), + &QShortcut::activated, ui.action_Save_to_Oldest_Slot, &QAction::trigger); } void GMainWindow::ShowUpdaterWidgets() { @@ -1636,7 +1640,7 @@ void GMainWindow::OnSaveState() { assert(action); Core::System::GetInstance().SendSignal(Core::System::Signal::Save, action->data().toUInt()); - UpdateSaveStates(); + newest_slot = action->data().toUInt(); } void GMainWindow::OnLoadState() { diff --git a/src/core/core.cpp b/src/core/core.cpp index fa6d0c30d7..3d915b7644 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -577,7 +577,9 @@ void System::serialize(Archive& ar, const unsigned int file_version) { ar&* memory.get(); ar&* kernel.get(); VideoCore::serialize(ar, file_version); - ar& Movie::GetInstance(); + if (file_version >= 1) { + ar& Movie::GetInstance(); + } // This needs to be set from somewhere - might as well be here! if (Archive::is_loading::value) { diff --git a/src/core/core.h b/src/core/core.h index 9fe98f7232..ee66ff5bf4 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -7,6 +7,7 @@ #include <memory> #include <mutex> #include <string> +#include <boost/serialization/version.hpp> #include "common/common_types.h" #include "core/custom_tex_cache.h" #include "core/frontend/applets/mii_selector.h" @@ -401,3 +402,5 @@ inline AudioCore::DspInterface& DSP() { } } // namespace Core + +BOOST_CLASS_VERSION(Core::System, 1) From 3278a4d7ef255e90626a9dd7b321e4a0bf0bafea Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Fri, 10 Apr 2020 14:02:18 +0100 Subject: [PATCH 111/129] Fix crashes when loading with cameras active --- src/core/hle/service/cam/cam.cpp | 13 +++++++++++++ src/core/hle/service/cam/cam.h | 10 ++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/cam/cam.cpp b/src/core/hle/service/cam/cam.cpp index e247d998fd..c093ed7e55 100644 --- a/src/core/hle/service/cam/cam.cpp +++ b/src/core/hle/service/cam/cam.cpp @@ -30,6 +30,19 @@ void Module::serialize(Archive& ar, const unsigned int) { ar& cameras; ar& ports; ar& is_camera_reload_pending; + if (Archive::is_loading::value) { + for (int i = 0; i < NumCameras; i++) { + LoadCameraImplementation(cameras[i], i); + } + for (std::size_t i = 0; i < ports.size(); i++) { + if (ports[i].is_busy) { + cameras[ports[i].camera_id].impl->StartCapture(); + } + if (ports[i].is_receiving) { + StartReceiving(static_cast<int>(i)); + } + } + } } SERIALIZE_IMPL(Module) diff --git a/src/core/hle/service/cam/cam.h b/src/core/hle/service/cam/cam.h index 04dc0e2ea5..7c36e02c5a 100644 --- a/src/core/hle/service/cam/cam.h +++ b/src/core/hle/service/cam/cam.h @@ -13,6 +13,7 @@ #include <boost/serialization/deque.hpp> #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/unique_ptr.hpp> +#include <boost/serialization/version.hpp> #include "common/common_types.h" #include "common/swap.h" #include "core/global.h" @@ -792,8 +793,12 @@ private: private: template <class Archive> - void serialize(Archive& ar, const unsigned int) { - ar& impl; + void serialize(Archive& ar, const unsigned int file_version) { + // For compatibility: put a nullptr here + if (file_version == 0) { + std::unique_ptr<Camera::CameraInterface> x; + ar& x; + } ar& contexts; ar& current_context; ar& frame_rate; @@ -883,3 +888,4 @@ void InstallInterfaces(Core::System& system); } // namespace Service::CAM SERVICE_CONSTRUCT(Service::CAM::Module) +BOOST_CLASS_VERSION(Service::CAM::Module::CameraConfig, 1) From 432ac24503082b2ec718b6364555bea05ab336f8 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Fri, 10 Apr 2020 16:51:01 +0100 Subject: [PATCH 112/129] Fix memory region serialization (OSK crash) --- src/common/serialization/boost_discrete_interval.hpp | 3 ++- src/common/serialization/boost_interval_set.hpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/common/serialization/boost_discrete_interval.hpp b/src/common/serialization/boost_discrete_interval.hpp index 961a9a7ef7..f04e3cabc6 100644 --- a/src/common/serialization/boost_discrete_interval.hpp +++ b/src/common/serialization/boost_discrete_interval.hpp @@ -6,6 +6,7 @@ #include <boost/icl/discrete_interval.hpp> #include "common/common_types.h" +#include "common/logging/log.h" namespace boost::serialization { @@ -25,7 +26,7 @@ void load(Archive& ar, boost::icl::discrete_interval<DomainT, Compare>& obj, ar >> lower; ar >> upper; ar >> bounds; - obj = boost::icl::discrete_interval(upper, lower, boost::icl::interval_bounds(bounds)); + obj = boost::icl::discrete_interval(lower, upper, boost::icl::interval_bounds(bounds)); } template <class Archive, class DomainT, ICL_COMPARE Compare> diff --git a/src/common/serialization/boost_interval_set.hpp b/src/common/serialization/boost_interval_set.hpp index d4e48e62a7..73a5603609 100644 --- a/src/common/serialization/boost_interval_set.hpp +++ b/src/common/serialization/boost_interval_set.hpp @@ -26,7 +26,7 @@ void load(Archive& ar, boost::icl::interval_set<T>& set, const unsigned int file for (u64 i = 0; i < count; i++) { typename boost::icl::interval_set<T>::interval_type value{}; ar >> value; - set.add(value); + set += value; } } From 79889786615fb5d37237b368341fa58998a24e3c Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Fri, 10 Apr 2020 19:36:38 +0100 Subject: [PATCH 113/129] Fix VFP registers serialization (0 fps when loading etc.) --- src/citra_qt/debugger/wait_tree.cpp | 1 + src/core/arm/arm_interface.h | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/citra_qt/debugger/wait_tree.cpp b/src/citra_qt/debugger/wait_tree.cpp index 15a7ada03e..30c1b00b56 100644 --- a/src/citra_qt/debugger/wait_tree.cpp +++ b/src/citra_qt/debugger/wait_tree.cpp @@ -236,6 +236,7 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { break; } + list.push_back(std::make_unique<WaitTreeText>(tr("object id = %1").arg(thread.GetObjectId()))); list.push_back(std::make_unique<WaitTreeText>(tr("processor = %1").arg(processor))); list.push_back(std::make_unique<WaitTreeText>(tr("thread id = %1").arg(thread.GetThreadId()))); list.push_back(std::make_unique<WaitTreeText>(tr("priority = %1(current) / %2(normal)") diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index a6b8a279a5..967c672e6f 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -8,6 +8,7 @@ #include <memory> #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/split_member.hpp> +#include <boost/serialization/version.hpp> #include "common/common_types.h" #include "core/arm/skyeye_common/arm_regformat.h" #include "core/arm/skyeye_common/vfp/asm_vfp.h" @@ -30,7 +31,8 @@ public: const auto r = GetCpuRegister(i); ar << r; } - for (std::size_t i = 0; i < 16; i++) { + std::size_t fpu_reg_count = file_version == 0 ? 16 : 64; + for (std::size_t i = 0; i < fpu_reg_count; i++) { const auto r = GetFpuRegister(i); ar << r; } @@ -49,7 +51,8 @@ public: ar >> r; SetCpuRegister(i, r); } - for (std::size_t i = 0; i < 16; i++) { + std::size_t fpu_reg_count = file_version == 0 ? 16 : 64; + for (std::size_t i = 0; i < fpu_reg_count; i++) { ar >> r; SetFpuRegister(i, r); } @@ -254,7 +257,8 @@ private: ar << pc; const auto cpsr = GetCPSR(); ar << cpsr; - for (int i = 0; i < 32; i++) { + int vfp_reg_count = file_version == 0 ? 32 : 64; + for (int i = 0; i < vfp_reg_count; i++) { const auto r = GetVFPReg(i); ar << r; } @@ -285,7 +289,8 @@ private: SetPC(r); ar >> r; SetCPSR(r); - for (int i = 0; i < 32; i++) { + int vfp_reg_count = file_version == 0 ? 32 : 64; + for (int i = 0; i < vfp_reg_count; i++) { ar >> r; SetVFPReg(i, r); } @@ -301,3 +306,6 @@ private: BOOST_SERIALIZATION_SPLIT_MEMBER() }; + +BOOST_CLASS_VERSION(ARM_Interface, 1) +BOOST_CLASS_VERSION(ARM_Interface::ThreadContext, 1) From 701cd8378623ea99b21c18e5eed8519fe9b78f4a Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Fri, 10 Apr 2020 20:20:54 +0100 Subject: [PATCH 114/129] Attempt to fix mac and linux builds --- .travis/linux/upload.sh | 6 +++--- .travis/macos/upload.sh | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis/linux/upload.sh b/.travis/linux/upload.sh index 548ee4905d..c40c0d71e7 100755 --- a/.travis/linux/upload.sh +++ b/.travis/linux/upload.sh @@ -8,9 +8,9 @@ COMPRESSION_FLAGS="-cJvf" mkdir "$REV_NAME" -cp build/bin/citra "$REV_NAME" -cp build/bin/citra-room "$REV_NAME" -cp build/bin/citra-qt "$REV_NAME" +cp build/bin/Release/citra "$REV_NAME" +cp build/bin/Release/citra-room "$REV_NAME" +cp build/bin/Release/citra-qt "$REV_NAME" # We need icons on Linux for .desktop entries mkdir "$REV_NAME/dist" diff --git a/.travis/macos/upload.sh b/.travis/macos/upload.sh index bdd7d7da7f..05760c0b44 100755 --- a/.travis/macos/upload.sh +++ b/.travis/macos/upload.sh @@ -8,9 +8,9 @@ COMPRESSION_FLAGS="-czvf" mkdir "$REV_NAME" -cp build/bin/citra "$REV_NAME" -cp -r build/bin/citra-qt.app "$REV_NAME" -cp build/bin/citra-room "$REV_NAME" +cp build/bin/Release/citra "$REV_NAME" +cp -r build/bin/Release/citra-qt.app "$REV_NAME" +cp build/bin/Release/citra-room "$REV_NAME" # move libs into folder for deployment macpack "${REV_NAME}/citra-qt.app/Contents/MacOS/citra-qt" -d "../Frameworks" From 7b3a8e9bf53eadf1c111db8b657a6dd236c04bd9 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Fri, 10 Apr 2020 20:22:40 +0100 Subject: [PATCH 115/129] Fix clang format --- src/core/movie.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/movie.h b/src/core/movie.h index e578b909cd..eff148090d 100644 --- a/src/core/movie.h +++ b/src/core/movie.h @@ -42,8 +42,8 @@ public: return s_instance; } - void StartPlayback( - const std::string& movie_file, std::function<void()> completion_callback = [] {}); + void StartPlayback(const std::string& movie_file, + std::function<void()> completion_callback = [] {}); void StartRecording(const std::string& movie_file); /// Prepare to override the clock before playing back movies From a210e7e2bd9ad3bb296c3882aede790df8c77246 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 11 Apr 2020 10:28:52 +0100 Subject: [PATCH 116/129] Sync GPU state after loading (fix FE terrain bug) --- src/core/core.cpp | 2 ++ src/video_core/rasterizer_interface.h | 2 ++ src/video_core/renderer_base.cpp | 4 ++++ src/video_core/renderer_base.h | 1 + src/video_core/renderer_opengl/gl_rasterizer.h | 6 +++--- 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 3d915b7644..bdcee4ebd3 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -44,6 +44,7 @@ #include "core/rpc/rpc_server.h" #include "core/settings.h" #include "network/network.h" +#include "video_core/renderer_base.h" #include "video_core/video_core.h" namespace Core { @@ -586,6 +587,7 @@ void System::serialize(Archive& ar, const unsigned int file_version) { Service::GSP::SetGlobalModule(*this); memory->SetDSP(*dsp_core); cheat_engine->Connect(); + VideoCore::g_renderer->Sync(); } } diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index a2510292e9..873e4273ea 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h @@ -87,5 +87,7 @@ public: virtual void LoadDiskResources(const std::atomic_bool& stop_loading, const DiskResourceLoadCallback& callback) {} + + virtual void SyncEntireState() {} }; } // namespace VideoCore diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp index 4065d1a7de..8d18b68008 100644 --- a/src/video_core/renderer_base.cpp +++ b/src/video_core/renderer_base.cpp @@ -28,3 +28,7 @@ void RendererBase::RefreshRasterizerSetting() { } } } + +void RendererBase::Sync() { + rasterizer->SyncEntireState(); +} diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index 7fcaf53702..578939a6e6 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h @@ -68,6 +68,7 @@ public: } void RefreshRasterizerSetting(); + void Sync(); protected: Frontend::EmuWindow& render_window; ///< Reference to the render window handle. diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 92cca2e4e4..fee8363b63 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -61,6 +61,9 @@ public: u32 pixel_stride, ScreenInfo& screen_info) override; bool AccelerateDrawBatch(bool is_indexed) override; + /// Syncs entire status to match PICA registers + void SyncEntireState() override; + private: struct SamplerInfo { using TextureConfig = Pica::TexturingRegs::TextureConfig; @@ -132,9 +135,6 @@ private: GLvec3 view; }; - /// Syncs entire status to match PICA registers - void SyncEntireState(); - /// Syncs the clip enabled status to match the PICA register void SyncClipEnabled(); From e9ab8f82d4e4057889340cc45431de4f8b75ee2b Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 11 Apr 2020 11:52:11 +0100 Subject: [PATCH 117/129] Add disk archive serialization (fix crash in driver renegade etc.) --- src/common/file_util.h | 74 +++++++++++++++++++++--------- src/core/file_sys/disk_archive.cpp | 4 ++ src/core/file_sys/disk_archive.h | 28 ++++++++++- 3 files changed, 83 insertions(+), 23 deletions(-) diff --git a/src/common/file_util.h b/src/common/file_util.h index 9eafa24164..d5915b8b73 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -16,6 +16,7 @@ #include <vector> #include <boost/serialization/split_member.hpp> #include <boost/serialization/string.hpp> +#include <boost/serialization/wrapper.hpp> #include "common/common_types.h" #ifdef _MSC_VER #include "common/string_util.h" @@ -41,6 +42,34 @@ enum class UserPath { UserDir, }; +// Replaces install-specific paths with standard placeholders, and back again +std::string SerializePath(const std::string& input, bool is_saving); + +// A serializable path string +struct Path : public boost::serialization::wrapper_traits<const Path> { + std::string& str; + + explicit Path(std::string& _str) : str(_str) {} + + static const Path make(std::string& str) { + return Path(str); + } + + template <class Archive> + void save(Archive& ar, const unsigned int) const { + auto s_path = SerializePath(str, true); + ar << s_path; + } + template <class Archive> + void load(Archive& ar, const unsigned int) const { + ar >> str; + str = SerializePath(str, false); + } + + BOOST_SERIALIZATION_SPLIT_MEMBER(); + friend class boost::serialization::access; +}; + // FileSystem tree node/ struct FSTEntry { bool isDirectory; @@ -48,6 +77,17 @@ struct FSTEntry { std::string physicalName; // name on disk std::string virtualName; // name in FST names table std::vector<FSTEntry> children; + +private: + template <class Archive> + void serialize(Archive& ar, const unsigned int) { + ar& isDirectory; + ar& size; + ar& Path::make(physicalName); + ar& Path::make(virtualName); + ar& children; + } + friend class boost::serialization::access; }; // Returns true if file filename exists @@ -146,9 +186,6 @@ void SetCurrentRomPath(const std::string& path); // directory. To be used in "multi-user" mode (that is, installed). const std::string& GetUserPath(UserPath path); -// Replaces install-specific paths with standard placeholders, and back again -std::string SerializePath(const std::string& input, bool is_saving); - // Returns the path to where the sys file are std::string GetSysDirectory(); @@ -322,27 +359,20 @@ private: u32 flags; template <class Archive> - void save(Archive& ar, const unsigned int) const { - auto s_filename = SerializePath(filename, true); - ar << s_filename; - ar << openmode; - ar << flags; - ar << Tell(); - } - - template <class Archive> - void load(Archive& ar, const unsigned int) { - ar >> filename; - filename = SerializePath(filename, false); - ar >> openmode; - ar >> flags; + void serialize(Archive& ar, const unsigned int) { + ar& Path::make(filename); + ar& openmode; + ar& flags; u64 pos; - ar >> pos; - Open(); - Seek(pos, SEEK_SET); + if (Archive::is_saving::value) { + pos = Tell(); + } + ar& pos; + if (Archive::is_loading::value) { + Open(); + Seek(pos, SEEK_SET); + } } - - BOOST_SERIALIZATION_SPLIT_MEMBER() friend class boost::serialization::access; }; diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp index 0614605468..6ace314bf9 100644 --- a/src/core/file_sys/disk_archive.cpp +++ b/src/core/file_sys/disk_archive.cpp @@ -5,6 +5,7 @@ #include <algorithm> #include <cstdio> #include <memory> +#include "common/archives.h" #include "common/common_types.h" #include "common/file_util.h" #include "common/logging/log.h" @@ -14,6 +15,9 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::DiskFile) +SERIALIZE_EXPORT_IMPL(FileSys::DiskDirectory) + namespace FileSys { ResultVal<std::size_t> DiskFile::Read(const u64 offset, const std::size_t length, diff --git a/src/core/file_sys/disk_archive.h b/src/core/file_sys/disk_archive.h index 9251749ce9..2f0e5691ae 100644 --- a/src/core/file_sys/disk_archive.h +++ b/src/core/file_sys/disk_archive.h @@ -10,6 +10,7 @@ #include <vector> #include <boost/serialization/base_object.hpp> #include <boost/serialization/unique_ptr.hpp> +#include <boost/serialization/vector.hpp> #include "common/common_types.h" #include "common/file_util.h" #include "core/file_sys/archive_backend.h" @@ -46,12 +47,16 @@ protected: Mode mode; std::unique_ptr<FileUtil::IOFile> file; +private: + DiskFile() = default; + template <class Archive> void serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object<FileBackend>(*this); - ar& mode; + ar& mode.hex; ar& file; } + friend class boost::serialization::access; }; class DiskDirectory : public DirectoryBackend { @@ -74,6 +79,27 @@ protected: // We need to remember the last entry we returned, so a subsequent call to Read will continue // from the next one. This iterator will always point to the next unread entry. std::vector<FileUtil::FSTEntry>::iterator children_iterator; + +private: + DiskDirectory() = default; + + template <class Archive> + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object<DirectoryBackend>(*this); + ar& directory; + u64 child_index; + if (Archive::is_saving::value) { + child_index = children_iterator - directory.children.begin(); + } + ar& child_index; + if (Archive::is_loading::value) { + children_iterator = directory.children.begin() + child_index; + } + } + friend class boost::serialization::access; }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::DiskFile) +BOOST_CLASS_EXPORT_KEY(FileSys::DiskDirectory) From 3871d74bc213e8fd8ef712ef4724df3fe629ad7f Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 11 Apr 2020 19:33:21 +0100 Subject: [PATCH 118/129] Fix mic sharedmemory not being deallocated --- src/core/hle/service/mic_u.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index 08ef5473f4..f0017ac4ca 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <boost/serialization/weak_ptr.hpp> #ifdef HAVE_CUBEB #include "audio_core/cubeb_input.h" #endif @@ -69,7 +70,7 @@ constexpr u64 GetBufferUpdateRate(SampleRate sample_rate) { // Variables holding the current mic buffer writing state struct State { - std::shared_ptr<Kernel::SharedMemory> memory_ref = nullptr; + std::weak_ptr<Kernel::SharedMemory> memory_ref{}; u8* sharedmem_buffer = nullptr; u32 sharedmem_size = 0; std::size_t size = 0; @@ -110,7 +111,9 @@ struct State { private: template <class Archive> void serialize(Archive& ar, const unsigned int) { - ar& memory_ref; + std::shared_ptr<Kernel::SharedMemory> _memory_ref = memory_ref.lock(); + ar& _memory_ref; + memory_ref = _memory_ref; ar& sharedmem_size; ar& size; ar& offset; @@ -118,7 +121,7 @@ private: ar& looped_buffer; ar& sample_size; ar& sample_rate; - sharedmem_buffer = memory_ref ? memory_ref->GetPointer() : nullptr; + sharedmem_buffer = _memory_ref ? _memory_ref->GetPointer() : nullptr; } friend class boost::serialization::access; }; From e6b40486c52142adfa7c4bd9e471280c1c600c60 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 11 Apr 2020 19:47:06 +0100 Subject: [PATCH 119/129] Add a couple of useful SVC logs --- src/core/hle/kernel/svc.cpp | 1 + src/core/hle/kernel/svc_wrapper.h | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 8f1ba5e011..25eb9bb4ec 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1607,6 +1607,7 @@ void SVC::CallSVC(u32 immediate) { "Running threads from exiting processes is unimplemented"); const FunctionDef* info = GetSVCInfo(immediate); + LOG_TRACE(Kernel_SVC, "calling {}", info->name); if (info) { if (info->func) { (this->*(info->func))(); diff --git a/src/core/hle/kernel/svc_wrapper.h b/src/core/hle/kernel/svc_wrapper.h index b4fbbe0de6..77334152d0 100644 --- a/src/core/hle/kernel/svc_wrapper.h +++ b/src/core/hle/kernel/svc_wrapper.h @@ -280,6 +280,26 @@ private: } }; + template <typename SVCT> + struct WrapPass<SVCT, ResultCode /*empty for T, Ts...*/> { + // Call function R(Context::svc)(Us...) and transfer the return value to registers + template <typename... Us> + static void Call(Context& context, SVCT svc, Us... u) { + static_assert(std::is_same_v<SVCT, ResultCode (Context::*)(Us...)>); + if constexpr (std::is_void_v<ResultCode>) { + (context.*svc)(u...); + } else { + ResultCode r = (context.*svc)(u...); + if (r.IsError()) { + LOG_ERROR(Kernel_SVC, "level={} summary={} module={} description={}", + r.level.ExtractValue(r.raw), r.summary.ExtractValue(r.raw), + r.module.ExtractValue(r.raw), r.description.ExtractValue(r.raw)); + } + SetParam<INDEX_RETURN, ResultCode, ResultCode, Us...>(context, r); + } + } + }; + template <typename T> struct WrapHelper; From 4be752dd980a18b922939acbd92a12f599cedf04 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 11 Apr 2020 19:47:31 +0100 Subject: [PATCH 120/129] Allow GDB debugging through loads --- src/core/core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index bdcee4ebd3..8768ba3e61 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -494,10 +494,10 @@ void System::Shutdown(bool is_deserializing) { perf_stats->GetMeanFrametime()); // Shutdown emulation session - GDBStub::Shutdown(); VideoCore::Shutdown(); HW::Shutdown(); if (!is_deserializing) { + GDBStub::Shutdown(); perf_stats.reset(); cheat_engine.reset(); app_loader.reset(); From 34af0d3452192a5d880a0b305d7fd31e9375da52 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 11 Apr 2020 20:33:38 +0100 Subject: [PATCH 121/129] Attempt to fix network bug --- src/core/hle/service/nwm/nwm_uds.cpp | 3 +++ src/core/savestate.cpp | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 1a95d2295b..8ebb8a6e35 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -504,6 +504,9 @@ void NWM_UDS::HandleDataFrame(const Network::WifiPacket& packet) { /// Callback to parse and handle a received wifi packet. void NWM_UDS::OnWifiPacketReceived(const Network::WifiPacket& packet) { + if (!initialized) { + return; + } switch (packet.type) { case Network::WifiPacket::PacketType::Beacon: HandleBeaconFrame(packet); diff --git a/src/core/savestate.cpp b/src/core/savestate.cpp index ece6406a14..2a6fb92cb9 100644 --- a/src/core/savestate.cpp +++ b/src/core/savestate.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include <chrono> +#include <boost/serialization/binary_object.hpp> #include <cryptopp/hex.h> #include "common/archives.h" #include "common/logging/log.h" @@ -11,6 +12,7 @@ #include "core/cheats/cheats.h" #include "core/core.h" #include "core/savestate.h" +#include "network/network.h" #include "video_core/video_core.h" namespace Core { @@ -23,6 +25,11 @@ struct CSTHeader { u64_le time; /// The time when this save state was created std::array<u8, 216> reserved; /// Make heading 256 bytes so it has consistent size + + template <class Archive> + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::binary_object(this, sizeof(CSTHeader)); + } }; static_assert(sizeof(CSTHeader) == 256, "CSTHeader should be 256 bytes"); #pragma pack(pop) @@ -127,6 +134,11 @@ void System::SaveState(u32 slot) const { } void System::LoadState(u32 slot) { + if (Network::GetRoomMember().lock()->IsConnected()) { + LOG_ERROR(Core, "Unable to load while connected to multiplayer"); + return; + } + const auto path = GetSaveStatePath(title_id, slot); if (!FileUtil::Exists(path)) { LOG_ERROR(Core, "File not exist {}", path); From 19872b599baa824ff26716a502a4c6ca441c1347 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 11 Apr 2020 20:47:14 +0100 Subject: [PATCH 122/129] Fix button state not persisting between loads --- src/core/hle/service/hid/hid.cpp | 6 ++++-- src/core/hle/service/hid/hid.h | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 981a4aa63b..4c87182766 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -30,7 +30,7 @@ SERIALIZE_EXPORT_IMPL(Service::HID::Module) namespace Service::HID { template <class Archive> -void Module::serialize(Archive& ar, const unsigned int) { +void Module::serialize(Archive& ar, const unsigned int file_version) { ar& shared_mem; ar& event_pad_or_touch_1; ar& event_pad_or_touch_2; @@ -46,7 +46,9 @@ void Module::serialize(Archive& ar, const unsigned int) { if (Archive::is_loading::value) { LoadInputDevices(); } - // Pad state not needed as it's always updated + if (file_version >= 1) { + ar& state.hex; + } // Update events are set in the constructor // Devices are set from the implementation (and are stateless afaik) } diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index ad526ac6f1..58a3c68a59 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -8,6 +8,7 @@ #include <atomic> #include <cstddef> #include <memory> +#include <boost/serialization/version.hpp> #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" @@ -348,3 +349,4 @@ void InstallInterfaces(Core::System& system); SERVICE_CONSTRUCT(Service::HID::Module) BOOST_CLASS_EXPORT_KEY(Service::HID::Module) +BOOST_CLASS_VERSION(Service::HID::Module, 1) From 77c4b26e6ce4d4c35b0789c361a9dda69c5a0d06 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 11 Apr 2020 22:25:57 +0100 Subject: [PATCH 123/129] Attempt to improve save/load during frame advance --- src/citra_qt/main.cpp | 3 ++ src/core/core.cpp | 67 +++++++++++++++++++++-------------------- src/core/perf_stats.cpp | 12 +++++--- src/core/perf_stats.h | 1 + 4 files changed, 46 insertions(+), 37 deletions(-) diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 0ef1e5bb19..bd1c95c52e 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -706,6 +706,7 @@ void GMainWindow::ConnectMenuEvents() { if (emulation_running) { ui.action_Enable_Frame_Advancing->setChecked(true); ui.action_Advance_Frame->setEnabled(true); + Core::System::GetInstance().frame_limiter.SetFrameAdvancing(true); Core::System::GetInstance().frame_limiter.AdvanceFrame(); } }); @@ -1640,6 +1641,7 @@ void GMainWindow::OnSaveState() { assert(action); Core::System::GetInstance().SendSignal(Core::System::Signal::Save, action->data().toUInt()); + Core::System::GetInstance().frame_limiter.AdvanceFrame(); newest_slot = action->data().toUInt(); } @@ -1648,6 +1650,7 @@ void GMainWindow::OnLoadState() { assert(action); Core::System::GetInstance().SendSignal(Core::System::Signal::Load, action->data().toUInt()); + Core::System::GetInstance().frame_limiter.AdvanceFrame(); } void GMainWindow::OnConfigure() { diff --git a/src/core/core.cpp b/src/core/core.cpp index 8768ba3e61..58f1ddefe9 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -89,6 +89,40 @@ System::ResultStatus System::RunLoop(bool tight_loop) { } } + Signal signal{Signal::None}; + u32 param{}; + { + std::lock_guard lock{signal_mutex}; + if (current_signal != Signal::None) { + signal = current_signal; + param = signal_param; + current_signal = Signal::None; + } + } + switch (signal) { + case Signal::Reset: + Reset(); + return ResultStatus::Success; + case Signal::Shutdown: + return ResultStatus::ShutdownRequested; + case Signal::Load: { + LOG_INFO(Core, "Begin load"); + System::LoadState(param); + LOG_INFO(Core, "Load completed"); + frame_limiter.WaitOnce(); + return ResultStatus::Success; + } + case Signal::Save: { + LOG_INFO(Core, "Begin save"); + System::SaveState(param); + LOG_INFO(Core, "Save completed"); + frame_limiter.WaitOnce(); + return ResultStatus::Success; + } + default: + break; + } + // All cores should have executed the same amount of ticks. If this is not the case an event was // scheduled with a cycles_into_future smaller then the current downcount. // So we have to get those cores to the same global time first @@ -163,39 +197,6 @@ System::ResultStatus System::RunLoop(bool tight_loop) { HW::Update(); Reschedule(); - Signal signal{Signal::None}; - u32 param{}; - { - std::lock_guard lock{signal_mutex}; - if (current_signal != Signal::None) { - signal = current_signal; - param = signal_param; - current_signal = Signal::None; - } - } - switch (signal) { - case Signal::Reset: - Reset(); - break; - case Signal::Shutdown: - return ResultStatus::ShutdownRequested; - break; - case Signal::Load: { - LOG_INFO(Core, "Begin load"); - System::LoadState(param); - LOG_INFO(Core, "Load completed"); - break; - } - case Signal::Save: { - LOG_INFO(Core, "Begin save"); - System::SaveState(param); - LOG_INFO(Core, "Save completed"); - break; - } - default: - break; - } - return status; } diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp index 94d6c17ca0..00ab24dbcd 100644 --- a/src/core/perf_stats.cpp +++ b/src/core/perf_stats.cpp @@ -117,6 +117,14 @@ double PerfStats::GetLastFrameTimeScale() { return duration_cast<DoubleSecs>(previous_frame_length).count() / FRAME_LENGTH; } +void FrameLimiter::WaitOnce() { + if (frame_advancing_enabled) { + // Frame advancing is enabled: wait on event instead of doing framelimiting + frame_advance_event.Wait(); + frame_advance_event.Reset(); + } +} + void FrameLimiter::DoFrameLimiting(microseconds current_system_time_us) { if (frame_advancing_enabled) { // Frame advancing is enabled: wait on event instead of doing framelimiting @@ -164,10 +172,6 @@ void FrameLimiter::SetFrameAdvancing(bool value) { } void FrameLimiter::AdvanceFrame() { - if (!frame_advancing_enabled) { - // Start frame advancing - frame_advancing_enabled = true; - } frame_advance_event.Set(); } diff --git a/src/core/perf_stats.h b/src/core/perf_stats.h index 0ef5168faa..c7d22ef8ec 100644 --- a/src/core/perf_stats.h +++ b/src/core/perf_stats.h @@ -98,6 +98,7 @@ public: */ void SetFrameAdvancing(bool value); void AdvanceFrame(); + void WaitOnce(); private: /// Emulated system time (in microseconds) at the last limiter invocation From d53e94db88d18178ed73a5bc48b8df8e2fa4c992 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sun, 12 Apr 2020 23:12:15 +0100 Subject: [PATCH 124/129] Show save/load errors to the user --- src/citra_qt/main.cpp | 3 +++ src/core/core.cpp | 20 +++++++++++++---- src/core/core.h | 1 + src/core/savestate.cpp | 49 ++++++++++++------------------------------ 4 files changed, 34 insertions(+), 39 deletions(-) diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index f6dc3f2ef9..7389b8c23e 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -2079,6 +2079,9 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det title = tr("System Archive Not Found"); status_message = tr("System Archive Missing"); + } else if (result == Core::System::ResultStatus::ErrorSavestate) { + title = tr("Save/load Error"); + message = QString::fromStdString(details); } else { title = tr("Fatal Error"); message = diff --git a/src/core/core.cpp b/src/core/core.cpp index 1421d7f70f..14b41207ae 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -107,15 +107,27 @@ System::ResultStatus System::RunLoop(bool tight_loop) { return ResultStatus::ShutdownRequested; case Signal::Load: { LOG_INFO(Core, "Begin load"); - System::LoadState(param); - LOG_INFO(Core, "Load completed"); + try { + System::LoadState(param); + LOG_INFO(Core, "Load completed"); + } catch (const std::exception& e) { + LOG_ERROR(Core, "Error loading: {}", e.what()); + status_details = e.what(); + return ResultStatus::ErrorSavestate; + } frame_limiter.WaitOnce(); return ResultStatus::Success; } case Signal::Save: { LOG_INFO(Core, "Begin save"); - System::SaveState(param); - LOG_INFO(Core, "Save completed"); + try { + System::SaveState(param); + LOG_INFO(Core, "Save completed"); + } catch (const std::exception& e) { + LOG_ERROR(Core, "Error saving: {}", e.what()); + status_details = e.what(); + return ResultStatus::ErrorSavestate; + } frame_limiter.WaitOnce(); return ResultStatus::Success; } diff --git a/src/core/core.h b/src/core/core.h index eb3dc01b3f..dca6a6888f 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -89,6 +89,7 @@ public: /// generic drivers installed ErrorVideoCore_ErrorBelowGL33, ///< Error in the video core due to the user not having /// OpenGL 3.3 or higher + ErrorSavestate, ///< Error saving or loading ShutdownRequested, ///< Emulated program requested a system shutdown ErrorUnknown ///< Any other error }; diff --git a/src/core/savestate.cpp b/src/core/savestate.cpp index 2a6fb92cb9..26fc0cbedf 100644 --- a/src/core/savestate.cpp +++ b/src/core/savestate.cpp @@ -90,26 +90,22 @@ std::vector<SaveStateInfo> ListSaveStates(u64 program_id) { void System::SaveState(u32 slot) const { std::ostringstream sstream{std::ios_base::binary}; - try { - oarchive oa{sstream}; - oa&* this; - } catch (const std::exception& e) { - LOG_ERROR(Core, "Error saving: {}", e.what()); - } + // Serialize + oarchive oa{sstream}; + oa&* this; + const std::string& str{sstream.str()}; auto buffer = Common::Compression::CompressDataZSTDDefault( reinterpret_cast<const u8*>(str.data()), str.size()); const auto path = GetSaveStatePath(title_id, slot); if (!FileUtil::CreateFullPath(path)) { - LOG_ERROR(Core, "Could not create path {}", path); - return; + throw std::runtime_error("Could not create path " + path); } FileUtil::IOFile file(path, "wb"); if (!file) { - LOG_ERROR(Core, "Could not open file {}", path); - return; + throw std::runtime_error("Could not open file " + path); } CSTHeader header{}; @@ -123,41 +119,27 @@ void System::SaveState(u32 slot) const { std::chrono::system_clock::now().time_since_epoch()) .count(); - if (file.WriteBytes(&header, sizeof(header)) != sizeof(header)) { - LOG_ERROR(Core, "Could not write to file {}", path); - return; - } - if (file.WriteBytes(buffer.data(), buffer.size()) != buffer.size()) { - LOG_ERROR(Core, "Could not write to file {}", path); - return; + if (file.WriteBytes(&header, sizeof(header)) != sizeof(header) || + file.WriteBytes(buffer.data(), buffer.size()) != buffer.size()) { + throw std::runtime_error("Could not write to file " + path); } } void System::LoadState(u32 slot) { if (Network::GetRoomMember().lock()->IsConnected()) { - LOG_ERROR(Core, "Unable to load while connected to multiplayer"); - return; + throw std::runtime_error("Unable to load while connected to multiplayer"); } const auto path = GetSaveStatePath(title_id, slot); - if (!FileUtil::Exists(path)) { - LOG_ERROR(Core, "File not exist {}", path); - return; - } std::vector<u8> decompressed; { std::vector<u8> buffer(FileUtil::GetSize(path) - sizeof(CSTHeader)); FileUtil::IOFile file(path, "rb"); - if (!file) { - LOG_ERROR(Core, "Could not open file {}", path); - return; - } file.Seek(sizeof(CSTHeader), SEEK_SET); // Skip header if (file.ReadBytes(buffer.data(), buffer.size()) != buffer.size()) { - LOG_ERROR(Core, "Could not read from file {}", path); - return; + throw std::runtime_error("Could not read from file at " + path); } decompressed = Common::Compression::DecompressDataZSTD(buffer); } @@ -166,12 +148,9 @@ void System::LoadState(u32 slot) { std::ios_base::binary}; decompressed.clear(); - try { - iarchive ia{sstream}; - ia&* this; - } catch (const std::exception& e) { - LOG_ERROR(Core, "Error loading: {}", e.what()); - } + // Deserialize + iarchive ia{sstream}; + ia&* this; } } // namespace Core From 4d6bd9b569fca16325d6c3968bd68d4a6290c172 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Mon, 13 Apr 2020 11:50:27 +0100 Subject: [PATCH 125/129] Fix the merge --- src/citra_qt/debugger/wait_tree.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/citra_qt/debugger/wait_tree.cpp b/src/citra_qt/debugger/wait_tree.cpp index 66b047e75c..32ee7a1dfe 100644 --- a/src/citra_qt/debugger/wait_tree.cpp +++ b/src/citra_qt/debugger/wait_tree.cpp @@ -216,7 +216,7 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren()); const auto& thread = static_cast<const Kernel::Thread&>(object); - const auto* process = thread.owner_process; + const auto& process = thread.owner_process; QString processor; switch (thread.processor_id) { From 3a651ac9fcb1630ebedc7668b43612815f078f11 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Mon, 13 Apr 2020 18:08:15 +0100 Subject: [PATCH 126/129] Fix clang format --- src/core/core.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/core.h b/src/core/core.h index dca6a6888f..e7fbd8ee36 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -316,7 +316,8 @@ private: * @param system_mode The system mode. * @return ResultStatus code, indicating if the operation succeeded. */ - ResultStatus Init(Frontend::EmuWindow& emu_window, u32 system_mode, u8 n3ds_mode, u32 num_cores); + ResultStatus Init(Frontend::EmuWindow& emu_window, u32 system_mode, u8 n3ds_mode, + u32 num_cores); /// Reschedule the core emulation void Reschedule(); From 824453b133f1873a1113c2c6f7fdc901116ebbad Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Thu, 16 Apr 2020 19:04:04 +0100 Subject: [PATCH 127/129] Remove the build type from the bin path --- .travis/linux/upload.sh | 6 +++--- .travis/macos/upload.sh | 6 +++--- CMakeLists.txt | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.travis/linux/upload.sh b/.travis/linux/upload.sh index c40c0d71e7..548ee4905d 100755 --- a/.travis/linux/upload.sh +++ b/.travis/linux/upload.sh @@ -8,9 +8,9 @@ COMPRESSION_FLAGS="-cJvf" mkdir "$REV_NAME" -cp build/bin/Release/citra "$REV_NAME" -cp build/bin/Release/citra-room "$REV_NAME" -cp build/bin/Release/citra-qt "$REV_NAME" +cp build/bin/citra "$REV_NAME" +cp build/bin/citra-room "$REV_NAME" +cp build/bin/citra-qt "$REV_NAME" # We need icons on Linux for .desktop entries mkdir "$REV_NAME/dist" diff --git a/.travis/macos/upload.sh b/.travis/macos/upload.sh index 05760c0b44..bdd7d7da7f 100755 --- a/.travis/macos/upload.sh +++ b/.travis/macos/upload.sh @@ -8,9 +8,9 @@ COMPRESSION_FLAGS="-czvf" mkdir "$REV_NAME" -cp build/bin/Release/citra "$REV_NAME" -cp -r build/bin/Release/citra-qt.app "$REV_NAME" -cp build/bin/Release/citra-room "$REV_NAME" +cp build/bin/citra "$REV_NAME" +cp -r build/bin/citra-qt.app "$REV_NAME" +cp build/bin/citra-room "$REV_NAME" # move libs into folder for deployment macpack "${REV_NAME}/citra-qt.app/Contents/MacOS/citra-qt" -d "../Frameworks" diff --git a/CMakeLists.txt b/CMakeLists.txt index 50153c808c..e85534e8f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -126,7 +126,7 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # set up output paths for executable binaries -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) # System imported libraries From d6c84227d85a9a2935c991b49513e26379c24600 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Thu, 16 Apr 2020 20:44:25 +0100 Subject: [PATCH 128/129] Fixed NWM not responding --- src/core/hle/service/nwm/nwm_uds.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 8ebb8a6e35..cba699f25c 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -552,8 +552,7 @@ boost::optional<Network::MacAddress> NWM_UDS::GetNodeMacAddress(u16 dest_node_id void NWM_UDS::Shutdown(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x03, 0, 0); - if (auto room_member = Network::GetRoomMember().lock()) - room_member->Unbind(wifi_packet_received); + initialized = false; for (auto bind_node : channel_data) { bind_node.second.event->Signal(); From f5b23eff4b9593f3212b16b964ec481565cf7fe9 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Fri, 17 Apr 2020 14:11:58 +0100 Subject: [PATCH 129/129] Correctly register AddressArbiter as a type of WakeupCallback --- src/core/hle/kernel/address_arbiter.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index 059ff14003..c7a263d9ef 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -11,6 +11,7 @@ #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/string.hpp> #include <boost/serialization/vector.hpp> +#include <boost/serialization/version.hpp> #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/thread.h" @@ -81,6 +82,9 @@ private: template <class Archive> void serialize(Archive& ar, const unsigned int file_version) { ar& boost::serialization::base_object<Object>(*this); + if (file_version > 0) { + ar& boost::serialization::base_object<WakeupCallback>(*this); + } ar& name; ar& waiting_threads; } @@ -89,4 +93,5 @@ private: } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::AddressArbiter) +BOOST_CLASS_VERSION(Kernel::AddressArbiter, 1) CONSTRUCT_KERNEL_OBJECT(Kernel::AddressArbiter)