diff options
Diffstat (limited to 'arm9/lib')
-rw-r--r-- | arm9/lib/include/OS_reset.h | 1 | ||||
-rw-r--r-- | arm9/lib/include/mmap.h | 1 | ||||
-rw-r--r-- | arm9/lib/src/OS_reset.c | 48 |
3 files changed, 49 insertions, 1 deletions
diff --git a/arm9/lib/include/OS_reset.h b/arm9/lib/include/OS_reset.h index d3cb4355..fd918370 100644 --- a/arm9/lib/include/OS_reset.h +++ b/arm9/lib/include/OS_reset.h @@ -18,6 +18,7 @@ static void OSi_SendToPxi(u16 data); void OS_ResetSystem(u32 parameter); void OSi_DoBoot(void); static void OSi_CpuClear32(register u32 data, register void *destp, register u32 size); +void OSi_ReloadRomData(void); void OSi_ReadCardRom32(u32 src, void *dst, s32 len); static inline u32 OS_GetResetParameter(void) diff --git a/arm9/lib/include/mmap.h b/arm9/lib/include/mmap.h index 386ee0e4..c43e65b6 100644 --- a/arm9/lib/include/mmap.h +++ b/arm9/lib/include/mmap.h @@ -29,6 +29,7 @@ extern u32 SDK_AUTOLOAD_DTCM_START[]; #define HW_DOWNLOAD_PARAMETER_SIZE 0x00000020 #define HW_RESET_PARAMETER_BUF (HW_MAIN_MEM + 0x007ffc20) +#define HW_ROM_BASE_OFFSET_BUF (HW_MAIN_MEM + 0x007ffc2c) #define HW_WM_BOOT_BUF (HW_MAIN_MEM + 0x007ffc40) #define HW_ARENA_INFO_BUF (HW_MAIN_MEM + 0x007ffda0) // Arena data structure #define HW_ROM_HEADER_BUF (HW_MAIN_MEM + 0x007ffe00) // ROM registration area data buffer diff --git a/arm9/lib/src/OS_reset.c b/arm9/lib/src/OS_reset.c index a5ef6987..b7bf5f0b 100644 --- a/arm9/lib/src/OS_reset.c +++ b/arm9/lib/src/OS_reset.c @@ -7,6 +7,7 @@ #include "MB_mb.h" #include "OS_terminate_proc.h" #include "OS_interrupt.h" +#include "OS_system.h" #include "sections.h" static u16 OSi_IsInitReset = 0; @@ -18,6 +19,10 @@ extern void PXI_SetFifoRecvCallback(u32 param1, void* callback); extern u32 PXI_SendWordByFifo(u32 param1, u32 data, u32 param2); extern void CARD_LockRom(u16 lockId); extern void MI_StopDma(u32 dma); +extern void DC_StoreAll(void); +extern void DC_InvalidateAll(void); +extern void IC_InvalidateAll(void); +extern void DC_WaitWriteBufferEmpty(void); extern void OSi_DoResetSystem(void); //in itcm, should technically be in this file ARM_FUNC void OS_InitReset(void) { @@ -136,7 +141,48 @@ enum CARD_ENUM_END }; -void OSi_ReadCardRom32(u32 src, void *dst, s32 len) //should be static, can't mark as such + +ARM_FUNC void OSi_ReloadRomData(void) +{ + u32 header = (u32)HW_ROM_HEADER_BUF; + const u32 rom_base = *(u32 *)HW_ROM_BASE_OFFSET_BUF; + + if (rom_base >= 0x8000) + { + OSi_ReadCardRom32(rom_base, (void *)header, 0x160); + } + + u32 src_arm9 = *(u32 *)(header + 0x20); + u32 dst_arm9 = *(u32 *)(header + 0x28); + u32 len_arm9 = *(u32 *)(header + 0x2c); + u32 src_arm7 = *(u32 *)(header + 0x30); + u32 dst_arm7 = *(u32 *)(header + 0x38); + u32 len_arm7 = *(u32 *)(header + 0x3c); + + OSIntrMode prevIntrMode = OS_DisableInterrupts(); + DC_StoreAll(); + DC_InvalidateAll(); + (void)OS_RestoreInterrupts(prevIntrMode); + + IC_InvalidateAll(); + DC_WaitWriteBufferEmpty(); + + src_arm9 += rom_base; + src_arm7 += rom_base; + + if (src_arm9 < 0x8000) + { + u32 diff = 0x8000 - src_arm9; + src_arm9 = 0x8000; + dst_arm9 += diff; + len_arm9 -= diff; + } + OSi_ReadCardRom32(src_arm9, (void *)dst_arm9, (s32)len_arm9); + + OSi_ReadCardRom32(src_arm7, (void *)dst_arm7, (s32)len_arm7); +} + +ARM_FUNC void OSi_ReadCardRom32(u32 src, void *dst, s32 len) //should be static, can't mark as such { vu32 *const hdr_GAME_BUF = (vu32 *)(HW_ROM_HEADER_BUF + 0x60); |