/* opencoreC - Thread Context Switch & Entry Trampoline */ .global switch_to .global thread_entry_trampoline .section .text /* * switch_to(uint64_t *prev_rsp_ptr, uint64_t next_rsp) * RDI = ¤t_thread.context.rsp (save current RSP here) * RSI = next thread's saved RSP */ switch_to: /* Save callee-saved registers of outgoing thread */ push rbp push rbx push r12 push r13 push r14 push r15 /* Save RSP of outgoing thread */ mov [rdi], rsp /* Load RSP of incoming thread */ mov rsp, rsi /* Restore callee-saved registers of incoming thread */ pop r15 pop r14 pop r13 pop r12 pop rbx pop rbp ret /* * thread_entry_trampoline: * Jumped to via 'ret' in switch_to when a newly created thread runs for the first time. * When create_user_thread created the stack: * R12 was populated with user_rsp * R13 was populated with entry_rip */ thread_entry_trampoline: /* Set user data segments (0x18 | 3 = 0x1B) */ mov ax, 0x1B mov ds, ax mov es, ax mov fs, ax mov gs, ax /* Build hardware IRETQ frame on kernel stack */ push 0x1B /* User SS */ push r12 /* User RSP */ push 0x3202 /* RFLAGS (IF=1, IOPL=3 for hardware drivers) */ push 0x23 /* User CS (0x20 | 3 = 0x23) */ push r13 /* User RIP */ /* Clear all general-purpose registers */ xor rax, rax xor rbx, rbx xor rcx, rcx xor rdx, rdx xor rsi, rsi xor rdi, rdi xor rbp, rbp xor r8, r8 xor r9, r9 xor r10, r10 xor r11, r11 xor r12, r12 xor r13, r13 xor r14, r14 xor r15, r15 /* Transition to Ring 3 */ iretq