diff options
Diffstat (limited to 'src/core')
19 files changed, 128 insertions, 47 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index 435ef6793..bd5f11d53 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -242,7 +242,7 @@ struct System::Impl { void Run() { std::unique_lock<std::mutex> lk(suspend_guard); - kernel.SuspendApplication(false); + kernel.SuspendEmulation(false); core_timing.SyncPause(false); is_paused.store(false, std::memory_order_relaxed); } @@ -251,7 +251,7 @@ struct System::Impl { std::unique_lock<std::mutex> lk(suspend_guard); core_timing.SyncPause(true); - kernel.SuspendApplication(true); + kernel.SuspendEmulation(true); is_paused.store(true, std::memory_order_relaxed); } @@ -261,7 +261,7 @@ struct System::Impl { std::unique_lock<std::mutex> StallApplication() { std::unique_lock<std::mutex> lk(suspend_guard); - kernel.SuspendApplication(true); + kernel.SuspendEmulation(true); core_timing.SyncPause(true); return lk; } @@ -269,7 +269,7 @@ struct System::Impl { void UnstallApplication() { if (!IsPaused()) { core_timing.SyncPause(false); - kernel.SuspendApplication(false); + kernel.SuspendEmulation(false); } } @@ -459,7 +459,7 @@ struct System::Impl { } Network::CancelPendingSocketOperations(); - kernel.SuspendApplication(true); + kernel.SuspendEmulation(true); if (services) { services->KillNVNFlinger(); } diff --git a/src/core/file_sys/control_metadata.h b/src/core/file_sys/control_metadata.h index 555b9d8f7..667efbbab 100644 --- a/src/core/file_sys/control_metadata.h +++ b/src/core/file_sys/control_metadata.h @@ -64,8 +64,8 @@ struct RawNACP { u64_le cache_storage_size; u64_le cache_storage_journal_size; u64_le cache_storage_data_and_journal_max_size; - u64_le cache_storage_max_index; - INSERT_PADDING_BYTES(0xE70); + u16_le cache_storage_max_index; + INSERT_PADDING_BYTES(0xE76); }; static_assert(sizeof(RawNACP) == 0x4000, "RawNACP has incorrect size."); diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index f13e232b2..e928cfebc 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h @@ -66,6 +66,7 @@ enum class SuspendType : u32 { Debug = 2, Backtrace = 3, Init = 4, + System = 5, Count, }; @@ -84,8 +85,9 @@ enum class ThreadState : u16 { DebugSuspended = (1 << (2 + SuspendShift)), BacktraceSuspended = (1 << (3 + SuspendShift)), InitSuspended = (1 << (4 + SuspendShift)), + SystemSuspended = (1 << (5 + SuspendShift)), - SuspendFlagMask = ((1 << 5) - 1) << SuspendShift, + SuspendFlagMask = ((1 << 6) - 1) << SuspendShift, }; DECLARE_ENUM_FLAG_OPERATORS(ThreadState); diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 34b25be66..4f4b02fac 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -1204,39 +1204,48 @@ const Kernel::KSharedMemory& KernelCore::GetHidBusSharedMem() const { return *impl->hidbus_shared_mem; } -void KernelCore::SuspendApplication(bool suspended) { +void KernelCore::SuspendEmulation(bool suspended) { const bool should_suspend{exception_exited || suspended}; - const auto activity = - should_suspend ? Svc::ProcessActivity::Paused : Svc::ProcessActivity::Runnable; + auto processes = GetProcessList(); - // Get the application process. - KScopedAutoObject<KProcess> process = ApplicationProcess(); - if (process.IsNull()) { - return; + for (auto& process : processes) { + KScopedLightLock ll{process->GetListLock()}; + + for (auto& thread : process->GetThreadList()) { + if (should_suspend) { + thread.RequestSuspend(SuspendType::System); + } else { + thread.Resume(SuspendType::System); + } + } } - // Set the new activity. - process->SetActivity(activity); + if (!should_suspend) { + return; + } // Wait for process execution to stop. - bool must_wait{should_suspend}; - - // KernelCore::SuspendApplication must be called from locked context, - // or we could race another call to SetActivity, interfering with waiting. - while (must_wait) { + // KernelCore::SuspendEmulation must be called from locked context, + // or we could race another call, interfering with waiting. + const auto TryWait = [&]() { KScopedSchedulerLock sl{*this}; - // Assume that all threads have finished running. - must_wait = false; - - for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { - if (Scheduler(i).GetSchedulerCurrentThread()->GetOwnerProcess() == - process.GetPointerUnsafe()) { - // A thread has not finished running yet. - // Continue waiting. - must_wait = true; + for (auto& process : processes) { + for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { + if (Scheduler(i).GetSchedulerCurrentThread()->GetOwnerProcess() == + process.GetPointerUnsafe()) { + // A thread has not finished running yet. + // Continue waiting. + return false; + } } } + + return true; + }; + + while (!TryWait()) { + // ... } } @@ -1260,7 +1269,7 @@ bool KernelCore::IsShuttingDown() const { void KernelCore::ExceptionalExitApplication() { exception_exited = true; - SuspendApplication(true); + SuspendEmulation(true); } void KernelCore::EnterSVCProfile() { diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 8ea5bed1c..57182c0c8 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -258,8 +258,8 @@ public: /// Gets the shared memory object for HIDBus services. const Kernel::KSharedMemory& GetHidBusSharedMem() const; - /// Suspend/unsuspend application process. - void SuspendApplication(bool suspend); + /// Suspend/unsuspend emulated processes. + void SuspendEmulation(bool suspend); /// Exceptional exit application process. void ExceptionalExitApplication(); diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 29a10ad13..ee9795532 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -329,9 +329,8 @@ bool ProfileManager::GetProfileBaseAndData(const ProfileInfo& user, ProfileBase& /// Returns if the system is allowing user registrations or not bool ProfileManager::CanSystemRegisterUser() const { - return false; // TODO(ogniK): Games shouldn't have - // access to user registration, when we - // emulate qlaunch. Update this to dynamically change. + // TODO: Both games and applets can register users. Determine when this condition is not meet. + return true; } bool ProfileManager::RemoveUser(UUID uuid) { diff --git a/src/core/hle/service/am/applet_manager.cpp b/src/core/hle/service/am/applet_manager.cpp index 4c7266f89..2e109181d 100644 --- a/src/core/hle/service/am/applet_manager.cpp +++ b/src/core/hle/service/am/applet_manager.cpp @@ -35,6 +35,21 @@ AppletStorageChannel& InitializeFakeCallerApplet(Core::System& system, return applet->caller_applet_broker->GetInData(); } +void PushInShowQlaunch(Core::System& system, AppletStorageChannel& channel) { + const CommonArguments arguments{ + .arguments_version = CommonArgumentVersion::Version3, + .size = CommonArgumentSize::Version3, + .library_version = 0, + .theme_color = ThemeColor::BasicBlack, + .play_startup_sound = true, + .system_tick = system.CoreTiming().GetClockTicks(), + }; + + std::vector<u8> argument_data(sizeof(arguments)); + std::memcpy(argument_data.data(), &arguments, sizeof(arguments)); + channel.Push(std::make_shared<IStorage>(system, std::move(argument_data))); +} + void PushInShowAlbum(Core::System& system, AppletStorageChannel& channel) { const CommonArguments arguments{ .arguments_version = CommonArgumentVersion::Version3, @@ -284,6 +299,9 @@ void AppletManager::CreateAndInsertByFrontendAppletParameters( // Starting from frontend, some applets require input data. switch (applet->applet_id) { + case AppletId::QLaunch: + PushInShowQlaunch(m_system, InitializeFakeCallerApplet(m_system, applet)); + break; case AppletId::Cabinet: PushInShowCabinetData(m_system, InitializeFakeCallerApplet(m_system, applet)); break; diff --git a/src/core/hle/service/am/service/application_functions.cpp b/src/core/hle/service/am/service/application_functions.cpp index b788fddd4..63dd12a47 100644 --- a/src/core/hle/service/am/service/application_functions.cpp +++ b/src/core/hle/service/am/service/application_functions.cpp @@ -15,6 +15,7 @@ #include "core/hle/service/cmif_serialization.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/filesystem/save_data_controller.h" +#include "core/hle/service/glue/glue_manager.h" #include "core/hle/service/ns/ns.h" #include "core/hle/service/sm/sm.h" @@ -40,7 +41,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_, std::shared_ {26, D<&IApplicationFunctions::GetSaveDataSize>, "GetSaveDataSize"}, {27, D<&IApplicationFunctions::CreateCacheStorage>, "CreateCacheStorage"}, {28, D<&IApplicationFunctions::GetSaveDataSizeMax>, "GetSaveDataSizeMax"}, - {29, nullptr, "GetCacheStorageMax"}, + {29, D<&IApplicationFunctions::GetCacheStorageMax>, "GetCacheStorageMax"}, {30, D<&IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed>, "BeginBlockingHomeButtonShortAndLongPressed"}, {31, D<&IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed>, "EndBlockingHomeButtonShortAndLongPressed"}, {32, D<&IApplicationFunctions::BeginBlockingHomeButton>, "BeginBlockingHomeButton"}, @@ -267,6 +268,22 @@ Result IApplicationFunctions::GetSaveDataSizeMax(Out<u64> out_max_normal_size, R_SUCCEED(); } +Result IApplicationFunctions::GetCacheStorageMax(Out<u32> out_cache_storage_index_max, + Out<u64> out_max_journal_size) { + LOG_DEBUG(Service_AM, "called"); + + std::vector<u8> nacp; + R_TRY(system.GetARPManager().GetControlProperty(&nacp, m_applet->program_id)); + + auto raw_nacp = std::make_unique<FileSys::RawNACP>(); + std::memcpy(raw_nacp.get(), nacp.data(), std::min(sizeof(*raw_nacp), nacp.size())); + + *out_cache_storage_index_max = static_cast<u32>(raw_nacp->cache_storage_max_index); + *out_max_journal_size = static_cast<u64>(raw_nacp->cache_storage_data_and_journal_max_size); + + R_SUCCEED(); +} + Result IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed(s64 unused) { LOG_WARNING(Service_AM, "(STUBBED) called"); diff --git a/src/core/hle/service/am/service/application_functions.h b/src/core/hle/service/am/service/application_functions.h index 3548202f8..10025a152 100644 --- a/src/core/hle/service/am/service/application_functions.h +++ b/src/core/hle/service/am/service/application_functions.h @@ -40,6 +40,7 @@ private: Result CreateCacheStorage(Out<u32> out_target_media, Out<u64> out_required_size, u16 index, u64 normal_size, u64 journal_size); Result GetSaveDataSizeMax(Out<u64> out_max_normal_size, Out<u64> out_max_journal_size); + Result GetCacheStorageMax(Out<u32> out_cache_storage_index_max, Out<u64> out_max_journal_size); Result BeginBlockingHomeButtonShortAndLongPressed(s64 unused); Result EndBlockingHomeButtonShortAndLongPressed(); Result BeginBlockingHomeButton(s64 timeout_ns); diff --git a/src/core/hle/service/am/service/library_applet_self_accessor.cpp b/src/core/hle/service/am/service/library_applet_self_accessor.cpp index 7a3a86e88..94bd4dae6 100644 --- a/src/core/hle/service/am/service/library_applet_self_accessor.cpp +++ b/src/core/hle/service/am/service/library_applet_self_accessor.cpp @@ -284,17 +284,17 @@ Result ILibraryAppletSelfAccessor::GetCurrentApplicationId(Out<u64> out_applicat } Result ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers( - Out<bool> out_no_users_available, Out<s32> out_users_count, + Out<bool> out_can_select_any_user, Out<s32> out_users_count, OutArray<Common::UUID, BufferAttr_HipcMapAlias> out_users) { const Service::Account::ProfileManager manager{}; - *out_no_users_available = true; + *out_can_select_any_user = false; *out_users_count = -1; LOG_INFO(Service_AM, "called"); if (manager.GetUserCount() > 0) { - *out_no_users_available = false; + *out_can_select_any_user = true; *out_users_count = static_cast<s32>(manager.GetUserCount()); const auto users = manager.GetAllUsers(); diff --git a/src/core/hle/service/am/service/library_applet_self_accessor.h b/src/core/hle/service/am/service/library_applet_self_accessor.h index a9743569f..3e60393c2 100644 --- a/src/core/hle/service/am/service/library_applet_self_accessor.h +++ b/src/core/hle/service/am/service/library_applet_self_accessor.h @@ -71,7 +71,7 @@ private: ErrorCode error_code, InLargeData<ErrorContext, BufferAttr_HipcMapAlias> error_context); Result GetMainAppletApplicationDesiredLanguage(Out<u64> out_desired_language); Result GetCurrentApplicationId(Out<u64> out_application_id); - Result GetMainAppletAvailableUsers(Out<bool> out_no_users_available, Out<s32> out_users_count, + Result GetMainAppletAvailableUsers(Out<bool> out_can_select_any_user, Out<s32> out_users_count, OutArray<Common::UUID, BufferAttr_HipcMapAlias> out_users); Result ShouldSetGpuTimeSliceManually(Out<bool> out_should_set_gpu_time_slice_manually); Result Cmd160(Out<u64> out_unknown0); diff --git a/src/core/hle/service/caps/caps_a.cpp b/src/core/hle/service/caps/caps_a.cpp index 47ff072c5..52228b830 100644 --- a/src/core/hle/service/caps/caps_a.cpp +++ b/src/core/hle/service/caps/caps_a.cpp @@ -16,7 +16,7 @@ IAlbumAccessorService::IAlbumAccessorService(Core::System& system_, // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "GetAlbumFileCount"}, - {1, nullptr, "GetAlbumFileList"}, + {1, C<&IAlbumAccessorService::GetAlbumFileList>, "GetAlbumFileList"}, {2, nullptr, "LoadAlbumFile"}, {3, C<&IAlbumAccessorService::DeleteAlbumFile>, "DeleteAlbumFile"}, {4, nullptr, "StorageCopyAlbumFile"}, @@ -62,6 +62,15 @@ IAlbumAccessorService::IAlbumAccessorService(Core::System& system_, IAlbumAccessorService::~IAlbumAccessorService() = default; +Result IAlbumAccessorService::GetAlbumFileList( + Out<u64> out_count, AlbumStorage storage, + OutArray<AlbumEntry, BufferAttr_HipcMapAlias> out_entries) { + LOG_INFO(Service_Capture, "called, storage={}", storage); + + const Result result = manager->GetAlbumFileList(out_entries, *out_count, storage, 0); + R_RETURN(TranslateResult(result)); +} + Result IAlbumAccessorService::DeleteAlbumFile(AlbumFileId file_id) { LOG_INFO(Service_Capture, "called, application_id=0x{:0x}, storage={}, type={}", file_id.application_id, file_id.storage, file_id.type); diff --git a/src/core/hle/service/caps/caps_a.h b/src/core/hle/service/caps/caps_a.h index 2cb9b4547..c7a5208e3 100644 --- a/src/core/hle/service/caps/caps_a.h +++ b/src/core/hle/service/caps/caps_a.h @@ -21,6 +21,9 @@ public: ~IAlbumAccessorService() override; private: + Result GetAlbumFileList(Out<u64> out_count, AlbumStorage storage, + OutArray<AlbumEntry, BufferAttr_HipcMapAlias> out_entries); + Result DeleteAlbumFile(AlbumFileId file_id); Result IsAlbumMounted(Out<bool> out_is_mounted, AlbumStorage storage); diff --git a/src/core/hle/service/erpt/erpt.cpp b/src/core/hle/service/erpt/erpt.cpp index 3ea862fad..39ae3a723 100644 --- a/src/core/hle/service/erpt/erpt.cpp +++ b/src/core/hle/service/erpt/erpt.cpp @@ -3,6 +3,8 @@ #include <memory> +#include "common/logging/log.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/erpt/erpt.h" #include "core/hle/service/server_manager.h" #include "core/hle/service/service.h" @@ -15,7 +17,7 @@ public: explicit ErrorReportContext(Core::System& system_) : ServiceFramework{system_, "erpt:c"} { // clang-format off static const FunctionInfo functions[] = { - {0, nullptr, "SubmitContext"}, + {0, C<&ErrorReportContext::SubmitContext>, "SubmitContext"}, {1, nullptr, "CreateReportV0"}, {2, nullptr, "SetInitialLaunchSettingsCompletionTime"}, {3, nullptr, "ClearInitialLaunchSettingsCompletionTime"}, @@ -36,6 +38,14 @@ public: RegisterHandlers(functions); } + +private: + Result SubmitContext(InBuffer<BufferAttr_HipcMapAlias> buffer_a, + InBuffer<BufferAttr_HipcMapAlias> buffer_b) { + LOG_WARNING(Service_SET, "(STUBBED) called, buffer_a_size={}, buffer_b_size={}", + buffer_a.size(), buffer_b.size()); + R_SUCCEED(); + } }; class ErrorReportSession final : public ServiceFramework<ErrorReportSession> { diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp index 63c2d3a58..2d49f30c8 100644 --- a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp @@ -336,7 +336,7 @@ FSP_SRV::FSP_SRV(Core::System& system_) {1012, nullptr, "GetFsStackUsage"}, {1013, nullptr, "UnsetSaveDataRootPath"}, {1014, nullptr, "OutputMultiProgramTagAccessLog"}, - {1016, nullptr, "FlushAccessLogOnSdCard"}, + {1016, &FSP_SRV::FlushAccessLogOnSdCard, "FlushAccessLogOnSdCard"}, {1017, nullptr, "OutputApplicationInfoAccessLog"}, {1018, nullptr, "SetDebugOption"}, {1019, nullptr, "UnsetDebugOption"}, @@ -706,6 +706,13 @@ void FSP_SRV::GetProgramIndexForAccessLog(HLERequestContext& ctx) { rb.Push(access_log_program_index); } +void FSP_SRV::FlushAccessLogOnSdCard(HLERequestContext& ctx) { + LOG_DEBUG(Service_FS, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + void FSP_SRV::GetCacheStorageSize(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto index{rp.Pop<s32>()}; diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.h b/src/core/hle/service/filesystem/fsp/fsp_srv.h index 26980af99..59406e6f9 100644 --- a/src/core/hle/service/filesystem/fsp/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp/fsp_srv.h @@ -58,6 +58,7 @@ private: void SetGlobalAccessLogMode(HLERequestContext& ctx); void GetGlobalAccessLogMode(HLERequestContext& ctx); void OutputAccessLogToSdCard(HLERequestContext& ctx); + void FlushAccessLogOnSdCard(HLERequestContext& ctx); void GetProgramIndexForAccessLog(HLERequestContext& ctx); void OpenMultiCommitManager(HLERequestContext& ctx); void GetCacheStorageSize(HLERequestContext& ctx); diff --git a/src/core/hle/service/glue/time/manager.cpp b/src/core/hle/service/glue/time/manager.cpp index cad755fa7..059ac3fc9 100644 --- a/src/core/hle/service/glue/time/manager.cpp +++ b/src/core/hle/service/glue/time/manager.cpp @@ -186,6 +186,10 @@ TimeManager::TimeManager(Core::System& system) } } +TimeManager::~TimeManager() { + ResetTimeZoneBinary(); +} + Result TimeManager::SetupStandardSteadyClockCore() { Common::UUID external_clock_source_id{}; auto res = m_set_sys->GetExternalSteadyClockSourceId(&external_clock_source_id); diff --git a/src/core/hle/service/glue/time/manager.h b/src/core/hle/service/glue/time/manager.h index 1de93f8f9..bb4b65049 100644 --- a/src/core/hle/service/glue/time/manager.h +++ b/src/core/hle/service/glue/time/manager.h @@ -26,6 +26,7 @@ namespace Service::Glue::Time { class TimeManager { public: explicit TimeManager(Core::System& system); + ~TimeManager(); std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp index b84b57d92..d8921e565 100644 --- a/src/core/memory/cheat_engine.cpp +++ b/src/core/memory/cheat_engine.cpp @@ -117,9 +117,9 @@ bool StandardVmCallbacks::IsAddressInRange(VAddr in) const { (in < metadata.heap_extents.base || in >= metadata.heap_extents.base + metadata.heap_extents.size) && (in < metadata.alias_extents.base || - in >= metadata.heap_extents.base + metadata.alias_extents.size) && + in >= metadata.alias_extents.base + metadata.alias_extents.size) && (in < metadata.aslr_extents.base || - in >= metadata.heap_extents.base + metadata.aslr_extents.size)) { + in >= metadata.aslr_extents.base + metadata.aslr_extents.size)) { LOG_DEBUG(CheatEngine, "Cheat attempting to access memory at invalid address={:016X}, if this " "persists, " |