add another pxi barrier for firmlaunch

fixes a race condition when booting gm9 from itself (especially noticeable on new3DS consoles)
This commit is contained in:
Wolfvak 2020-08-19 23:11:45 -03:00
parent 0038e7d0ab
commit 68a4ceac5b
5 changed files with 13 additions and 4 deletions

View File

@ -196,13 +196,16 @@ void __attribute__((noreturn)) MainLoop(void)
gicEnableInterrupt(VBLANK_INTERRUPT); gicEnableInterrupt(VBLANK_INTERRUPT);
// ARM9 won't try anything funny until this point // ARM9 won't try anything funny until this point
PXI_Barrier(ARM11_READY_BARRIER); PXI_Barrier(PXI_BOOT_BARRIER);
// Process IRQs until the ARM9 tells us it's time to boot something else // Process IRQs until the ARM9 tells us it's time to boot something else
do { do {
ARM_WFI(); ARM_WFI();
} while(!legacy_boot); } while(!legacy_boot);
// Wait for the ARM9 to do its firmlaunch setup
PXI_Barrier(PXI_FIRMLAUNCH_BARRIER);
SYS_CoreZeroShutdown(); SYS_CoreZeroShutdown();
SYS_CoreShutdown(); SYS_CoreShutdown();
} }

View File

@ -110,6 +110,7 @@ u32 BootFirmHandler(const char* bootpath, bool verbose, bool delete) {
DeinitSDCardFS(); DeinitSDCardFS();
PXI_DoCMD(PXI_SET_VMODE, (u32[]){1}, 1); PXI_DoCMD(PXI_SET_VMODE, (u32[]){1}, 1);
PXI_DoCMD(PXI_LEGACY_MODE, NULL, 0); PXI_DoCMD(PXI_LEGACY_MODE, NULL, 0);
PXI_Barrier(PXI_FIRMLAUNCH_BARRIER);
BootFirm((FirmHeader*) firm, fixpath); BootFirm((FirmHeader*) firm, fixpath);
while(1); while(1);
} }
@ -2272,7 +2273,10 @@ u32 GodMode(int entrypoint) {
// bootloader handler // bootloader handler
if (bootloader) { if (bootloader) {
const char* bootfirm_paths[] = { BOOTFIRM_PATHS }; const char* bootfirm_paths[] = { BOOTFIRM_PATHS };
if (IsBootableFirm(firm_in_mem, FIRM_MAX_SIZE)) BootFirm(firm_in_mem, "sdmc:/bootonce.firm"); if (IsBootableFirm(firm_in_mem, FIRM_MAX_SIZE)) {
PXI_Barrier(PXI_FIRMLAUNCH_BARRIER);
BootFirm(firm_in_mem, "sdmc:/bootonce.firm");
}
for (u32 i = 0; i < sizeof(bootfirm_paths) / sizeof(char*); i++) { for (u32 i = 0; i < sizeof(bootfirm_paths) / sizeof(char*); i++) {
BootFirmHandler(bootfirm_paths[i], false, (BOOTFIRM_TEMPS >> i) & 0x1); BootFirmHandler(bootfirm_paths[i], false, (BOOTFIRM_TEMPS >> i) & 0x1);
} }

View File

@ -18,7 +18,7 @@ void main(int argc, char** argv, int entrypoint)
// Don't even try to send any messages until the // Don't even try to send any messages until the
// ARM11 says it's ready // ARM11 says it's ready
PXI_Barrier(ARM11_READY_BARRIER); PXI_Barrier(PXI_BOOT_BARRIER);
// A pointer to the shared memory region is // A pointer to the shared memory region is
// stored in the thread ID register in the ARM9 // stored in the thread ID register in the ARM9

View File

@ -1428,6 +1428,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) {
DeinitSDCardFS(); DeinitSDCardFS();
PXI_DoCMD(PXI_SET_VMODE, (u32[]){1}, 1); PXI_DoCMD(PXI_SET_VMODE, (u32[]){1}, 1);
PXI_DoCMD(PXI_LEGACY_MODE, NULL, 0); PXI_DoCMD(PXI_LEGACY_MODE, NULL, 0);
PXI_Barrier(PXI_FIRMLAUNCH_BARRIER);
BootFirm((FirmHeader*)(void*)firm, fixpath); BootFirm((FirmHeader*)(void*)firm, fixpath);
while(1); while(1);
} else if (err_str) snprintf(err_str, _ERR_STR_LEN, "not a bootable firm"); } else if (err_str) snprintf(err_str, _ERR_STR_LEN, "not a bootable firm");

View File

@ -48,7 +48,8 @@ enum {
* those used by any other software * those used by any other software
*/ */
enum { enum {
ARM11_READY_BARRIER = 19, PXI_BOOT_BARRIER = 19,
PXI_FIRMLAUNCH_BARRIER = 153,
}; };
#define PXI_FIFO_LEN (16) #define PXI_FIFO_LEN (16)