diff options
Diffstat (limited to 'src/core/hle')
95 files changed, 1004 insertions, 409 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index aa2c83937..3366fd8ce 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -1066,7 +1066,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_) RegisterHandlers(functions); - auto& kernel = Core::System::GetInstance().Kernel(); + auto& kernel = system.Kernel(); gpu_error_detected_event = Kernel::WritableEvent::CreateEventPair( kernel, Kernel::ResetType::Manual, "IApplicationFunctions:GpuErrorDetectedSystemEvent"); } @@ -1143,13 +1143,21 @@ void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest( void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - u128 uid = rp.PopRaw<u128>(); // What does this do? - LOG_WARNING(Service, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]); + u128 user_id = rp.PopRaw<u128>(); + + LOG_DEBUG(Service_AM, "called, uid={:016X}{:016X}", user_id[1], user_id[0]); + + FileSys::SaveDataDescriptor descriptor{}; + descriptor.title_id = Core::CurrentProcess()->GetTitleID(); + descriptor.user_id = user_id; + descriptor.type = FileSys::SaveDataType::SaveData; + const auto res = system.GetFileSystemController().CreateSaveData( + FileSys::SaveDataSpaceId::NandUser, descriptor); IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(RESULT_SUCCESS); + rb.Push(res.Code()); rb.Push<u64>(0); -} // namespace Service::AM +} void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) { // Takes an input u32 Result, no output. @@ -1261,8 +1269,8 @@ void IApplicationFunctions::ExtendSaveData(Kernel::HLERequestContext& ctx) { "new_journal={:016X}", static_cast<u8>(type), user_id[1], user_id[0], new_normal_size, new_journal_size); - const auto title_id = system.CurrentProcess()->GetTitleID(); - FileSystem::WriteSaveDataSize(type, title_id, user_id, {new_normal_size, new_journal_size}); + system.GetFileSystemController().WriteSaveDataSize( + type, system.CurrentProcess()->GetTitleID(), user_id, {new_normal_size, new_journal_size}); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); @@ -1281,8 +1289,8 @@ void IApplicationFunctions::GetSaveDataSize(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called with type={:02X}, user_id={:016X}{:016X}", static_cast<u8>(type), user_id[1], user_id[0]); - const auto title_id = system.CurrentProcess()->GetTitleID(); - const auto size = FileSystem::ReadSaveDataSize(type, title_id, user_id); + const auto size = system.GetFileSystemController().ReadSaveDataSize( + type, system.CurrentProcess()->GetTitleID(), user_id); IPC::ResponseBuilder rb{ctx, 6}; rb.Push(RESULT_SUCCESS); diff --git a/src/core/hle/service/am/applet_ae.h b/src/core/hle/service/am/applet_ae.h index 9e006cd9d..0e0d10858 100644 --- a/src/core/hle/service/am/applet_ae.h +++ b/src/core/hle/service/am/applet_ae.h @@ -9,6 +9,10 @@ #include "core/hle/service/service.h" namespace Service { +namespace FileSystem { +class FileSystemController; +} + namespace NVFlinger { class NVFlinger; } diff --git a/src/core/hle/service/am/applet_oe.h b/src/core/hle/service/am/applet_oe.h index 22c05419d..99a65e7b5 100644 --- a/src/core/hle/service/am/applet_oe.h +++ b/src/core/hle/service/am/applet_oe.h @@ -9,6 +9,10 @@ #include "core/hle/service/service.h" namespace Service { +namespace FileSystem { +class FileSystemController; +} + namespace NVFlinger { class NVFlinger; } diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp index d3e97776b..e9cf1e840 100644 --- a/src/core/hle/service/aoc/aoc_u.cpp +++ b/src/core/hle/service/aoc/aoc_u.cpp @@ -29,9 +29,9 @@ static bool CheckAOCTitleIDMatchesBase(u64 title_id, u64 base) { return (title_id & DLC_BASE_TITLE_ID_MASK) == base; } -static std::vector<u64> AccumulateAOCTitleIDs() { +static std::vector<u64> AccumulateAOCTitleIDs(Core::System& system) { std::vector<u64> add_on_content; - const auto& rcu = Core::System::GetInstance().GetContentProvider(); + const auto& rcu = system.GetContentProvider(); const auto list = rcu.ListEntriesFilter(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data); std::transform(list.begin(), list.end(), std::back_inserter(add_on_content), @@ -47,7 +47,8 @@ static std::vector<u64> AccumulateAOCTitleIDs() { return add_on_content; } -AOC_U::AOC_U() : ServiceFramework("aoc:u"), add_on_content(AccumulateAOCTitleIDs()) { +AOC_U::AOC_U(Core::System& system) + : ServiceFramework("aoc:u"), add_on_content(AccumulateAOCTitleIDs(system)), system(system) { // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "CountAddOnContentByApplicationId"}, @@ -65,7 +66,7 @@ AOC_U::AOC_U() : ServiceFramework("aoc:u"), add_on_content(AccumulateAOCTitleIDs RegisterHandlers(functions); - auto& kernel = Core::System::GetInstance().Kernel(); + auto& kernel = system.Kernel(); aoc_change_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual, "GetAddOnContentListChanged:Event"); } @@ -86,7 +87,7 @@ void AOC_U::CountAddOnContent(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - const auto current = Core::System::GetInstance().CurrentProcess()->GetTitleID(); + const auto current = system.CurrentProcess()->GetTitleID(); const auto& disabled = Settings::values.disabled_addons[current]; if (std::find(disabled.begin(), disabled.end(), "DLC") != disabled.end()) { @@ -113,7 +114,7 @@ void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_AOC, "called with offset={}, count={}, process_id={}", offset, count, process_id); - const auto current = Core::System::GetInstance().CurrentProcess()->GetTitleID(); + const auto current = system.CurrentProcess()->GetTitleID(); std::vector<u32> out; const auto& disabled = Settings::values.disabled_addons[current]; @@ -159,7 +160,7 @@ void AOC_U::GetAddOnContentBaseId(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); - const auto title_id = Core::System::GetInstance().CurrentProcess()->GetTitleID(); + const auto title_id = system.CurrentProcess()->GetTitleID(); FileSys::PatchManager pm{title_id}; const auto res = pm.GetControlMetadata(); @@ -196,8 +197,8 @@ void AOC_U::GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx) { rb.PushCopyObjects(aoc_change_event.readable); } -void InstallInterfaces(SM::ServiceManager& service_manager) { - std::make_shared<AOC_U>()->InstallAsService(service_manager); +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { + std::make_shared<AOC_U>(system)->InstallAsService(service_manager); } } // namespace Service::AOC diff --git a/src/core/hle/service/aoc/aoc_u.h b/src/core/hle/service/aoc/aoc_u.h index 5effea730..848b2f416 100644 --- a/src/core/hle/service/aoc/aoc_u.h +++ b/src/core/hle/service/aoc/aoc_u.h @@ -14,7 +14,7 @@ namespace Service::AOC { class AOC_U final : public ServiceFramework<AOC_U> { public: - AOC_U(); + explicit AOC_U(Core::System& system); ~AOC_U() override; private: @@ -26,9 +26,10 @@ private: std::vector<u64> add_on_content; Kernel::EventPair aoc_change_event; + Core::System& system; }; /// Registers all AOC services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager); +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); } // namespace Service::AOC diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp index 3c7ca2c44..afce581e5 100644 --- a/src/core/hle/service/btdrv/btdrv.cpp +++ b/src/core/hle/service/btdrv/btdrv.cpp @@ -16,7 +16,7 @@ namespace Service::BtDrv { class Bt final : public ServiceFramework<Bt> { public: - explicit Bt() : ServiceFramework{"bt"} { + explicit Bt(Core::System& system) : ServiceFramework{"bt"} { // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "LeClientReadCharacteristic"}, @@ -33,7 +33,7 @@ public: // clang-format on RegisterHandlers(functions); - auto& kernel = Core::System::GetInstance().Kernel(); + auto& kernel = system.Kernel(); register_event = Kernel::WritableEvent::CreateEventPair( kernel, Kernel::ResetType::Automatic, "BT:RegisterEvent"); } @@ -163,9 +163,9 @@ public: } }; -void InstallInterfaces(SM::ServiceManager& sm) { +void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { std::make_shared<BtDrv>()->InstallAsService(sm); - std::make_shared<Bt>()->InstallAsService(sm); + std::make_shared<Bt>(system)->InstallAsService(sm); } } // namespace Service::BtDrv diff --git a/src/core/hle/service/btdrv/btdrv.h b/src/core/hle/service/btdrv/btdrv.h index 164e56f43..191410dbc 100644 --- a/src/core/hle/service/btdrv/btdrv.h +++ b/src/core/hle/service/btdrv/btdrv.h @@ -8,9 +8,13 @@ namespace Service::SM { class ServiceManager; } +namespace Core { +class System; +} + namespace Service::BtDrv { /// Registers all BtDrv services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& sm); +void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); } // namespace Service::BtDrv diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp index b439ee7ec..920fc6ff7 100644 --- a/src/core/hle/service/btm/btm.cpp +++ b/src/core/hle/service/btm/btm.cpp @@ -17,7 +17,7 @@ namespace Service::BTM { class IBtmUserCore final : public ServiceFramework<IBtmUserCore> { public: - explicit IBtmUserCore() : ServiceFramework{"IBtmUserCore"} { + explicit IBtmUserCore(Core::System& system) : ServiceFramework{"IBtmUserCore"} { // clang-format off static const FunctionInfo functions[] = { {0, &IBtmUserCore::AcquireBleScanEvent, "AcquireBleScanEvent"}, @@ -56,7 +56,7 @@ public: // clang-format on RegisterHandlers(functions); - auto& kernel = Core::System::GetInstance().Kernel(); + auto& kernel = system.Kernel(); scan_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic, "IBtmUserCore:ScanEvent"); connection_event = Kernel::WritableEvent::CreateEventPair( @@ -108,7 +108,7 @@ private: class BTM_USR final : public ServiceFramework<BTM_USR> { public: - explicit BTM_USR() : ServiceFramework{"btm:u"} { + explicit BTM_USR(Core::System& system) : ServiceFramework{"btm:u"}, system(system) { // clang-format off static const FunctionInfo functions[] = { {0, &BTM_USR::GetCore, "GetCore"}, @@ -123,8 +123,10 @@ private: IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<IBtmUserCore>(); + rb.PushIpcInterface<IBtmUserCore>(system); } + + Core::System& system; }; class BTM final : public ServiceFramework<BTM> { @@ -268,11 +270,11 @@ private: } }; -void InstallInterfaces(SM::ServiceManager& sm) { +void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { std::make_shared<BTM>()->InstallAsService(sm); std::make_shared<BTM_DBG>()->InstallAsService(sm); std::make_shared<BTM_SYS>()->InstallAsService(sm); - std::make_shared<BTM_USR>()->InstallAsService(sm); + std::make_shared<BTM_USR>(system)->InstallAsService(sm); } } // namespace Service::BTM diff --git a/src/core/hle/service/btm/btm.h b/src/core/hle/service/btm/btm.h index e6425a7e3..c6b878043 100644 --- a/src/core/hle/service/btm/btm.h +++ b/src/core/hle/service/btm/btm.h @@ -8,8 +8,12 @@ namespace Service::SM { class ServiceManager; } +namespace Core { +class System; +}; + namespace Service::BTM { -void InstallInterfaces(SM::ServiceManager& sm); +void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); } // namespace Service::BTM diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp index 01fa06ad3..b2ebf6240 100644 --- a/src/core/hle/service/fatal/fatal.cpp +++ b/src/core/hle/service/fatal/fatal.cpp @@ -20,8 +20,8 @@ namespace Service::Fatal { -Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) - : ServiceFramework(name), module(std::move(module)) {} +Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name) + : ServiceFramework(name), module(std::move(module)), system(system) {} Module::Interface::~Interface() = default; @@ -64,7 +64,8 @@ enum class FatalType : u32 { ErrorScreen = 2, }; -static void GenerateErrorReport(ResultCode error_code, const FatalInfo& info) { +static void GenerateErrorReport(Core::System& system, ResultCode error_code, + const FatalInfo& info) { const auto title_id = Core::CurrentProcess()->GetTitleID(); std::string crash_report = fmt::format( "Yuzu {}-{} crash report\n" @@ -101,18 +102,19 @@ static void GenerateErrorReport(ResultCode error_code, const FatalInfo& info) { LOG_ERROR(Service_Fatal, "{}", crash_report); - Core::System::GetInstance().GetReporter().SaveCrashReport( + system.GetReporter().SaveCrashReport( title_id, error_code, info.set_flags, info.program_entry_point, info.sp, info.pc, info.pstate, info.afsr0, info.afsr1, info.esr, info.far, info.registers, info.backtrace, info.backtrace_size, info.ArchAsString(), info.unk10); } -static void ThrowFatalError(ResultCode error_code, FatalType fatal_type, const FatalInfo& info) { +static void ThrowFatalError(Core::System& system, ResultCode error_code, FatalType fatal_type, + const FatalInfo& info) { LOG_ERROR(Service_Fatal, "Threw fatal error type {} with error code 0x{:X}", static_cast<u32>(fatal_type), error_code.raw); switch (fatal_type) { case FatalType::ErrorReportAndScreen: - GenerateErrorReport(error_code, info); + GenerateErrorReport(system, error_code, info); [[fallthrough]]; case FatalType::ErrorScreen: // Since we have no fatal:u error screen. We should just kill execution instead @@ -120,7 +122,7 @@ static void ThrowFatalError(ResultCode error_code, FatalType fatal_type, const F break; // Should not throw a fatal screen but should generate an error report case FatalType::ErrorReport: - GenerateErrorReport(error_code, info); + GenerateErrorReport(system, error_code, info); break; } } @@ -130,7 +132,7 @@ void Module::Interface::ThrowFatal(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto error_code = rp.Pop<ResultCode>(); - ThrowFatalError(error_code, FatalType::ErrorScreen, {}); + ThrowFatalError(system, error_code, FatalType::ErrorScreen, {}); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -141,7 +143,8 @@ void Module::Interface::ThrowFatalWithPolicy(Kernel::HLERequestContext& ctx) { const auto error_code = rp.Pop<ResultCode>(); const auto fatal_type = rp.PopEnum<FatalType>(); - ThrowFatalError(error_code, fatal_type, {}); // No info is passed with ThrowFatalWithPolicy + ThrowFatalError(system, error_code, fatal_type, + {}); // No info is passed with ThrowFatalWithPolicy IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -157,15 +160,15 @@ void Module::Interface::ThrowFatalWithCpuContext(Kernel::HLERequestContext& ctx) ASSERT_MSG(fatal_info.size() == sizeof(FatalInfo), "Invalid fatal info buffer size!"); std::memcpy(&info, fatal_info.data(), sizeof(FatalInfo)); - ThrowFatalError(error_code, fatal_type, info); + ThrowFatalError(system, error_code, fatal_type, info); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } -void InstallInterfaces(SM::ServiceManager& service_manager) { +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { auto module = std::make_shared<Module>(); - std::make_shared<Fatal_P>(module)->InstallAsService(service_manager); - std::make_shared<Fatal_U>(module)->InstallAsService(service_manager); + std::make_shared<Fatal_P>(module, system)->InstallAsService(service_manager); + std::make_shared<Fatal_U>(module, system)->InstallAsService(service_manager); } } // namespace Service::Fatal diff --git a/src/core/hle/service/fatal/fatal.h b/src/core/hle/service/fatal/fatal.h index 09371ff7f..bd9339dfc 100644 --- a/src/core/hle/service/fatal/fatal.h +++ b/src/core/hle/service/fatal/fatal.h @@ -6,13 +6,17 @@ #include "core/hle/service/service.h" +namespace Core { +class System; +} + namespace Service::Fatal { class Module final { public: class Interface : public ServiceFramework<Interface> { public: - explicit Interface(std::shared_ptr<Module> module, const char* name); + explicit Interface(std::shared_ptr<Module> module, Core::System& system, const char* name); ~Interface() override; void ThrowFatal(Kernel::HLERequestContext& ctx); @@ -21,9 +25,10 @@ public: protected: std::shared_ptr<Module> module; + Core::System& system; }; }; -void InstallInterfaces(SM::ServiceManager& service_manager); +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); } // namespace Service::Fatal diff --git a/src/core/hle/service/fatal/fatal_p.cpp b/src/core/hle/service/fatal/fatal_p.cpp index 9e5f872ff..066ccf6b0 100644 --- a/src/core/hle/service/fatal/fatal_p.cpp +++ b/src/core/hle/service/fatal/fatal_p.cpp @@ -6,8 +6,8 @@ namespace Service::Fatal { -Fatal_P::Fatal_P(std::shared_ptr<Module> module) - : Module::Interface(std::move(module), "fatal:p") {} +Fatal_P::Fatal_P(std::shared_ptr<Module> module, Core::System& system) + : Module::Interface(std::move(module), system, "fatal:p") {} Fatal_P::~Fatal_P() = default; diff --git a/src/core/hle/service/fatal/fatal_p.h b/src/core/hle/service/fatal/fatal_p.h index 6e9c5979f..c6d953cb5 100644 --- a/src/core/hle/service/fatal/fatal_p.h +++ b/src/core/hle/service/fatal/fatal_p.h @@ -10,7 +10,7 @@ namespace Service::Fatal { class Fatal_P final : public Module::Interface { public: - explicit Fatal_P(std::shared_ptr<Module> module); + explicit Fatal_P(std::shared_ptr<Module> module, Core::System& system); ~Fatal_P() override; }; diff --git a/src/core/hle/service/fatal/fatal_u.cpp b/src/core/hle/service/fatal/fatal_u.cpp index 1572a2051..8d72ed485 100644 --- a/src/core/hle/service/fatal/fatal_u.cpp +++ b/src/core/hle/service/fatal/fatal_u.cpp @@ -6,7 +6,8 @@ namespace Service::Fatal { -Fatal_U::Fatal_U(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "fatal:u") { +Fatal_U::Fatal_U(std::shared_ptr<Module> module, Core::System& system) + : Module::Interface(std::move(module), system, "fatal:u") { static const FunctionInfo functions[] = { {0, &Fatal_U::ThrowFatal, "ThrowFatal"}, {1, &Fatal_U::ThrowFatalWithPolicy, "ThrowFatalWithPolicy"}, diff --git a/src/core/hle/service/fatal/fatal_u.h b/src/core/hle/service/fatal/fatal_u.h index 72cb6d076..34c5c7f95 100644 --- a/src/core/hle/service/fatal/fatal_u.h +++ b/src/core/hle/service/fatal/fatal_u.h @@ -10,7 +10,7 @@ namespace Service::Fatal { class Fatal_U final : public Module::Interface { public: - explicit Fatal_U(std::shared_ptr<Module> module); + explicit Fatal_U(std::shared_ptr<Module> module, Core::System& system); ~Fatal_U() override; }; diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 8ce110dd1..14cd0e322 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -8,6 +8,7 @@ #include "common/file_util.h" #include "core/core.h" #include "core/file_sys/bis_factory.h" +#include "core/file_sys/card_image.h" #include "core/file_sys/control_metadata.h" #include "core/file_sys/errors.h" #include "core/file_sys/mode.h" @@ -25,14 +26,10 @@ #include "core/hle/service/filesystem/fsp_pr.h" #include "core/hle/service/filesystem/fsp_srv.h" #include "core/loader/loader.h" +#include "core/settings.h" namespace Service::FileSystem { -// Size of emulated sd card free space, reported in bytes. -// Just using 32GB because thats reasonable -// TODO(DarkLordZach): Eventually make this configurable in settings. -constexpr u64 EMULATED_SD_REPORTED_SIZE = 32000000000; - // A default size for normal/journal save data size if application control metadata cannot be found. // This should be large enough to satisfy even the most extreme requirements (~4.2GB) constexpr u64 SUFFICIENT_SAVE_DATA_SIZE = 0xF0000000; @@ -226,13 +223,6 @@ ResultVal<FileSys::VirtualDir> VfsDirectoryServiceWrapper::OpenDirectory(const s return MakeResult(dir); } -u64 VfsDirectoryServiceWrapper::GetFreeSpaceSize() const { - if (backing->IsWritable()) - return EMULATED_SD_REPORTED_SIZE; - - return 0; -} - ResultVal<FileSys::EntryType> VfsDirectoryServiceWrapper::GetEntryType( const std::string& path_) const { std::string path(FileUtil::SanitizePath(path_)); @@ -251,44 +241,39 @@ ResultVal<FileSys::EntryType> VfsDirectoryServiceWrapper::GetEntryType( return FileSys::ERROR_PATH_NOT_FOUND; } -/** - * Map of registered file systems, identified by type. Once an file system is registered here, it - * is never removed until UnregisterFileSystems is called. - */ -static std::unique_ptr<FileSys::RomFSFactory> romfs_factory; -static std::unique_ptr<FileSys::SaveDataFactory> save_data_factory; -static std::unique_ptr<FileSys::SDMCFactory> sdmc_factory; -static std::unique_ptr<FileSys::BISFactory> bis_factory; +FileSystemController::FileSystemController() = default; + +FileSystemController::~FileSystemController() = default; -ResultCode RegisterRomFS(std::unique_ptr<FileSys::RomFSFactory>&& factory) { - ASSERT_MSG(romfs_factory == nullptr, "Tried to register a second RomFS"); +ResultCode FileSystemController::RegisterRomFS(std::unique_ptr<FileSys::RomFSFactory>&& factory) { romfs_factory = std::move(factory); LOG_DEBUG(Service_FS, "Registered RomFS"); return RESULT_SUCCESS; } -ResultCode RegisterSaveData(std::unique_ptr<FileSys::SaveDataFactory>&& factory) { - ASSERT_MSG(romfs_factory == nullptr, "Tried to register a second save data"); +ResultCode FileSystemController::RegisterSaveData( + std::unique_ptr<FileSys::SaveDataFactory>&& factory) { + ASSERT_MSG(save_data_factory == nullptr, "Tried to register a second save data"); save_data_factory = std::move(factory); LOG_DEBUG(Service_FS, "Registered save data"); return RESULT_SUCCESS; } -ResultCode RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory) { +ResultCode FileSystemController::RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory) { ASSERT_MSG(sdmc_factory == nullptr, "Tried to register a second SDMC"); sdmc_factory = std::move(factory); LOG_DEBUG(Service_FS, "Registered SDMC"); return RESULT_SUCCESS; } -ResultCode RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory) { +ResultCode FileSystemController::RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory) { ASSERT_MSG(bis_factory == nullptr, "Tried to register a second BIS"); bis_factory = std::move(factory); LOG_DEBUG(Service_FS, "Registered BIS"); return RESULT_SUCCESS; } -void SetPackedUpdate(FileSys::VirtualFile update_raw) { +void FileSystemController::SetPackedUpdate(FileSys::VirtualFile update_raw) { LOG_TRACE(Service_FS, "Setting packed update for romfs"); if (romfs_factory == nullptr) @@ -297,7 +282,7 @@ void SetPackedUpdate(FileSys::VirtualFile update_raw) { romfs_factory->SetPackedUpdate(std::move(update_raw)); } -ResultVal<FileSys::VirtualFile> OpenRomFSCurrentProcess() { +ResultVal<FileSys::VirtualFile> FileSystemController::OpenRomFSCurrentProcess() const { LOG_TRACE(Service_FS, "Opening RomFS for current process"); if (romfs_factory == nullptr) { @@ -308,8 +293,8 @@ ResultVal<FileSys::VirtualFile> OpenRomFSCurrentProcess() { return romfs_factory->OpenCurrentProcess(); } -ResultVal<FileSys::VirtualFile> OpenRomFS(u64 title_id, FileSys::StorageId storage_id, - FileSys::ContentRecordType type) { +ResultVal<FileSys::VirtualFile> FileSystemController::OpenRomFS( + u64 title_id, FileSys::StorageId storage_id, FileSys::ContentRecordType type) const { LOG_TRACE(Service_FS, "Opening RomFS for title_id={:016X}, storage_id={:02X}, type={:02X}", title_id, static_cast<u8>(storage_id), static_cast<u8>(type)); @@ -321,8 +306,20 @@ ResultVal<FileSys::VirtualFile> OpenRomFS(u64 title_id, FileSys::StorageId stora return romfs_factory->Open(title_id, storage_id, type); } -ResultVal<FileSys::VirtualDir> OpenSaveData(FileSys::SaveDataSpaceId space, - const FileSys::SaveDataDescriptor& descriptor) { +ResultVal<FileSys::VirtualDir> FileSystemController::CreateSaveData( + FileSys::SaveDataSpaceId space, const FileSys::SaveDataDescriptor& save_struct) const { + LOG_TRACE(Service_FS, "Creating Save Data for space_id={:01X}, save_struct={}", + static_cast<u8>(space), save_struct.DebugInfo()); + + if (save_data_factory == nullptr) { + return FileSys::ERROR_ENTITY_NOT_FOUND; + } + + return save_data_factory->Create(space, save_struct); +} + +ResultVal<FileSys::VirtualDir> FileSystemController::OpenSaveData( + FileSys::SaveDataSpaceId space, const FileSys::SaveDataDescriptor& descriptor) const { LOG_TRACE(Service_FS, "Opening Save Data for space_id={:01X}, save_struct={}", static_cast<u8>(space), descriptor.DebugInfo()); @@ -333,7 +330,8 @@ ResultVal<FileSys::VirtualDir> OpenSaveData(FileSys::SaveDataSpaceId space, return save_data_factory->Open(space, descriptor); } -ResultVal<FileSys::VirtualDir> OpenSaveDataSpace(FileSys::SaveDataSpaceId space) { +ResultVal<FileSys::VirtualDir> FileSystemController::OpenSaveDataSpace( + FileSys::SaveDataSpaceId space) const { LOG_TRACE(Service_FS, "Opening Save Data Space for space_id={:01X}", static_cast<u8>(space)); if (save_data_factory == nullptr) { @@ -343,7 +341,7 @@ ResultVal<FileSys::VirtualDir> OpenSaveDataSpace(FileSys::SaveDataSpaceId space) return MakeResult(save_data_factory->GetSaveDataSpaceDirectory(space)); } -ResultVal<FileSys::VirtualDir> OpenSDMC() { +ResultVal<FileSys::VirtualDir> FileSystemController::OpenSDMC() const { LOG_TRACE(Service_FS, "Opening SDMC"); if (sdmc_factory == nullptr) { @@ -353,7 +351,92 @@ ResultVal<FileSys::VirtualDir> OpenSDMC() { return sdmc_factory->Open(); } -FileSys::SaveDataSize ReadSaveDataSize(FileSys::SaveDataType type, u64 title_id, u128 user_id) { +ResultVal<FileSys::VirtualDir> FileSystemController::OpenBISPartition( + FileSys::BisPartitionId id) const { + LOG_TRACE(Service_FS, "Opening BIS Partition with id={:08X}", static_cast<u32>(id)); + + if (bis_factory == nullptr) { + return FileSys::ERROR_ENTITY_NOT_FOUND; + } + + auto part = bis_factory->OpenPartition(id); + if (part == nullptr) { + return FileSys::ERROR_INVALID_ARGUMENT; + } + + return MakeResult<FileSys::VirtualDir>(std::move(part)); +} + +ResultVal<FileSys::VirtualFile> FileSystemController::OpenBISPartitionStorage( + FileSys::BisPartitionId id) const { + LOG_TRACE(Service_FS, "Opening BIS Partition Storage with id={:08X}", static_cast<u32>(id)); + + if (bis_factory == nullptr) { + return FileSys::ERROR_ENTITY_NOT_FOUND; + } + + auto part = bis_factory->OpenPartitionStorage(id); + if (part == nullptr) { + return FileSys::ERROR_INVALID_ARGUMENT; + } + + return MakeResult<FileSys::VirtualFile>(std::move(part)); +} + +u64 FileSystemController::GetFreeSpaceSize(FileSys::StorageId id) const { + switch (id) { + case FileSys::StorageId::None: + case FileSys::StorageId::GameCard: + return 0; + case FileSys::StorageId::SdCard: + if (sdmc_factory == nullptr) + return 0; + return sdmc_factory->GetSDMCFreeSpace(); + case FileSys::StorageId::Host: + if (bis_factory == nullptr) + return 0; + return bis_factory->GetSystemNANDFreeSpace() + bis_factory->GetUserNANDFreeSpace(); + case FileSys::StorageId::NandSystem: + if (bis_factory == nullptr) + return 0; + return bis_factory->GetSystemNANDFreeSpace(); + case FileSys::StorageId::NandUser: + if (bis_factory == nullptr) + return 0; + return bis_factory->GetUserNANDFreeSpace(); + } + + return 0; +} + +u64 FileSystemController::GetTotalSpaceSize(FileSys::StorageId id) const { + switch (id) { + case FileSys::StorageId::None: + case FileSys::StorageId::GameCard: + return 0; + case FileSys::StorageId::SdCard: + if (sdmc_factory == nullptr) + return 0; + return sdmc_factory->GetSDMCTotalSpace(); + case FileSys::StorageId::Host: + if (bis_factory == nullptr) + return 0; + return bis_factory->GetFullNANDTotalSpace(); + case FileSys::StorageId::NandSystem: + if (bis_factory == nullptr) + return 0; + return bis_factory->GetSystemNANDTotalSpace(); + case FileSys::StorageId::NandUser: + if (bis_factory == nullptr) + return 0; + return bis_factory->GetUserNANDTotalSpace(); + } + + return 0; +} + +FileSys::SaveDataSize FileSystemController::ReadSaveDataSize(FileSys::SaveDataType type, + u64 title_id, u128 user_id) const { if (save_data_factory == nullptr) { return {0, 0}; } @@ -385,13 +468,32 @@ FileSys::SaveDataSize ReadSaveDataSize(FileSys::SaveDataType type, u64 title_id, return value; } -void WriteSaveDataSize(FileSys::SaveDataType type, u64 title_id, u128 user_id, - FileSys::SaveDataSize new_value) { +void FileSystemController::WriteSaveDataSize(FileSys::SaveDataType type, u64 title_id, u128 user_id, + FileSys::SaveDataSize new_value) const { if (save_data_factory != nullptr) save_data_factory->WriteSaveDataSize(type, title_id, user_id, new_value); } -FileSys::RegisteredCache* GetSystemNANDContents() { +void FileSystemController::SetGameCard(FileSys::VirtualFile file) { + gamecard = std::make_unique<FileSys::XCI>(file); + const auto dir = gamecard->ConcatenatedPseudoDirectory(); + gamecard_registered = std::make_unique<FileSys::RegisteredCache>(dir); + gamecard_placeholder = std::make_unique<FileSys::PlaceholderCache>(dir); +} + +FileSys::XCI* FileSystemController::GetGameCard() const { + return gamecard.get(); +} + +FileSys::RegisteredCache* FileSystemController::GetGameCardContents() const { + return gamecard_registered.get(); +} + +FileSys::PlaceholderCache* FileSystemController::GetGameCardPlaceholder() const { + return gamecard_placeholder.get(); +} + +FileSys::RegisteredCache* FileSystemController::GetSystemNANDContents() const { LOG_TRACE(Service_FS, "Opening System NAND Contents"); if (bis_factory == nullptr) @@ -400,7 +502,7 @@ FileSys::RegisteredCache* GetSystemNANDContents() { return bis_factory->GetSystemNANDContents(); } -FileSys::RegisteredCache* GetUserNANDContents() { +FileSys::RegisteredCache* FileSystemController::GetUserNANDContents() const { LOG_TRACE(Service_FS, "Opening User NAND Contents"); if (bis_factory == nullptr) @@ -409,7 +511,7 @@ FileSys::RegisteredCache* GetUserNANDContents() { return bis_factory->GetUserNANDContents(); } -FileSys::RegisteredCache* GetSDMCContents() { +FileSys::RegisteredCache* FileSystemController::GetSDMCContents() const { LOG_TRACE(Service_FS, "Opening SDMC Contents"); if (sdmc_factory == nullptr) @@ -418,7 +520,143 @@ FileSys::RegisteredCache* GetSDMCContents() { return sdmc_factory->GetSDMCContents(); } -FileSys::VirtualDir GetModificationLoadRoot(u64 title_id) { +FileSys::PlaceholderCache* FileSystemController::GetSystemNANDPlaceholder() const { + LOG_TRACE(Service_FS, "Opening System NAND Placeholder"); + + if (bis_factory == nullptr) + return nullptr; + + return bis_factory->GetSystemNANDPlaceholder(); +} + +FileSys::PlaceholderCache* FileSystemController::GetUserNANDPlaceholder() const { + LOG_TRACE(Service_FS, "Opening User NAND Placeholder"); + + if (bis_factory == nullptr) + return nullptr; + + return bis_factory->GetUserNANDPlaceholder(); +} + +FileSys::PlaceholderCache* FileSystemController::GetSDMCPlaceholder() const { + LOG_TRACE(Service_FS, "Opening SDMC Placeholder"); + + if (sdmc_factory == nullptr) + return nullptr; + + return sdmc_factory->GetSDMCPlaceholder(); +} + +FileSys::RegisteredCache* FileSystemController::GetRegisteredCacheForStorage( + FileSys::StorageId id) const { + switch (id) { + case FileSys::StorageId::None: + case FileSys::StorageId::Host: + UNIMPLEMENTED(); + return nullptr; + case FileSys::StorageId::GameCard: + return GetGameCardContents(); + case FileSys::StorageId::NandSystem: + return GetSystemNANDContents(); + case FileSys::StorageId::NandUser: + return GetUserNANDContents(); + case FileSys::StorageId::SdCard: + return GetSDMCContents(); + } + + return nullptr; +} + +FileSys::PlaceholderCache* FileSystemController::GetPlaceholderCacheForStorage( + FileSys::StorageId id) const { + switch (id) { + case FileSys::StorageId::None: + case FileSys::StorageId::Host: + UNIMPLEMENTED(); + return nullptr; + case FileSys::StorageId::GameCard: + return GetGameCardPlaceholder(); + case FileSys::StorageId::NandSystem: + return GetSystemNANDPlaceholder(); + case FileSys::StorageId::NandUser: + return GetUserNANDPlaceholder(); + case FileSys::StorageId::SdCard: + return GetSDMCPlaceholder(); + } + + return nullptr; +} + +FileSys::VirtualDir FileSystemController::GetSystemNANDContentDirectory() const { + LOG_TRACE(Service_FS, "Opening system NAND content directory"); + + if (bis_factory == nullptr) + return nullptr; + + return bis_factory->GetSystemNANDContentDirectory(); +} + +FileSys::VirtualDir FileSystemController::GetUserNANDContentDirectory() const { + LOG_TRACE(Service_FS, "Opening user NAND content directory"); + + if (bis_factory == nullptr) + return nullptr; + + return bis_factory->GetUserNANDContentDirectory(); +} + +FileSys::VirtualDir FileSystemController::GetSDMCContentDirectory() const { + LOG_TRACE(Service_FS, "Opening SDMC content directory"); + + if (sdmc_factory == nullptr) + return nullptr; + + return sdmc_factory->GetSDMCContentDirectory(); +} + +FileSys::VirtualDir FileSystemController::GetNANDImageDirectory() const { + LOG_TRACE(Service_FS, "Opening NAND image directory"); + + if (bis_factory == nullptr) + return nullptr; + + return bis_factory->GetImageDirectory(); +} + +FileSys::VirtualDir FileSystemController::GetSDMCImageDirectory() const { + LOG_TRACE(Service_FS, "Opening SDMC image directory"); + + if (sdmc_factory == nullptr) + return nullptr; + + return sdmc_factory->GetImageDirectory(); +} + +FileSys::VirtualDir FileSystemController::GetContentDirectory(ContentStorageId id) const { + switch (id) { + case ContentStorageId::System: + return GetSystemNANDContentDirectory(); + case ContentStorageId::User: + return GetUserNANDContentDirectory(); + case ContentStorageId::SdCard: + return GetSDMCContentDirectory(); + } + + return nullptr; +} + +FileSys::VirtualDir FileSystemController::GetImageDirectory(ImageDirectoryId id) const { + switch (id) { + case ImageDirectoryId::NAND: + return GetNANDImageDirectory(); + case ImageDirectoryId::SdCard: + return GetSDMCImageDirectory(); + } + + return nullptr; +} + +FileSys::VirtualDir FileSystemController::GetModificationLoadRoot(u64 title_id) const { LOG_TRACE(Service_FS, "Opening mod load root for tid={:016X}", title_id); if (bis_factory == nullptr) @@ -427,7 +665,7 @@ FileSys::VirtualDir GetModificationLoadRoot(u64 title_id) { return bis_factory->GetModificationLoadRoot(title_id); } -FileSys::VirtualDir GetModificationDumpRoot(u64 title_id) { +FileSys::VirtualDir FileSystemController::GetModificationDumpRoot(u64 title_id) const { LOG_TRACE(Service_FS, "Opening mod dump root for tid={:016X}", title_id); if (bis_factory == nullptr) @@ -436,7 +674,7 @@ FileSys::VirtualDir GetModificationDumpRoot(u64 title_id) { return bis_factory->GetModificationDumpRoot(title_id); } -void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite) { +void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite) { if (overwrite) { bis_factory = nullptr; save_data_factory = nullptr; @@ -473,11 +711,10 @@ void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite) { } void InstallInterfaces(Core::System& system) { - romfs_factory = nullptr; - CreateFactories(*system.GetFilesystem(), false); std::make_shared<FSP_LDR>()->InstallAsService(system.ServiceManager()); std::make_shared<FSP_PR>()->InstallAsService(system.ServiceManager()); - std::make_shared<FSP_SRV>(system.GetReporter())->InstallAsService(system.ServiceManager()); + std::make_shared<FSP_SRV>(system.GetFileSystemController(), system.GetReporter()) + ->InstallAsService(system.ServiceManager()); } } // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h index 3849dd89e..3e0c03ec0 100644 --- a/src/core/hle/service/filesystem/filesystem.h +++ b/src/core/hle/service/filesystem/filesystem.h @@ -14,10 +14,13 @@ namespace FileSys { class BISFactory; class RegisteredCache; class RegisteredCacheUnion; +class PlaceholderCache; class RomFSFactory; class SaveDataFactory; class SDMCFactory; +class XCI; +enum class BisPartitionId : u32; enum class ContentRecordType : u8; enum class Mode : u32; enum class SaveDataSpaceId : u8; @@ -36,34 +39,91 @@ class ServiceManager; namespace FileSystem { -ResultCode RegisterRomFS(std::unique_ptr<FileSys::RomFSFactory>&& factory); -ResultCode RegisterSaveData(std::unique_ptr<FileSys::SaveDataFactory>&& factory); -ResultCode RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory); -ResultCode RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory); - -void SetPackedUpdate(FileSys::VirtualFile update_raw); -ResultVal<FileSys::VirtualFile> OpenRomFSCurrentProcess(); -ResultVal<FileSys::VirtualFile> OpenRomFS(u64 title_id, FileSys::StorageId storage_id, - FileSys::ContentRecordType type); -ResultVal<FileSys::VirtualDir> OpenSaveData(FileSys::SaveDataSpaceId space, - const FileSys::SaveDataDescriptor& descriptor); -ResultVal<FileSys::VirtualDir> OpenSaveDataSpace(FileSys::SaveDataSpaceId space); -ResultVal<FileSys::VirtualDir> OpenSDMC(); - -FileSys::SaveDataSize ReadSaveDataSize(FileSys::SaveDataType type, u64 title_id, u128 user_id); -void WriteSaveDataSize(FileSys::SaveDataType type, u64 title_id, u128 user_id, - FileSys::SaveDataSize new_value); +enum class ContentStorageId : u32 { + System, + User, + SdCard, +}; -FileSys::RegisteredCache* GetSystemNANDContents(); -FileSys::RegisteredCache* GetUserNANDContents(); -FileSys::RegisteredCache* GetSDMCContents(); +enum class ImageDirectoryId : u32 { + NAND, + SdCard, +}; -FileSys::VirtualDir GetModificationLoadRoot(u64 title_id); -FileSys::VirtualDir GetModificationDumpRoot(u64 title_id); +class FileSystemController { +public: + FileSystemController(); + ~FileSystemController(); + + ResultCode RegisterRomFS(std::unique_ptr<FileSys::RomFSFactory>&& factory); + ResultCode RegisterSaveData(std::unique_ptr<FileSys::SaveDataFactory>&& factory); + ResultCode RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory); + ResultCode RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory); + + void SetPackedUpdate(FileSys::VirtualFile update_raw); + ResultVal<FileSys::VirtualFile> OpenRomFSCurrentProcess() const; + ResultVal<FileSys::VirtualFile> OpenRomFS(u64 title_id, FileSys::StorageId storage_id, + FileSys::ContentRecordType type) const; + ResultVal<FileSys::VirtualDir> CreateSaveData( + FileSys::SaveDataSpaceId space, const FileSys::SaveDataDescriptor& save_struct) const; + ResultVal<FileSys::VirtualDir> OpenSaveData( + FileSys::SaveDataSpaceId space, const FileSys::SaveDataDescriptor& save_struct) const; + ResultVal<FileSys::VirtualDir> OpenSaveDataSpace(FileSys::SaveDataSpaceId space) const; + ResultVal<FileSys::VirtualDir> OpenSDMC() const; + ResultVal<FileSys::VirtualDir> OpenBISPartition(FileSys::BisPartitionId id) const; + ResultVal<FileSys::VirtualFile> OpenBISPartitionStorage(FileSys::BisPartitionId id) const; + + u64 GetFreeSpaceSize(FileSys::StorageId id) const; + u64 GetTotalSpaceSize(FileSys::StorageId id) const; + + FileSys::SaveDataSize ReadSaveDataSize(FileSys::SaveDataType type, u64 title_id, + u128 user_id) const; + void WriteSaveDataSize(FileSys::SaveDataType type, u64 title_id, u128 user_id, + FileSys::SaveDataSize new_value) const; + + void SetGameCard(FileSys::VirtualFile file); + FileSys::XCI* GetGameCard() const; + + FileSys::RegisteredCache* GetSystemNANDContents() const; + FileSys::RegisteredCache* GetUserNANDContents() const; + FileSys::RegisteredCache* GetSDMCContents() const; + FileSys::RegisteredCache* GetGameCardContents() const; + + FileSys::PlaceholderCache* GetSystemNANDPlaceholder() const; + FileSys::PlaceholderCache* GetUserNANDPlaceholder() const; + FileSys::PlaceholderCache* GetSDMCPlaceholder() const; + FileSys::PlaceholderCache* GetGameCardPlaceholder() const; + + FileSys::RegisteredCache* GetRegisteredCacheForStorage(FileSys::StorageId id) const; + FileSys::PlaceholderCache* GetPlaceholderCacheForStorage(FileSys::StorageId id) const; + + FileSys::VirtualDir GetSystemNANDContentDirectory() const; + FileSys::VirtualDir GetUserNANDContentDirectory() const; + FileSys::VirtualDir GetSDMCContentDirectory() const; + + FileSys::VirtualDir GetNANDImageDirectory() const; + FileSys::VirtualDir GetSDMCImageDirectory() const; + + FileSys::VirtualDir GetContentDirectory(ContentStorageId id) const; + FileSys::VirtualDir GetImageDirectory(ImageDirectoryId id) const; + + FileSys::VirtualDir GetModificationLoadRoot(u64 title_id) const; + FileSys::VirtualDir GetModificationDumpRoot(u64 title_id) const; + + // Creates the SaveData, SDMC, and BIS Factories. Should be called once and before any function + // above is called. + void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite = true); -// Creates the SaveData, SDMC, and BIS Factories. Should be called once and before any function -// above is called. -void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite = true); +private: + std::unique_ptr<FileSys::RomFSFactory> romfs_factory; + std::unique_ptr<FileSys::SaveDataFactory> save_data_factory; + std::unique_ptr<FileSys::SDMCFactory> sdmc_factory; + std::unique_ptr<FileSys::BISFactory> bis_factory; + + std::unique_ptr<FileSys::XCI> gamecard; + std::unique_ptr<FileSys::RegisteredCache> gamecard_registered; + std::unique_ptr<FileSys::PlaceholderCache> gamecard_placeholder; +}; void InstallInterfaces(Core::System& system); @@ -160,12 +220,6 @@ public: ResultVal<FileSys::VirtualDir> OpenDirectory(const std::string& path); /** - * Get the free space - * @return The number of free bytes in the archive - */ - u64 GetFreeSpaceSize() const; - - /** * Get the type of the specified path * @return The type of the specified path or error code */ diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index d3cd46a9b..eb982ad49 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -19,6 +19,7 @@ #include "core/file_sys/mode.h" #include "core/file_sys/nca_metadata.h" #include "core/file_sys/patch_manager.h" +#include "core/file_sys/romfs_factory.h" #include "core/file_sys/savedata_factory.h" #include "core/file_sys/system_archive/system_archive.h" #include "core/file_sys/vfs.h" @@ -30,6 +31,18 @@ namespace Service::FileSystem { +struct SizeGetter { + std::function<u64()> get_free_size; + std::function<u64()> get_total_size; + + static SizeGetter FromStorageId(const FileSystemController& fsc, FileSys::StorageId id) { + return { + [&fsc, id] { return fsc.GetFreeSpaceSize(id); }, + [&fsc, id] { return fsc.GetTotalSpaceSize(id); }, + }; + } +}; + enum class FileSystemType : u8 { Invalid0 = 0, Invalid1 = 1, @@ -289,8 +302,8 @@ private: class IFileSystem final : public ServiceFramework<IFileSystem> { public: - explicit IFileSystem(FileSys::VirtualDir backend) - : ServiceFramework("IFileSystem"), backend(std::move(backend)) { + explicit IFileSystem(FileSys::VirtualDir backend, SizeGetter size) + : ServiceFramework("IFileSystem"), backend(std::move(backend)), size(std::move(size)) { static const FunctionInfo functions[] = { {0, &IFileSystem::CreateFile, "CreateFile"}, {1, &IFileSystem::DeleteFile, "DeleteFile"}, @@ -467,14 +480,31 @@ public: rb.Push(RESULT_SUCCESS); } + void GetFreeSpaceSize(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_FS, "called"); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(RESULT_SUCCESS); + rb.Push(size.get_free_size()); + } + + void GetTotalSpaceSize(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_FS, "called"); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(RESULT_SUCCESS); + rb.Push(size.get_total_size()); + } + private: VfsDirectoryServiceWrapper backend; + SizeGetter size; }; class ISaveDataInfoReader final : public ServiceFramework<ISaveDataInfoReader> { public: - explicit ISaveDataInfoReader(FileSys::SaveDataSpaceId space) - : ServiceFramework("ISaveDataInfoReader") { + explicit ISaveDataInfoReader(FileSys::SaveDataSpaceId space, FileSystemController& fsc) + : ServiceFramework("ISaveDataInfoReader"), fsc(fsc) { static const FunctionInfo functions[] = { {0, &ISaveDataInfoReader::ReadSaveDataInfo, "ReadSaveDataInfo"}, }; @@ -520,8 +550,13 @@ private: } void FindAllSaves(FileSys::SaveDataSpaceId space) { - const auto save_root = OpenSaveDataSpace(space); - ASSERT(save_root.Succeeded()); + const auto save_root = fsc.OpenSaveDataSpace(space); + + if (save_root.Failed() || *save_root == nullptr) { + LOG_ERROR(Service_FS, "The save root for the space_id={:02X} was invalid!", + static_cast<u8>(space)); + return; + } for (const auto& type : (*save_root)->GetSubdirectories()) { if (type->GetName() == "save") { @@ -610,11 +645,13 @@ private: }; static_assert(sizeof(SaveDataInfo) == 0x60, "SaveDataInfo has incorrect size."); + FileSystemController& fsc; std::vector<SaveDataInfo> info; u64 next_entry_index = 0; }; -FSP_SRV::FSP_SRV(const Core::Reporter& reporter) : ServiceFramework("fsp-srv"), reporter(reporter) { +FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter) + : ServiceFramework("fsp-srv"), fsc(fsc), reporter(reporter) { // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "OpenFileSystem"}, @@ -754,7 +791,8 @@ void FSP_SRV::OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx) { void FSP_SRV::OpenSdCardFileSystem(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_FS, "called"); - IFileSystem filesystem(OpenSDMC().Unwrap()); + IFileSystem filesystem(fsc.OpenSDMC().Unwrap(), + SizeGetter::FromStorageId(fsc, FileSys::StorageId::SdCard)); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -768,8 +806,10 @@ void FSP_SRV::CreateSaveDataFileSystem(Kernel::HLERequestContext& ctx) { auto save_create_struct = rp.PopRaw<std::array<u8, 0x40>>(); u128 uid = rp.PopRaw<u128>(); - LOG_WARNING(Service_FS, "(STUBBED) called save_struct = {}, uid = {:016X}{:016X}", - save_struct.DebugInfo(), uid[1], uid[0]); + LOG_DEBUG(Service_FS, "called save_struct = {}, uid = {:016X}{:016X}", save_struct.DebugInfo(), + uid[1], uid[0]); + + fsc.CreateSaveData(FileSys::SaveDataSpaceId::NandUser, save_struct); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); @@ -786,14 +826,24 @@ void FSP_SRV::OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto parameters = rp.PopRaw<Parameters>(); - auto dir = OpenSaveData(parameters.save_data_space_id, parameters.descriptor); + auto dir = fsc.OpenSaveData(parameters.save_data_space_id, parameters.descriptor); if (dir.Failed()) { IPC::ResponseBuilder rb{ctx, 2, 0, 0}; rb.Push(FileSys::ERROR_ENTITY_NOT_FOUND); return; } - IFileSystem filesystem(std::move(dir.Unwrap())); + FileSys::StorageId id; + if (parameters.save_data_space_id == FileSys::SaveDataSpaceId::NandUser) { + id = FileSys::StorageId::NandUser; + } else if (parameters.save_data_space_id == FileSys::SaveDataSpaceId::SdCardSystem || + parameters.save_data_space_id == FileSys::SaveDataSpaceId::SdCardUser) { + id = FileSys::StorageId::SdCard; + } else { + id = FileSys::StorageId::NandSystem; + } + + IFileSystem filesystem(std::move(dir.Unwrap()), SizeGetter::FromStorageId(fsc, id)); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -812,7 +862,7 @@ void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<ISaveDataInfoReader>(std::make_shared<ISaveDataInfoReader>(space)); + rb.PushIpcInterface<ISaveDataInfoReader>(std::make_shared<ISaveDataInfoReader>(space, fsc)); } void FSP_SRV::SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { @@ -836,7 +886,7 @@ void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_FS, "called"); - auto romfs = OpenRomFSCurrentProcess(); + auto romfs = fsc.OpenRomFSCurrentProcess(); if (romfs.Failed()) { // TODO (bunnei): Find the right error code to use here LOG_CRITICAL(Service_FS, "no file system interface available!"); @@ -861,7 +911,7 @@ void FSP_SRV::OpenDataStorageByDataId(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_FS, "called with storage_id={:02X}, unknown={:08X}, title_id={:016X}", static_cast<u8>(storage_id), unknown, title_id); - auto data = OpenRomFS(title_id, storage_id, FileSys::ContentRecordType::Data); + auto data = fsc.OpenRomFS(title_id, storage_id, FileSys::ContentRecordType::Data); if (data.Failed()) { const auto archive = FileSys::SystemArchive::SynthesizeSystemArchive(title_id); diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h index b5486a193..d52b55999 100644 --- a/src/core/hle/service/filesystem/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp_srv.h @@ -32,7 +32,7 @@ enum class LogMode : u32 { class FSP_SRV final : public ServiceFramework<FSP_SRV> { public: - explicit FSP_SRV(const Core::Reporter& reporter); + explicit FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter); ~FSP_SRV() override; private: @@ -51,6 +51,8 @@ private: void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx); void GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx); + FileSystemController& fsc; + FileSys::VirtualFile romfs; u64 current_process_id = 0; u32 access_log_program_index = 0; diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index d1ec12ef9..42b4ee861 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp @@ -149,7 +149,8 @@ private: class INotificationService final : public ServiceFramework<INotificationService> { public: - INotificationService(Common::UUID uuid) : ServiceFramework("INotificationService"), uuid(uuid) { + INotificationService(Common::UUID uuid, Core::System& system) + : ServiceFramework("INotificationService"), uuid(uuid) { // clang-format off static const FunctionInfo functions[] = { {0, &INotificationService::GetEvent, "GetEvent"}, @@ -159,6 +160,9 @@ public: // clang-format on RegisterHandlers(functions); + + notification_event = Kernel::WritableEvent::CreateEventPair( + system.Kernel(), Kernel::ResetType::Manual, "INotificationService:NotifyEvent"); } private: @@ -167,13 +171,6 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - - if (!is_event_created) { - auto& kernel = Core::System::GetInstance().Kernel(); - notification_event = Kernel::WritableEvent::CreateEventPair( - kernel, Kernel::ResetType::Manual, "INotificationService:NotifyEvent"); - is_event_created = true; - } rb.PushCopyObjects(notification_event.readable); } @@ -261,21 +258,21 @@ void Module::Interface::CreateNotificationService(Kernel::HLERequestContext& ctx IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<INotificationService>(uuid); + rb.PushIpcInterface<INotificationService>(uuid, system); } -Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) - : ServiceFramework(name), module(std::move(module)) {} +Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name) + : ServiceFramework(name), module(std::move(module)), system(system) {} Module::Interface::~Interface() = default; -void InstallInterfaces(SM::ServiceManager& service_manager) { +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { auto module = std::make_shared<Module>(); - std::make_shared<Friend>(module, "friend:a")->InstallAsService(service_manager); - std::make_shared<Friend>(module, "friend:m")->InstallAsService(service_manager); - std::make_shared<Friend>(module, "friend:s")->InstallAsService(service_manager); - std::make_shared<Friend>(module, "friend:u")->InstallAsService(service_manager); - std::make_shared<Friend>(module, "friend:v")->InstallAsService(service_manager); + std::make_shared<Friend>(module, system, "friend:a")->InstallAsService(service_manager); + std::make_shared<Friend>(module, system, "friend:m")->InstallAsService(service_manager); + std::make_shared<Friend>(module, system, "friend:s")->InstallAsService(service_manager); + std::make_shared<Friend>(module, system, "friend:u")->InstallAsService(service_manager); + std::make_shared<Friend>(module, system, "friend:v")->InstallAsService(service_manager); } } // namespace Service::Friend diff --git a/src/core/hle/service/friend/friend.h b/src/core/hle/service/friend/friend.h index 38d05fa8e..24f3fc969 100644 --- a/src/core/hle/service/friend/friend.h +++ b/src/core/hle/service/friend/friend.h @@ -6,13 +6,17 @@ #include "core/hle/service/service.h" +namespace Core { +class System; +} + namespace Service::Friend { class Module final { public: class Interface : public ServiceFramework<Interface> { public: - explicit Interface(std::shared_ptr<Module> module, const char* name); + explicit Interface(std::shared_ptr<Module> module, Core::System& system, const char* name); ~Interface() override; void CreateFriendService(Kernel::HLERequestContext& ctx); @@ -20,10 +24,11 @@ public: protected: std::shared_ptr<Module> module; + Core::System& system; }; }; /// Registers all Friend services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager); +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); } // namespace Service::Friend diff --git a/src/core/hle/service/friend/interface.cpp b/src/core/hle/service/friend/interface.cpp index 5b384f733..58155f652 100644 --- a/src/core/hle/service/friend/interface.cpp +++ b/src/core/hle/service/friend/interface.cpp @@ -6,8 +6,8 @@ namespace Service::Friend { -Friend::Friend(std::shared_ptr<Module> module, const char* name) - : Interface(std::move(module), name) { +Friend::Friend(std::shared_ptr<Module> module, Core::System& system, const char* name) + : Interface(std::move(module), system, name) { static const FunctionInfo functions[] = { {0, &Friend::CreateFriendService, "CreateFriendService"}, {1, &Friend::CreateNotificationService, "CreateNotificationService"}, diff --git a/src/core/hle/service/friend/interface.h b/src/core/hle/service/friend/interface.h index 1963def39..465a35770 100644 --- a/src/core/hle/service/friend/interface.h +++ b/src/core/hle/service/friend/interface.h @@ -10,7 +10,7 @@ namespace Service::Friend { class Friend final : public Module::Interface { public: - explicit Friend(std::shared_ptr<Module> module, const char* name); + explicit Friend(std::shared_ptr<Module> module, Core::System& system, const char* name); ~Friend() override; }; diff --git a/src/core/hle/service/hid/controllers/controller_base.cpp b/src/core/hle/service/hid/controllers/controller_base.cpp index 0993a7815..8091db9d7 100644 --- a/src/core/hle/service/hid/controllers/controller_base.cpp +++ b/src/core/hle/service/hid/controllers/controller_base.cpp @@ -6,7 +6,7 @@ namespace Service::HID { -ControllerBase::ControllerBase() = default; +ControllerBase::ControllerBase(Core::System& system) : system(system) {} ControllerBase::~ControllerBase() = default; void ControllerBase::ActivateController() { diff --git a/src/core/hle/service/hid/controllers/controller_base.h b/src/core/hle/service/hid/controllers/controller_base.h index 5e5097a03..8bc69c372 100644 --- a/src/core/hle/service/hid/controllers/controller_base.h +++ b/src/core/hle/service/hid/controllers/controller_base.h @@ -11,10 +11,14 @@ namespace Core::Timing { class CoreTiming; } +namespace Core { +class System; +} + namespace Service::HID { class ControllerBase { public: - ControllerBase(); + explicit ControllerBase(Core::System& system); virtual ~ControllerBase(); // Called when the controller is initialized @@ -46,5 +50,7 @@ protected: s64_le entry_count; }; static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size"); + + Core::System& system; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp index c5c2e032a..8e8263f5b 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.cpp +++ b/src/core/hle/service/hid/controllers/debug_pad.cpp @@ -14,7 +14,8 @@ constexpr s32 HID_JOYSTICK_MAX = 0x7fff; constexpr s32 HID_JOYSTICK_MIN = -0x7fff; enum class JoystickId : std::size_t { Joystick_Left, Joystick_Right }; -Controller_DebugPad::Controller_DebugPad() = default; +Controller_DebugPad::Controller_DebugPad(Core::System& system) + : ControllerBase(system), system(system) {} Controller_DebugPad::~Controller_DebugPad() = default; void Controller_DebugPad::OnInit() {} diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/core/hle/service/hid/controllers/debug_pad.h index e584b92ec..6c4de817e 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.h +++ b/src/core/hle/service/hid/controllers/debug_pad.h @@ -16,7 +16,7 @@ namespace Service::HID { class Controller_DebugPad final : public ControllerBase { public: - Controller_DebugPad(); + explicit Controller_DebugPad(Core::System& system); ~Controller_DebugPad() override; // Called when the controller is initialized @@ -89,5 +89,6 @@ private: buttons; std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID> analogs; + Core::System& system; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp index a179252e3..80da0a0d3 100644 --- a/src/core/hle/service/hid/controllers/gesture.cpp +++ b/src/core/hle/service/hid/controllers/gesture.cpp @@ -10,7 +10,8 @@ namespace Service::HID { constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3BA00; -Controller_Gesture::Controller_Gesture() = default; +Controller_Gesture::Controller_Gesture(Core::System& system) + : ControllerBase(system), system(system) {} Controller_Gesture::~Controller_Gesture() = default; void Controller_Gesture::OnInit() {} diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h index f305fe90f..396897527 100644 --- a/src/core/hle/service/hid/controllers/gesture.h +++ b/src/core/hle/service/hid/controllers/gesture.h @@ -12,7 +12,7 @@ namespace Service::HID { class Controller_Gesture final : public ControllerBase { public: - Controller_Gesture(); + explicit Controller_Gesture(Core::System& system); ~Controller_Gesture() override; // Called when the controller is initialized @@ -59,5 +59,6 @@ private: std::array<GestureState, 17> gesture_states; }; SharedMemory shared_memory{}; + Core::System& system; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp index 92d7bfb52..e587b2e15 100644 --- a/src/core/hle/service/hid/controllers/keyboard.cpp +++ b/src/core/hle/service/hid/controllers/keyboard.cpp @@ -12,7 +12,8 @@ namespace Service::HID { constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800; constexpr u8 KEYS_PER_BYTE = 8; -Controller_Keyboard::Controller_Keyboard() = default; +Controller_Keyboard::Controller_Keyboard(Core::System& system) + : ControllerBase(system), system(system) {} Controller_Keyboard::~Controller_Keyboard() = default; void Controller_Keyboard::OnInit() {} diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h index 73cd2c7bb..ef586f7eb 100644 --- a/src/core/hle/service/hid/controllers/keyboard.h +++ b/src/core/hle/service/hid/controllers/keyboard.h @@ -15,7 +15,7 @@ namespace Service::HID { class Controller_Keyboard final : public ControllerBase { public: - Controller_Keyboard(); + explicit Controller_Keyboard(Core::System& system); ~Controller_Keyboard() override; // Called when the controller is initialized @@ -53,5 +53,6 @@ private: keyboard_keys; std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeKeyboard::NumKeyboardMods> keyboard_mods; + Core::System& system; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp index 11ab096d9..88f2ca4c1 100644 --- a/src/core/hle/service/hid/controllers/mouse.cpp +++ b/src/core/hle/service/hid/controllers/mouse.cpp @@ -11,7 +11,7 @@ namespace Service::HID { constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400; -Controller_Mouse::Controller_Mouse() = default; +Controller_Mouse::Controller_Mouse(Core::System& system) : ControllerBase(system), system(system) {} Controller_Mouse::~Controller_Mouse() = default; void Controller_Mouse::OnInit() {} diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h index 9d46eecbe..df2da6ae3 100644 --- a/src/core/hle/service/hid/controllers/mouse.h +++ b/src/core/hle/service/hid/controllers/mouse.h @@ -14,7 +14,7 @@ namespace Service::HID { class Controller_Mouse final : public ControllerBase { public: - Controller_Mouse(); + explicit Controller_Mouse(Core::System& system); ~Controller_Mouse() override; // Called when the controller is initialized @@ -53,5 +53,6 @@ private: std::unique_ptr<Input::MouseDevice> mouse_device; std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeMouseButton::NumMouseButtons> mouse_button_devices; + Core::System& system; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index e47fe8188..f7a0aa4ff 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -93,7 +93,7 @@ u32 Controller_NPad::IndexToNPad(std::size_t index) { }; } -Controller_NPad::Controller_NPad() = default; +Controller_NPad::Controller_NPad(Core::System& system) : ControllerBase(system), system(system) {} Controller_NPad::~Controller_NPad() = default; void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { @@ -168,7 +168,7 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { } void Controller_NPad::OnInit() { - auto& kernel = Core::System::GetInstance().Kernel(); + auto& kernel = system.Kernel(); styleset_changed_event = Kernel::WritableEvent::CreateEventPair( kernel, Kernel::ResetType::Automatic, "npad:NpadStyleSetChanged"); diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index f28b36806..f72a9900c 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -20,7 +20,7 @@ constexpr u32 NPAD_UNKNOWN = 16; // TODO(ogniK): What is this? class Controller_NPad final : public ControllerBase { public: - Controller_NPad(); + explicit Controller_NPad(Core::System& system); ~Controller_NPad() override; // Called when the controller is initialized @@ -327,5 +327,6 @@ private: std::array<ControllerPad, 10> npad_pad_states{}; bool IsControllerSupported(NPadControllerType controller); bool is_in_lr_assignment_mode{false}; + Core::System& system; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/stubbed.cpp b/src/core/hle/service/hid/controllers/stubbed.cpp index 946948f5e..9b829341e 100644 --- a/src/core/hle/service/hid/controllers/stubbed.cpp +++ b/src/core/hle/service/hid/controllers/stubbed.cpp @@ -9,7 +9,8 @@ namespace Service::HID { -Controller_Stubbed::Controller_Stubbed() = default; +Controller_Stubbed::Controller_Stubbed(Core::System& system) + : ControllerBase(system), system(system) {} Controller_Stubbed::~Controller_Stubbed() = default; void Controller_Stubbed::OnInit() {} diff --git a/src/core/hle/service/hid/controllers/stubbed.h b/src/core/hle/service/hid/controllers/stubbed.h index 24469f03e..37d7d8538 100644 --- a/src/core/hle/service/hid/controllers/stubbed.h +++ b/src/core/hle/service/hid/controllers/stubbed.h @@ -10,7 +10,7 @@ namespace Service::HID { class Controller_Stubbed final : public ControllerBase { public: - Controller_Stubbed(); + explicit Controller_Stubbed(Core::System& system); ~Controller_Stubbed() override; // Called when the controller is initialized @@ -30,5 +30,6 @@ public: private: bool smart_update{}; std::size_t common_offset{}; + Core::System& system; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index 1a8445a43..25912fd69 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp @@ -13,7 +13,8 @@ namespace Service::HID { constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400; -Controller_Touchscreen::Controller_Touchscreen() = default; +Controller_Touchscreen::Controller_Touchscreen(Core::System& system) + : ControllerBase(system), system(system) {} Controller_Touchscreen::~Controller_Touchscreen() = default; void Controller_Touchscreen::OnInit() {} diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h index 76fc340e9..3429c84db 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.h +++ b/src/core/hle/service/hid/controllers/touchscreen.h @@ -14,7 +14,7 @@ namespace Service::HID { class Controller_Touchscreen final : public ControllerBase { public: - Controller_Touchscreen(); + explicit Controller_Touchscreen(Core::System& system); ~Controller_Touchscreen() override; // Called when the controller is initialized @@ -69,5 +69,6 @@ private: TouchScreenSharedMemory shared_memory{}; std::unique_ptr<Input::TouchDevice> touch_device; s64_le last_touch{}; + Core::System& system; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/xpad.cpp b/src/core/hle/service/hid/controllers/xpad.cpp index 1a9da9576..1bce044b4 100644 --- a/src/core/hle/service/hid/controllers/xpad.cpp +++ b/src/core/hle/service/hid/controllers/xpad.cpp @@ -10,7 +10,7 @@ namespace Service::HID { constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00; -Controller_XPad::Controller_XPad() = default; +Controller_XPad::Controller_XPad(Core::System& system) : ControllerBase(system), system(system) {} Controller_XPad::~Controller_XPad() = default; void Controller_XPad::OnInit() {} diff --git a/src/core/hle/service/hid/controllers/xpad.h b/src/core/hle/service/hid/controllers/xpad.h index 2864e6617..c445ebec0 100644 --- a/src/core/hle/service/hid/controllers/xpad.h +++ b/src/core/hle/service/hid/controllers/xpad.h @@ -12,7 +12,7 @@ namespace Service::HID { class Controller_XPad final : public ControllerBase { public: - Controller_XPad(); + explicit Controller_XPad(Core::System& system); ~Controller_XPad() override; // Called when the controller is initialized @@ -56,5 +56,6 @@ private: }; static_assert(sizeof(SharedMemory) == 0x1000, "SharedMemory is an invalid size"); SharedMemory shared_memory{}; + Core::System& system; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index f8b1ca816..33145b891 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -42,13 +42,14 @@ constexpr s64 accelerometer_update_ticks = static_cast<s64>(Core::Timing::BASE_C constexpr s64 gyroscope_update_ticks = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 100); constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; -IAppletResource::IAppletResource() : ServiceFramework("IAppletResource") { +IAppletResource::IAppletResource(Core::System& system) + : ServiceFramework("IAppletResource"), system(system) { static const FunctionInfo functions[] = { {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, }; RegisterHandlers(functions); - auto& kernel = Core::System::GetInstance().Kernel(); + auto& kernel = system.Kernel(); shared_mem = Kernel::SharedMemory::Create( kernel, nullptr, SHARED_MEMORY_SIZE, Kernel::MemoryPermission::ReadWrite, Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory"); @@ -74,7 +75,7 @@ IAppletResource::IAppletResource() : ServiceFramework("IAppletResource") { GetController<Controller_Stubbed>(HidController::Unknown3).SetCommonHeaderOffset(0x5000); // Register update callbacks - auto& core_timing = Core::System::GetInstance().CoreTiming(); + auto& core_timing = system.CoreTiming(); pad_update_event = core_timing.RegisterEvent("HID::UpdatePadCallback", [this](u64 userdata, s64 cycles_late) { UpdateControllers(userdata, cycles_late); @@ -96,7 +97,7 @@ void IAppletResource::DeactivateController(HidController controller) { } IAppletResource ::~IAppletResource() { - Core::System::GetInstance().CoreTiming().UnscheduleEvent(pad_update_event, 0); + system.CoreTiming().UnscheduleEvent(pad_update_event, 0); } void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) { @@ -108,7 +109,7 @@ void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) { } void IAppletResource::UpdateControllers(u64 userdata, s64 cycles_late) { - auto& core_timing = Core::System::GetInstance().CoreTiming(); + auto& core_timing = system.CoreTiming(); const bool should_reload = Settings::values.is_device_reload_pending.exchange(false); for (const auto& controller : controllers) { @@ -141,13 +142,13 @@ private: std::shared_ptr<IAppletResource> Hid::GetAppletResource() { if (applet_resource == nullptr) { - applet_resource = std::make_shared<IAppletResource>(); + applet_resource = std::make_shared<IAppletResource>(system); } return applet_resource; } -Hid::Hid() : ServiceFramework("hid") { +Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) { // clang-format off static const FunctionInfo functions[] = { {0, &Hid::CreateAppletResource, "CreateAppletResource"}, @@ -286,7 +287,7 @@ void Hid::CreateAppletResource(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); if (applet_resource == nullptr) { - applet_resource = std::make_shared<IAppletResource>(); + applet_resource = std::make_shared<IAppletResource>(system); } IPC::ResponseBuilder rb{ctx, 2, 0, 1}; @@ -1053,14 +1054,14 @@ void ReloadInputDevices() { Settings::values.is_device_reload_pending.store(true); } -void InstallInterfaces(SM::ServiceManager& service_manager) { - std::make_shared<Hid>()->InstallAsService(service_manager); +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { + std::make_shared<Hid>(system)->InstallAsService(service_manager); std::make_shared<HidBus>()->InstallAsService(service_manager); std::make_shared<HidDbg>()->InstallAsService(service_manager); std::make_shared<HidSys>()->InstallAsService(service_manager); std::make_shared<HidTmp>()->InstallAsService(service_manager); - std::make_shared<IRS>()->InstallAsService(service_manager); + std::make_shared<IRS>(system)->InstallAsService(service_manager); std::make_shared<IRS_SYS>()->InstallAsService(service_manager); std::make_shared<XCD_SYS>()->InstallAsService(service_manager); diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 2fd6d9fc7..35b663679 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -42,7 +42,7 @@ enum class HidController : std::size_t { class IAppletResource final : public ServiceFramework<IAppletResource> { public: - IAppletResource(); + explicit IAppletResource(Core::System& system); ~IAppletResource() override; void ActivateController(HidController controller); @@ -61,7 +61,7 @@ public: private: template <typename T> void MakeController(HidController controller) { - controllers[static_cast<std::size_t>(controller)] = std::make_unique<T>(); + controllers[static_cast<std::size_t>(controller)] = std::make_unique<T>(system); } void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); @@ -70,6 +70,7 @@ private: Kernel::SharedPtr<Kernel::SharedMemory> shared_mem; Core::Timing::EventType* pad_update_event; + Core::System& system; std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)> controllers{}; @@ -77,7 +78,7 @@ private: class Hid final : public ServiceFramework<Hid> { public: - Hid(); + explicit Hid(Core::System& system); ~Hid() override; std::shared_ptr<IAppletResource> GetAppletResource(); @@ -126,12 +127,13 @@ private: void SwapNpadAssignment(Kernel::HLERequestContext& ctx); std::shared_ptr<IAppletResource> applet_resource; + Core::System& system; }; /// Reload input devices. Used when input configuration changed void ReloadInputDevices(); /// Registers all HID services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager); +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); } // namespace Service::HID diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp index 2c4625c99..5e79e2c1a 100644 --- a/src/core/hle/service/hid/irs.cpp +++ b/src/core/hle/service/hid/irs.cpp @@ -11,7 +11,7 @@ namespace Service::HID { -IRS::IRS() : ServiceFramework{"irs"} { +IRS::IRS(Core::System& system) : ServiceFramework{"irs"}, system(system) { // clang-format off static const FunctionInfo functions[] = { {302, &IRS::ActivateIrsensor, "ActivateIrsensor"}, @@ -37,7 +37,7 @@ IRS::IRS() : ServiceFramework{"irs"} { RegisterHandlers(functions); - auto& kernel = Core::System::GetInstance().Kernel(); + auto& kernel = system.Kernel(); shared_mem = Kernel::SharedMemory::Create( kernel, nullptr, 0x8000, Kernel::MemoryPermission::ReadWrite, Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "IRS:SharedMemory"); @@ -98,7 +98,7 @@ void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 5}; rb.Push(RESULT_SUCCESS); - rb.PushRaw<u64>(Core::System::GetInstance().CoreTiming().GetTicks()); + rb.PushRaw<u64>(system.CoreTiming().GetTicks()); rb.PushRaw<u32>(0); } diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h index 12de6bfb3..eb4e898dd 100644 --- a/src/core/hle/service/hid/irs.h +++ b/src/core/hle/service/hid/irs.h @@ -15,7 +15,7 @@ namespace Service::HID { class IRS final : public ServiceFramework<IRS> { public: - explicit IRS(); + explicit IRS(Core::System& system); ~IRS() override; private: @@ -39,6 +39,7 @@ private: void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx); Kernel::SharedPtr<Kernel::SharedMemory> shared_mem; const u32 device_handle{0xABCD}; + Core::System& system; }; class IRS_SYS final : public ServiceFramework<IRS_SYS> { diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index 8ddad8682..3164ca26e 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp @@ -78,7 +78,7 @@ public: class RelocatableObject final : public ServiceFramework<RelocatableObject> { public: - explicit RelocatableObject() : ServiceFramework{"ldr:ro"} { + explicit RelocatableObject(Core::System& system) : ServiceFramework{"ldr:ro"}, system(system) { // clang-format off static const FunctionInfo functions[] = { {0, &RelocatableObject::LoadNro, "LoadNro"}, @@ -364,7 +364,7 @@ public: vm_manager.ReprotectRange(*map_address + header.rw_offset, header.rw_size, Kernel::VMAPermission::ReadWrite); - Core::System::GetInstance().InvalidateCpuInstructionCaches(); + system.InvalidateCpuInstructionCaches(); nro.insert_or_assign(*map_address, NROInfo{hash, nro_address, nro_size, bss_address, bss_size}); @@ -430,7 +430,7 @@ public: .IsSuccess()); } - Core::System::GetInstance().InvalidateCpuInstructionCaches(); + system.InvalidateCpuInstructionCaches(); nro.erase(iter); IPC::ResponseBuilder rb{ctx, 2}; @@ -516,13 +516,14 @@ private: Common::Is4KBAligned(header.text_size) && Common::Is4KBAligned(header.ro_size) && Common::Is4KBAligned(header.rw_size); } + Core::System& system; }; -void InstallInterfaces(SM::ServiceManager& sm) { +void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { std::make_shared<DebugMonitor>()->InstallAsService(sm); std::make_shared<ProcessManager>()->InstallAsService(sm); std::make_shared<Shell>()->InstallAsService(sm); - std::make_shared<RelocatableObject>()->InstallAsService(sm); + std::make_shared<RelocatableObject>(system)->InstallAsService(sm); } } // namespace Service::LDR diff --git a/src/core/hle/service/ldr/ldr.h b/src/core/hle/service/ldr/ldr.h index 412410c4f..7ac8c0b65 100644 --- a/src/core/hle/service/ldr/ldr.h +++ b/src/core/hle/service/ldr/ldr.h @@ -11,6 +11,6 @@ class ServiceManager; namespace Service::LDR { /// Registers all LDR services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& sm); +void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); } // namespace Service::LDR diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp index a5cb06f8a..a42c22d44 100644 --- a/src/core/hle/service/nfp/nfp.cpp +++ b/src/core/hle/service/nfp/nfp.cpp @@ -23,9 +23,9 @@ constexpr ResultCode ERR_TAG_FAILED(ErrorModule::NFP, constexpr ResultCode ERR_NO_APPLICATION_AREA(ErrorModule::NFP, 152); } // namespace ErrCodes -Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) - : ServiceFramework(name), module(std::move(module)) { - auto& kernel = Core::System::GetInstance().Kernel(); +Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name) + : ServiceFramework(name), module(std::move(module)), system(system) { + auto& kernel = system.Kernel(); nfc_tag_load = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic, "IUser:NFCTagDetected"); } @@ -34,8 +34,8 @@ Module::Interface::~Interface() = default; class IUser final : public ServiceFramework<IUser> { public: - IUser(Module::Interface& nfp_interface) - : ServiceFramework("NFP::IUser"), nfp_interface(nfp_interface) { + IUser(Module::Interface& nfp_interface, Core::System& system) + : ServiceFramework("NFP::IUser"), nfp_interface(nfp_interface), system(system) { static const FunctionInfo functions[] = { {0, &IUser::Initialize, "Initialize"}, {1, &IUser::Finalize, "Finalize"}, @@ -65,7 +65,7 @@ public: }; RegisterHandlers(functions); - auto& kernel = Core::System::GetInstance().Kernel(); + auto& kernel = system.Kernel(); deactivate_event = Kernel::WritableEvent::CreateEventPair( kernel, Kernel::ResetType::Automatic, "IUser:DeactivateEvent"); availability_change_event = Kernel::WritableEvent::CreateEventPair( @@ -324,6 +324,7 @@ private: Kernel::EventPair deactivate_event; Kernel::EventPair availability_change_event; const Module::Interface& nfp_interface; + Core::System& system; }; void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) { @@ -331,7 +332,7 @@ void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<IUser>(*this); + rb.PushIpcInterface<IUser>(*this, system); } bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) { @@ -353,9 +354,9 @@ const Module::Interface::AmiiboFile& Module::Interface::GetAmiiboBuffer() const return amiibo; } -void InstallInterfaces(SM::ServiceManager& service_manager) { +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { auto module = std::make_shared<Module>(); - std::make_shared<NFP_User>(module)->InstallAsService(service_manager); + std::make_shared<NFP_User>(module, system)->InstallAsService(service_manager); } } // namespace Service::NFP diff --git a/src/core/hle/service/nfp/nfp.h b/src/core/hle/service/nfp/nfp.h index a1817e991..9718ef745 100644 --- a/src/core/hle/service/nfp/nfp.h +++ b/src/core/hle/service/nfp/nfp.h @@ -16,7 +16,7 @@ class Module final { public: class Interface : public ServiceFramework<Interface> { public: - explicit Interface(std::shared_ptr<Module> module, const char* name); + explicit Interface(std::shared_ptr<Module> module, Core::System& system, const char* name); ~Interface() override; struct ModelInfo { @@ -43,9 +43,10 @@ public: protected: std::shared_ptr<Module> module; + Core::System& system; }; }; -void InstallInterfaces(SM::ServiceManager& service_manager); +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); } // namespace Service::NFP diff --git a/src/core/hle/service/nfp/nfp_user.cpp b/src/core/hle/service/nfp/nfp_user.cpp index 784a87c1b..298184f17 100644 --- a/src/core/hle/service/nfp/nfp_user.cpp +++ b/src/core/hle/service/nfp/nfp_user.cpp @@ -6,8 +6,8 @@ namespace Service::NFP { -NFP_User::NFP_User(std::shared_ptr<Module> module) - : Module::Interface(std::move(module), "nfp:user") { +NFP_User::NFP_User(std::shared_ptr<Module> module, Core::System& system) + : Module::Interface(std::move(module), system, "nfp:user") { static const FunctionInfo functions[] = { {0, &NFP_User::CreateUserInterface, "CreateUserInterface"}, }; diff --git a/src/core/hle/service/nfp/nfp_user.h b/src/core/hle/service/nfp/nfp_user.h index 65d9aaf48..1686ebf20 100644 --- a/src/core/hle/service/nfp/nfp_user.h +++ b/src/core/hle/service/nfp/nfp_user.h @@ -10,7 +10,7 @@ namespace Service::NFP { class NFP_User final : public Module::Interface { public: - explicit NFP_User(std::shared_ptr<Module> module); + explicit NFP_User(std::shared_ptr<Module> module, Core::System& system); ~NFP_User() override; }; diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp index 76b12b482..24d1813a7 100644 --- a/src/core/hle/service/nifm/nifm.cpp +++ b/src/core/hle/service/nifm/nifm.cpp @@ -31,7 +31,7 @@ public: class IRequest final : public ServiceFramework<IRequest> { public: - explicit IRequest() : ServiceFramework("IRequest") { + explicit IRequest(Core::System& system) : ServiceFramework("IRequest") { static const FunctionInfo functions[] = { {0, &IRequest::GetRequestState, "GetRequestState"}, {1, &IRequest::GetResult, "GetResult"}, @@ -61,7 +61,7 @@ public: }; RegisterHandlers(functions); - auto& kernel = Core::System::GetInstance().Kernel(); + auto& kernel = system.Kernel(); event1 = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic, "IRequest:Event1"); event2 = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic, @@ -130,7 +130,7 @@ public: class IGeneralService final : public ServiceFramework<IGeneralService> { public: - IGeneralService(); + IGeneralService(Core::System& system); private: void GetClientId(Kernel::HLERequestContext& ctx) { @@ -155,7 +155,7 @@ private: IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<IRequest>(); + rb.PushIpcInterface<IRequest>(system); } void RemoveNetworkProfile(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_NIFM, "(STUBBED) called"); @@ -198,9 +198,11 @@ private: rb.Push(RESULT_SUCCESS); rb.Push<u8>(0); } + Core::System& system; }; -IGeneralService::IGeneralService() : ServiceFramework("IGeneralService") { +IGeneralService::IGeneralService(Core::System& system) + : ServiceFramework("IGeneralService"), system(system) { static const FunctionInfo functions[] = { {1, &IGeneralService::GetClientId, "GetClientId"}, {2, &IGeneralService::CreateScanRequest, "CreateScanRequest"}, @@ -245,7 +247,8 @@ IGeneralService::IGeneralService() : ServiceFramework("IGeneralService") { class NetworkInterface final : public ServiceFramework<NetworkInterface> { public: - explicit NetworkInterface(const char* name) : ServiceFramework{name} { + explicit NetworkInterface(const char* name, Core::System& system) + : ServiceFramework{name}, system(system) { static const FunctionInfo functions[] = { {4, &NetworkInterface::CreateGeneralServiceOld, "CreateGeneralServiceOld"}, {5, &NetworkInterface::CreateGeneralService, "CreateGeneralService"}, @@ -258,7 +261,7 @@ public: IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<IGeneralService>(); + rb.PushIpcInterface<IGeneralService>(system); } void CreateGeneralService(Kernel::HLERequestContext& ctx) { @@ -266,14 +269,17 @@ public: IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<IGeneralService>(); + rb.PushIpcInterface<IGeneralService>(system); } + +private: + Core::System& system; }; -void InstallInterfaces(SM::ServiceManager& service_manager) { - std::make_shared<NetworkInterface>("nifm:a")->InstallAsService(service_manager); - std::make_shared<NetworkInterface>("nifm:s")->InstallAsService(service_manager); - std::make_shared<NetworkInterface>("nifm:u")->InstallAsService(service_manager); +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { + std::make_shared<NetworkInterface>("nifm:a", system)->InstallAsService(service_manager); + std::make_shared<NetworkInterface>("nifm:s", system)->InstallAsService(service_manager); + std::make_shared<NetworkInterface>("nifm:u", system)->InstallAsService(service_manager); } } // namespace Service::NIFM diff --git a/src/core/hle/service/nifm/nifm.h b/src/core/hle/service/nifm/nifm.h index 4616b3b48..6857e18f9 100644 --- a/src/core/hle/service/nifm/nifm.h +++ b/src/core/hle/service/nifm/nifm.h @@ -8,9 +8,13 @@ namespace Service::SM { class ServiceManager; } +namespace Core { +class System; +} + namespace Service::NIFM { /// Registers all NIFM services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager); +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); } // namespace Service::NIFM diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp index f319a3ca1..75d414952 100644 --- a/src/core/hle/service/nim/nim.cpp +++ b/src/core/hle/service/nim/nim.cpp @@ -126,7 +126,7 @@ public: class IEnsureNetworkClockAvailabilityService final : public ServiceFramework<IEnsureNetworkClockAvailabilityService> { public: - IEnsureNetworkClockAvailabilityService() + explicit IEnsureNetworkClockAvailabilityService(Core::System& system) : ServiceFramework("IEnsureNetworkClockAvailabilityService") { static const FunctionInfo functions[] = { {0, &IEnsureNetworkClockAvailabilityService::StartTask, "StartTask"}, @@ -139,7 +139,7 @@ public: }; RegisterHandlers(functions); - auto& kernel = Core::System::GetInstance().Kernel(); + auto& kernel = system.Kernel(); finished_event = Kernel::WritableEvent::CreateEventPair( kernel, Kernel::ResetType::Automatic, "IEnsureNetworkClockAvailabilityService:FinishEvent"); @@ -200,7 +200,7 @@ private: class NTC final : public ServiceFramework<NTC> { public: - explicit NTC() : ServiceFramework{"ntc"} { + explicit NTC(Core::System& system) : ServiceFramework{"ntc"}, system(system) { // clang-format off static const FunctionInfo functions[] = { {0, &NTC::OpenEnsureNetworkClockAvailabilityService, "OpenEnsureNetworkClockAvailabilityService"}, @@ -218,7 +218,7 @@ private: IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<IEnsureNetworkClockAvailabilityService>(); + rb.PushIpcInterface<IEnsureNetworkClockAvailabilityService>(system); } // TODO(ogniK): Do we need these? @@ -235,13 +235,14 @@ private: IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } + Core::System& system; }; -void InstallInterfaces(SM::ServiceManager& sm) { +void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { std::make_shared<NIM>()->InstallAsService(sm); std::make_shared<NIM_ECA>()->InstallAsService(sm); std::make_shared<NIM_SHP>()->InstallAsService(sm); - std::make_shared<NTC>()->InstallAsService(sm); + std::make_shared<NTC>(system)->InstallAsService(sm); } } // namespace Service::NIM diff --git a/src/core/hle/service/nim/nim.h b/src/core/hle/service/nim/nim.h index 2a2a92df0..dbe25dc01 100644 --- a/src/core/hle/service/nim/nim.h +++ b/src/core/hle/service/nim/nim.h @@ -8,8 +8,12 @@ namespace Service::SM { class ServiceManager; } +namespace Core { +class System; +} + namespace Service::NIM { -void InstallInterfaces(SM::ServiceManager& sm); +void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); } // namespace Service::NIM diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp index ce88a2941..15c156ce1 100644 --- a/src/core/hle/service/ns/ns.cpp +++ b/src/core/hle/service/ns/ns.cpp @@ -617,7 +617,8 @@ public: } }; -void InstallInterfaces(SM::ServiceManager& service_manager) { +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { + std::make_shared<NS>("ns:am2")->InstallAsService(service_manager); std::make_shared<NS>("ns:ec")->InstallAsService(service_manager); std::make_shared<NS>("ns:rid")->InstallAsService(service_manager); @@ -628,7 +629,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager) { std::make_shared<NS_SU>()->InstallAsService(service_manager); std::make_shared<NS_VM>()->InstallAsService(service_manager); - std::make_shared<PL_U>()->InstallAsService(service_manager); + std::make_shared<PL_U>(system)->InstallAsService(service_manager); } } // namespace Service::NS diff --git a/src/core/hle/service/ns/ns.h b/src/core/hle/service/ns/ns.h index 0e8256cb4..13a64ad88 100644 --- a/src/core/hle/service/ns/ns.h +++ b/src/core/hle/service/ns/ns.h @@ -6,7 +6,13 @@ #include "core/hle/service/service.h" -namespace Service::NS { +namespace Service { + +namespace FileSystem { +class FileSystemController; +} // namespace FileSystem + +namespace NS { class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> { public: @@ -91,6 +97,7 @@ private: }; /// Registers all NS services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager); +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); -} // namespace Service::NS +} // namespace NS +} // namespace Service diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index 2a522136d..7dcdb4a07 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp @@ -150,7 +150,9 @@ struct PL_U::Impl { std::vector<FontRegion> shared_font_regions; }; -PL_U::PL_U() : ServiceFramework("pl:u"), impl{std::make_unique<Impl>()} { +PL_U::PL_U(Core::System& system) + : ServiceFramework("pl:u"), impl{std::make_unique<Impl>()}, system(system) { + static const FunctionInfo functions[] = { {0, &PL_U::RequestLoad, "RequestLoad"}, {1, &PL_U::GetLoadState, "GetLoadState"}, @@ -160,8 +162,11 @@ PL_U::PL_U() : ServiceFramework("pl:u"), impl{std::make_unique<Impl>()} { {5, &PL_U::GetSharedFontInOrderOfPriority, "GetSharedFontInOrderOfPriority"}, }; RegisterHandlers(functions); + + auto& fsc = system.GetFileSystemController(); + // Attempt to load shared font data from disk - const auto* nand = FileSystem::GetSystemNANDContents(); + const auto* nand = fsc.GetSystemNANDContents(); std::size_t offset = 0; // Rebuild shared fonts from data ncas if (nand->HasEntry(static_cast<u64>(FontArchives::Standard), @@ -324,7 +329,7 @@ void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) { Kernel::MemoryState::Shared); // Create shared font memory object - auto& kernel = Core::System::GetInstance().Kernel(); + auto& kernel = system.Kernel(); impl->shared_font_mem = Kernel::SharedMemory::Create( kernel, Core::CurrentProcess(), SHARED_FONT_MEM_SIZE, Kernel::MemoryPermission::ReadWrite, Kernel::MemoryPermission::Read, SHARED_FONT_MEM_VADDR, Kernel::MemoryRegion::BASE, diff --git a/src/core/hle/service/ns/pl_u.h b/src/core/hle/service/ns/pl_u.h index 253f26a2a..1063f4204 100644 --- a/src/core/hle/service/ns/pl_u.h +++ b/src/core/hle/service/ns/pl_u.h @@ -7,11 +7,17 @@ #include <memory> #include "core/hle/service/service.h" -namespace Service::NS { +namespace Service { + +namespace FileSystem { +class FileSystemController; +} // namespace FileSystem + +namespace NS { class PL_U final : public ServiceFramework<PL_U> { public: - PL_U(); + explicit PL_U(Core::System& system); ~PL_U() override; private: @@ -24,6 +30,9 @@ private: struct Impl; std::unique_ptr<Impl> impl; + Core::System& system; }; -} // namespace Service::NS +} // namespace NS + +} // namespace Service diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h index 5b8248433..1b52511a5 100644 --- a/src/core/hle/service/nvdrv/devices/nvdevice.h +++ b/src/core/hle/service/nvdrv/devices/nvdevice.h @@ -9,6 +9,7 @@ #include "common/common_types.h" #include "common/swap.h" #include "core/hle/service/nvdrv/nvdata.h" +#include "core/hle/service/service.h" namespace Core { class System; @@ -38,8 +39,9 @@ public: * @param output A buffer where the output data will be written to. * @returns The result code of the ioctl. */ - virtual u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) = 0; + virtual u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) = 0; protected: Core::System& system; diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index 926a1285d..f764388bc 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -17,8 +17,9 @@ nvdisp_disp0::nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_de : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} nvdisp_disp0 ::~nvdisp_disp0() = default; -u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) { +u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) { UNIMPLEMENTED_MSG("Unimplemented ioctl"); return 0; } diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h index e79e490ff..6fcdeee84 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h @@ -20,8 +20,9 @@ public: explicit nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); ~nvdisp_disp0() override; - u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) override; + u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) override; /// Performs a screen flip, drawing the buffer pointed to by the handle. void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride, diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 24ab3f2e9..6bc053f27 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -26,8 +26,9 @@ nvhost_as_gpu::nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_ : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} nvhost_as_gpu::~nvhost_as_gpu() = default; -u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) { +u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) { LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", command.raw, input.size(), output.size()); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h index 30ca5f4c3..169fb8f0e 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h @@ -20,8 +20,9 @@ public: explicit nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); ~nvhost_as_gpu() override; - u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) override; + u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) override; private: enum class IoctlCommand : u32_le { diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 9a66a5f88..ff6b1abae 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -19,8 +19,9 @@ nvhost_ctrl::nvhost_ctrl(Core::System& system, EventInterface& events_interface) : nvdevice(system), events_interface{events_interface} {} nvhost_ctrl::~nvhost_ctrl() = default; -u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) { +u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) { LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", command.raw, input.size(), output.size()); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h index 14e6e7e57..9898623de 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h @@ -17,8 +17,9 @@ public: explicit nvhost_ctrl(Core::System& system, EventInterface& events_interface); ~nvhost_ctrl() override; - u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) override; + u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) override; private: enum class IoctlCommand : u32_le { diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index 988effd90..389ace76f 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -15,14 +15,15 @@ namespace Service::Nvidia::Devices { nvhost_ctrl_gpu::nvhost_ctrl_gpu(Core::System& system) : nvdevice(system) {} nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default; -u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) { +u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, + const std::vector<u8>& input2, std::vector<u8>& output, + std::vector<u8>& output2, IoctlCtrl& ctrl, IoctlVersion version) { LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", command.raw, input.size(), output.size()); switch (static_cast<IoctlCommand>(command.raw)) { case IoctlCommand::IocGetCharacteristicsCommand: - return GetCharacteristics(input, output); + return GetCharacteristics(input, output, output2, version); case IoctlCommand::IocGetTPCMasksCommand: return GetTPCMasks(input, output); case IoctlCommand::IocGetActiveSlotMaskCommand: @@ -44,7 +45,8 @@ u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vec return 0; } -u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output) { +u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output, + std::vector<u8>& output2, IoctlVersion version) { LOG_DEBUG(Service_NVDRV, "called"); IoctlCharacteristics params{}; std::memcpy(¶ms, input.data(), input.size()); @@ -85,7 +87,13 @@ u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vecto params.gc.gr_compbit_store_base_hw = 0x0; params.gpu_characteristics_buf_size = 0xA0; params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED) - std::memcpy(output.data(), ¶ms, output.size()); + + if (version == IoctlVersion::Version3) { + std::memcpy(output.data(), input.data(), output.size()); + std::memcpy(output2.data(), ¶ms.gc, output2.size()); + } else { + std::memcpy(output.data(), ¶ms, output.size()); + } return 0; } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h index 2b035ae3f..642b0a2cb 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h @@ -16,8 +16,9 @@ public: explicit nvhost_ctrl_gpu(Core::System& system); ~nvhost_ctrl_gpu() override; - u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) override; + u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) override; private: enum class IoctlCommand : u32_le { @@ -162,7 +163,8 @@ private: }; static_assert(sizeof(IoctlGetGpuTime) == 8, "IoctlGetGpuTime is incorrect size"); - u32 GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output); + u32 GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output, + std::vector<u8>& output2, IoctlVersion version); u32 GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& output); u32 GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output); u32 ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index b4ee2a255..2b8d1bef6 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -17,8 +17,9 @@ nvhost_gpu::nvhost_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev) : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} nvhost_gpu::~nvhost_gpu() = default; -u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) { +u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) { LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", command.raw, input.size(), output.size()); @@ -50,7 +51,7 @@ u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u return SubmitGPFIFO(input, output); } if (command.cmd == NVGPU_IOCTL_CHANNEL_KICKOFF_PB) { - return KickoffPB(input, output); + return KickoffPB(input, output, input2, version); } } @@ -173,7 +174,8 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp return 0; } -u32 nvhost_gpu::KickoffPB(const std::vector<u8>& input, std::vector<u8>& output) { +u32 nvhost_gpu::KickoffPB(const std::vector<u8>& input, std::vector<u8>& output, + const std::vector<u8>& input2, IoctlVersion version) { if (input.size() < sizeof(IoctlSubmitGpfifo)) { UNIMPLEMENTED(); } @@ -183,9 +185,13 @@ u32 nvhost_gpu::KickoffPB(const std::vector<u8>& input, std::vector<u8>& output) params.num_entries, params.flags.raw); Tegra::CommandList entries(params.num_entries); - Memory::ReadBlock(params.address, entries.data(), - params.num_entries * sizeof(Tegra::CommandListHeader)); - + if (version == IoctlVersion::Version2) { + std::memcpy(entries.data(), input2.data(), + params.num_entries * sizeof(Tegra::CommandListHeader)); + } else { + Memory::ReadBlock(params.address, entries.data(), + params.num_entries * sizeof(Tegra::CommandListHeader)); + } UNIMPLEMENTED_IF(params.flags.add_wait.Value() != 0); UNIMPLEMENTED_IF(params.flags.add_increment.Value() != 0); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index d2e8fbae9..d056dd046 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h @@ -24,8 +24,9 @@ public: explicit nvhost_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); ~nvhost_gpu() override; - u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) override; + u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) override; private: enum class IoctlCommand : u32_le { @@ -183,7 +184,8 @@ private: u32 AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& output); u32 AllocateObjectContext(const std::vector<u8>& input, std::vector<u8>& output); u32 SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& output); - u32 KickoffPB(const std::vector<u8>& input, std::vector<u8>& output); + u32 KickoffPB(const std::vector<u8>& input, std::vector<u8>& output, + const std::vector<u8>& input2, IoctlVersion version); u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output); u32 ChannelSetTimeout(const std::vector<u8>& input, std::vector<u8>& output); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index f572ad30f..bdae8b887 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp @@ -13,8 +13,9 @@ namespace Service::Nvidia::Devices { nvhost_nvdec::nvhost_nvdec(Core::System& system) : nvdevice(system) {} nvhost_nvdec::~nvhost_nvdec() = default; -u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) { +u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) { LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", command.raw, input.size(), output.size()); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h index 2710f0511..cbdac8069 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h @@ -16,8 +16,9 @@ public: explicit nvhost_nvdec(Core::System& system); ~nvhost_nvdec() override; - u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) override; + u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) override; private: enum class IoctlCommand : u32_le { diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp index 38282956f..96e7b7dab 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp @@ -13,8 +13,9 @@ namespace Service::Nvidia::Devices { nvhost_nvjpg::nvhost_nvjpg(Core::System& system) : nvdevice(system) {} nvhost_nvjpg::~nvhost_nvjpg() = default; -u32 nvhost_nvjpg::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) { +u32 nvhost_nvjpg::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) { LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", command.raw, input.size(), output.size()); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h index 379766693..98dcac52f 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h @@ -16,8 +16,9 @@ public: explicit nvhost_nvjpg(Core::System& system); ~nvhost_nvjpg() override; - u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) override; + u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) override; private: enum class IoctlCommand : u32_le { diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp index 70e8091db..c695b8863 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp @@ -13,8 +13,9 @@ namespace Service::Nvidia::Devices { nvhost_vic::nvhost_vic(Core::System& system) : nvdevice(system) {} nvhost_vic::~nvhost_vic() = default; -u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) { +u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) { LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", command.raw, input.size(), output.size()); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h index 7d111977e..bec32bea1 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h @@ -16,8 +16,9 @@ public: explicit nvhost_vic(Core::System& system); ~nvhost_vic() override; - u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) override; + u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) override; private: enum class IoctlCommand : u32_le { diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index 223b496b7..8c742316c 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp @@ -28,8 +28,9 @@ VAddr nvmap::GetObjectAddress(u32 handle) const { return object->addr; } -u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) { +u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) { switch (static_cast<IoctlCommand>(command.raw)) { case IoctlCommand::Create: return IocCreate(input, output); diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h index bf4a101c2..73c2e8809 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.h +++ b/src/core/hle/service/nvdrv/devices/nvmap.h @@ -22,8 +22,9 @@ public: /// Returns the allocated address of an nvmap object given its handle. VAddr GetObjectAddress(u32 handle) const; - u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) override; + u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) override; /// Represents an nvmap object. struct Object { diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp index d5be64ed2..5e0c23602 100644 --- a/src/core/hle/service/nvdrv/interface.cpp +++ b/src/core/hle/service/nvdrv/interface.cpp @@ -33,42 +33,77 @@ void NVDRV::Open(Kernel::HLERequestContext& ctx) { rb.Push<u32>(0); } -void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_NVDRV, "called"); - +void NVDRV::IoctlBase(Kernel::HLERequestContext& ctx, IoctlVersion version) { IPC::RequestParser rp{ctx}; u32 fd = rp.Pop<u32>(); u32 command = rp.Pop<u32>(); - std::vector<u8> output(ctx.GetWriteBufferSize()); + /// Ioctl 3 has 2 outputs, first in the input params, second is the result + std::vector<u8> output(ctx.GetWriteBufferSize(0)); + std::vector<u8> output2; + if (version == IoctlVersion::Version3) { + output2.resize((ctx.GetWriteBufferSize(1))); + } + + /// Ioctl2 has 2 inputs. It's used to pass data directly instead of providing a pointer. + /// KickOfPB uses this + auto input = ctx.ReadBuffer(0); + + std::vector<u8> input2; + if (version == IoctlVersion::Version2) { + input2 = ctx.ReadBuffer(1); + } IoctlCtrl ctrl{}; - u32 result = nvdrv->Ioctl(fd, command, ctx.ReadBuffer(), output, ctrl); + u32 result = nvdrv->Ioctl(fd, command, input, input2, output, output2, ctrl, version); if (ctrl.must_delay) { ctrl.fresh_call = false; - ctx.SleepClientThread( - "NVServices::DelayedResponse", ctrl.timeout, - [=](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, - Kernel::ThreadWakeupReason reason) { - IoctlCtrl ctrl2{ctrl}; - std::vector<u8> output2 = output; - u32 result = nvdrv->Ioctl(fd, command, ctx.ReadBuffer(), output2, ctrl2); - ctx.WriteBuffer(output2); - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(RESULT_SUCCESS); - rb.Push(result); - }, - nvdrv->GetEventWriteable(ctrl.event_id)); + ctx.SleepClientThread("NVServices::DelayedResponse", ctrl.timeout, + [=](Kernel::SharedPtr<Kernel::Thread> thread, + Kernel::HLERequestContext& ctx, + Kernel::ThreadWakeupReason reason) { + IoctlCtrl ctrl2{ctrl}; + std::vector<u8> tmp_output = output; + std::vector<u8> tmp_output2 = output2; + u32 result = nvdrv->Ioctl(fd, command, input, input2, tmp_output, + tmp_output2, ctrl2, version); + ctx.WriteBuffer(tmp_output, 0); + if (version == IoctlVersion::Version3) { + ctx.WriteBuffer(tmp_output2, 1); + } + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(result); + }, + nvdrv->GetEventWriteable(ctrl.event_id)); } else { ctx.WriteBuffer(output); + if (version == IoctlVersion::Version3) { + ctx.WriteBuffer(output2, 1); + } } IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(result); } +void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_NVDRV, "called"); + IoctlBase(ctx, IoctlVersion::Version1); +} + +void NVDRV::Ioctl2(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_NVDRV, "called"); + IoctlBase(ctx, IoctlVersion::Version2); +} + +void NVDRV::Ioctl3(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_NVDRV, "called"); + IoctlBase(ctx, IoctlVersion::Version3); +} + void NVDRV::Close(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_NVDRV, "called"); @@ -154,8 +189,8 @@ NVDRV::NVDRV(std::shared_ptr<Module> nvdrv, const char* name) {8, &NVDRV::SetClientPID, "SetClientPID"}, {9, &NVDRV::DumpGraphicsMemoryInfo, "DumpGraphicsMemoryInfo"}, {10, nullptr, "InitializeDevtools"}, - {11, &NVDRV::Ioctl, "Ioctl2"}, - {12, nullptr, "Ioctl3"}, + {11, &NVDRV::Ioctl2, "Ioctl2"}, + {12, &NVDRV::Ioctl3, "Ioctl3"}, {13, &NVDRV::FinishInitialize, "FinishInitialize"}, }; RegisterHandlers(functions); diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/interface.h index 10a0ecd52..9269ce00c 100644 --- a/src/core/hle/service/nvdrv/interface.h +++ b/src/core/hle/service/nvdrv/interface.h @@ -24,6 +24,8 @@ public: private: void Open(Kernel::HLERequestContext& ctx); void Ioctl(Kernel::HLERequestContext& ctx); + void Ioctl2(Kernel::HLERequestContext& ctx); + void Ioctl3(Kernel::HLERequestContext& ctx); void Close(Kernel::HLERequestContext& ctx); void Initialize(Kernel::HLERequestContext& ctx); void QueryEvent(Kernel::HLERequestContext& ctx); @@ -31,6 +33,7 @@ private: void FinishInitialize(Kernel::HLERequestContext& ctx); void GetStatus(Kernel::HLERequestContext& ctx); void DumpGraphicsMemoryInfo(Kernel::HLERequestContext& ctx); + void IoctlBase(Kernel::HLERequestContext& ctx, IoctlVersion version); std::shared_ptr<Module> nvdrv; diff --git a/src/core/hle/service/nvdrv/nvdata.h b/src/core/hle/service/nvdrv/nvdata.h index ac03cbc23..529b03471 100644 --- a/src/core/hle/service/nvdrv/nvdata.h +++ b/src/core/hle/service/nvdrv/nvdata.h @@ -34,6 +34,12 @@ enum class EventState { Busy = 3, }; +enum class IoctlVersion : u32 { + Version1, + Version2, + Version3, +}; + struct IoctlCtrl { // First call done to the servioce for services that call itself again after a call. bool fresh_call{true}; diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 2011a226a..307a7e928 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp @@ -71,13 +71,14 @@ u32 Module::Open(const std::string& device_name) { return fd; } -u32 Module::Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl) { +u32 Module::Ioctl(u32 fd, u32 command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version) { auto itr = open_files.find(fd); ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device"); auto& device = itr->second; - return device->ioctl({command}, input, output, ctrl); + return device->ioctl({command}, input, input2, output, output2, ctrl, version); } ResultCode Module::Close(u32 fd) { diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index a339ab672..f8bb28969 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h @@ -106,8 +106,9 @@ public: /// Opens a device node and returns a file descriptor to it. u32 Open(const std::string& device_name); /// Sends an ioctl command to the specified file descriptor. - u32 Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output, - IoctlCtrl& ctrl); + u32 Ioctl(u32 fd, u32 command, const std::vector<u8>& input, const std::vector<u8>& input2, + std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, + IoctlVersion version); /// Closes a device file descriptor and returns operation success. ResultCode Close(u32 fd); diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index f9db79370..2e4d707b9 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -29,26 +29,28 @@ namespace Service::NVFlinger { constexpr s64 frame_ticks = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 60); constexpr s64 frame_ticks_30fps = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 30); -NVFlinger::NVFlinger(Core::Timing::CoreTiming& core_timing) : core_timing{core_timing} { - displays.emplace_back(0, "Default"); - displays.emplace_back(1, "External"); - displays.emplace_back(2, "Edid"); - displays.emplace_back(3, "Internal"); - displays.emplace_back(4, "Null"); +NVFlinger::NVFlinger(Core::System& system) : system(system) { + displays.emplace_back(0, "Default", system); + displays.emplace_back(1, "External", system); + displays.emplace_back(2, "Edid", system); + displays.emplace_back(3, "Internal", system); + displays.emplace_back(4, "Null", system); // Schedule the screen composition events - composition_event = core_timing.RegisterEvent("ScreenComposition", [this](u64 userdata, - s64 cycles_late) { - Compose(); - const auto ticks = Settings::values.force_30fps_mode ? frame_ticks_30fps : GetNextTicks(); - this->core_timing.ScheduleEvent(std::max<s64>(0LL, ticks - cycles_late), composition_event); - }); - - core_timing.ScheduleEvent(frame_ticks, composition_event); + composition_event = system.CoreTiming().RegisterEvent( + "ScreenComposition", [this](u64 userdata, s64 cycles_late) { + Compose(); + const auto ticks = + Settings::values.force_30fps_mode ? frame_ticks_30fps : GetNextTicks(); + this->system.CoreTiming().ScheduleEvent(std::max<s64>(0LL, ticks - cycles_late), + composition_event); + }); + + system.CoreTiming().ScheduleEvent(frame_ticks, composition_event); } NVFlinger::~NVFlinger() { - core_timing.UnscheduleEvent(composition_event, 0); + system.CoreTiming().UnscheduleEvent(composition_event, 0); } void NVFlinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) { @@ -185,11 +187,9 @@ void NVFlinger::Compose() { MicroProfileFlip(); if (!buffer) { - auto& system_instance = Core::System::GetInstance(); - // There was no queued buffer to draw, render previous frame - system_instance.GetPerfStats().EndGameFrame(); - system_instance.GPU().SwapBuffers({}); + system.GetPerfStats().EndGameFrame(); + system.GPU().SwapBuffers({}); continue; } diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h index 988be8726..5d7e3bfb8 100644 --- a/src/core/hle/service/nvflinger/nvflinger.h +++ b/src/core/hle/service/nvflinger/nvflinger.h @@ -38,7 +38,7 @@ class BufferQueue; class NVFlinger final { public: - explicit NVFlinger(Core::Timing::CoreTiming& core_timing); + explicit NVFlinger(Core::System& system); ~NVFlinger(); /// Sets the NVDrv module instance to use to send buffers to the GPU. @@ -105,8 +105,7 @@ private: /// Event that handles screen composition. Core::Timing::EventType* composition_event; - /// Core timing instance for registering/unregistering the composition event. - Core::Timing::CoreTiming& core_timing; + Core::System& system; }; } // namespace Service::NVFlinger diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp index 7e134f5c1..18d895263 100644 --- a/src/core/hle/service/prepo/prepo.cpp +++ b/src/core/hle/service/prepo/prepo.cpp @@ -2,34 +2,31 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include <json.hpp> -#include "common/file_util.h" #include "common/hex_util.h" #include "common/logging/log.h" -#include "common/scm_rev.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/process.h" #include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/prepo/prepo.h" #include "core/hle/service/service.h" #include "core/reporter.h" -#include "core/settings.h" namespace Service::PlayReport { class PlayReport final : public ServiceFramework<PlayReport> { public: - explicit PlayReport(const char* name) : ServiceFramework{name} { + explicit PlayReport(const char* name, Core::System& system) + : ServiceFramework{name}, system(system) { // clang-format off static const FunctionInfo functions[] = { - {10100, nullptr, "SaveReportOld"}, - {10101, &PlayReport::SaveReportWithUserOld, "SaveReportWithUserOld"}, - {10102, nullptr, "SaveReport"}, - {10103, nullptr, "SaveReportWithUser"}, + {10100, &PlayReport::SaveReport<Core::Reporter::PlayReportType::Old>, "SaveReportOld"}, + {10101, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::Old>, "SaveReportWithUserOld"}, + {10102, &PlayReport::SaveReport<Core::Reporter::PlayReportType::New>, "SaveReport"}, + {10103, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::New>, "SaveReportWithUser"}, {10200, nullptr, "RequestImmediateTransmission"}, {10300, nullptr, "GetTransmissionStatus"}, - {20100, nullptr, "SaveSystemReport"}, - {20101, nullptr, "SaveSystemReportWithUser"}, + {20100, &PlayReport::SaveSystemReport, "SaveSystemReport"}, + {20101, &PlayReport::SaveSystemReportWithUser, "SaveSystemReportWithUser"}, {20200, nullptr, "SetOperationMode"}, {30100, nullptr, "ClearStorage"}, {30200, nullptr, "ClearStatistics"}, @@ -47,7 +44,28 @@ public: } private: - void SaveReportWithUserOld(Kernel::HLERequestContext& ctx) { + template <Core::Reporter::PlayReportType Type> + void SaveReport(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto process_id = rp.PopRaw<u64>(); + + const auto data1 = ctx.ReadBuffer(0); + const auto data2 = ctx.ReadBuffer(1); + + LOG_DEBUG(Service_PREPO, + "called, type={:02X}, process_id={:016X}, data1_size={:016X}, data2_size={:016X}", + static_cast<u8>(Type), process_id, data1.size(), data2.size()); + + const auto& reporter{system.GetReporter()}; + reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), {data1, data2}, + process_id); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + } + + template <Core::Reporter::PlayReportType Type> + void SaveReportWithUser(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto user_id = rp.PopRaw<u128>(); const auto process_id = rp.PopRaw<u64>(); @@ -57,24 +75,65 @@ private: LOG_DEBUG( Service_PREPO, - "called, user_id={:016X}{:016X}, unk1={:016X}, data1_size={:016X}, data2_size={:016X}", - user_id[1], user_id[0], process_id, data1.size(), data2.size()); + "called, type={:02X}, user_id={:016X}{:016X}, process_id={:016X}, data1_size={:016X}, " + "data2_size={:016X}", + static_cast<u8>(Type), user_id[1], user_id[0], process_id, data1.size(), data2.size()); + + const auto& reporter{system.GetReporter()}; + reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), {data1, data2}, + process_id, user_id); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + } + + void SaveSystemReport(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto title_id = rp.PopRaw<u64>(); + + const auto data1 = ctx.ReadBuffer(0); + const auto data2 = ctx.ReadBuffer(1); + + LOG_DEBUG(Service_PREPO, "called, title_id={:016X}, data1_size={:016X}, data2_size={:016X}", + title_id, data1.size(), data2.size()); + + const auto& reporter{system.GetReporter()}; + reporter.SavePlayReport(Core::Reporter::PlayReportType::System, title_id, {data1, data2}); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + } - const auto& reporter{Core::System::GetInstance().GetReporter()}; - reporter.SavePlayReport(Core::CurrentProcess()->GetTitleID(), process_id, {data1, data2}, - user_id); + void SaveSystemReportWithUser(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto user_id = rp.PopRaw<u128>(); + const auto title_id = rp.PopRaw<u64>(); + + const auto data1 = ctx.ReadBuffer(0); + const auto data2 = ctx.ReadBuffer(1); + + LOG_DEBUG(Service_PREPO, + "called, user_id={:016X}{:016X}, title_id={:016X}, data1_size={:016X}, " + "data2_size={:016X}", + user_id[1], user_id[0], title_id, data1.size(), data2.size()); + + const auto& reporter{system.GetReporter()}; + reporter.SavePlayReport(Core::Reporter::PlayReportType::System, title_id, {data1, data2}, + std::nullopt, user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } + + Core::System& system; }; -void InstallInterfaces(SM::ServiceManager& service_manager) { - std::make_shared<PlayReport>("prepo:a")->InstallAsService(service_manager); - std::make_shared<PlayReport>("prepo:a2")->InstallAsService(service_manager); - std::make_shared<PlayReport>("prepo:m")->InstallAsService(service_manager); - std::make_shared<PlayReport>("prepo:s")->InstallAsService(service_manager); - std::make_shared<PlayReport>("prepo:u")->InstallAsService(service_manager); +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { + std::make_shared<PlayReport>("prepo:a", system)->InstallAsService(service_manager); + std::make_shared<PlayReport>("prepo:a2", system)->InstallAsService(service_manager); + std::make_shared<PlayReport>("prepo:m", system)->InstallAsService(service_manager); + std::make_shared<PlayReport>("prepo:s", system)->InstallAsService(service_manager); + std::make_shared<PlayReport>("prepo:u", system)->InstallAsService(service_manager); } } // namespace Service::PlayReport diff --git a/src/core/hle/service/prepo/prepo.h b/src/core/hle/service/prepo/prepo.h index 0e7b01331..a5682ee26 100644 --- a/src/core/hle/service/prepo/prepo.h +++ b/src/core/hle/service/prepo/prepo.h @@ -8,8 +8,12 @@ namespace Service::SM { class ServiceManager; } +namespace Core { +class System; +} + namespace Service::PlayReport { -void InstallInterfaces(SM::ServiceManager& service_manager); +void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); } // namespace Service::PlayReport diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 3a0f8c3f6..831a427de 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -198,49 +198,50 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system) { // NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it // here and pass it into the respective InstallInterfaces functions. - auto nv_flinger = std::make_shared<NVFlinger::NVFlinger>(system.CoreTiming()); + auto nv_flinger = std::make_shared<NVFlinger::NVFlinger>(system); + system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false); SM::ServiceManager::InstallInterfaces(sm); Account::InstallInterfaces(system); AM::InstallInterfaces(*sm, nv_flinger, system); - AOC::InstallInterfaces(*sm); + AOC::InstallInterfaces(*sm, system); APM::InstallInterfaces(system); Audio::InstallInterfaces(*sm, system); BCAT::InstallInterfaces(*sm); BPC::InstallInterfaces(*sm); - BtDrv::InstallInterfaces(*sm); - BTM::InstallInterfaces(*sm); + BtDrv::InstallInterfaces(*sm, system); + BTM::InstallInterfaces(*sm, system); Capture::InstallInterfaces(*sm); ERPT::InstallInterfaces(*sm); ES::InstallInterfaces(*sm); EUPLD::InstallInterfaces(*sm); - Fatal::InstallInterfaces(*sm); + Fatal::InstallInterfaces(*sm, system); FGM::InstallInterfaces(*sm); FileSystem::InstallInterfaces(system); - Friend::InstallInterfaces(*sm); + Friend::InstallInterfaces(*sm, system); Glue::InstallInterfaces(system); GRC::InstallInterfaces(*sm); - HID::InstallInterfaces(*sm); + HID::InstallInterfaces(*sm, system); LBL::InstallInterfaces(*sm); LDN::InstallInterfaces(*sm); - LDR::InstallInterfaces(*sm); + LDR::InstallInterfaces(*sm, system); LM::InstallInterfaces(*sm); Migration::InstallInterfaces(*sm); Mii::InstallInterfaces(*sm); MM::InstallInterfaces(*sm); NCM::InstallInterfaces(*sm); NFC::InstallInterfaces(*sm); - NFP::InstallInterfaces(*sm); - NIFM::InstallInterfaces(*sm); - NIM::InstallInterfaces(*sm); + NFP::InstallInterfaces(*sm, system); + NIFM::InstallInterfaces(*sm, system); + NIM::InstallInterfaces(*sm, system); NPNS::InstallInterfaces(*sm); - NS::InstallInterfaces(*sm); + NS::InstallInterfaces(*sm, system); Nvidia::InstallInterfaces(*sm, *nv_flinger, system); PCIe::InstallInterfaces(*sm); PCTL::InstallInterfaces(*sm); PCV::InstallInterfaces(*sm); - PlayReport::InstallInterfaces(*sm); + PlayReport::InstallInterfaces(*sm, system); PM::InstallInterfaces(system); PSC::InstallInterfaces(*sm); PSM::InstallInterfaces(*sm); diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index c6c4bdae5..aef964861 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -18,10 +18,6 @@ namespace Core { class System; } -namespace FileSys { -class VfsFilesystem; -} - namespace Kernel { class ClientPort; class ServerPort; @@ -31,6 +27,10 @@ class HLERequestContext; namespace Service { +namespace FileSystem { +class FileSystemController; +} // namespace FileSystem + namespace SM { class ServiceManager; } diff --git a/src/core/hle/service/time/interface.cpp b/src/core/hle/service/time/interface.cpp index 1030185e0..9565e7de5 100644 --- a/src/core/hle/service/time/interface.cpp +++ b/src/core/hle/service/time/interface.cpp @@ -7,8 +7,8 @@ namespace Service::Time { Time::Time(std::shared_ptr<Module> time, std::shared_ptr<SharedMemory> shared_memory, - const char* name) - : Module::Interface(std::move(time), std::move(shared_memory), name) { + Core::System& system, const char* name) + : Module::Interface(std::move(time), std::move(shared_memory), system, name) { // clang-format off static const FunctionInfo functions[] = { {0, &Time::GetStandardUserSystemClock, "GetStandardUserSystemClock"}, diff --git a/src/core/hle/service/time/interface.h b/src/core/hle/service/time/interface.h index bdf0883e2..5c63a07f4 100644 --- a/src/core/hle/service/time/interface.h +++ b/src/core/hle/service/time/interface.h @@ -13,7 +13,7 @@ class SharedMemory; class Time final : public Module::Interface { public: explicit Time(std::shared_ptr<Module> time, std::shared_ptr<SharedMemory> shared_memory, - const char* name); + Core::System& system, const char* name); ~Time() override; }; diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index ae6446204..1b9ab8401 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -126,8 +126,8 @@ private: class ISteadyClock final : public ServiceFramework<ISteadyClock> { public: - ISteadyClock(std::shared_ptr<SharedMemory> shared_memory) - : ServiceFramework("ISteadyClock"), shared_memory(shared_memory) { + ISteadyClock(std::shared_ptr<SharedMemory> shared_memory, Core::System& system) + : ServiceFramework("ISteadyClock"), shared_memory(shared_memory), system(system) { static const FunctionInfo functions[] = { {0, &ISteadyClock::GetCurrentTimePoint, "GetCurrentTimePoint"}, }; @@ -150,12 +150,13 @@ private: } SteadyClockTimePoint GetCurrentTimePoint() const { - const auto& core_timing = Core::System::GetInstance().CoreTiming(); + const auto& core_timing = system.CoreTiming(); const auto ms = Core::Timing::CyclesToMs(core_timing.GetTicks()); return {static_cast<u64_le>(ms.count() / 1000), {}}; } std::shared_ptr<SharedMemory> shared_memory; + Core::System& system; }; class ITimeZoneService final : public ServiceFramework<ITimeZoneService> { @@ -290,7 +291,7 @@ void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<ISteadyClock>(shared_memory); + rb.PushIpcInterface<ISteadyClock>(shared_memory, system); } void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) { @@ -325,7 +326,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { return; } - const auto& core_timing = Core::System::GetInstance().CoreTiming(); + const auto& core_timing = system.CoreTiming(); const auto ms = Core::Timing::CyclesToMs(core_timing.GetTicks()); const SteadyClockTimePoint steady_clock_time_point{static_cast<u64_le>(ms.count() / 1000), {}}; @@ -407,8 +408,10 @@ void Module::Interface::SetStandardUserSystemClockAutomaticCorrectionEnabled( } Module::Interface::Interface(std::shared_ptr<Module> time, - std::shared_ptr<SharedMemory> shared_memory, const char* name) - : ServiceFramework(name), time(std::move(time)), shared_memory(std::move(shared_memory)) {} + std::shared_ptr<SharedMemory> shared_memory, Core::System& system, + const char* name) + : ServiceFramework(name), time(std::move(time)), shared_memory(std::move(shared_memory)), + system(system) {} Module::Interface::~Interface() = default; @@ -416,9 +419,11 @@ void InstallInterfaces(Core::System& system) { auto time = std::make_shared<Module>(); auto shared_mem = std::make_shared<SharedMemory>(system); - std::make_shared<Time>(time, shared_mem, "time:a")->InstallAsService(system.ServiceManager()); - std::make_shared<Time>(time, shared_mem, "time:s")->InstallAsService(system.ServiceManager()); - std::make_shared<Time>(std::move(time), shared_mem, "time:u") + std::make_shared<Time>(time, shared_mem, system, "time:a") + ->InstallAsService(system.ServiceManager()); + std::make_shared<Time>(time, shared_mem, system, "time:s") + ->InstallAsService(system.ServiceManager()); + std::make_shared<Time>(std::move(time), shared_mem, system, "time:u") ->InstallAsService(system.ServiceManager()); } diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h index e0708f856..c32d32860 100644 --- a/src/core/hle/service/time/time.h +++ b/src/core/hle/service/time/time.h @@ -80,7 +80,8 @@ public: class Interface : public ServiceFramework<Interface> { public: explicit Interface(std::shared_ptr<Module> time, - std::shared_ptr<SharedMemory> shared_memory, const char* name); + std::shared_ptr<SharedMemory> shared_memory, Core::System& system, + const char* name); ~Interface() override; void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx); @@ -97,6 +98,7 @@ public: protected: std::shared_ptr<Module> time; std::shared_ptr<SharedMemory> shared_memory; + Core::System& system; }; }; diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp index a8d088305..006a6d9ff 100644 --- a/src/core/hle/service/vi/display/vi_display.cpp +++ b/src/core/hle/service/vi/display/vi_display.cpp @@ -15,8 +15,8 @@ namespace Service::VI { -Display::Display(u64 id, std::string name) : id{id}, name{std::move(name)} { - auto& kernel = Core::System::GetInstance().Kernel(); +Display::Display(u64 id, std::string name, Core::System& system) : id{id}, name{std::move(name)} { + auto& kernel = system.Kernel(); vsync_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual, fmt::format("Display VSync Event {}", id)); } diff --git a/src/core/hle/service/vi/display/vi_display.h b/src/core/hle/service/vi/display/vi_display.h index 2acd46ff8..f56b5badc 100644 --- a/src/core/hle/service/vi/display/vi_display.h +++ b/src/core/hle/service/vi/display/vi_display.h @@ -26,7 +26,7 @@ public: /// @param id The unique ID for this display. /// @param name The name for this display. /// - Display(u64 id, std::string name); + Display(u64 id, std::string name, Core::System& system); ~Display(); Display(const Display&) = delete; |