From c1fbe684ef7981e5b3c48ce9027b6ea81092eec0 Mon Sep 17 00:00:00 2001 From: Takoroka <137927095+Takoroka@users.noreply.github.com> Date: Thu, 29 Oct 2026 03:22:44 -0400 Subject: core: use the 12 GiB layout and auto-stub IPC for Switch 2 titles Switch 2 titles size their heap from the total memory and stop at the first unimplemented command, so they only booted with the 12 GiB layout and EDEN_NX2_AUTO_STUB set by hand. Detect them from main.npdm before the kernel starts and apply the layout as a per-game value (the configured layout comes back once the game is closed), and auto-stub unknown commands from Switch 2 processes. --- src/core/core.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/core/core.cpp') diff --git a/src/core/core.cpp b/src/core/core.cpp index eee91ef4fc..f3d224b1ce 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -24,6 +24,7 @@ #include "core/device_memory.h" #include "core/file_sys/fs_filesystem.h" #include "core/file_sys/patch_manager.h" +#include "core/file_sys/program_metadata.h" #include "core/file_sys/registered_cache.h" #include "core/file_sys/romfs_factory.h" #include "core/file_sys/savedata_factory.h" @@ -109,6 +110,19 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, return vfs->OpenFile(path, FileSys::OpenMode::Read); } +namespace { + +// Switch 2 titles boot as a loose ExeFS, with main.npdm next to main. +bool IsSwitch2Program(const FileSys::VirtualFile& file) { + const auto dir = file != nullptr ? file->GetContainingDirectory() : nullptr; + const auto npdm = dir != nullptr ? dir->GetFile("main.npdm") : nullptr; + FileSys::ProgramMetadata metadata; + return npdm != nullptr && metadata.Load(npdm) == Loader::ResultStatus::Success && + metadata.IsSwitch2(); +} + +} // namespace + struct System::Impl { explicit Impl(System& system) : kernel{system}, fs_controller{system}, hid_core{kernel}, cpu_manager{system}, @@ -299,6 +313,16 @@ struct System::Impl { fs_controller.InitTempStorage(); } + // Switch 2 titles size their heap from the total memory and need the 12 GiB layout. Set it + // as a per-game value, so RestoreGlobalState brings back the configured layout afterwards. + if (virtual_filesystem != nullptr && + Settings::values.memory_layout_mode.GetValue() != Settings::MemoryLayout::Memory_12Gb && + IsSwitch2Program(GetGameFileFromPath(virtual_filesystem, filepath))) { + LOG_INFO(Core, "Switch 2 program: using the 12 GiB memory layout"); + Settings::values.memory_layout_mode.SetGlobal(false); + Settings::values.memory_layout_mode.SetValue(Settings::MemoryLayout::Memory_12Gb); + } + InitializeKernel(system); if (params.applet_type == Service::AM::AppletType::Application) { -- cgit v1.2.3