43 lines
1.1 KiB
ArmAsm
43 lines
1.1 KiB
ArmAsm
.intel_syntax noprefix
|
|
|
|
// void context_switch(UINT64* old_rsp, UINT64 new_rsp)
|
|
// rdi = &old_rsp (pointer to save current RSP)
|
|
// rsi = new_rsp (value of new stack pointer)
|
|
//
|
|
// Saves/restores callee-saved registers only.
|
|
// The caller-saved registers are already saved on the task's stack
|
|
// by the ISR stub (for preemptive switching) or are not in use
|
|
// (for the initial switch).
|
|
//
|
|
// For preemptive switching:
|
|
// - Timer IRQ fires, ISR stub pushes rax-r11 + trap_frame
|
|
// - C code runs (isr_dispatch → timer handler → scheduler)
|
|
// - context_switch saves/restores callee-saved regs + switches RSP
|
|
// - On return, C code unwinds, isr_common pops rax-r11 + iretq
|
|
//
|
|
// For new tasks:
|
|
// - task_create sets up a fake trap_frame on the stack
|
|
// - context_switch pops callee-saved regs, returns into task_entry_trampoline
|
|
.global context_switch
|
|
context_switch:
|
|
push rbx
|
|
push rbp
|
|
push r12
|
|
push r13
|
|
push r14
|
|
push r15
|
|
|
|
mov [rdi], rsp // save current RSP
|
|
mov rsp, rsi // switch to new stack
|
|
|
|
pop r15
|
|
pop r14
|
|
pop r13
|
|
pop r12
|
|
pop rbp
|
|
pop rbx
|
|
|
|
ret
|
|
|
|
.section .note.GNU-stack,"",@progbits
|