Add option to run rosalina on N3DS SAFE_FIRM.

Also enables a qtm error bypass
This commit is contained in:
TuxSH 2020-05-02 23:05:49 +01:00
parent 7dc2b7123b
commit 166bdbeb7d
6 changed files with 58 additions and 16 deletions

View File

@ -95,6 +95,7 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
"( ) Show GBA boot screen in patched AGB_FIRM", "( ) Show GBA boot screen in patched AGB_FIRM",
"( ) Set developer UNITINFO", "( ) Set developer UNITINFO",
"( ) Disable Arm11 exception handlers", "( ) Disable Arm11 exception handlers",
"( ) Enable Rosalina on SAFE_FIRM",
}; };
static const char *optionsDescription[] = { "Select the default EmuNAND.\n\n" static const char *optionsDescription[] = { "Select the default EmuNAND.\n\n"
@ -193,7 +194,16 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
"Note: Disabling the exception handlers\n" "Note: Disabling the exception handlers\n"
"will disqualify you from submitting\n" "will disqualify you from submitting\n"
"issues or bug reports to the Luma3DS\n" "issues or bug reports to the Luma3DS\n"
"GitHub repository!" "GitHub repository!",
"Enables Rosalina, the kernel ext.\n"
"and sysmodule reimplementations on\n"
"SAFE_FIRM (New 3DS only).\n\n"
"Also suppresses QTM error 0xF96183FE,\n"
"allowing to use 8.1-11.3 N3DS on\n"
"New 2DS XL consoles.\n\n"
"Only select this if you know what you\n"
"are doing!",
}; };
FirmwareSource nandType = FIRMWARE_SYSNAND; FirmwareSource nandType = FIRMWARE_SYSNAND;
@ -229,7 +239,8 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
{ .visible = true }, { .visible = true },
{ .visible = true }, { .visible = true },
{ .visible = true }, { .visible = true },
{ .visible = true } { .visible = true },
{ .visible = ISN3DS },
}; };
//Calculate the amount of the various kinds of options and pre-select the first single one //Calculate the amount of the various kinds of options and pre-select the first single one

View File

@ -34,7 +34,7 @@
#define CONFIG_FILE "config.bin" #define CONFIG_FILE "config.bin"
#define CONFIG_VERSIONMAJOR 2 #define CONFIG_VERSIONMAJOR 2
#define CONFIG_VERSIONMINOR 3 #define CONFIG_VERSIONMINOR 4
#define BOOTCFG_NAND BOOTCONFIG(0, 7) #define BOOTCFG_NAND BOOTCONFIG(0, 7)
#define BOOTCFG_FIRM BOOTCONFIG(3, 7) #define BOOTCFG_FIRM BOOTCONFIG(3, 7)
@ -60,7 +60,8 @@ enum singleOptions
PATCHVERSTRING, PATCHVERSTRING,
SHOWGBABOOT, SHOWGBABOOT,
PATCHUNITINFO, PATCHUNITINFO,
DISABLEARM11EXCHANDLERS DISABLEARM11EXCHANDLERS,
ENABLESAFEFIRMROSALINA,
}; };
typedef enum ConfigurationStatus typedef enum ConfigurationStatus

View File

@ -278,7 +278,8 @@ static inline void mergeSection0(FirmwareType firmType, u32 firmVersion, bool lo
srcModuleSize = moduleList[nbModules].size = ((Cxi *)src)->ncch.contentSize * 0x200; srcModuleSize = moduleList[nbModules].size = ((Cxi *)src)->ncch.contentSize * 0x200;
} }
if(firmType == NATIVE_FIRM && (ISN3DS || firmVersion >= 0x1D)) // SAFE_FIRM only for N3DS and only if ENABLESAFEFIRMROSALINA is on
if((firmType == NATIVE_FIRM || firmType == SAFE_FIRM) && (ISN3DS || firmVersion >= 0x1D))
{ {
//2) Merge that info with our own modules' //2) Merge that info with our own modules'
for(u8 *src = (u8 *)0x18180000; memcmp(((Cxi *)src)->ncch.magic, "NCCH", 4) == 0; src += srcModuleSize) for(u8 *src = (u8 *)0x18180000; memcmp(((Cxi *)src)->ncch.magic, "NCCH", 4) == 0; src += srcModuleSize)
@ -303,7 +304,9 @@ static inline void mergeSection0(FirmwareType firmType, u32 firmVersion, bool lo
//3) Read or copy the modules //3) Read or copy the modules
u8 *dst = firm->section[0].address; u8 *dst = firm->section[0].address;
const char *extModuleSizeError = "The external FIRM modules are too large."; const char *extModuleSizeError = "The external FIRM modules are too large.";
for(u32 i = 0, dstModuleSize, maxModuleSize = firmType == NATIVE_FIRM ? 0x80000 : 0x600000; i < nbModules; i++, dst += dstModuleSize, maxModuleSize -= dstModuleSize) // SAFE_FIRM only for N3DS and only if ENABLESAFEFIRMROSALINA is on
u32 maxModuleSize = (firmType == NATIVE_FIRM || firmType == SAFE_FIRM) ? 0x80000 : 0x600000;
for(u32 i = 0, dstModuleSize; i < nbModules; i++, dst += dstModuleSize, maxModuleSize -= dstModuleSize)
{ {
if(loadFromStorage) if(loadFromStorage)
{ {
@ -335,7 +338,7 @@ static inline void mergeSection0(FirmwareType firmType, u32 firmVersion, bool lo
memcpy(dst, moduleList[i].src, dstModuleSize); memcpy(dst, moduleList[i].src, dstModuleSize);
} }
//4) Patch NATIVE_FIRM if necessary //4) Patch NATIVE_FIRM/SAFE_FIRM (N3DS) if necessary
if(nbModules == 6) if(nbModules == 6)
{ {
if(patchK11ModuleLoading(firm->section[0].size, dst - firm->section[0].address, (u8 *)firm + firm->section[1].offset, firm->section[1].size) != 0) if(patchK11ModuleLoading(firm->section[0].size, dst - firm->section[0].address, (u8 *)firm + firm->section[1].offset, firm->section[1].size) != 0)
@ -522,6 +525,31 @@ u32 patch1x2xNativeAndSafeFirm(void)
ret += patchArm9ExceptionHandlersInstall(arm9Section, kernel9Size); ret += patchArm9ExceptionHandlersInstall(arm9Section, kernel9Size);
ret += patchSvcBreak9(arm9Section, kernel9Size, (u32)firm->section[2].address); ret += patchSvcBreak9(arm9Section, kernel9Size, (u32)firm->section[2].address);
if(ISN3DS && CONFIG(ENABLESAFEFIRMROSALINA))
{
u8 *arm11Section1 = (u8 *)firm + firm->section[1].offset;
//Find the Kernel11 SVC table and handler, exceptions page and free space locations
u32 baseK11VA;
u8 *freeK11Space;
u32 *arm11SvcHandler,
*arm11ExceptionsPage,
*arm11SvcTable = getKernel11Info(arm11Section1, firm->section[1].size, &baseK11VA, &freeK11Space, &arm11SvcHandler, &arm11ExceptionsPage);
ret += installK11Extension(arm11Section1, firm->section[1].size, false, baseK11VA, arm11ExceptionsPage, &freeK11Space);
ret += patchKernel11(arm11Section1, firm->section[1].size, baseK11VA, arm11SvcTable, arm11ExceptionsPage);
// Add some other patches to the mix, as we can now launch homebrew on SAFE_FIRM:
//Apply firmlaunch patches
ret += patchFirmlaunches(process9Offset, process9Size, process9MemAddr);
ret += patchKernel9Panic(arm9Section, kernel9Size);
ret += patchP9AccessChecks(process9Offset, process9Size);
mergeSection0(NATIVE_FIRM, 0x45, false); // may change in the future
firm->section[0].size = 0;
}
return ret; return ret;
} }

View File

@ -33,5 +33,6 @@ enum singleOptions
PATCHVERSTRING, PATCHVERSTRING,
SHOWGBABOOT, SHOWGBABOOT,
PATCHUNITINFO, PATCHUNITINFO,
DISABLEARM11EXCHANDLERS DISABLEARM11EXCHANDLERS,
ENABLESAFEFIRMROSALINA,
}; };

View File

@ -246,24 +246,24 @@ bool doErrfThrowHook(u32 *cmdbuf)
u8 *srcerrbuf = (u8 *)r0_to_r7_r12_usr[(spsr & 0x20) ? 4 : 6]; u8 *srcerrbuf = (u8 *)r0_to_r7_r12_usr[(spsr & 0x20) ? 4 : 6];
const char *pname = codeSetOfProcess(currentCoreContext->objectContext.currentProcess)->processName; const char *pname = codeSetOfProcess(currentCoreContext->objectContext.currentProcess)->processName;
static const struct const struct
{ {
const char *name; const char *name;
Result errCode; Result errCode;
bool enabled;
} errorCodesToIgnore[] = } errorCodesToIgnore[] =
{ {
/* /*
If you're getting this error, you have broken your head-tracking hardware, If you're getting this error, you may have broken your head-tracking hardware,
and should uncomment the following line: and you need to enable the qtm error bypass below:
*/ */
//{ "qtm", (Result)0xF96183FE }, { "qtm", 0xF96183FEu, CONFIG(ENABLESAFEFIRMROSALINA)},
{ "", 0, false}, // impossible case to ensure the array has at least 1 element
{ "", 0 }, // impossible case to ensure the array has at least 1 element
}; };
for(u32 i = 0; i < sizeof(errorCodesToIgnore) / sizeof(errorCodesToIgnore[0]); i++) for(u32 i = 0; i < sizeof(errorCodesToIgnore) / sizeof(errorCodesToIgnore[0]); i++)
{ {
if(strcmp(pname, errorCodesToIgnore[i].name) == 0 && (Result)cmdbuf[2] == errorCodesToIgnore[i].errCode) if(errorCodesToIgnore[i].enabled && strcmp(pname, errorCodesToIgnore[i].name) == 0 && (Result)cmdbuf[2] == errorCodesToIgnore[i].errCode)
{ {
srcerrbuf[0] = 5; srcerrbuf[0] = 5;
cmdbuf[0] = 0x10040; cmdbuf[0] = 0x10040;

View File

@ -35,7 +35,8 @@ enum singleOptions
PATCHVERSTRING, PATCHVERSTRING,
SHOWGBABOOT, SHOWGBABOOT,
PATCHUNITINFO, PATCHUNITINFO,
DISABLEARM11EXCHANDLERS DISABLEARM11EXCHANDLERS,
ENABLESAFEFIRMROSALINA,
}; };
extern u32 config, multiConfig, bootConfig; extern u32 config, multiConfig, bootConfig;