Files
opencoreC/kernel/asm/ring3_enter.S
T

65 lines
1.5 KiB
ArmAsm

/* opencoreC - Ring 3 User Mode Transition (IRETQ) */
.global enter_user_mode
.extern set_kernel_stack
.section .text
/*
* void enter_user_mode(uint64_t entry_rip, uint64_t user_rsp, uint64_t pml4_paddr, uint64_t kernel_stack_top);
* RDI = entry_rip
* RSI = user_rsp
* RDX = pml4_paddr
* RCX = kernel_stack_top
*/
enter_user_mode:
/* 1. Save kernel stack in TSS (RSP0) for future interrupts/syscalls */
push rdi
push rsi
push rdx
mov rdi, rcx
call set_kernel_stack
pop rdx
pop rsi
pop rdi
/* 2. Switch to User Address Space (PML4) */
mov cr3, rdx
/* 3. Build IRETQ Stack Frame:
* [RSP + 32] = SS (User Data: 0x18 | 3 = 0x1B)
* [RSP + 24] = RSP (User Stack Pointer)
* [RSP + 16] = RFLAGS (Interrupt Flag Enabled: 0x202)
* [RSP + 8] = CS (User Code: 0x20 | 3 = 0x23)
* [RSP + 0] = RIP (User Entry Point)
*/
mov ax, 0x1B
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
push 0x1B /* User SS */
push rsi /* User RSP */
push 0x0202 /* RFLAGS (IF enabled) */
push 0x23 /* User CS */
push rdi /* User RIP */
/* 4. Clear 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
/* 5. Jump to Ring 3 */
iretq