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:
parent
0b33551d94
commit
d412711868
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user