More cleanup, ARM9 exceptions for Luma and payloads are always enabled (FIRM ARM9 and ARM11 exceptions need Dev. options not to be "none")

This commit is contained in:
Aurora 2016-09-03 02:02:03 +02:00
parent 0b33551d94
commit d412711868
3 changed files with 32 additions and 34 deletions

View File

@ -34,16 +34,16 @@
void installArm9Handlers(void) void installArm9Handlers(void)
{ {
const u32 offsets[] = {0x08, 0x18, 0x20, 0x28}; const u32 offsets[] = {0x08, 0x18, 0x20, 0x28};
memcpy((void *)0x01FF8000, arm9_exceptions + 32, arm9_exceptions_size - 32); memcpy((void *)0x01FF8000, arm9_exceptions + 32, arm9_exceptions_size - 32);
//IRQHandler is at 0x08000000, but we won't handle it for some reasons /* IRQHandler is at 0x08000000, but we won't handle it for some reasons
//svcHandler is at 0x08000010, but we won't handle svc either svcHandler is at 0x08000010, but we won't handle svc either */
for(u32 i = 0; i < 4; i++) for(u32 i = 0; i < 4; i++)
{ {
*(vu32 *)(0x08000000 + offsets[i]) = 0xE51FF004; *(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; u32 *initFPU;
for(initFPU = exceptionsPage; initFPU < (exceptionsPage + 0x400) && (initFPU[0] != 0xE59F0008 || initFPU[1] != 0xE5900000); initFPU++); for(initFPU = exceptionsPage; initFPU < (exceptionsPage + 0x400) && (initFPU[0] != 0xE59F0008 || initFPU[1] != 0xE5900000); initFPU++);
u32 *mcuReboot; u32 *mcuReboot;
for(mcuReboot = exceptionsPage; mcuReboot < (exceptionsPage + 0x400) && (mcuReboot[0] != 0xE59F4104 || mcuReboot[1] != 0xE3A0A0C2); mcuReboot++); for(mcuReboot = exceptionsPage; mcuReboot < (exceptionsPage + 0x400) && (mcuReboot[0] != 0xE59F4104 || mcuReboot[1] != 0xE3A0A0C2); mcuReboot++);
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++); for(freeSpace = initFPU; freeSpace < (exceptionsPage + 0x400) && (freeSpace[0] != 0xFFFFFFFF || freeSpace[1] != 0xFFFFFFFF); freeSpace++);
memcpy(freeSpace, arm11_exceptions + 32, arm11_exceptions_size - 32); 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[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[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[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 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++) for(u32 *pos = freeSpace; pos < (u32 *)((u8 *)freeSpace + arm11_exceptions_size - 32); pos++)
{ {
switch(*pos) //Perform relocations switch(*pos) //Perform relocations
@ -105,12 +105,12 @@ void detectAndProcessExceptionDumps(void)
const char *handledExceptionNames[] = { const char *handledExceptionNames[] = {
"FIQ", "undefined instruction", "prefetch abort", "data abort" "FIQ", "undefined instruction", "prefetch abort", "data abort"
}; };
const char *registerNames[] = { const char *registerNames[] = {
"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12",
"SP", "LR", "PC", "CPSR", "FPEXC" "SP", "LR", "PC", "CPSR", "FPEXC"
}; };
char hexstring[] = "00000000"; char hexstring[] = "00000000";
char arm11Str[] = "Processor: ARM11 (core X)"; char arm11Str[] = "Processor: ARM11 (core X)";
@ -120,10 +120,10 @@ void detectAndProcessExceptionDumps(void)
drawString("An exception occurred", 10, 10, COLOR_RED); drawString("An exception occurred", 10, 10, COLOR_RED);
int posY = drawString(dumpHeader->processor == 11 ? arm11Str : "Processor: ARM9", 10, 30, COLOR_WHITE) + SPACING_Y; 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("Exception type: ", 10, posY, COLOR_WHITE);
posY = drawString(handledExceptionNames[dumpHeader->type], 10 + 17 * SPACING_X, posY, COLOR_WHITE); posY = drawString(handledExceptionNames[dumpHeader->type], 10 + 17 * SPACING_X, posY, COLOR_WHITE);
if(dumpHeader->type == 2) if(dumpHeader->type == 2)
{ {
if((regs[16] & 0x20) == 0 && dumpHeader->codeDumpSize >= 4) if((regs[16] & 0x20) == 0 && dumpHeader->codeDumpSize >= 4)
@ -149,7 +149,7 @@ void detectAndProcessExceptionDumps(void)
memcpy(processNameStr + 17, (char *)additionalData, 8); memcpy(processNameStr + 17, (char *)additionalData, 8);
posY = drawString(processNameStr, 10, posY, COLOR_WHITE); posY = drawString(processNameStr, 10, posY, COLOR_WHITE);
} }
posY += 3 * SPACING_Y; posY += 3 * SPACING_Y;
for(u32 i = 0; i < 17; i += 2) for(u32 i = 0; i < 17; i += 2)
@ -169,14 +169,14 @@ void detectAndProcessExceptionDumps(void)
} }
posY += 2 * SPACING_Y; posY += 2 * SPACING_Y;
u32 mode = regs[16] & 0xF; u32 mode = regs[16] & 0xF;
if(dumpHeader->type == 3 && (mode == 7 || mode == 11)) 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 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; 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("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; posY = drawString(path, 10, posY, COLOR_WHITE) + 2 * SPACING_Y;
drawString("Press any button to shutdown", 10, posY, COLOR_WHITE); drawString("Press any button to shutdown", 10, posY, COLOR_WHITE);

View File

@ -74,11 +74,7 @@ void main(void)
//Attempt to read the configuration file //Attempt to read the configuration file
needConfig = readConfig() ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION; needConfig = readConfig() ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION;
if(DEV_OPTIONS != 2) detectAndProcessExceptionDumps();
{
detectAndProcessExceptionDumps();
installArm9Handlers();
}
//Determine if this is a firmlaunch boot //Determine if this is a firmlaunch boot
if(launchedFirmTidLow[5] != 0) if(launchedFirmTidLow[5] != 0)
@ -93,6 +89,8 @@ void main(void)
nandType = (FirmwareSource)BOOTCONFIG(0, 3); nandType = (FirmwareSource)BOOTCONFIG(0, 3);
firmSource = (FirmwareSource)BOOTCONFIG(2, 1); firmSource = (FirmwareSource)BOOTCONFIG(2, 1);
isA9lh = BOOTCONFIG(3, 1) != 0; isA9lh = BOOTCONFIG(3, 1) != 0;
if(isA9lh) installArm9Handlers();
} }
else else
{ {
@ -105,6 +103,8 @@ void main(void)
//Determine if booting with A9LH //Determine if booting with A9LH
isA9lh = !PDN_SPI_CNT; isA9lh = !PDN_SPI_CNT;
if(isA9lh) installArm9Handlers();
//Save old options and begin saving the new boot configuration //Save old options and begin saving the new boot configuration
configTemp = (configData.config & 0xFFFFFFC0) | ((u32)isA9lh << 3); configTemp = (configData.config & 0xFFFFFFC0) | ((u32)isA9lh << 3);
@ -339,10 +339,10 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
//Apply UNITINFO patch //Apply UNITINFO patch
if(DEV_OPTIONS == 1) patchUnitInfoValueSet(arm9Section, section[2].size); 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 codeSetOffset;
u32 stackAddress = getInfoForArm11ExceptionHandlers(arm11Section1, section[1].size, &codeSetOffset); u32 stackAddress = getInfoForArm11ExceptionHandlers(arm11Section1, section[1].size, &codeSetOffset);
installArm11Handlers(arm11ExceptionsPage, stackAddress, codeSetOffset); installArm11Handlers(arm11ExceptionsPage, stackAddress, codeSetOffset);
@ -381,7 +381,7 @@ static inline void patchLegacyFirm(FirmwareType firmType)
arm9Loader(arm9Section); arm9Loader(arm9Section);
firm->arm9Entry = (u8 *)0x801301C; firm->arm9Entry = (u8 *)0x801301C;
} }
//Apply UNITINFO patch //Apply UNITINFO patch
if(DEV_OPTIONS == 1) patchUnitInfoValueSet(arm9Section, section[3].size); if(DEV_OPTIONS == 1) patchUnitInfoValueSet(arm9Section, section[3].size);

View File

@ -241,19 +241,17 @@ void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size)
for(u32 r0 = 0x08000000; *off != 0xE3A01040; off++) //Until mov r1, #0x40 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) //Discard everything that's not str rX, [r0, #imm](!)
continue; //Discard everything that's not str rX, [r0, #imm](!) if((*off & 0xFE5F0000) != 0xE4000000) continue;
int rD = (*off >> 12) & 0xF, u32 rD = (*off >> 12) & 0xF,
offset = (*off & 0xFFF) * ((((*off >> 23) & 1) == 0) ? -1 : 1), offset = (*off & 0xFFF) * ((((*off >> 23) & 1) == 0) ? -1 : 1);
writeback = (*off >> 21) & 1, bool writeback = ((*off >> 21) & 1) != 0,
pre = (*off >> 24) & 1; pre = ((*off >> 24) & 1) != 0;
u32 addr = r0 + ((pre || !writeback) ? offset : 0); u32 addr = r0 + ((pre || !writeback) ? offset : 0);
if((addr & 7) != 0 && addr != 0x08000014 && addr != 0x08000004) if((addr & 7) != 0 && addr != 0x08000014 && addr != 0x08000004) *off = 0xE1A00000; //nop
*off = 0xE1A00000; //nop else *off = 0xE5800000 | (rD << 12) | (addr & 0xFFF); //Preserve IRQ and SVC handlers
else
*off = 0xE5800000 | (rD << 12) | (addr & 0xFFF); //Preserve IRQ and SVC handlers
if(!pre) addr += offset; if(!pre) addr += offset;
if(writeback) r0 = addr; if(writeback) r0 = addr;
@ -291,7 +289,7 @@ void patchSvcBreak9(u8 *pos, u32 size, u32 kernel9Address)
void patchSvcBreak11(u8 *pos, u32 *arm11SvcTable) 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); u32 *addr = (u32 *)(pos + arm11SvcTable[0x3C] - 0xFFF00000);
*addr = 0xE12FFF7F; *addr = 0xE12FFF7F;
} }