mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-26 05:42:17 +00:00
set.mitm: fake compatibility for usb!usb30_force_enabled on 9.0.0+ (#1391)
* set.mitm: fake compatibility for usb!usb30_force_enabled on 9.0.0+ * set.mitm: add value meaning comment for usb!usb30_force_enabled * loader: pretend to be polite about patch ordering
This commit is contained in:
parent
c9015581ca
commit
a6729171d3
14 changed files with 205 additions and 24 deletions
|
@ -1,9 +1,13 @@
|
||||||
; Disable uploading error reports to Nintendo
|
|
||||||
[eupld]
|
[eupld]
|
||||||
|
; Disable uploading error reports to Nintendo
|
||||||
; upload_enabled = u8!0x0
|
; upload_enabled = u8!0x0
|
||||||
|
[usb]
|
||||||
|
; Enable USB 3.0 superspeed for homebrew
|
||||||
|
; 0 = USB 3.0 support is system default (usually disabled), 1 = USB 3.0 support is enabled.
|
||||||
|
; usb30_force_enabled = u8!0x0
|
||||||
|
[ro]
|
||||||
; Control whether RO should ease its validation of NROs.
|
; Control whether RO should ease its validation of NROs.
|
||||||
; (note: this is normally not necessary, and ips patches can be used.)
|
; (note: this is normally not necessary, and ips patches can be used.)
|
||||||
[ro]
|
|
||||||
; ease_nro_restriction = u8!0x1
|
; ease_nro_restriction = u8!0x1
|
||||||
; Atmosphere custom settings
|
; Atmosphere custom settings
|
||||||
[atmosphere]
|
[atmosphere]
|
||||||
|
|
|
@ -286,6 +286,10 @@ namespace ams::secmon::smc {
|
||||||
/* Get the log configuration. */
|
/* Get the log configuration. */
|
||||||
args.r[1] = (static_cast<u64>(static_cast<u8>(secmon::GetLogPort())) << 32) | static_cast<u64>(secmon::GetLogBaudRate());
|
args.r[1] = (static_cast<u64>(static_cast<u8>(secmon::GetLogPort())) << 32) | static_cast<u64>(secmon::GetLogBaudRate());
|
||||||
break;
|
break;
|
||||||
|
case ConfigItem::ExosphereForceEnableUsb30:
|
||||||
|
/* Get whether usb 3.0 should be force-enabled. */
|
||||||
|
args.r[1] = GetSecmonConfiguration().IsUsb30ForceEnabled();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return SmcResult::InvalidArgument;
|
return SmcResult::InvalidArgument;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ namespace ams::secmon::smc {
|
||||||
ExosphereEmummcType = 65007,
|
ExosphereEmummcType = 65007,
|
||||||
ExospherePayloadAddress = 65008,
|
ExospherePayloadAddress = 65008,
|
||||||
ExosphereLogConfiguration = 65009,
|
ExosphereLogConfiguration = 65009,
|
||||||
|
ExosphereForceEnableUsb30 = 65010,
|
||||||
};
|
};
|
||||||
|
|
||||||
SmcResult SmcGetConfigUser(SmcArguments &args);
|
SmcResult SmcGetConfigUser(SmcArguments &args);
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#define EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS (1 << 4u)
|
#define EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS (1 << 4u)
|
||||||
#define EXOSPHERE_FLAG_BLANK_PRODINFO (1 << 5u)
|
#define EXOSPHERE_FLAG_BLANK_PRODINFO (1 << 5u)
|
||||||
#define EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC (1 << 6u)
|
#define EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC (1 << 6u)
|
||||||
|
#define EXOSPHERE_FLAG_FORCE_ENABLE_USB_30 (1 << 7u)
|
||||||
|
|
||||||
#define EXOSPHERE_LOG_FLAG_INVERTED (1 << 0u)
|
#define EXOSPHERE_LOG_FLAG_INVERTED (1 << 0u)
|
||||||
|
|
||||||
|
|
|
@ -256,6 +256,24 @@ static int stratosphere_ini_handler(void *user, const char *section, const char
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int system_settings_ini_handler(void *user, const char *section, const char *name, const char *value) {
|
||||||
|
uint32_t *flags = (uint32_t *)user;
|
||||||
|
if (strcmp(section, "usb") == 0) {
|
||||||
|
if (strcmp(name, "usb30_force_enabled") == 0) {
|
||||||
|
if (strcmp(value, "u8!0x1") == 0) {
|
||||||
|
*flags |= EXOSPHERE_FLAG_FORCE_ENABLE_USB_30;
|
||||||
|
} else if (strcmp(value, "u8!0x0") == 0) {
|
||||||
|
*flags &= ~(EXOSPHERE_FLAG_FORCE_ENABLE_USB_30);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static bool is_nca_present(const char *nca_name) {
|
static bool is_nca_present(const char *nca_name) {
|
||||||
char path[0x100];
|
char path[0x100];
|
||||||
snprintf(path, sizeof(path), "system:/contents/registered/%s.nca", nca_name);
|
snprintf(path, sizeof(path), "system:/contents/registered/%s.nca", nca_name);
|
||||||
|
@ -537,6 +555,15 @@ static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int ke
|
||||||
/* Apply lcd vendor. */
|
/* Apply lcd vendor. */
|
||||||
exo_cfg.lcd_vendor = display_get_lcd_vendor();
|
exo_cfg.lcd_vendor = display_get_lcd_vendor();
|
||||||
|
|
||||||
|
/* Read and parse system settings.ini to determine usb 3.0 enable. */
|
||||||
|
char *settings_ini = calloc(1, 0x20000);
|
||||||
|
if (read_from_file(settings_ini, 0x1FFFF, "atmosphere/config/system_settings.ini")) {
|
||||||
|
if (ini_parse_string(settings_ini, system_settings_ini_handler, &exo_cfg.flags[0]) < 0) {
|
||||||
|
fatal_error("[NXBOOT] Failed to parse system_settings.ini!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(settings_ini);
|
||||||
|
|
||||||
if ((exo_cfg.target_firmware < ATMOSPHERE_TARGET_FIRMWARE_MIN) || (exo_cfg.target_firmware > ATMOSPHERE_TARGET_FIRMWARE_MAX)) {
|
if ((exo_cfg.target_firmware < ATMOSPHERE_TARGET_FIRMWARE_MIN) || (exo_cfg.target_firmware > ATMOSPHERE_TARGET_FIRMWARE_MAX)) {
|
||||||
fatal_error("[NXBOOT] Invalid Exosphere target firmware!\n");
|
fatal_error("[NXBOOT] Invalid Exosphere target firmware!\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ namespace ams::secmon {
|
||||||
SecureMonitorConfigurationFlag_EnableUserModePerformanceCounterAccess = (1u << 4),
|
SecureMonitorConfigurationFlag_EnableUserModePerformanceCounterAccess = (1u << 4),
|
||||||
SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary = (1u << 5),
|
SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary = (1u << 5),
|
||||||
SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc = (1u << 6),
|
SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc = (1u << 6),
|
||||||
|
SecureMonitorConfigurationFlag_ForceEnableUsb30 = (1u << 7),
|
||||||
|
|
||||||
SecureMonitorConfigurationFlag_Default = SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForKernel,
|
SecureMonitorConfigurationFlag_Default = SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForKernel,
|
||||||
};
|
};
|
||||||
|
@ -101,6 +102,7 @@ namespace ams::secmon {
|
||||||
constexpr bool EnableUserModePerformanceCounterAccess() const { return (this->flags[0] & SecureMonitorConfigurationFlag_EnableUserModePerformanceCounterAccess) != 0; }
|
constexpr bool EnableUserModePerformanceCounterAccess() const { return (this->flags[0] & SecureMonitorConfigurationFlag_EnableUserModePerformanceCounterAccess) != 0; }
|
||||||
constexpr bool ShouldUseBlankCalibrationBinary() const { return (this->flags[0] & SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary) != 0; }
|
constexpr bool ShouldUseBlankCalibrationBinary() const { return (this->flags[0] & SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary) != 0; }
|
||||||
constexpr bool AllowWritingToCalibrationBinarySysmmc() const { return (this->flags[0] & SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc) != 0; }
|
constexpr bool AllowWritingToCalibrationBinarySysmmc() const { return (this->flags[0] & SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc) != 0; }
|
||||||
|
constexpr bool IsUsb30ForceEnabled() const { return (this->flags[0] & SecureMonitorConfigurationFlag_ForceEnableUsb30) != 0; }
|
||||||
|
|
||||||
constexpr bool IsDevelopmentFunctionEnabled(bool for_kern) const { return for_kern ? this->IsDevelopmentFunctionEnabledForKernel() : this->IsDevelopmentFunctionEnabledForUser(); }
|
constexpr bool IsDevelopmentFunctionEnabled(bool for_kern) const { return for_kern ? this->IsDevelopmentFunctionEnabledForKernel() : this->IsDevelopmentFunctionEnabledForUser(); }
|
||||||
};
|
};
|
||||||
|
|
|
@ -78,6 +78,10 @@ namespace ams::spl {
|
||||||
return ::ams::spl::GetConfigBool(::ams::spl::ConfigItem::DisableProgramVerification);
|
return ::ams::spl::GetConfigBool(::ams::spl::ConfigItem::DisableProgramVerification);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool IsUsb30ForceEnabled() {
|
||||||
|
return ::ams::spl::GetConfigBool(::ams::spl::ConfigItem::ExosphereForceEnableUsb30);
|
||||||
|
}
|
||||||
|
|
||||||
Result SetBootReason(BootReasonValue boot_reason);
|
Result SetBootReason(BootReasonValue boot_reason);
|
||||||
Result GetBootReason(BootReasonValue *out);
|
Result GetBootReason(BootReasonValue *out);
|
||||||
|
|
||||||
|
|
|
@ -223,26 +223,30 @@ namespace ams::spl {
|
||||||
Package2Hash = 17,
|
Package2Hash = 17,
|
||||||
|
|
||||||
/* Extension config items for exosphere. */
|
/* Extension config items for exosphere. */
|
||||||
ExosphereApiVersion = 65000,
|
ExosphereApiVersion = 65000,
|
||||||
ExosphereNeedsReboot = 65001,
|
ExosphereNeedsReboot = 65001,
|
||||||
ExosphereNeedsShutdown = 65002,
|
ExosphereNeedsShutdown = 65002,
|
||||||
ExosphereGitCommitHash = 65003,
|
ExosphereGitCommitHash = 65003,
|
||||||
ExosphereHasRcmBugPatch = 65004,
|
ExosphereHasRcmBugPatch = 65004,
|
||||||
ExosphereBlankProdInfo = 65005,
|
ExosphereBlankProdInfo = 65005,
|
||||||
ExosphereAllowCalWrites = 65006,
|
ExosphereAllowCalWrites = 65006,
|
||||||
ExosphereEmummcType = 65007,
|
ExosphereEmummcType = 65007,
|
||||||
ExospherePayloadAddress = 65008,
|
ExospherePayloadAddress = 65008,
|
||||||
|
ExosphereLogConfiguration = 65009,
|
||||||
|
ExosphereForceEnableUsb30 = 65010,
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extensions to libnx spl config item enum. */
|
/* Extensions to libnx spl config item enum. */
|
||||||
constexpr inline SplConfigItem SplConfigItem_ExosphereApiVersion = static_cast<SplConfigItem>(65000);
|
constexpr inline SplConfigItem SplConfigItem_ExosphereApiVersion = static_cast<SplConfigItem>(65000);
|
||||||
constexpr inline SplConfigItem SplConfigItem_ExosphereNeedsReboot = static_cast<SplConfigItem>(65001);
|
constexpr inline SplConfigItem SplConfigItem_ExosphereNeedsReboot = static_cast<SplConfigItem>(65001);
|
||||||
constexpr inline SplConfigItem SplConfigItem_ExosphereNeedsShutdown = static_cast<SplConfigItem>(65002);
|
constexpr inline SplConfigItem SplConfigItem_ExosphereNeedsShutdown = static_cast<SplConfigItem>(65002);
|
||||||
constexpr inline SplConfigItem SplConfigItem_ExosphereGitCommitHash = static_cast<SplConfigItem>(65003);
|
constexpr inline SplConfigItem SplConfigItem_ExosphereGitCommitHash = static_cast<SplConfigItem>(65003);
|
||||||
constexpr inline SplConfigItem SplConfigItem_ExosphereHasRcmBugPatch = static_cast<SplConfigItem>(65004);
|
constexpr inline SplConfigItem SplConfigItem_ExosphereHasRcmBugPatch = static_cast<SplConfigItem>(65004);
|
||||||
constexpr inline SplConfigItem SplConfigItem_ExosphereBlankProdInfo = static_cast<SplConfigItem>(65005);
|
constexpr inline SplConfigItem SplConfigItem_ExosphereBlankProdInfo = static_cast<SplConfigItem>(65005);
|
||||||
constexpr inline SplConfigItem SplConfigItem_ExosphereAllowCalWrites = static_cast<SplConfigItem>(65006);
|
constexpr inline SplConfigItem SplConfigItem_ExosphereAllowCalWrites = static_cast<SplConfigItem>(65006);
|
||||||
constexpr inline SplConfigItem SplConfigItem_ExosphereEmummcType = static_cast<SplConfigItem>(65007);
|
constexpr inline SplConfigItem SplConfigItem_ExosphereEmummcType = static_cast<SplConfigItem>(65007);
|
||||||
constexpr inline SplConfigItem SplConfigItem_ExospherePayloadAddress = static_cast<SplConfigItem>(65008);
|
constexpr inline SplConfigItem SplConfigItem_ExospherePayloadAddress = static_cast<SplConfigItem>(65008);
|
||||||
|
constexpr inline SplConfigItem SplConfigItem_ExosphereLogConfiguration = static_cast<SplConfigItem>(65009);
|
||||||
|
constexpr inline SplConfigItem SplConfigItem_ExosphereForceEnableUsb30 = static_cast<SplConfigItem>(65010);
|
||||||
|
|
|
@ -307,6 +307,10 @@ namespace ams::boot2 {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsUsbRequiredToMountSdCard() {
|
||||||
|
return hos::GetVersion() >= hos::Version_9_0_0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Boot2 API. */
|
/* Boot2 API. */
|
||||||
|
@ -347,8 +351,10 @@ namespace ams::boot2 {
|
||||||
/* Launch pcv. */
|
/* Launch pcv. */
|
||||||
LaunchProgram(nullptr, ncm::ProgramLocation::Make(ncm::SystemProgramId::Pcv, ncm::StorageId::BuiltInSystem), 0);
|
LaunchProgram(nullptr, ncm::ProgramLocation::Make(ncm::SystemProgramId::Pcv, ncm::StorageId::BuiltInSystem), 0);
|
||||||
|
|
||||||
/* Launch usb. */
|
/* On 9.0.0+, FS depends on the USB sysmodule having been launched in order to mount the SD card. */
|
||||||
LaunchProgram(nullptr, ncm::ProgramLocation::Make(ncm::SystemProgramId::Usb, ncm::StorageId::BuiltInSystem), 0);
|
if (IsUsbRequiredToMountSdCard()) {
|
||||||
|
LaunchProgram(nullptr, ncm::ProgramLocation::Make(ncm::SystemProgramId::Usb, ncm::StorageId::BuiltInSystem), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for the SD card required services to be ready. */
|
/* Wait for the SD card required services to be ready. */
|
||||||
|
@ -371,6 +377,11 @@ namespace ams::boot2 {
|
||||||
void LaunchPostSdCardBootPrograms() {
|
void LaunchPostSdCardBootPrograms() {
|
||||||
/* This code is normally run by boot2. */
|
/* This code is normally run by boot2. */
|
||||||
|
|
||||||
|
/* Launch the usb system module, if we haven't already. */
|
||||||
|
if (!IsUsbRequiredToMountSdCard()) {
|
||||||
|
LaunchProgram(nullptr, ncm::ProgramLocation::Make(ncm::SystemProgramId::Usb, ncm::StorageId::BuiltInSystem), 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Find out whether we are maintenance mode. */
|
/* Find out whether we are maintenance mode. */
|
||||||
const bool maintenance = IsMaintenanceMode();
|
const bool maintenance = IsMaintenanceMode();
|
||||||
if (maintenance) {
|
if (maintenance) {
|
||||||
|
|
|
@ -310,6 +310,9 @@ namespace ams::settings::fwdbg {
|
||||||
/* Disable uploading error reports to Nintendo. */
|
/* Disable uploading error reports to Nintendo. */
|
||||||
R_ABORT_UNLESS(ParseSettingsItemValue("eupld", "upload_enabled", "u8!0x0"));
|
R_ABORT_UNLESS(ParseSettingsItemValue("eupld", "upload_enabled", "u8!0x0"));
|
||||||
|
|
||||||
|
/* Enable USB 3.0 superspeed for homebrew */
|
||||||
|
R_ABORT_UNLESS(ParseSettingsItemValue("usb", "usb30_force_enabled", spl::IsUsb30ForceEnabled() ? "u8!0x1" : "u8!0x0"));
|
||||||
|
|
||||||
/* Control whether RO should ease its validation of NROs. */
|
/* Control whether RO should ease its validation of NROs. */
|
||||||
/* (note: this is normally not necessary, and ips patches can be used.) */
|
/* (note: this is normally not necessary, and ips patches can be used.) */
|
||||||
R_ABORT_UNLESS(ParseSettingsItemValue("ro", "ease_nro_restriction", "u8!0x1"));
|
R_ABORT_UNLESS(ParseSettingsItemValue("ro", "ease_nro_restriction", "u8!0x1"));
|
||||||
|
|
37
stratosphere/loader/source/ldr_embedded_usb_patches.inc
Normal file
37
stratosphere/loader/source/ldr_embedded_usb_patches.inc
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2021 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Patch fallback case to mov w0, #1 rather than retrieving settings flag. */
|
||||||
|
constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_9_0_0[] = {
|
||||||
|
{ 0x521C, "\x20\x00\x80\x52", 4 },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Patch fallback case to mov w0, #1 rather than retrieving settings flag. */
|
||||||
|
constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_10_0_0[] = {
|
||||||
|
{ 0x5494, "\x20\x00\x80\x52", 4 },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Patch getter functions to return 1. */
|
||||||
|
constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_11_0_0[] = {
|
||||||
|
{ 0x85DC, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 },
|
||||||
|
{ 0x866C, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 },
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr inline const EmbeddedPatch Usb30ForceEnablePatches[] = {
|
||||||
|
{ ParseModuleId("C0D3F4E87E8B0FE9BBE9F1968A20767F3DC08E03"), util::size(Usb30ForceEnablePatches_9_0_0), Usb30ForceEnablePatches_9_0_0 },
|
||||||
|
{ ParseModuleId("B9C700CA8335F8BAA0D2041D8D09F772890BA988"), util::size(Usb30ForceEnablePatches_10_0_0), Usb30ForceEnablePatches_10_0_0 },
|
||||||
|
{ ParseModuleId("95BAF06A69650C215A5DD50CF8BD2A603E7AD3C2"), util::size(Usb30ForceEnablePatches_11_0_0), Usb30ForceEnablePatches_11_0_0 },
|
||||||
|
};
|
|
@ -30,8 +30,12 @@ namespace ams::ldr {
|
||||||
constexpr const char * const LoaderSdMountName = "#amsldr-sdpatch";
|
constexpr const char * const LoaderSdMountName = "#amsldr-sdpatch";
|
||||||
static_assert(sizeof(LoaderSdMountName) <= fs::MountNameLengthMax);
|
static_assert(sizeof(LoaderSdMountName) <= fs::MountNameLengthMax);
|
||||||
|
|
||||||
os::Mutex g_ldr_sd_lock(false);
|
constinit os::SdkMutex g_ldr_sd_lock;
|
||||||
bool g_mounted_sd;
|
constinit bool g_mounted_sd;
|
||||||
|
|
||||||
|
constinit os::SdkMutex g_embedded_patch_lock;
|
||||||
|
constinit bool g_got_embedded_patch_settings;
|
||||||
|
constinit bool g_force_enable_usb30;
|
||||||
|
|
||||||
bool EnsureSdCardMounted() {
|
bool EnsureSdCardMounted() {
|
||||||
std::scoped_lock lk(g_ldr_sd_lock);
|
std::scoped_lock lk(g_ldr_sd_lock);
|
||||||
|
@ -51,6 +55,59 @@ namespace ams::ldr {
|
||||||
return (g_mounted_sd = true);
|
return (g_mounted_sd = true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsUsb30ForceEnabled() {
|
||||||
|
std::scoped_lock lk(g_embedded_patch_lock);
|
||||||
|
|
||||||
|
if (!g_got_embedded_patch_settings) {
|
||||||
|
g_force_enable_usb30 = spl::IsUsb30ForceEnabled();
|
||||||
|
g_got_embedded_patch_settings = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_force_enable_usb30;
|
||||||
|
}
|
||||||
|
|
||||||
|
consteval u8 ParseNybble(char c) {
|
||||||
|
AMS_ASSUME(('0' <= c && c <= '9') || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f'));
|
||||||
|
if ('0' <= c && c <= '9') {
|
||||||
|
return c - '0' + 0x0;
|
||||||
|
} else if ('A' <= c && c <= 'F') {
|
||||||
|
return c - 'A' + 0xA;
|
||||||
|
} else /* if ('a' <= c && c <= 'f') */ {
|
||||||
|
return c - 'a' + 0xa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
consteval ro::ModuleId ParseModuleId(const char *str) {
|
||||||
|
/* Parse a static module id. */
|
||||||
|
ro::ModuleId module_id = {};
|
||||||
|
|
||||||
|
size_t ofs = 0;
|
||||||
|
while (str[0] != 0) {
|
||||||
|
AMS_ASSUME(ofs < sizeof(module_id));
|
||||||
|
AMS_ASSUME(str[1] != 0);
|
||||||
|
|
||||||
|
module_id.build_id[ofs] = (ParseNybble(str[0]) << 4) | (ParseNybble(str[1]) << 0);
|
||||||
|
|
||||||
|
str += 2;
|
||||||
|
ofs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return module_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct EmbeddedPatchEntry {
|
||||||
|
uintptr_t offset;
|
||||||
|
const void * const data;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EmbeddedPatch {
|
||||||
|
ro::ModuleId module_id;
|
||||||
|
size_t num_entries;
|
||||||
|
const EmbeddedPatchEntry *entries;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "ldr_embedded_usb_patches.inc"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,4 +122,24 @@ namespace ams::ldr {
|
||||||
ams::patcher::LocateAndApplyIpsPatchesToModule(LoaderSdMountName, NsoPatchesDirectory, NsoPatchesProtectedSize, NsoPatchesProtectedOffset, &module_id, reinterpret_cast<u8 *>(mapped_nso), mapped_size);
|
ams::patcher::LocateAndApplyIpsPatchesToModule(LoaderSdMountName, NsoPatchesDirectory, NsoPatchesProtectedSize, NsoPatchesProtectedOffset, &module_id, reinterpret_cast<u8 *>(mapped_nso), mapped_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Apply embedded patches. */
|
||||||
|
void ApplyEmbeddedPatchesToModule(const u8 *build_id, uintptr_t mapped_nso, size_t mapped_size) {
|
||||||
|
/* Make module id. */
|
||||||
|
ro::ModuleId module_id;
|
||||||
|
std::memcpy(&module_id.build_id, build_id, sizeof(module_id.build_id));
|
||||||
|
|
||||||
|
if (IsUsb30ForceEnabled()) {
|
||||||
|
for (const auto &patch : Usb30ForceEnablePatches) {
|
||||||
|
if (std::memcmp(std::addressof(patch.module_id), std::addressof(module_id), sizeof(module_id)) == 0) {
|
||||||
|
for (size_t i = 0; i < patch.num_entries; ++i) {
|
||||||
|
const auto &entry = patch.entries[i];
|
||||||
|
if (entry.offset + entry.size <= mapped_size) {
|
||||||
|
std::memcpy(reinterpret_cast<void *>(mapped_nso + entry.offset), entry.data, entry.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -21,4 +21,7 @@ namespace ams::ldr {
|
||||||
/* Apply IPS patches. */
|
/* Apply IPS patches. */
|
||||||
void LocateAndApplyIpsPatchesToModule(const u8 *build_id, uintptr_t mapped_nso, size_t mapped_size);
|
void LocateAndApplyIpsPatchesToModule(const u8 *build_id, uintptr_t mapped_nso, size_t mapped_size);
|
||||||
|
|
||||||
|
/* Apply embedded patches. */
|
||||||
|
void ApplyEmbeddedPatchesToModule(const u8 *build_id, uintptr_t mapped_nso, size_t mapped_size);
|
||||||
|
|
||||||
}
|
}
|
|
@ -534,6 +534,9 @@ namespace ams::ldr {
|
||||||
std::memset(reinterpret_cast<void *>(map_address + ro_end), 0, nso_header->rw_dst_offset - ro_end);
|
std::memset(reinterpret_cast<void *>(map_address + ro_end), 0, nso_header->rw_dst_offset - ro_end);
|
||||||
std::memset(reinterpret_cast<void *>(map_address + rw_end), 0, nso_header->bss_size);
|
std::memset(reinterpret_cast<void *>(map_address + rw_end), 0, nso_header->bss_size);
|
||||||
|
|
||||||
|
/* Apply embedded patches. */
|
||||||
|
ApplyEmbeddedPatchesToModule(nso_header->build_id, map_address, nso_size);
|
||||||
|
|
||||||
/* Apply IPS patches. */
|
/* Apply IPS patches. */
|
||||||
LocateAndApplyIpsPatchesToModule(nso_header->build_id, map_address, nso_size);
|
LocateAndApplyIpsPatchesToModule(nso_header->build_id, map_address, nso_size);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue