
- Move emuNAND hook to ITCM, fixing previously untested emuNAND support for 5.0 (and possibly more versions). This was a very long-standing bug - Fix booting on versions 4.x to 8.x, and restore full support for 5.x to 8.x. All Arm11 custom sysmodules and k11ext have been disabled on 4.x because the Luma3DS v13.0 changes couldn't be ported (this means no Rosalina and no region-free and such, and while I could restore some of the functionality, you should just update *after* installing Luma, like you've been instructed to)
228 lines
4.6 KiB
ArmAsm
228 lines
4.6 KiB
ArmAsm
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
|
|
@ Code originally from delebile and mid-kid
|
|
|
|
.section .large_patch.reboot, "aw", %progbits
|
|
.arm
|
|
.align 4
|
|
|
|
#define copy_launch_stub_stack_top 0x01FFB800
|
|
#define copy_launch_stub_stack_bottom 0x01FFA800
|
|
#define copy_launch_stub_addr 0x01FF9000
|
|
|
|
#define argv_addr (copy_launch_stub_stack_bottom - 0x100)
|
|
#define fname_addr (copy_launch_stub_stack_bottom - 0x200)
|
|
#define low_tid_addr (copy_launch_stub_stack_bottom - 0x300)
|
|
|
|
#define firm_addr 0x20001000
|
|
#define firm_maxsize 0x07FFF000
|
|
|
|
.global rebootPatch
|
|
rebootPatch:
|
|
@ Interesting registers and locations to keep in mind, set just before this code is ran:
|
|
@ - r1: FIRM path in exefs.
|
|
@ - r7 (or r8): pointer to file object
|
|
@ - *r7: vtable
|
|
@ - *(vtable + 0x28): fread function
|
|
@ - *(r7 + 8): file handle
|
|
|
|
sub r7, r0, #8
|
|
mov r8, r1
|
|
|
|
pxi_wait_recv:
|
|
ldr r2, =0x44846
|
|
ldr r0, =0x10008000
|
|
readPxiLoop1:
|
|
ldrh r1, [r0, #4]
|
|
lsls r1, #0x17
|
|
bmi readPxiLoop1
|
|
ldr r0, [r0, #0xC]
|
|
cmp r0, r2
|
|
bne pxi_wait_recv
|
|
|
|
@ Open file
|
|
add r0, r7, #8
|
|
adr r1, rebootPatchFileName
|
|
mov r2, #1
|
|
adr r6, rebootPatchFopenPtr
|
|
ldr r6, [r6]
|
|
orr r6, #1
|
|
blx r6
|
|
cmp r0, #0
|
|
bne panic
|
|
|
|
@ Read file
|
|
mov r0, r7
|
|
adr r1, bytes_read
|
|
ldr r2, =firm_addr
|
|
ldr r3, =firm_maxsize
|
|
ldr r6, [r7]
|
|
ldr r6, [r6, #0x28]
|
|
blx r6
|
|
|
|
@ Copy the low TID (in UTF-16) of the wanted firm
|
|
ldr r0, =low_tid_addr
|
|
add r1, r8, #0x1A
|
|
mov r2, #0x10
|
|
bl memcpy16
|
|
|
|
@ Copy argv[0]
|
|
ldr r0, =fname_addr
|
|
adr r1, rebootPatchFileName
|
|
mov r2, #82
|
|
bl memcpy16
|
|
|
|
ldr r0, =argv_addr
|
|
ldr r1, =fname_addr
|
|
ldr r2, =low_tid_addr
|
|
stmia r0, {r1, r2}
|
|
|
|
@ Set kernel state
|
|
mov r0, #0
|
|
mov r1, #0
|
|
mov r2, #0
|
|
mov r3, #0
|
|
svc 0x7C
|
|
|
|
goto_reboot:
|
|
@ Jump to reboot code
|
|
ldr r0, kernel_func_displ
|
|
add r0, pc @ pc is two instructions ahead of the instruction being executed (12 = 2*4 + 4)
|
|
svc 0x7B
|
|
|
|
die:
|
|
b die
|
|
|
|
memcpy16:
|
|
cmp r2, #0
|
|
bxeq lr
|
|
add r2, r0, r2
|
|
copy_loop16:
|
|
ldrh r3, [r1], #2
|
|
strh r3, [r0], #2
|
|
cmp r0, r2
|
|
blo copy_loop16
|
|
bx lr
|
|
|
|
panic:
|
|
mov r1, r0 @ unused register
|
|
mov r0, #0
|
|
svc 0x3C @ svcBreak(USERBREAK_PANIC)
|
|
b die
|
|
|
|
kernel_func_displ:
|
|
.word kernelcode_start - goto_reboot - 12
|
|
|
|
bytes_read:
|
|
.word 0
|
|
|
|
.global rebootPatchFopenPtr
|
|
rebootPatchFopenPtr:
|
|
.word 0
|
|
|
|
.pool
|
|
|
|
.global rebootPatchFileName
|
|
rebootPatchFileName:
|
|
.skip 2*(80+1)
|
|
|
|
.balign 4
|
|
kernelcode_start:
|
|
|
|
msr cpsr_cxsf, #0xD3 @ disable interrupts and clear flags
|
|
|
|
ldr sp, =copy_launch_stub_stack_top
|
|
|
|
ldr r0, =copy_launch_stub_addr
|
|
adr r1, copy_launch_stub
|
|
mov r2, #(copy_launch_stub_end - copy_launch_stub)
|
|
bl memcpy32
|
|
|
|
@ Disable MPU
|
|
ldr r0, =0x42078 @ alt vector select, enable itcm
|
|
mcr p15, 0, r0, c1, c0, 0
|
|
|
|
bl flushCaches
|
|
|
|
ldr r0, =copy_launch_stub_addr
|
|
bx r0
|
|
|
|
copy_launch_stub:
|
|
|
|
ldr r4, =firm_addr
|
|
|
|
mov r5, #0
|
|
load_section_loop:
|
|
@ Such checks. Very ghetto. Wow.
|
|
add r3, r4, #0x40
|
|
add r3, r5,lsl #5
|
|
add r3, r5,lsl #4
|
|
ldmia r3, {r6-r8}
|
|
cmp r8, #0
|
|
movne r0, r7
|
|
addne r1, r4, r6
|
|
movne r2, r8
|
|
blne memcpy32
|
|
add r5, #1
|
|
cmp r5, #4
|
|
blo load_section_loop
|
|
|
|
mov r0, #2 @ argc
|
|
ldr r1, =argv_addr @ argv
|
|
ldr r2, =0xBABE @ magic word
|
|
|
|
mov r5, #0x20000000
|
|
ldr r6, [r4, #0x08]
|
|
str r6, [r5, #-4] @ store arm11 entrypoint
|
|
|
|
ldr lr, [r4, #0x0c]
|
|
bx lr
|
|
|
|
memcpy32:
|
|
add r2, r0, r2
|
|
copy_loop32:
|
|
ldr r3, [r1], #4
|
|
str r3, [r0], #4
|
|
cmp r0, r2
|
|
blo copy_loop32
|
|
bx lr
|
|
|
|
.pool
|
|
|
|
copy_launch_stub_end:
|
|
|
|
flushCaches:
|
|
|
|
@ Clean and flush data cache
|
|
mov r1, #0 @ segment counter
|
|
outer_loop:
|
|
mov r0, #0 @ line counter
|
|
|
|
inner_loop:
|
|
orr r2, r1, r0 @ generate segment and line address
|
|
mcr p15, 0, r2, c7, c14, 2 @ clean and flush the line
|
|
add r0, #0x20 @ increment to next line
|
|
cmp r0, #0x400
|
|
bne inner_loop
|
|
|
|
add r1, #0x40000000
|
|
cmp r1, #0
|
|
bne outer_loop
|
|
|
|
@ Drain write buffer
|
|
mcr p15, 0, r1, c7, c10, 4
|
|
|
|
@ Flush instruction cache
|
|
mcr p15, 0, r1, c7, c5, 0
|
|
|
|
bx lr
|
|
|
|
.pool
|
|
.balign 4
|
|
|
|
_rebootPatchEnd:
|
|
|
|
.global rebootPatchSize
|
|
rebootPatchSize:
|
|
.word _rebootPatchEnd - rebootPatch
|