This repository has been archived on 2022-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
Luma3DS-3GX/mset/source/firmlaunchax.c
2015-08-04 21:57:37 -04:00

73 lines
2.4 KiB
C

#include "firmlaunchax.h"
#include <stdint.h>
#include "firmcompat.h"
#include "appcompat.h"
#include "arm11_tools.h"
#include "jump_table.h"
void setup_gpu()
{
volatile uint32_t *top_left1 = (volatile uint32_t *)(fw->gpu_regs + 0x468);
volatile uint32_t *top_left2 = (volatile uint32_t *)(fw->gpu_regs + 0x46C);
volatile uint32_t *top_right1 = (volatile uint32_t *)(fw->gpu_regs + 0x494);
volatile uint32_t *top_right2 = (volatile uint32_t *)(fw->gpu_regs + 0x498);
volatile uint32_t *top_selected = (volatile uint32_t *)(fw->gpu_regs + 0x478);
volatile uint32_t *bottom1 = (volatile uint32_t *)(fw->gpu_regs + 0x568);
volatile uint32_t *bottom2 = (volatile uint32_t *)(fw->gpu_regs + 0x56C);
volatile uint32_t *bottom_selected = (volatile uint32_t *)(fw->gpu_regs + 0x578);
uint32_t *save = (uint32_t *)(fw->fcram_address + 0x3FFFE00);
if (*top_selected) {
save[0] = *top_left2;
save[1] = *top_right2;
} else {
save[0] = *top_left1;
save[1] = *top_right1;
}
if (*bottom_selected) {
save[2] = *bottom2;
} else {
save[2] = *bottom1;
}
}
void firmlaunch_arm9hax()
{
invalidate_data_cache();
invalidate_instruction_cache();
// Copy arm9 code
uint32_t code_offset = 0x3F00000;
asm_memcpy((void *)(fw->fcram_address + code_offset),
(void *)(fw->fcram_address + APP_CFW_OFFSET), ARM9_PAYLOAD_MAXSIZE);
// Prepare framebuffer info for arm9
setup_gpu();
// Copy the jump table
asm_memcpy((void *)fw->jump_table_address, &jump_table, (&jump_table_end - &jump_table + 1) * 4);
// Write firmware-specific offsets to the jump table
*(uint32_t *)(fw->jump_table_address +
(&jt_return - &jump_table) * 4) = fw->func_patch_return;
*(uint32_t *)(fw->jump_table_address +
(&jt_pdn_regs - &jump_table) * 4) = fw->pdn_regs;
*(uint32_t *)(fw->jump_table_address +
(&jt_pxi_regs - &jump_table) * 4) = fw->pxi_regs;
// Patch arm11 functions
*(uint32_t *)fw->func_patch_address = 0xE51FF004;
*(uint32_t *)(fw->func_patch_address + 4) = 0xFFFF0C80;
*(uint32_t *)fw->reboot_patch_address = 0xE51FF004;
*(uint32_t *)(fw->reboot_patch_address + 4) = 0x1FFF4C80+4;
invalidate_data_cache();
// Trigger reboot
((void (*)())fw->reboot_func_address)(0, 0, 2, 0);
while (1) {};
}