Add support for k9/p9 exception handling on all FIRMs
This commit is contained in:
parent
1d77206ae4
commit
a63fb971d4
@ -24,6 +24,41 @@ u32 config,
|
|||||||
firmSource,
|
firmSource,
|
||||||
emuOffset;
|
emuOffset;
|
||||||
|
|
||||||
|
static inline void patchExceptionHandlersInstall(u8 *arm9Section)
|
||||||
|
{
|
||||||
|
static const u8 pattern[] = {
|
||||||
|
0x18, 0x10, 0x80, 0xE5,
|
||||||
|
0x10, 0x10, 0x80, 0xE5,
|
||||||
|
0x20, 0x10, 0x80, 0xE5,
|
||||||
|
0x28, 0x10, 0x80, 0xE5,
|
||||||
|
}; //i.e when it stores ldr pc, [pc, #-4]
|
||||||
|
|
||||||
|
u32* off = (u32 *)(memsearch(arm9Section, pattern, section[2].size, sizeof(pattern)));
|
||||||
|
if(off == NULL) return;
|
||||||
|
off += sizeof(pattern)/4;
|
||||||
|
|
||||||
|
u32 r0 = 0x08000000;
|
||||||
|
|
||||||
|
for(; *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](!)
|
||||||
|
|
||||||
|
int rD = (*off >> 12) & 0xf;
|
||||||
|
int offset = (*off & 0xfff) * ((((*off >> 23) & 1) == 0) ? -1 : 1);
|
||||||
|
int writeback = (*off >> 21) & 1, pre = (*off >> 24) & 1;
|
||||||
|
|
||||||
|
u32 addr = r0 + ((pre || !writeback) ? offset : 0);
|
||||||
|
if(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
u32 bootType,
|
u32 bootType,
|
||||||
@ -72,7 +107,11 @@ void main(void)
|
|||||||
|
|
||||||
u32 devMode = CONFIG(5);
|
u32 devMode = CONFIG(5);
|
||||||
|
|
||||||
if(devMode) detectAndProcessExceptionDumps();
|
if(devMode)
|
||||||
|
{
|
||||||
|
detectAndProcessExceptionDumps();
|
||||||
|
installArm9Handlers();
|
||||||
|
}
|
||||||
|
|
||||||
bootType = 0;
|
bootType = 0;
|
||||||
firmType = 0;
|
firmType = 0;
|
||||||
@ -139,7 +178,7 @@ void main(void)
|
|||||||
/* If L and R/A/Select or one of the single payload buttons are pressed,
|
/* If L and R/A/Select or one of the single payload buttons are pressed,
|
||||||
chainload an external payload */
|
chainload an external payload */
|
||||||
if(devMode || (pressed & SINGLE_PAYLOAD_BUTTONS) || ((pressed & BUTTON_L1) && (pressed & L_PAYLOAD_BUTTONS)))
|
if(devMode || (pressed & SINGLE_PAYLOAD_BUTTONS) || ((pressed & BUTTON_L1) && (pressed & L_PAYLOAD_BUTTONS)))
|
||||||
loadPayload(pressed, devMode);
|
loadPayload(pressed);
|
||||||
|
|
||||||
//If screens are inited or the corresponding option is set, load splash screen
|
//If screens are inited or the corresponding option is set, load splash screen
|
||||||
if(PDN_GPU_CNT != 1 || CONFIG(8)) loadSplash();
|
if(PDN_GPU_CNT != 1 || CONFIG(8)) loadSplash();
|
||||||
@ -193,6 +232,8 @@ void main(void)
|
|||||||
|
|
||||||
loadFirm(firmType, !firmType && updatedSys == !firmSource);
|
loadFirm(firmType, !firmType && updatedSys == !firmSource);
|
||||||
|
|
||||||
|
patchExceptionHandlersInstall((u8 *)firm + section[2].offset);
|
||||||
|
|
||||||
switch(firmType)
|
switch(firmType)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "screeninit.h"
|
#include "screeninit.h"
|
||||||
#include "exceptions.h"
|
|
||||||
#include "fatfs/ff.h"
|
#include "fatfs/ff.h"
|
||||||
#include "buttons.h"
|
#include "buttons.h"
|
||||||
#include "../build/loader.h"
|
#include "../build/loader.h"
|
||||||
@ -50,7 +49,7 @@ void fileWrite(const void *buffer, const char *path, u32 size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadPayload(u32 pressed, u32 devMode)
|
void loadPayload(u32 pressed)
|
||||||
{
|
{
|
||||||
const char *pattern;
|
const char *pattern;
|
||||||
|
|
||||||
@ -76,9 +75,6 @@ void loadPayload(u32 pressed, u32 devMode)
|
|||||||
|
|
||||||
if(result == FR_OK && info.fname[0])
|
if(result == FR_OK && info.fname[0])
|
||||||
{
|
{
|
||||||
//Only when "Enable developer features" is set
|
|
||||||
if(devMode) installArm9Handlers();
|
|
||||||
|
|
||||||
initScreens();
|
initScreens();
|
||||||
|
|
||||||
u32 *const loaderAddress = (u32 *)0x24FFFB00;
|
u32 *const loaderAddress = (u32 *)0x24FFFB00;
|
||||||
|
@ -12,5 +12,5 @@ u32 mountFs(void);
|
|||||||
u32 fileRead(void *dest, const char *path);
|
u32 fileRead(void *dest, const char *path);
|
||||||
void fileWrite(const void *buffer, const char *path, u32 size);
|
void fileWrite(const void *buffer, const char *path, u32 size);
|
||||||
void findDumpFile(const char *path, char *fileName);
|
void findDumpFile(const char *path, char *fileName);
|
||||||
void loadPayload(u32 pressed, u32 devMode);
|
void loadPayload(u32 pressed);
|
||||||
void firmRead(void *dest, const char *firmFolder);
|
void firmRead(void *dest, const char *firmFolder);
|
Reference in New Issue
Block a user