From e7a96c7907fb8cb888f21d348b66de2121fdd1ca Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 10 Sep 2026 22:28:39 +0200 Subject: [PATCH] [hle] Firmware 23.0.0 (#4390) Preparing when something inevitably requires *at least* this reporting of version/etc. Authored-by: @Maufeat Signed-off-by: lizzie - [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions). - [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md) - [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability. ------------------- Co-authored-by: Maufeat Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4390 Reviewed-by: Maufeat Reviewed-by: MaranBr --- .../system_archive/system_version.cpp | 12 +++++--- src/core/hle/api_version.h | 17 +++++------ src/core/hle/kernel/svc/svc_info.cpp | 7 +++++ src/core/hle/kernel/svc_types.h | 7 ++++- .../am/service/application_creator.cpp | 3 +- .../am/service/library_applet_creator.cpp | 17 ++--------- .../service/am/service/self_controller.cpp | 7 +++++ .../hle/service/am/service/self_controller.h | 1 + .../hle/service/filesystem/fsp/fsp_srv.cpp | 28 ++++++++++++++++++- src/core/hle/service/filesystem/fsp/fsp_srv.h | 1 + .../service/pctl/parental_control_service.cpp | 14 ++++++++-- .../service/pctl/parental_control_service.h | 3 +- src/core/hle/service/pctl/pctl_types.h | 23 ++++++++++++++- 13 files changed, 107 insertions(+), 33 deletions(-) diff --git a/src/core/file_sys/system_archive/system_version.cpp b/src/core/file_sys/system_archive/system_version.cpp index 2dbe4a8a01..be6cde7275 100644 --- a/src/core/file_sys/system_archive/system_version.cpp +++ b/src/core/file_sys/system_archive/system_version.cpp @@ -40,10 +40,14 @@ VirtualDir SystemVersion() { VirtualFile file = std::make_shared(file_data, "file"); // the "/digest" - std::vector digest_data(sizeof(HLE::ApiVersion::VERSION_DIGEST)); - std::memcpy(digest_data.data(), HLE::ApiVersion::VERSION_DIGEST, sizeof(HLE::ApiVersion::VERSION_DIGEST)); - VirtualFile digest_file = std::make_shared(digest_data, "digest"); - return std::make_shared(std::vector{file, digest_file}, std::vector{}, "data"); + if (HLE::ApiVersion::VERSION_DIGEST[0] == '\0') { + return std::make_shared(std::vector{file}, std::vector{}, "data"); + } else { + std::vector digest_data(sizeof(HLE::ApiVersion::VERSION_DIGEST)); + std::memcpy(digest_data.data(), HLE::ApiVersion::VERSION_DIGEST, sizeof(HLE::ApiVersion::VERSION_DIGEST)); + VirtualFile digest_file = std::make_shared(digest_data, "digest"); + return std::make_shared(std::vector{file, digest_file}, std::vector{}, "data"); + } } } // namespace FileSys::SystemArchive diff --git a/src/core/hle/api_version.h b/src/core/hle/api_version.h index 29b4f4008c..0aff969296 100644 --- a/src/core/hle/api_version.h +++ b/src/core/hle/api_version.h @@ -16,8 +16,8 @@ namespace HLE::ApiVersion { // Horizon OS version constants. -constexpr u8 HOS_VERSION_MAJOR = 22; -constexpr u8 HOS_VERSION_MINOR = 5; +constexpr u8 HOS_VERSION_MAJOR = 23; +constexpr u8 HOS_VERSION_MINOR = 0; constexpr u8 HOS_VERSION_MICRO = 0; // NintendoSDK version constants. @@ -25,15 +25,16 @@ constexpr u8 SDK_REVISION_MAJOR = 1; constexpr u8 SDK_REVISION_MINOR = 0; constexpr char PLATFORM_STRING[0x20] = "NX"; -constexpr char VERSION_HASH[0x40] = "ae93061abbc7791fcf8d2f7e7b7b2d62163af697"; -constexpr char DISPLAY_VERSION[0x18] = "22.5.0"; -constexpr char DISPLAY_TITLE[0x80] = "NintendoSDK Firmware for NX 22.5.0-1.0 "; -constexpr char VERSION_DIGEST[0x40] = "CusHY#00160500#WxlZDREksAFSi6bQJEV6nm6-cHLg2jikdYRVN3bwqyE="; +constexpr char VERSION_HASH[0x40] = "c2663accb7490a6ccfe9bc4dfd120ca215490525"; +constexpr char DISPLAY_VERSION[0x18] = "23.0.0"; +constexpr char DISPLAY_TITLE[0x80] = "NintendoSDK Firmware for NX 23.0.0-4.0"; +// Leave empty when there's no digest (N/A) +constexpr char VERSION_DIGEST[0x40] = ""; // Atmosphere version constants. constexpr u8 ATMOSPHERE_RELEASE_VERSION_MAJOR = 1; -constexpr u8 ATMOSPHERE_RELEASE_VERSION_MINOR = 11; -constexpr u8 ATMOSPHERE_RELEASE_VERSION_MICRO = 2; +constexpr u8 ATMOSPHERE_RELEASE_VERSION_MINOR = 12; +constexpr u8 ATMOSPHERE_RELEASE_VERSION_MICRO = 0; constexpr u32 AtmosphereTargetFirmwareWithRevision(u8 major, u8 minor, u8 micro, u8 rev) { return u32{major} << 24 | u32{minor} << 16 | u32{micro} << 8 | u32{rev}; diff --git a/src/core/hle/kernel/svc/svc_info.cpp b/src/core/hle/kernel/svc/svc_info.cpp index e6190ac33a..863bb58fa8 100644 --- a/src/core/hle/kernel/svc/svc_info.cpp +++ b/src/core/hle/kernel/svc/svc_info.cpp @@ -210,6 +210,13 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle *result = system.Kernel().CurrentScheduler()->GetIdleThread()->GetCpuTime(); R_SUCCEED(); } + case InfoType::Unknown37: + case InfoType::Unknown38: { + LOG_WARNING(Kernel_SVC, "(STUBBED) called, info_id={:#x}, info_sub_id={:#x}, handle={:#08x}", + info_id, info_sub_id, handle); + *result = 0; + R_SUCCEED(); + } case InfoType::MesosphereMeta: { enum MesosphereMetaInfo : u64 { KernelVersion = 0, diff --git a/src/core/hle/kernel/svc_types.h b/src/core/hle/kernel/svc_types.h index fce3dea476..b0f4796da4 100644 --- a/src/core/hle/kernel/svc_types.h +++ b/src/core/hle/kernel/svc_types.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project @@ -158,6 +158,11 @@ enum class InfoType : u32 { IoRegionHint = 27, AliasRegionExtraSize = 28, + TransferMemoryHint = 34, + + Unknown37 = 37, + Unknown38 = 38, + MesosphereMeta = 65000, MesosphereCurrentProcess = 65001, }; diff --git a/src/core/hle/service/am/service/application_creator.cpp b/src/core/hle/service/am/service/application_creator.cpp index e3bb92c3a4..4eb2f29e22 100644 --- a/src/core/hle/service/am/service/application_creator.cpp +++ b/src/core/hle/service/am/service/application_creator.cpp @@ -16,6 +16,7 @@ #include "core/hle/service/cmif_serialization.h" #include "core/loader/loader.h" #include "core/launch_timestamp_cache.h" +#include "core/hle/api_version.h" namespace Service::AM { @@ -87,7 +88,7 @@ Result IApplicationCreator::CreateSystemApplication( std::vector control; std::unique_ptr loader; - auto process = CreateProcess(system, application_id, 1, 22); + auto process = CreateProcess(system, application_id, 1, HLE::ApiVersion::HOS_VERSION_MAJOR); R_UNLESS(process != nullptr, ResultUnknown); const auto applet = std::make_shared(system, std::move(process), true); diff --git a/src/core/hle/service/am/service/library_applet_creator.cpp b/src/core/hle/service/am/service/library_applet_creator.cpp index c20a77f8c4..ce80ce946f 100644 --- a/src/core/hle/service/am/service/library_applet_creator.cpp +++ b/src/core/hle/service/am/service/library_applet_creator.cpp @@ -13,6 +13,8 @@ #include "core/hle/service/am/process_creation.h" #include "core/hle/service/am/service/library_applet_accessor.h" #include "core/hle/service/am/service/library_applet_creator.h" + +#include "core/hle/api_version.h" #include "core/hle/service/am/service/storage.h" #include "core/hle/service/am/window_system.h" #include "core/hle/service/cmif_serialization.h" @@ -108,20 +110,7 @@ std::shared_ptr CreateGuestApplet(Core::System& system, return {}; } - // TODO: enable other versions of applets - enum : u8 { - Firmware1400 = 14, - Firmware1500 = 15, - Firmware1600 = 16, - Firmware1700 = 17, - Firmware1800 = 18, - Firmware1900 = 19, - Firmware2000 = 20, - Firmware2100 = 21, - Firmware2200 = 22, - }; - - auto process = CreateProcess(system, program_id, Firmware1400, Firmware2200); + auto process = CreateProcess(system, program_id, 1, HLE::ApiVersion::HOS_VERSION_MAJOR); if (process) { const auto applet = std::make_shared(system, std::move(process), false); applet->program_id = program_id; diff --git a/src/core/hle/service/am/service/self_controller.cpp b/src/core/hle/service/am/service/self_controller.cpp index 70ce7443c4..3a654b9daa 100644 --- a/src/core/hle/service/am/service/self_controller.cpp +++ b/src/core/hle/service/am/service/self_controller.cpp @@ -71,6 +71,7 @@ ISelfController::ISelfController(Core::System& system_, std::shared_ptr {120, D<&ISelfController::SaveCurrentScreenshot>, "SaveCurrentScreenshot"}, {130, D<&ISelfController::SetRecordVolumeMuted>, "SetRecordVolumeMuted"}, {230, D<&ISelfController::Unknown230>, "Unknown230"}, + {240, D<&ISelfController::Unknown240>, "Unknown240"}, {1000, nullptr, "GetDebugStorageChannel"}, }; // clang-format on @@ -422,4 +423,10 @@ Result ISelfController::Unknown230(u32 in_val, Out out_val) { R_SUCCEED(); } +Result ISelfController::Unknown240(u32 in_val) { + LOG_WARNING(Service_AM, "(STUBBED) called, in_val={}", in_val); + + R_SUCCEED(); +} + } // namespace Service::AM diff --git a/src/core/hle/service/am/service/self_controller.h b/src/core/hle/service/am/service/self_controller.h index b6403abde2..c9f480f575 100644 --- a/src/core/hle/service/am/service/self_controller.h +++ b/src/core/hle/service/am/service/self_controller.h @@ -68,6 +68,7 @@ private: Result SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option); Result SetRecordVolumeMuted(bool muted); Result Unknown230(u32 in_val, Out out_val); + Result Unknown240(u32 in_val); Kernel::KProcess* const m_process; const std::shared_ptr m_applet; diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp index fdbd50ed7a..7d270b7b6f 100644 --- a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp @@ -54,7 +54,7 @@ FSP_SRV::FSP_SRV(Core::System& system_) static const FunctionInfo functions[] = { {0, nullptr, "OpenFileSystem"}, {1, D<&FSP_SRV::SetCurrentProcess>, "SetCurrentProcess"}, - {2, nullptr, "OpenDataFileSystemByCurrentProcess"}, + {2, D<&FSP_SRV::OpenDataFileSystemByCurrentProcess>, "OpenDataFileSystemByCurrentProcess"}, {7, D<&FSP_SRV::OpenFileSystemWithPatch>, "OpenFileSystemWithPatch"}, {8, nullptr, "OpenFileSystemWithId"}, {9, nullptr, "OpenDataFileSystemByApplicationId"}, @@ -118,6 +118,7 @@ FSP_SRV::FSP_SRV(Core::System& system_) {204, nullptr, "OpenDataFileSystemByProgramIndex"}, {205, D<&FSP_SRV::OpenDataStorageWithProgramIndex>, "OpenDataStorageWithProgramIndex"}, {206, nullptr, "OpenDataStorageByPath"}, + {210, D<&FSP_SRV::SetCurrentProcess>, "SetCurrentProcess"}, {400, nullptr, "OpenDeviceOperator"}, {500, nullptr, "OpenSdCardDetectionEventNotifier"}, {501, nullptr, "OpenGameCardDetectionEventNotifier"}, @@ -460,6 +461,31 @@ Result FSP_SRV::OpenSaveDataTransferProhibiter( R_SUCCEED(); } +Result FSP_SRV::OpenDataFileSystemByCurrentProcess(OutInterface out_interface) { + LOG_DEBUG(Service_FS, "called"); + + if (!romfs) { + auto current_romfs = romfs_controller->OpenRomFSCurrentProcess(); + if (!current_romfs) { + LOG_CRITICAL(Service_FS, "No file system interface available!"); + R_RETURN(ResultUnknown); + } + + romfs = current_romfs; + } + + auto extracted_romfs = FileSys::ExtractRomFS(romfs); + if (!extracted_romfs) { + LOG_CRITICAL(Service_FS, "Failed to extract RomFS for the current process!"); + R_RETURN(ResultUnknown); + } + + *out_interface = std::make_shared( + system, extracted_romfs, SizeGetter::FromStorageId(fsc, FileSys::StorageId::NandUser)); + + R_SUCCEED(); +} + Result FSP_SRV::OpenDataStorageByCurrentProcess(OutInterface out_interface) { LOG_DEBUG(Service_FS, "called"); diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.h b/src/core/hle/service/filesystem/fsp/fsp_srv.h index 0ea41903e4..156cf4e571 100644 --- a/src/core/hle/service/filesystem/fsp/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp/fsp_srv.h @@ -51,6 +51,7 @@ public: private: Result SetCurrentProcess(ClientProcessId pid); + Result OpenDataFileSystemByCurrentProcess(OutInterface out_interface); Result OpenFileSystemWithPatch(OutInterface out_interface, FileSystemProxyType type, u64 open_program_id); Result OpenSdCardFileSystem(OutInterface out_interface); diff --git a/src/core/hle/service/pctl/parental_control_service.cpp b/src/core/hle/service/pctl/parental_control_service.cpp index 97c178799e..51953c2657 100644 --- a/src/core/hle/service/pctl/parental_control_service.cpp +++ b/src/core/hle/service/pctl/parental_control_service.cpp @@ -4,6 +4,8 @@ // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include + #include "core/core.h" #include "core/file_sys/control_metadata.h" #include "core/file_sys/patch_manager.h" @@ -94,6 +96,7 @@ IParentalControlService::IParentalControlService(Core::System& system_, Capabili {1457, D<&IParentalControlService::GetPlayTimerEventToRequestSuspension>, "GetPlayTimerEventToRequestSuspension"}, {1458, D<&IParentalControlService::IsPlayTimerAlarmDisabled>, "IsPlayTimerAlarmDisabled"}, {1459, D<&IParentalControlService::GetPlayTimerRemainingTimeDisplayInfo>, "GetPlayTimerRemainingTimeDisplayInfo"}, + {1460, D<&IParentalControlService::Unknown1460>, "Unknown1460"}, {1471, nullptr, "NotifyWrongPinCodeInputManyTimes"}, {1472, nullptr, "CancelNetworkRequest"}, {1473, D<&IParentalControlService::GetUnlinkedEvent>, "GetUnlinkedEvent"}, @@ -440,8 +443,15 @@ Result IParentalControlService::IsPlayTimerAlarmDisabled(Out out_play_time R_SUCCEED(); } -Result IParentalControlService::GetPlayTimerRemainingTimeDisplayInfo(/* Out 0x18 */) { - LOG_INFO(Service_PCTL, "called"); +Result IParentalControlService::GetPlayTimerRemainingTimeDisplayInfo(Out out_display_info) { + LOG_DEBUG(Service_PCTL, "called"); + *out_display_info = {.state = PlayTimerDisplayState::NotConfigured}; + R_SUCCEED(); +} + +Result IParentalControlService::Unknown1460(u8 in_unk, Out out_display_info) { + LOG_DEBUG(Service_PCTL, "called, in_unk={}", in_unk); + *out_display_info = {.state = PlayTimerDisplayState::NotConfigured}; R_SUCCEED(); } diff --git a/src/core/hle/service/pctl/parental_control_service.h b/src/core/hle/service/pctl/parental_control_service.h index 92d1d38429..9dabe3d059 100644 --- a/src/core/hle/service/pctl/parental_control_service.h +++ b/src/core/hle/service/pctl/parental_control_service.h @@ -55,7 +55,8 @@ private: Result GetPlayTimerSettingsOld(Out out_play_timer_settings); Result GetPlayTimerEventToRequestSuspension(OutCopyHandle out_event); Result IsPlayTimerAlarmDisabled(Out out_play_timer_alarm_disabled); - Result GetPlayTimerRemainingTimeDisplayInfo(); + Result GetPlayTimerRemainingTimeDisplayInfo(Out out_display_info); + Result Unknown1460(u8 in_unk, Out out_display_info); Result GetUnlinkedEvent(OutCopyHandle out_event); Result GetStereoVisionRestriction(Out out_stereo_vision_restriction); Result SetStereoVisionRestriction(bool stereo_vision_restriction); diff --git a/src/core/hle/service/pctl/pctl_types.h b/src/core/hle/service/pctl/pctl_types.h index a559c5d35f..3a5a19099d 100644 --- a/src/core/hle/service/pctl/pctl_types.h +++ b/src/core/hle/service/pctl/pctl_types.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project @@ -49,4 +49,25 @@ struct PlayTimerSettings { }; static_assert(sizeof(PlayTimerSettings) == 0x44, "PlayTimerSettings has incorrect size."); +enum class PlayTimerDisplayState : u8 { + TimesUp = 0, + BedtimeAlarm = 1, + RemainingTime = 2, + Unknown3 = 3, + Unknown4 = 4, + Unknown5 = 5, + TimerDisabled = 6, + NotConfigured = 7, +}; + +// This is nn::pctl::PlayTimerRemainingTimeDisplayInfo +struct PlayTimerRemainingTimeDisplayInfo { + PlayTimerDisplayState state; + INSERT_PADDING_BYTES(0x7); + u64 unknown_08; + u64 remaining_time; +}; +static_assert(sizeof(PlayTimerRemainingTimeDisplayInfo) == 0x18, + "PlayTimerRemainingTimeDisplayInfo has incorrect size."); + } // namespace Service::PCTL