diff --git a/Makefile b/Makefile index d85056f77..26bc306a7 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,10 @@ $(strip $1): @echo "Building $(strip $1)" @$$(MAKE) -f $(CURRENT_DIRECTORY)/atmosphere.mk ATMOSPHERE_MAKEFILE_TARGET="$(strip $1)" ATMOSPHERE_BUILD_NAME="$(strip $2)" ATMOSPHERE_BOARD="$(strip $3)" ATMOSPHERE_CPU="$(strip $4)" $(strip $5) +dist-no-debug-$(strip $1): + @echo "Building $(strip $1)" + @$$(MAKE) -f $(CURRENT_DIRECTORY)/atmosphere.mk dist-no-debug ATMOSPHERE_MAKEFILE_TARGET="$(strip $1)" ATMOSPHERE_BUILD_NAME="$(strip $2)" ATMOSPHERE_BOARD="$(strip $3)" ATMOSPHERE_CPU="$(strip $4)" $(strip $5) + clean-$(strip $1): @echo "Cleaning $(strip $1)" @$$(MAKE) -f $(CURRENT_DIRECTORY)/atmosphere.mk clean ATMOSPHERE_MAKEFILE_TARGET="$(strip $1)" ATMOSPHERE_BUILD_NAME="$(strip $2)" ATMOSPHERE_BOARD="$(strip $3)" ATMOSPHERE_CPU="$(strip $4)" $(strip $5) diff --git a/atmosphere.mk b/atmosphere.mk index 7d80c94be..691597a3e 100644 --- a/atmosphere.mk +++ b/atmosphere.mk @@ -54,7 +54,7 @@ dist: dist-no-debug cp $(CURRENT_DIRECTORY)/troposphere/daybreak/daybreak.elf $(DIST_DIR)/daybreak.elf cp $(CURRENT_DIRECTORY)/troposphere/haze/haze.elf $(DIST_DIR)/haze.elf cp $(CURRENT_DIRECTORY)/troposphere/reboot_to_payload/reboot_to_payload.elf $(DIST_DIR)/reboot_to_payload.elf - cd $(DIST_DIR); zip -r ../atmosphere-$(ATMOSPHERE_VERSION)-debug.zip ./*; cd ../; + cd $(DIST_DIR); zip -1 -r ../atmosphere-$(ATMOSPHERE_VERSION)-debug.zip ./*; cd ../; rm -rf $(DIST_DIR) dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR) diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp index 899de49db..c3b92f62e 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp @@ -111,6 +111,7 @@ namespace ams::erpt { struct CreateReportOptionFlag { using SubmitFsInfo = util::BitFlagSet::Flag<0>; + using Unknown0x20000 = util::BitFlagSet::Flag<17>; /* TODO: What is this, it's checked in Reporter::CreateReport or below */ }; using CreateReportOptionFlagSet = util::BitFlagSet; diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_game_card.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_game_card.hpp index ccfc0fc8f..44cc8bdd4 100644 --- a/libraries/libstratosphere/include/stratosphere/fs/fs_game_card.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs/fs_game_card.hpp @@ -52,7 +52,8 @@ namespace ams::fs { struct GameCardErrorReportInfo { u16 game_card_crc_error_num; - u16 reserved1; + u8 last_deactivate_reason; + u8 reserved1; u16 asic_crc_error_num; u16 reserved2; u16 refresh_num; @@ -73,7 +74,8 @@ namespace ams::fs { u32 awaken_count; u32 read_count_from_insert; u32 read_count_from_awaken; - u8 reserved5[8]; + u32 last_deactivate_reason_result; + u32 reserved5; }; static_assert(util::is_pod::value); static_assert(sizeof(GameCardErrorReportInfo) == 0x40); diff --git a/libraries/libstratosphere/include/stratosphere/util/util_compression.hpp b/libraries/libstratosphere/include/stratosphere/util/util_compression.hpp index a9f03641b..543503d65 100644 --- a/libraries/libstratosphere/include/stratosphere/util/util_compression.hpp +++ b/libraries/libstratosphere/include/stratosphere/util/util_compression.hpp @@ -18,14 +18,18 @@ #include namespace ams::util { + + constexpr size_t DecompressZstdWithBicWorkBufferSizeDefault = 0x176E8; /* Compression utilities. */ int CompressLZ4(void *dst, size_t dst_size, const void *src, size_t src_size); size_t CompressZstd(void *dst, size_t dst_size, const void *src, size_t src_size); + size_t CompressZstdWithBic(void *dst, size_t dst_size, const void *src, size_t src_size); /* Decompression utilities. */ int DecompressLZ4(void *dst, size_t dst_size, const void *src, size_t src_size); size_t DecompressZstd(void *dst, size_t dst_size, const void *src, size_t src_size); - bool DecompressZstdForLoader(void* workspace, size_t workspace_size, void *dst, size_t dst_size, size_t expected_dec_size, const void *src, size_t src_size); + size_t DecompressZstdWithBic(void *dst, size_t dst_size, const void *src, size_t src_size); + bool DecompressZstdWithBic(void* workspace, size_t workspace_size, void *dst, size_t dst_size, size_t expected_dec_size, const void *src, size_t src_size); } \ No newline at end of file diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.hpp index 5d9d7ad17..b032a6ca1 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.hpp @@ -19,5 +19,6 @@ namespace ams::erpt::srv { Result SubmitFsInfo(); + void ClearFsInfo(); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp index 1b7840783..dda71d939 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp @@ -363,6 +363,8 @@ namespace ams::erpt::srv { R_ABORT_UNLESS(record->Add(FieldId_GameCardReadCountFromAwaken, ei.read_count_from_awaken)); R_ABORT_UNLESS(record->Add(FieldId_GameCardLastReadErrorPageAddress, ei.last_read_error_page_address)); R_ABORT_UNLESS(record->Add(FieldId_GameCardLastReadErrorPageCount, ei.last_read_error_page_count)); + R_ABORT_UNLESS(record->Add(FieldId_GameCardLastDeactivateReasonResult, ei.last_deactivate_reason_result)); + R_ABORT_UNLESS(record->Add(FieldId_GameCardLastDeactivateReason, ei.last_deactivate_reason)); /* Submit the record. */ R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); @@ -496,4 +498,27 @@ namespace ams::erpt::srv { R_SUCCEED(); } + void ClearFsInfo() { + Context::ClearContext(CategoryId_NANDTypeInfo); + Context::ClearContext(CategoryId_NANDSpeedModeInfo); + Context::ClearContext(CategoryId_NANDExtendedCsd); + Context::ClearContext(CategoryId_NANDPatrolInfo); + Context::ClearContext(CategoryId_NANDErrorInfo); + Context::ClearContext(CategoryId_NANDDriverLog); + Context::ClearContext(CategoryId_MicroSDTypeInfo); + Context::ClearContext(CategoryId_MicroSDSpeedModeInfo); + Context::ClearContext(CategoryId_SdCardSizeSpec); + Context::ClearContext(CategoryId_SdCardActivationInfo); + Context::ClearContext(CategoryId_SdCardErrorInfo); + Context::ClearContext(CategoryId_SdCardDriverLog); + Context::ClearContext(CategoryId_GameCardCIDInfo); + Context::ClearContext(CategoryId_GameCardErrorInfo); + Context::ClearContext(CategoryId_GameCardDetailedErrorInfo); + Context::ClearContext(CategoryId_GameCardLogInfo); + Context::ClearContext(CategoryId_FsProxyErrorInfo); + Context::ClearContext(CategoryId_FsProxyErrorInfo2); + Context::ClearContext(CategoryId_FsProxyErrorInfo3); + Context::ClearContext(CategoryId_FsMemoryInfo); + } + } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp index d24736272..cb26409f1 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp @@ -426,13 +426,7 @@ namespace ams::erpt::srv { auto report_guard = SCOPE_GUARD { const auto delete_res = report->Delete(); R_ASSERT(delete_res); - AMS_UNUSED(delete_res); - /* if (erpt::ResultInvalidPowerState::Includes(result)) { - * Nintendo ignores this and sends "power_state_violation" play report if this error happens. - * } else { - * Nintendo sends "write_failure" play report if any other error happens. - * } - */ + AMS_UNUSED(delete_res); }; R_TRY(Context::WriteContextsToReport(report.get())); @@ -499,6 +493,20 @@ namespace ams::erpt::srv { static_cast(Context::ClearContext(CategoryId_ErrorInfo)); static_cast(Context::ClearContext(CategoryId_ErrorInfoAuto)); static_cast(Context::ClearContext(CategoryId_ErrorInfoDefaults)); + + #if defined(ATMOSPHERE_OS_HORIZON) + /* TODO: What else is missing? */ + if (hos::GetVersion() >= hos::Version_17_0_0 && flags.Test()) { + ClearFsInfo(); + } + + /* if (erpt::ResultInvalidPowerState::Includes(...)) { + * Nintendo ignores this and sends "power_state_violation" play report if this error happens. + * } else { + * Nintendo sends "write_failure" play report if any other error happens. + * } + */ + #endif }; /* Get the context entry pointer. */ diff --git a/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_board_driver_api.cpp b/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_board_driver_api.cpp index 827a02c1c..e687f9bbc 100644 --- a/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_board_driver_api.cpp +++ b/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_board_driver_api.cpp @@ -104,25 +104,25 @@ namespace ams::pinmux::driver::board::nintendo::nx { #if defined(AMS_PINMUX_CONFIG_RIGHT_RAIL_AS_UART) UpdateSinglePinmuxPad({ .index = PinmuxPadIndex_Uart2Tx, - .option = 0, /* PinmuxPadPm_Pm0 | PinmuxOpt_NoPupd | PinmuxOpt_Output */ - .option_mask = (0x7|0x18|0x60), /* PinmuxOptBitMask_Pm | PinmuxOptBitMask_Pupd | PinmuxOptBitMask_Dir */ + .option = (u32)PinmuxPadPm_Pm0 | PinmuxOpt_NoPupd | PinmuxOpt_Output, + .option_mask = (u32)PinmuxOptBitMask_Pm | PinmuxOptBitMask_Pupd | PinmuxOptBitMask_Dir, }); UpdateSinglePinmuxPad({ .index = PinmuxPadIndex_Uart2Cts, - .option = 0x20, /* PinmuxPadPm_Pm0 | PinmuxOpt_NoPupd | PinmuxOpt_Input */ - .option_mask = (0x7|0x18|0x60), /* PinmuxOptBitMask_Pm | PinmuxOptBitMask_Pupd | PinmuxOptBitMask_Dir */ + .option = (u32)PinmuxPadPm_Pm0 | PinmuxOpt_NoPupd | PinmuxOpt_Input, + .option_mask = (u32)PinmuxOptBitMask_Pm | PinmuxOptBitMask_Pupd | PinmuxOptBitMask_Dir, }); #endif #if defined(AMS_PINMUX_CONFIG_LEFT_RAIL_AS_UART) UpdateSinglePinmuxPad({ .index = PinmuxPadIndex_Uart3Tx, - .option = 0, /* PinmuxPadPm_Pm0 | PinmuxOpt_NoPupd | PinmuxOpt_Output */ - .option_mask = (0x7|0x18|0x60), /* PinmuxOptBitMask_Pm | PinmuxOptBitMask_Pupd | PinmuxOptBitMask_Dir */ + .option = (u32)PinmuxPadPm_Pm0 | PinmuxOpt_NoPupd | PinmuxOpt_Output, + .option_mask = (u32)PinmuxOptBitMask_Pm | PinmuxOptBitMask_Pupd | PinmuxOptBitMask_Dir, }); UpdateSinglePinmuxPad({ .index = PinmuxPadIndex_Uart3Cts, - .option = 0x20, /* PinmuxPadPm_Pm0 | PinmuxOpt_NoPupd | PinmuxOpt_Input */ - .option_mask = (0x7|0x18|0x60), /* PinmuxOptBitMask_Pm | PinmuxOptBitMask_Pupd | PinmuxOptBitMask_Dir */ + .option = (u32)PinmuxPadPm_Pm0 | PinmuxOpt_NoPupd | PinmuxOpt_Input, + .option_mask = (u32)PinmuxOptBitMask_Pm | PinmuxOptBitMask_Pupd | PinmuxOptBitMask_Dir, }); #endif } diff --git a/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_platform_pads.cpp b/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_platform_pads.cpp index c7c9de2c2..081b7aba7 100644 --- a/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_platform_pads.cpp +++ b/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_platform_pads.cpp @@ -24,170 +24,6 @@ namespace ams::pinmux::driver::board::nintendo::nx { uintptr_t g_apb_misc_virtual_address = dd::QueryIoMapping(0x70000000, 0x4000); - enum PinmuxPadMask : u32 { - PinmuxPadMask_Pm = 0x3, - PinmuxPadMask_Pupd = 0xC, - PinmuxPadMask_Tristate = 0x10, - PinmuxPadMask_Park = 0x20, - PinmuxPadMask_EInput = 0x40, - PinmuxPadMask_Lock = 0x80, - PinmuxPadMask_ELpdr = 0x100, - PinmuxPadMask_EHsm = 0x200, - PinmuxPadMask_EIoHv = 0x400, - PinmuxPadMask_EOd = 0x800, - PinmuxPadMask_ESchmt = 0x1000, - PinmuxPadMask_DrvType = 0x6000, - PinmuxPadMask_Preemp = 0x8000, - PinmuxPadMask_IoReset = 0x10000, - }; - - enum PinmuxPadBitOffset : u32 { - PinmuxPadBitOffset_Pm = 0x0, - PinmuxPadBitOffset_Pupd = 0x2, - PinmuxPadBitOffset_Tristate = 0x4, - PinmuxPadBitOffset_Park = 0x5, - PinmuxPadBitOffset_EInput = 0x6, - PinmuxPadBitOffset_Lock = 0x7, - PinmuxPadBitOffset_ELpdr = 0x8, - PinmuxPadBitOffset_EHsm = 0x9, - PinmuxPadBitOffset_EIoHv = 0xA, - PinmuxPadBitOffset_EOd = 0xB, - PinmuxPadBitOffset_ESchmt = 0xC, - PinmuxPadBitOffset_DrvType = 0xD, - PinmuxPadBitOffset_Preemp = 0xF, - PinmuxPadBitOffset_IoReset = 0x10, - }; - - enum PinmuxOptBitMask : u32 { - PinmuxOptBitMask_Pm = 0x7, - PinmuxOptBitMask_Pupd = 0x18, - PinmuxOptBitMask_Dir = 0x60, - PinmuxOptBitMask_Lock = 0x80, - PinmuxOptBitMask_IoReset = 0x100, - PinmuxOptBitMask_IoHv = 0x200, - PinmuxOptBitMask_Park = 0x400, - PinmuxOptBitMask_Lpdr = 0x800, - PinmuxOptBitMask_Hsm = 0x1000, - PinmuxOptBitMask_Schmt = 0x2000, - PinmuxOptBitMask_DrvType = 0xC000, - PinmuxOptBitMask_Preemp = 0x10000, - }; - - enum PinmuxOptBitOffset { - PinmuxOptBitOffset_Pm = 0x0, - PinmuxOptBitOffset_Pupd = 0x3, - PinmuxOptBitOffset_Dir = 0x5, - PinmuxOptBitOffset_Lock = 0x7, - PinmuxOptBitOffset_IoReset = 0x8, - PinmuxOptBitOffset_IoHv = 0x9, - PinmuxOptBitOffset_Park = 0xA, - PinmuxOptBitOffset_Lpdr = 0xB, - PinmuxOptBitOffset_Hsm = 0xC, - PinmuxOptBitOffset_Schmt = 0xD, - PinmuxOptBitOffset_DrvType = 0xE, - PinmuxOptBitOffset_Preemp = 0x10, - }; - - enum PinmuxDrivePadMask : u32{ - PinmuxDrivePadMask_DrvDn = 0x0001F000, - PinmuxDrivePadMask_DrvUp = 0x01F00000, - PinmuxDrivePadMask_CzDrvDn = 0x0007F000, - PinmuxDrivePadMask_CzDrvUp = 0x07F00000, - PinmuxDrivePadMask_SlwR = 0x30000000, - PinmuxDrivePadMask_SlwF = 0xC0000000, - }; - - enum PinmuxDrivePadBitOffset : u32 { - PinmuxDrivePadBitOffset_DrvDn = 12, - PinmuxDrivePadBitOffset_DrvUp = 20, - PinmuxDrivePadBitOffset_CzDrvDn = 12, - PinmuxDrivePadBitOffset_CzDrvUp = 20, - PinmuxDrivePadBitOffset_SlwR = 28, - PinmuxDrivePadBitOffset_SlwF = 30, - }; - - enum PinmuxDriveOptBitMask : u32 { - PinmuxDriveOptBitMask_DrvDn = 0x0001F000, - PinmuxDriveOptBitMask_DrvUp = 0x01F00000, - PinmuxDriveOptBitMask_CzDrvDn = 0x0007F000, - PinmuxDriveOptBitMask_CzDrvUp = 0x07F00000, - PinmuxDriveOptBitMask_SlwR = 0x30000000, - PinmuxDriveOptBitMask_SlwF = 0xC0000000, - }; - - enum PinmuxDriveOptBitOffset : u32 { - PinmuxDriveOptBitOffset_DrvDn = 12, - PinmuxDriveOptBitOffset_DrvUp = 20, - PinmuxDriveOptBitOffset_CzDrvDn = 12, - PinmuxDriveOptBitOffset_CzDrvUp = 20, - PinmuxDriveOptBitOffset_SlwR = 28, - PinmuxDriveOptBitOffset_SlwF = 30, - }; - - enum PinmuxOpt : u32 { - /* Pm */ - PinmuxOpt_Gpio = 0x4, - PinmuxOpt_Unused = 0x5, - - /* Pupd */ - PinmuxOpt_NoPupd = 0x0, - PinmuxOpt_PullDown = 0x8, - PinmuxOpt_PullUp = 0x10, - - /* Dir */ - PinmuxOpt_Output = 0x0, - PinmuxOpt_Input = 0x20, - PinmuxOpt_Bidirection = 0x40, - PinmuxOpt_OpenDrain = 0x60, - - /* Lock */ - PinmuxOpt_Unlock = 0x0, - PinmuxOpt_Lock = 0x80, - - /* IoReset */ - PinmuxOpt_DisableIoReset = 0x0, - PinmuxOpt_EnableIoReset = 0x100, - - /* IoHv */ - PinmuxOpt_NormalVoltage = 0x0, - PinmuxOpt_HighVoltage = 0x200, - - /* Park */ - PinmuxOpt_ResetOnLowPower = 0x0, - PinmuxOpt_ParkOnLowPower = 0x400, - - /* Lpdr */ - PinmuxOpt_DisableBaseDriver = 0x0, - PinmuxOpt_EnableBaseDriver = 0x800, - - /* Hsm */ - PinmuxOpt_DisableHighSpeedMode = 0x0, - PinmuxOpt_EnableHighSpeedMode = 0x1000, - - /* Schmt */ - PinmuxOpt_CmosMode = 0x0, - PinmuxOpt_SchmittTrigger = 0x2000, - - /* DrvType */ - PinmuxOpt_DrvType1X = 0x0, - PinmuxOpt_DrvType2X = 0x4000, - PinmuxOpt_DrvType3X = 0x8000, - PinmuxOpt_DrvType4X = 0xC000, - - /* Preemp */ - PinmuxOpt_DisablePreemp = 0x0, - PinmuxOpt_EnablePreemp = 0x10000, - }; - - enum PinmuxPadPm : u32 { - PinmuxPadPm_Default = 0xFFFFFFFF, - PinmuxPadPm_Pm0 = 0x0, - PinmuxPadPm_Pm1 = 0x1, - PinmuxPadPm_Pm2 = 0x2, - PinmuxPadPm_Pm3 = 0x3, - PinmuxPadPm_Safe = 0x4, - }; - struct PinmuxPadCharacter { u32 reg_offset; u32 reg_mask; diff --git a/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_platform_pads.hpp b/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_platform_pads.hpp index 6ec386b70..5e1087d13 100644 --- a/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_platform_pads.hpp +++ b/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_platform_pads.hpp @@ -30,6 +30,170 @@ namespace ams::pinmux::driver::board::nintendo::nx { u32 option_mask; }; + enum PinmuxPadMask : u32 { + PinmuxPadMask_Pm = 0x3, + PinmuxPadMask_Pupd = 0xC, + PinmuxPadMask_Tristate = 0x10, + PinmuxPadMask_Park = 0x20, + PinmuxPadMask_EInput = 0x40, + PinmuxPadMask_Lock = 0x80, + PinmuxPadMask_ELpdr = 0x100, + PinmuxPadMask_EHsm = 0x200, + PinmuxPadMask_EIoHv = 0x400, + PinmuxPadMask_EOd = 0x800, + PinmuxPadMask_ESchmt = 0x1000, + PinmuxPadMask_DrvType = 0x6000, + PinmuxPadMask_Preemp = 0x8000, + PinmuxPadMask_IoReset = 0x10000, + }; + + enum PinmuxPadBitOffset : u32 { + PinmuxPadBitOffset_Pm = 0x0, + PinmuxPadBitOffset_Pupd = 0x2, + PinmuxPadBitOffset_Tristate = 0x4, + PinmuxPadBitOffset_Park = 0x5, + PinmuxPadBitOffset_EInput = 0x6, + PinmuxPadBitOffset_Lock = 0x7, + PinmuxPadBitOffset_ELpdr = 0x8, + PinmuxPadBitOffset_EHsm = 0x9, + PinmuxPadBitOffset_EIoHv = 0xA, + PinmuxPadBitOffset_EOd = 0xB, + PinmuxPadBitOffset_ESchmt = 0xC, + PinmuxPadBitOffset_DrvType = 0xD, + PinmuxPadBitOffset_Preemp = 0xF, + PinmuxPadBitOffset_IoReset = 0x10, + }; + + enum PinmuxOptBitMask : u32 { + PinmuxOptBitMask_Pm = 0x7, + PinmuxOptBitMask_Pupd = 0x18, + PinmuxOptBitMask_Dir = 0x60, + PinmuxOptBitMask_Lock = 0x80, + PinmuxOptBitMask_IoReset = 0x100, + PinmuxOptBitMask_IoHv = 0x200, + PinmuxOptBitMask_Park = 0x400, + PinmuxOptBitMask_Lpdr = 0x800, + PinmuxOptBitMask_Hsm = 0x1000, + PinmuxOptBitMask_Schmt = 0x2000, + PinmuxOptBitMask_DrvType = 0xC000, + PinmuxOptBitMask_Preemp = 0x10000, + }; + + enum PinmuxOptBitOffset { + PinmuxOptBitOffset_Pm = 0x0, + PinmuxOptBitOffset_Pupd = 0x3, + PinmuxOptBitOffset_Dir = 0x5, + PinmuxOptBitOffset_Lock = 0x7, + PinmuxOptBitOffset_IoReset = 0x8, + PinmuxOptBitOffset_IoHv = 0x9, + PinmuxOptBitOffset_Park = 0xA, + PinmuxOptBitOffset_Lpdr = 0xB, + PinmuxOptBitOffset_Hsm = 0xC, + PinmuxOptBitOffset_Schmt = 0xD, + PinmuxOptBitOffset_DrvType = 0xE, + PinmuxOptBitOffset_Preemp = 0x10, + }; + + enum PinmuxDrivePadMask : u32 { + PinmuxDrivePadMask_DrvDn = 0x0001F000, + PinmuxDrivePadMask_DrvUp = 0x01F00000, + PinmuxDrivePadMask_CzDrvDn = 0x0007F000, + PinmuxDrivePadMask_CzDrvUp = 0x07F00000, + PinmuxDrivePadMask_SlwR = 0x30000000, + PinmuxDrivePadMask_SlwF = 0xC0000000, + }; + + enum PinmuxDrivePadBitOffset : u32 { + PinmuxDrivePadBitOffset_DrvDn = 12, + PinmuxDrivePadBitOffset_DrvUp = 20, + PinmuxDrivePadBitOffset_CzDrvDn = 12, + PinmuxDrivePadBitOffset_CzDrvUp = 20, + PinmuxDrivePadBitOffset_SlwR = 28, + PinmuxDrivePadBitOffset_SlwF = 30, + }; + + enum PinmuxDriveOptBitMask : u32 { + PinmuxDriveOptBitMask_DrvDn = 0x0001F000, + PinmuxDriveOptBitMask_DrvUp = 0x01F00000, + PinmuxDriveOptBitMask_CzDrvDn = 0x0007F000, + PinmuxDriveOptBitMask_CzDrvUp = 0x07F00000, + PinmuxDriveOptBitMask_SlwR = 0x30000000, + PinmuxDriveOptBitMask_SlwF = 0xC0000000, + }; + + enum PinmuxDriveOptBitOffset : u32 { + PinmuxDriveOptBitOffset_DrvDn = 12, + PinmuxDriveOptBitOffset_DrvUp = 20, + PinmuxDriveOptBitOffset_CzDrvDn = 12, + PinmuxDriveOptBitOffset_CzDrvUp = 20, + PinmuxDriveOptBitOffset_SlwR = 28, + PinmuxDriveOptBitOffset_SlwF = 30, + }; + + enum PinmuxOpt : u32 { + /* Pm */ + PinmuxOpt_Gpio = 0x4, + PinmuxOpt_Unused = 0x5, + + /* Pupd */ + PinmuxOpt_NoPupd = 0x0, + PinmuxOpt_PullDown = 0x8, + PinmuxOpt_PullUp = 0x10, + + /* Dir */ + PinmuxOpt_Output = 0x0, + PinmuxOpt_Input = 0x20, + PinmuxOpt_Bidirection = 0x40, + PinmuxOpt_OpenDrain = 0x60, + + /* Lock */ + PinmuxOpt_Unlock = 0x0, + PinmuxOpt_Lock = 0x80, + + /* IoReset */ + PinmuxOpt_DisableIoReset = 0x0, + PinmuxOpt_EnableIoReset = 0x100, + + /* IoHv */ + PinmuxOpt_NormalVoltage = 0x0, + PinmuxOpt_HighVoltage = 0x200, + + /* Park */ + PinmuxOpt_ResetOnLowPower = 0x0, + PinmuxOpt_ParkOnLowPower = 0x400, + + /* Lpdr */ + PinmuxOpt_DisableBaseDriver = 0x0, + PinmuxOpt_EnableBaseDriver = 0x800, + + /* Hsm */ + PinmuxOpt_DisableHighSpeedMode = 0x0, + PinmuxOpt_EnableHighSpeedMode = 0x1000, + + /* Schmt */ + PinmuxOpt_CmosMode = 0x0, + PinmuxOpt_SchmittTrigger = 0x2000, + + /* DrvType */ + PinmuxOpt_DrvType1X = 0x0, + PinmuxOpt_DrvType2X = 0x4000, + PinmuxOpt_DrvType3X = 0x8000, + PinmuxOpt_DrvType4X = 0xC000, + + /* Preemp */ + PinmuxOpt_DisablePreemp = 0x0, + PinmuxOpt_EnablePreemp = 0x10000, + }; + + enum PinmuxPadPm : u32 { + PinmuxPadPm_Default = 0xFFFFFFFF, + PinmuxPadPm_Pm0 = 0x0, + PinmuxPadPm_Pm1 = 0x1, + PinmuxPadPm_Pm2 = 0x2, + PinmuxPadPm_Pm3 = 0x3, + PinmuxPadPm_Safe = 0x4, + }; + void InitializePlatformPads(); void UpdateSinglePinmuxPad(const PinmuxPadConfig &config); diff --git a/libraries/libstratosphere/source/util/util_compression_lz4.cpp b/libraries/libstratosphere/source/util/util_compression_lz4.cpp new file mode 100644 index 000000000..f56904f71 --- /dev/null +++ b/libraries/libstratosphere/source/util/util_compression_lz4.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "lz4.h" + +namespace ams::util { + + int CompressLZ4(void *dst, size_t dst_size, const void *src, size_t src_size) { + /* Size checks. */ + AMS_ABORT_UNLESS(dst_size <= std::numeric_limits::max()); + AMS_ABORT_UNLESS(src_size <= std::numeric_limits::max()); + + /* This is just a thin wrapper around LZ4. */ + return LZ4_compress_default(reinterpret_cast(src), reinterpret_cast(dst), static_cast(src_size), static_cast(dst_size)); + } + + int DecompressLZ4(void *dst, size_t dst_size, const void *src, size_t src_size) { + /* Size checks. */ + AMS_ABORT_UNLESS(dst_size <= std::numeric_limits::max()); + AMS_ABORT_UNLESS(src_size <= std::numeric_limits::max()); + + /* This is just a thin wrapper around LZ4. */ + return LZ4_decompress_safe(reinterpret_cast(src), reinterpret_cast(dst), static_cast(src_size), static_cast(dst_size)); + } + +} \ No newline at end of file diff --git a/libraries/libstratosphere/source/util/util_compression_zstd.cpp b/libraries/libstratosphere/source/util/util_compression_zstd.cpp new file mode 100644 index 000000000..6a48780a6 --- /dev/null +++ b/libraries/libstratosphere/source/util/util_compression_zstd.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#define ZSTD_STATIC_LINKING_ONLY + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#define ZSTDLIB_VISIBLE static +#define ZSTDLIB_HIDDEN static +#include "zstd.h" +#include "zstd.inc" +#pragma GCC diagnostic pop + +namespace ams::util { + + size_t CompressZstd(void *dst, size_t dst_size, const void *src, size_t src_size) { + /* Basic size checks. */ + AMS_ABORT_UNLESS(dst_size <= std::numeric_limits::max()); + AMS_ABORT_UNLESS(src_size <= std::numeric_limits::max()); + + /* Additionally, we must check the compression boundary. */ + auto bound = ZSTD_compressBound(src_size); + AMS_ABORT_UNLESS(!ZSTD_isError(bound)); + AMS_ABORT_UNLESS(dst_size >= bound); + + /* Use Zstd default level. */ + int compressionLevel = 3; + + /* This is just a wrapper around Zstd. */ + return ZSTD_compress(dst, dst_size, src, src_size, compressionLevel); + } + + size_t DecompressZstd(void *dst, size_t dst_size, const void *src, size_t src_size) { + /* Basic size checks. */ + AMS_ABORT_UNLESS(dst_size <= std::numeric_limits::max()); + AMS_ABORT_UNLESS(src_size <= std::numeric_limits::max()); + + /* Additionally, we must check the decompression boundary. */ + auto bound = ZSTD_decompressBound(src, src_size); + AMS_ABORT_UNLESS(!ZSTD_isError(bound)); + AMS_ABORT_UNLESS(dst_size >= bound); + + /* This is just a wrapper around Zstd. */ + return ZSTD_decompress(dst, dst_size, src, src_size); + } + +} \ No newline at end of file diff --git a/libraries/libstratosphere/source/util/util_compression.cpp b/libraries/libstratosphere/source/util/util_compression_zstd_bic.cpp similarity index 59% rename from libraries/libstratosphere/source/util/util_compression.cpp rename to libraries/libstratosphere/source/util/util_compression_zstd_bic.cpp index f17021024..a7aa9ebc7 100644 --- a/libraries/libstratosphere/source/util/util_compression.cpp +++ b/libraries/libstratosphere/source/util/util_compression_zstd_bic.cpp @@ -14,24 +14,21 @@ * along with this program. If not, see . */ #include -#include "lz4.h" #define ZSTD_STATIC_LINKING_ONLY #define ZSTD_ZBIC_SUPPORT 1 + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#define ZSTDLIB_VISIBLE static +#define ZSTDLIB_HIDDEN static #include "zstd.h" +#include "zstd.inc" +#pragma GCC diagnostic pop namespace ams::util { + static_assert(sizeof(ZSTD_DCtx) <= DecompressZstdWithBicWorkBufferSizeDefault); - /* Compression utilities. */ - int CompressLZ4(void *dst, size_t dst_size, const void *src, size_t src_size) { - /* Size checks. */ - AMS_ABORT_UNLESS(dst_size <= std::numeric_limits::max()); - AMS_ABORT_UNLESS(src_size <= std::numeric_limits::max()); - - /* This is just a thin wrapper around LZ4. */ - return LZ4_compress_default(reinterpret_cast(src), reinterpret_cast(dst), static_cast(src_size), static_cast(dst_size)); - } - - size_t CompressZstd(void *dst, size_t dst_size, const void *src, size_t src_size) { + size_t CompressZstdWithBic(void *dst, size_t dst_size, const void *src, size_t src_size) { /* Basic size checks. */ AMS_ABORT_UNLESS(dst_size <= std::numeric_limits::max()); AMS_ABORT_UNLESS(src_size <= std::numeric_limits::max()); @@ -44,21 +41,11 @@ namespace ams::util { /* Use Zstd default level. */ int compressionLevel = 3; - /* This is just a wrapper around Zstd. */ + /* This is just a wrapper around Zstd with BIC support enabled. */ return ZSTD_compress(dst, dst_size, src, src_size, compressionLevel); } - - /* Decompression utilities. */ - int DecompressLZ4(void *dst, size_t dst_size, const void *src, size_t src_size) { - /* Size checks. */ - AMS_ABORT_UNLESS(dst_size <= std::numeric_limits::max()); - AMS_ABORT_UNLESS(src_size <= std::numeric_limits::max()); - - /* This is just a thin wrapper around LZ4. */ - return LZ4_decompress_safe(reinterpret_cast(src), reinterpret_cast(dst), static_cast(src_size), static_cast(dst_size)); - } - size_t DecompressZstd(void *dst, size_t dst_size, const void *src, size_t src_size) { + size_t DecompressZstdWithBic(void *dst, size_t dst_size, const void *src, size_t src_size) { /* Basic size checks. */ AMS_ABORT_UNLESS(dst_size <= std::numeric_limits::max()); AMS_ABORT_UNLESS(src_size <= std::numeric_limits::max()); @@ -68,14 +55,22 @@ namespace ams::util { AMS_ABORT_UNLESS(!ZSTD_isError(bound)); AMS_ABORT_UNLESS(dst_size >= bound); - /* This is just a wrapper around Zstd. */ + /* This is just a wrapper around Zstd with BIC support enabled. */ return ZSTD_decompress(dst, dst_size, src, src_size); } - bool DecompressZstdForLoader(void* workspace, size_t workspace_size, void *dst, size_t dst_size, size_t expected_dec_size, const void *src, size_t src_size) { + bool DecompressZstdWithBic(void* workspace, size_t workspace_size, void *dst, size_t dst_size, size_t expected_dec_size, const void *src, size_t src_size) { /* Check decompression margin. */ auto margin = ZSTD_decompressionMargin(src, src_size); if (ZSTD_isError(margin)) { + auto error_code = ZSTD_getErrorCode(margin); + auto error_string = ZSTD_getErrorString(error_code); + + AMS_LOG("[util] Can't determine decompression margin: %u (%s)\n", error_code, error_string); + + /* TODO: Unused variables in non-debug build. */ + AMS_UNUSED(error_code, error_string); + return false; } @@ -86,20 +81,30 @@ namespace ams::util { /* Make sure we fit in the destination buffer. */ if (margin + expected_dec_size > dst_size) { + AMS_LOG("[util] Not enough space for decompression %lu + %lu > %lu\n", margin, expected_dec_size, dst_size); return false; } - /* This is a runtime assert in Loader code. We replicate it here. */ - AMS_ABORT_UNLESS(ZSTD_estimateDCtxSize() == workspace_size); + /* This is a runtime assert in Loader code. Note that Nintendo does == comparison here. */ + AMS_ABORT_UNLESS(ZSTD_estimateDCtxSize() <= workspace_size); /* Decompress using a static decompression context. */ auto dctx = ZSTD_initStaticDCtx(workspace, workspace_size); size_t dec_size = ZSTD_decompressDCtx(dctx, dst, dst_size, src, src_size); if (ZSTD_isError(dec_size)) { + auto error_code = ZSTD_getErrorCode(margin); + auto error_string = ZSTD_getErrorString(error_code); + + AMS_LOG("[util] Decompression failed: %u (%s)\n", error_code, error_string); + + /* TODO: Unused variables in non-debug build. */ + AMS_UNUSED(error_code, error_string); + return false; } + /* Make sure we match the expected size. */ if (dec_size != expected_dec_size) { return false; } diff --git a/libraries/libstratosphere/source/util/zstd.c b/libraries/libstratosphere/source/util/zstd.inc similarity index 100% rename from libraries/libstratosphere/source/util/zstd.c rename to libraries/libstratosphere/source/util/zstd.inc diff --git a/libraries/libvapours/include/vapours/results/results_common.hpp b/libraries/libvapours/include/vapours/results/results_common.hpp index a9a72505b..a013d7c9d 100644 --- a/libraries/libvapours/include/vapours/results/results_common.hpp +++ b/libraries/libvapours/include/vapours/results/results_common.hpp @@ -494,6 +494,14 @@ namespace ams::result::impl { } \ } +#define R_UNLESS_LOG(expr, res, ...) \ + { \ + if (!(expr)) { \ + AMS_LOG(__VA_ARGS__); \ + R_THROW(res); \ + } \ + } + /// Evaluates a boolean expression, and succeeds if that expression is true. #define R_SUCCEED_IF(expr) R_UNLESS(!(expr), ResultSuccess()) diff --git a/stratosphere/loader/source/ldr_process_creation.cpp b/stratosphere/loader/source/ldr_process_creation.cpp index 276484824..bea773f44 100644 --- a/stratosphere/loader/source/ldr_process_creation.cpp +++ b/stratosphere/loader/source/ldr_process_creation.cpp @@ -121,8 +121,7 @@ namespace ams::ldr { NsoHeader g_nso_headers[Nso_Count]; /* Global Zstd decompression context. */ - constexpr size_t ZstdDctxWorkspaceSize = 0x176E8; - alignas(8) u8 g_zstd_dctx_workspace[ZstdDctxWorkspaceSize]; + alignas(8) u8 g_zstd_dctx_workspace[util::DecompressZstdWithBicWorkBufferSizeDefault]; Result ValidateProgramVersion(ncm::ProgramId program_id, u32 version) { /* No version verification is done before 8.1.0. */ @@ -220,7 +219,7 @@ namespace ams::ldr { /* Read NSO header. */ size_t read_size; R_TRY(fs::ReadFile(std::addressof(read_size), file, 0, g_nso_headers + ctx.nso_count, sizeof(NsoHeader))); - R_UNLESS(read_size == sizeof(NsoHeader), ldr::ResultInvalidNso()); + R_UNLESS_LOG(read_size == sizeof(NsoHeader), ldr::ResultInvalidNso(), "[ldr] NSO header truncated!\n"); /* Note nso is present. */ switch (i) { @@ -259,7 +258,7 @@ namespace ams::ldr { Result CheckAutoLoad(const AutoLoadModuleContext &ctx, u32 acid_flags) { /* We must always have a main. */ - R_UNLESS(ctx.ali.has_main, ldr::ResultInvalidNso()); + R_UNLESS_LOG(ctx.ali.has_main, ldr::ResultInvalidNso(), "[ldr] Missing main!\n"); /* Validate flags and extents for all present NSOs. */ for (int i = 0; i < ctx.nso_count; ++i) { @@ -267,11 +266,11 @@ namespace ams::ldr { /* All NSOs must not be --X. */ /* This is "probably" not checked on Ounce? */ - R_UNLESS((hdr.flags & NsoHeader::Flag_PreventCodeReads) == 0, ldr::ResultInvalidNso()); + R_UNLESS_LOG((hdr.flags & NsoHeader::Flag_PreventCodeReads) == 0, ldr::ResultInvalidNso(), "[ldr] NSO[%d] --x not allowed!\n", i); /* Zstd compression only allowed on main, and only when both rtld+sdk are present. */ if (i != ctx.main_nso_idx || ctx.rtld_idx < 0 || ctx.sdk_nso_idx < 0) { - R_UNLESS((hdr.flags & NsoHeader::Flag_UseZbicCompression) == 0, ldr::ResultInvalidNso()); + R_UNLESS_LOG((hdr.flags & NsoHeader::Flag_UseZbicCompression) == 0, ldr::ResultInvalidNso(), "[ldr] NSO[%d] zbic not allowed!\n", i); } /* NSOs must have page-aligned segments. */ @@ -294,13 +293,13 @@ namespace ams::ldr { const bool has_browser_dll = (acid_flags & Acid::AcidFlag_LoadBrowserCoreDll) != 0; if (ctx.ali.has_rtld || ctx.ali.has_sdk) { /* If we have sdk we must have rtld. */ - R_UNLESS(ctx.ali.has_rtld, ldr::ResultInvalidNso()); + R_UNLESS_LOG(ctx.ali.has_rtld, ldr::ResultInvalidNso(), "[ldr] Missing rtld!\n"); /* If we have rtld, we must not have browser core dll. */ - R_UNLESS(!has_browser_dll, ldr::ResultInvalidNso()); + R_UNLESS_LOG(!has_browser_dll, ldr::ResultInvalidNso(), "[ldr] BrowserCoreDll must not be present!\n"); } else { /* We must not have both subsdk and browser dll. */ - R_UNLESS(!(ctx.ali.has_subsdk && has_browser_dll), ldr::ResultInvalidNso()); + R_UNLESS_LOG(!(ctx.ali.has_subsdk && has_browser_dll), ldr::ResultInvalidNso(), "[ldr] Can't have both subsdk and BrowserCoreDll!\n"); } R_SUCCEED(); @@ -385,6 +384,8 @@ namespace ams::ldr { /* If the signature check fails, we need to check if this is allowable. */ if (!is_signature_valid) { + AMS_LOG("[ldr] invalid signature!\n"); + /* We have to enforce signature checks on prod and when we have a signature to check on dev. */ R_UNLESS(IsDevelopmentForAcidProductionCheck(), ldr::ResultInvalidNcaSignature()); R_UNLESS(!code_verification_data.has_data, ldr::ResultInvalidNcaSignature()); @@ -635,10 +636,13 @@ namespace ams::ldr { R_SUCCEED(); } - Result LoadAutoLoadModuleSegment(fs::FileHandle file, size_t file_offset, size_t compressed_size, size_t segment_size, bool is_compressed, bool is_zstd, uintptr_t map_base, uintptr_t map_end) { + Result LoadAutoLoadModuleSegment(fs::FileHandle file, size_t file_offset, size_t compressed_size, size_t segment_size, bool is_compressed, bool is_zbic, uintptr_t map_base, uintptr_t map_end) { /* Select read size based on compression. */ size_t file_size = is_compressed ? compressed_size : segment_size; + AMS_LOG("[ldr] Loading segment @ 0x%016lx: compressed=%d, file_size=0x%08lx, compressed_size=0x%08lx, segment_size=0x%08lx\n", + map_base, is_compressed, file_size, compressed_size, segment_size); + /* Validate size. */ R_UNLESS(file_size <= segment_size, ldr::ResultInvalidNso()); R_UNLESS(file_size <= std::numeric_limits::max(), ldr::ResultInvalidNso()); @@ -648,19 +652,19 @@ namespace ams::ldr { uintptr_t load_address = is_compressed ? map_end - compressed_size : map_base; size_t read_size; R_TRY(fs::ReadFile(std::addressof(read_size), file, file_offset, reinterpret_cast(load_address), file_size)); - R_UNLESS(read_size == file_size, ldr::ResultInvalidNso()); + R_UNLESS_LOG(read_size == file_size, ldr::ResultInvalidNso(), "[ldr] Couldn't read segment from file!\n"); /* Uncompress if necessary. */ R_SUCCEED_IF(!is_compressed); auto compressed_data_buf = reinterpret_cast(load_address); - if (is_zstd) { - bool decompressed = util::DecompressZstdForLoader(reinterpret_cast(g_zstd_dctx_workspace), ZstdDctxWorkspaceSize, reinterpret_cast(map_base), static_cast(map_end - map_base), segment_size, compressed_data_buf, file_size); - R_UNLESS(decompressed, ldr::ResultInvalidNso()); + if (is_zbic) { + bool decompressed = util::DecompressZstdWithBic(reinterpret_cast(g_zstd_dctx_workspace), sizeof(g_zstd_dctx_workspace), reinterpret_cast(map_base), static_cast(map_end - map_base), segment_size, compressed_data_buf, file_size); + R_UNLESS_LOG(decompressed, ldr::ResultInvalidNso(), "[ldr] Failed to decompress segment with zbic!\n"); } else { bool decompressed = (util::DecompressLZ4(reinterpret_cast(map_base), segment_size, compressed_data_buf, file_size) == static_cast(segment_size)); - R_UNLESS(decompressed, ldr::ResultInvalidNso()); + R_UNLESS_LOG(decompressed, ldr::ResultInvalidNso(), "[ldr] Failed to decompress segment with lz4!\n"); } R_SUCCEED(); @@ -675,12 +679,12 @@ namespace ams::ldr { crypto::GenerateSha256(hash, sizeof(hash), reinterpret_cast(map_address + nso_header->segments[segment].dst_offset), nso_header->segments[segment].size); - R_UNLESS(std::memcmp(hash, nso_header->segment_hashes[segment], sizeof(hash)) == 0, ldr::ResultInvalidNso()); + R_UNLESS_LOG(std::memcmp(hash, nso_header->segment_hashes[segment], sizeof(hash)) == 0, ldr::ResultInvalidNso(), "[ldr] Invalid segment hash!\n"); R_SUCCEED(); } Result LoadAutoLoadModule(os::NativeHandle process_handle, fs::FileHandle file, const NsoHeader *nso_header, uintptr_t nso_address, size_t nso_size, size_t map_size) { - const bool is_zstd = (nso_header->flags & NsoHeader::Flag_UseZbicCompression) != 0; + const bool is_zbic = (nso_header->flags & NsoHeader::Flag_UseZbicCompression) != 0; /* Map and read data from file. */ { @@ -694,11 +698,11 @@ namespace ams::ldr { /* Load NSO segments. */ R_TRY(LoadAutoLoadModuleSegment(file, nso_header->segments[NsoHeader::Segment_Text].file_offset, nso_header->text_compressed_size, nso_header->text_size, - (nso_header->flags & NsoHeader::Flag_CompressedText) != 0, is_zstd, map_address + nso_header->text_dst_offset, map_end)); + (nso_header->flags & NsoHeader::Flag_CompressedText) != 0, is_zbic, map_address + nso_header->text_dst_offset, map_end)); R_TRY(LoadAutoLoadModuleSegment(file, nso_header->segments[NsoHeader::Segment_Ro].file_offset, nso_header->ro_compressed_size, nso_header->ro_size, - (nso_header->flags & NsoHeader::Flag_CompressedRo) != 0, is_zstd, map_address + nso_header->ro_dst_offset, map_end)); + (nso_header->flags & NsoHeader::Flag_CompressedRo) != 0, is_zbic, map_address + nso_header->ro_dst_offset, map_end)); R_TRY(LoadAutoLoadModuleSegment(file, nso_header->segments[NsoHeader::Segment_Rw].file_offset, nso_header->rw_compressed_size, nso_header->rw_size, - (nso_header->flags & NsoHeader::Flag_CompressedRw) != 0, is_zstd, map_address + nso_header->rw_dst_offset, map_end)); + (nso_header->flags & NsoHeader::Flag_CompressedRw) != 0, is_zbic, map_address + nso_header->rw_dst_offset, map_end)); /* Clear unused space to zero. */ const size_t text_end = static_cast(nso_header->text_dst_offset) + static_cast(nso_header->text_size); @@ -744,14 +748,15 @@ namespace ams::ldr { for (int i = 0; i < ctx.nso_count; i++) { const NsoIndex nso_idx = static_cast(ctx.ali.nso_indices[i]); + const bool is_zbic = (ctx.headers[i].flags & NsoHeader::Flag_UseZbicCompression) != 0; + const size_t map_size = is_zbic ? (total_end - process_info->nso_address[i]) : process_info->nso_size[i]; + + AMS_LOG("[ldr] module[%d]: idx=%d, path='%s', zbic=%d\n", i, (int)nso_idx, GetNsoPath(nso_idx), is_zbic); fs::FileHandle file; R_TRY(fs::OpenFile(std::addressof(file), GetNsoPath(nso_idx), fs::OpenMode_Read)); ON_SCOPE_EXIT { fs::CloseFile(file); }; - const bool is_zstd = (ctx.headers[i].flags & NsoHeader::Flag_UseZbicCompression) != 0; - const size_t map_size = is_zstd ? (total_end - process_info->nso_address[i]) : process_info->nso_size[i]; - R_TRY(LoadAutoLoadModule(process_info->process_handle, file, ctx.headers + i, process_info->nso_address[i], process_info->nso_size[i], map_size)); }