diff --git a/source/exceptions.c b/source/exceptions.c index 11fd75a..ad6e5eb 100644 --- a/source/exceptions.c +++ b/source/exceptions.c @@ -34,16 +34,16 @@ void installArm9Handlers(void) { const u32 offsets[] = {0x08, 0x18, 0x20, 0x28}; - + memcpy((void *)0x01FF8000, arm9_exceptions + 32, arm9_exceptions_size - 32); - //IRQHandler is at 0x08000000, but we won't handle it for some reasons - //svcHandler is at 0x08000010, but we won't handle svc either + /* IRQHandler is at 0x08000000, but we won't handle it for some reasons + svcHandler is at 0x08000010, but we won't handle svc either */ for(u32 i = 0; i < 4; i++) { *(vu32 *)(0x08000000 + offsets[i]) = 0xE51FF004; - *(vu32 *)(0x08000000 + offsets[i] + 4) = *((const u32 *)arm9_exceptions + 1 + i); + *(vu32 *)(0x08000000 + offsets[i] + 4) = *((u32 *)arm9_exceptions + 1 + i); } } @@ -51,7 +51,7 @@ void installArm11Handlers(u32 *exceptionsPage, u32 stackAddress, u32 codeSetOffs { u32 *initFPU; for(initFPU = exceptionsPage; initFPU < (exceptionsPage + 0x400) && (initFPU[0] != 0xE59F0008 || initFPU[1] != 0xE5900000); initFPU++); - + u32 *mcuReboot; for(mcuReboot = exceptionsPage; mcuReboot < (exceptionsPage + 0x400) && (mcuReboot[0] != 0xE59F4104 || mcuReboot[1] != 0xE3A0A0C2); mcuReboot++); mcuReboot--; @@ -60,12 +60,12 @@ void installArm11Handlers(u32 *exceptionsPage, u32 stackAddress, u32 codeSetOffs for(freeSpace = initFPU; freeSpace < (exceptionsPage + 0x400) && (freeSpace[0] != 0xFFFFFFFF || freeSpace[1] != 0xFFFFFFFF); freeSpace++); memcpy(freeSpace, arm11_exceptions + 32, arm11_exceptions_size - 32); - + exceptionsPage[1] = MAKE_BRANCH(exceptionsPage + 1, (u8 *)freeSpace + *(u32 *)(arm11_exceptions + 8) - 32); //Undefined Instruction exceptionsPage[3] = MAKE_BRANCH(exceptionsPage + 3, (u8 *)freeSpace + *(u32 *)(arm11_exceptions + 12) - 32); //Prefetch Abort exceptionsPage[4] = MAKE_BRANCH(exceptionsPage + 4, (u8 *)freeSpace + *(u32 *)(arm11_exceptions + 16) - 32); //Data Abort exceptionsPage[7] = MAKE_BRANCH(exceptionsPage + 7, (u8 *)freeSpace + *(u32 *)(arm11_exceptions + 4) - 32); //FIQ - + for(u32 *pos = freeSpace; pos < (u32 *)((u8 *)freeSpace + arm11_exceptions_size - 32); pos++) { switch(*pos) //Perform relocations @@ -105,12 +105,12 @@ void detectAndProcessExceptionDumps(void) const char *handledExceptionNames[] = { "FIQ", "undefined instruction", "prefetch abort", "data abort" }; - + const char *registerNames[] = { "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", "SP", "LR", "PC", "CPSR", "FPEXC" }; - + char hexstring[] = "00000000"; char arm11Str[] = "Processor: ARM11 (core X)"; @@ -120,10 +120,10 @@ void detectAndProcessExceptionDumps(void) drawString("An exception occurred", 10, 10, COLOR_RED); int posY = drawString(dumpHeader->processor == 11 ? arm11Str : "Processor: ARM9", 10, 30, COLOR_WHITE) + SPACING_Y; - + posY = drawString("Exception type: ", 10, posY, COLOR_WHITE); posY = drawString(handledExceptionNames[dumpHeader->type], 10 + 17 * SPACING_X, posY, COLOR_WHITE); - + if(dumpHeader->type == 2) { if((regs[16] & 0x20) == 0 && dumpHeader->codeDumpSize >= 4) @@ -149,7 +149,7 @@ void detectAndProcessExceptionDumps(void) memcpy(processNameStr + 17, (char *)additionalData, 8); posY = drawString(processNameStr, 10, posY, COLOR_WHITE); } - + posY += 3 * SPACING_Y; for(u32 i = 0; i < 17; i += 2) @@ -169,14 +169,14 @@ void detectAndProcessExceptionDumps(void) } posY += 2 * SPACING_Y; - + u32 mode = regs[16] & 0xF; if(dumpHeader->type == 3 && (mode == 7 || mode == 11)) { posY = drawString("Incorrect dump: failed to dump code and/or stack", 10, posY, 0x00FFFF) + 2 * SPACING_Y; //In yellow if(dumpHeader->processor != 9) posY -= SPACING_Y; } - + posY = drawString("You can find a dump in the following file:", 10, posY, COLOR_WHITE) + SPACING_Y; posY = drawString(path, 10, posY, COLOR_WHITE) + 2 * SPACING_Y; drawString("Press any button to shutdown", 10, posY, COLOR_WHITE); diff --git a/source/firm.c b/source/firm.c index b582bb8..9c37677 100755 --- a/source/firm.c +++ b/source/firm.c @@ -74,11 +74,7 @@ void main(void) //Attempt to read the configuration file needConfig = readConfig() ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION; - if(DEV_OPTIONS != 2) - { - detectAndProcessExceptionDumps(); - installArm9Handlers(); - } + detectAndProcessExceptionDumps(); //Determine if this is a firmlaunch boot if(launchedFirmTidLow[5] != 0) @@ -93,6 +89,8 @@ void main(void) nandType = (FirmwareSource)BOOTCONFIG(0, 3); firmSource = (FirmwareSource)BOOTCONFIG(2, 1); isA9lh = BOOTCONFIG(3, 1) != 0; + + if(isA9lh) installArm9Handlers(); } else { @@ -105,6 +103,8 @@ void main(void) //Determine if booting with A9LH isA9lh = !PDN_SPI_CNT; + if(isA9lh) installArm9Handlers(); + //Save old options and begin saving the new boot configuration configTemp = (configData.config & 0xFFFFFFC0) | ((u32)isA9lh << 3); @@ -339,10 +339,10 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 //Apply UNITINFO patch if(DEV_OPTIONS == 1) patchUnitInfoValueSet(arm9Section, section[2].size); - - if(DEV_OPTIONS != 2) + + if(isA9lh && DEV_OPTIONS != 2) { - //Install arm11 exception handlers + //Install ARM11 exception handlers u32 codeSetOffset; u32 stackAddress = getInfoForArm11ExceptionHandlers(arm11Section1, section[1].size, &codeSetOffset); installArm11Handlers(arm11ExceptionsPage, stackAddress, codeSetOffset); @@ -381,7 +381,7 @@ static inline void patchLegacyFirm(FirmwareType firmType) arm9Loader(arm9Section); firm->arm9Entry = (u8 *)0x801301C; } - + //Apply UNITINFO patch if(DEV_OPTIONS == 1) patchUnitInfoValueSet(arm9Section, section[3].size); diff --git a/source/patches.c b/source/patches.c index b44e4a4..4c0db8a 100644 --- a/source/patches.c +++ b/source/patches.c @@ -241,19 +241,17 @@ void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size) for(u32 r0 = 0x08000000; *off != 0xE3A01040; off++) //Until mov r1, #0x40 { - if((*off >> 26) != 0x39 || ((*off >> 16) & 0xF) != 0 || ((*off >> 25) & 1) != 0 || ((*off >> 20) & 5) != 0) - continue; //Discard everything that's not str rX, [r0, #imm](!) + //Discard everything that's not str rX, [r0, #imm](!) + if((*off & 0xFE5F0000) != 0xE4000000) continue; - int rD = (*off >> 12) & 0xF, - offset = (*off & 0xFFF) * ((((*off >> 23) & 1) == 0) ? -1 : 1), - writeback = (*off >> 21) & 1, - pre = (*off >> 24) & 1; + u32 rD = (*off >> 12) & 0xF, + offset = (*off & 0xFFF) * ((((*off >> 23) & 1) == 0) ? -1 : 1); + bool writeback = ((*off >> 21) & 1) != 0, + pre = ((*off >> 24) & 1) != 0; u32 addr = r0 + ((pre || !writeback) ? offset : 0); - if((addr & 7) != 0 && addr != 0x08000014 && addr != 0x08000004) - *off = 0xE1A00000; //nop - else - *off = 0xE5800000 | (rD << 12) | (addr & 0xFFF); //Preserve IRQ and SVC handlers + if((addr & 7) != 0 && addr != 0x08000014 && addr != 0x08000004) *off = 0xE1A00000; //nop + else *off = 0xE5800000 | (rD << 12) | (addr & 0xFFF); //Preserve IRQ and SVC handlers if(!pre) addr += offset; if(writeback) r0 = addr; @@ -291,7 +289,7 @@ void patchSvcBreak9(u8 *pos, u32 size, u32 kernel9Address) void patchSvcBreak11(u8 *pos, u32 *arm11SvcTable) { - //Same as above, for NFIRM arm11 + //Same as above, for NATIVE_FIRM ARM11 u32 *addr = (u32 *)(pos + arm11SvcTable[0x3C] - 0xFFF00000); *addr = 0xE12FFF7F; }