Gupje/armT_stub.S
2024-08-02 16:05:02 +02:00

187 lines
3.8 KiB
ArmAsm

.align 1
.thumb
start:
@ Store R0 to the stack
push {r0}
LDR R0, addr_debugger_storage
stmia r0, {r0-r7}
@ Also store r0 by using r1
ldr r1, addr_debugger_storage
pop {r0}
str r0, [r1, #0]
# Keep using r0
LDR R0, addr_debugger_storage
@ Store R8 to R15, not available directly in thumb mode
mov r1, r8
str r1, [r0, #0x20]
mov r1, r9
str r1, [r0, #0x24]
mov r1, r10
str r1, [r0, #0x28]
mov r1, r11
str r1, [r0, #0x2c]
mov r1, r12 //ip scratch
str r1, [r0, #0x30]
mov r1, sp //sp
str r1, [r0, #0x34]
mov r1, lr //lr
str r1, [r0, #0x38]
mov r1, pc //pc
str r1, [r0, #0x3c]
// set debugger stack (r13 sp, r14 lr, r15 pc)
ldr r0, addr_debugger_stack
mov sp, r0
// Compare to see if we need to jump into the debugger or need to continue the 'normal' execution flow
// Default is jump in debugger
// CNT_EXEC 0x7f0
ldr r1, addr_debugger_storage
ldr r0, =0x700
add r0, #0xf0
add r0, r0, r1
CMP r0, #0x77
beq start_normal
@ TODO, use r8, how can I clear it
ldr r2, addr_debugger_main
mov r12, r2
bx r12
// Continue 'normal' execution flow
start_normal:
BL sync_processor_state
// Restore LR, TODO
@ LDR LR, [r1, #240]
@ // Restore the stack pointer
@ LDR R0, [r1, #248]
@ MOV SP, R0
// Also restore X0
LDR R0, [r1, #0]
// 0x7ec DBG_JUMP_TO
@ LDR r1, [r1, #0x7ec]
@ bx r1
.text
.global restore_and_jump
restore_and_jump:
// Restores all registers except for LR and SP
BL sync_processor_state
// restore SP, LR
ldr r0, addr_debugger_storage
ldr r1, [r0, #0x34]
mov sp, r1 //SP
ldr r1, [r0, #0x38]
mov lr, r1 //LR
@ Load JUMP_ADDR 0x7fc into r12
ldr r0, addr_debugger_storage
ldr r1, =0x7fc
add r1, r1, r0
ldr r1, [r1] @ JUMP_ADDR
mov r12, r1
// Restore r0 and r1
ldr r0, addr_debugger_storage
ldr r1, [r0, #4]
ldr r0, [r0]
@ At this point everything is restored except for r12, which contains the jump address
bx r12
.text
.global debugger_sync_special_regs
debugger_sync_special_regs:
@ mov r4, #0x77
// TODO, what special regs??
bx LR
.text
.global dump_special_regs
dump_special_regs:
// TODO, what special regs??
bx LR
.text
.global debugger_dump_special_regs
debugger_dump_special_regs:
BL dump_special_regs
B debugger_main
.text
.global sync_processor_state
sync_processor_state:
@ Syncs general purpose registers back to the cpu and branches to the LR
@ Load r8-r12
ldr r0, addr_debugger_storage
ldr r1, [r0, #0x20]
mov r8, r1
ldr r1, [r0, #0x24]
mov r9, r1
ldr r1, [r0, #0x28]
mov r10, r1
ldr r1, [r0, #0x2c]
mov r11, r1
ldr r1, [r0, #0x30]
mov r12, r1
@ Not restoring SP, LR and PC. Left here as reference
@ ldr r1, [r0, #0x34]
@ mov r13, r1 //sp
@ ldr r1, [r0, #0x38]
@ mov r14, r1 //lr
@ ldr r1, [r0, #0x3c]
@ mov r15, r1 //pc
@ load r0-r7
ldr r0, addr_debugger_storage
ldmia r0, {r0-r7}
bx lr
.text
.global restore_and_return
restore_and_return:
B sync_processor_state
// restore SP, LR
ldr r0, addr_debugger_storage
ldr r1, [r0, #0x30]
mov r12, r1 //IP
ldr r1, [r0, #0x34]
mov sp, r1 //SP
ldr r1, [r0, #0x38]
mov lr, r1 //LR
// Restore r0 and r1
@ ldr r0, addr_debugger_storage
ldr r1, [r0, #4]
ldr r0, [r0]
@ At this point everything is restored including the LR. Return to it
BX LR
.text
.global sync_debugger
sync_debugger:
BL sync_processor_state
b debugger_main
.align 4
addr_debugger_storage: .word debugger_storage
addr_debugger_stack: .word debugger_stack
addr_debugger_main: .word debugger_main