diff options
Diffstat (limited to 'kernel/source/application.asm')
-rw-r--r-- | kernel/source/application.asm | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/kernel/source/application.asm b/kernel/source/application.asm new file mode 100644 index 0000000..ed8b190 --- /dev/null +++ b/kernel/source/application.asm @@ -0,0 +1,171 @@ +bits 64 + +extern do_syscall + +section .text + +syscall_entry: + mov r11, rsp + mov rsp, 0xfffffffffffff000 + push r11 + push rcx + + push rdx + push rsi + push rdi + push rax + + mov rdi, rsp + lea rsi, [rsp + 8] + lea rdx, [rsp + 16] + lea rcx, [rsp + 24] + + call do_syscall + + pop rax + pop rdi + pop rsi + pop rdx + + xor r8, r8 + xor r9, r9 + xor r10, r10 + xor r11, r11 + or r11, 0x200 + pop rcx + pop rsp + + o64 sysret + +global init_applications_asm +init_applications_asm: + + ;efer <- efer | 0x1 + mov rcx, 0xc0000080 + rdmsr + or al, 1 + wrmsr + + ;lstar <- syscall_entry + mov rdx, syscall_entry + mov eax, edx + shr rdx, 32 + mov ecx, 0xc0000082 + wrmsr + + ;star <- 0x0030.0028.0000.0000 + mov edx, 0x00300028 + xor eax, eax + mov ecx, 0xc0000081 + wrmsr + + ;sfmask <- 0x0000.0000.0000.0200 (if) + xor edx, edx + mov eax, 0x200 + mov ecx, 0xc0000084 + wrmsr + + ret + +section .bss + +resume_stack: + resb 4096 + +section .text + +extern restore_syscall_stack +;rdi = pointer to copy +;rsi = intended rsp + +global resume_thread +resume_thread: +;rdi = ptr to cpu_state +;rdi is not inside stack +;interrupts are disabled + + mov al, byte [rdi + 160] ;in_syscall + test al, al + jnz .in_syscall + + mov rax, 0x3b + mov rbx, 0x43 + +.common: + push rax + mov rax, qword [rdi + 56] ;rsp + push rax + mov rax, qword [rdi + 128] ;rflags + push rax + push rbx + mov rax, qword [rdi + 136] ;rip + push rax + + mov rax, qword [rdi + 144] ;cr3 + mov cr3, rax + + mov rax, qword [rdi] + mov rbx, qword [rdi + 8] + mov rcx, qword [rdi + 16] + mov rdx, qword [rdi + 24] + mov rsi, qword [rdi + 40] + mov rbp, qword [rdi + 48] + mov r8, qword [rdi + 64] + mov r9, qword [rdi + 72] + mov r10, qword [rdi + 80] + mov r11, qword [rdi + 88] + mov r12, qword [rdi + 96] + mov r13, qword [rdi + 104] + mov r14, qword [rdi + 112] + mov r15, qword [rdi + 120] + mov rdi, qword [rdi + 32] + + iretq + +.in_syscall: + mov rsp, resume_stack + 4096 + + push rdi + mov rsi, qword [rdi + 56] ;rsp + mov rdi, qword [rdi + 152] ;kernel_stack_copy + call restore_syscall_stack + pop rdi + + mov rax, 0x30 + mov rbx, 0x28 + jmp .common + +extern copy_syscall_stack +;rdi = bottom + +global save_thread_state +save_thread_state: +;rdi = pointer to cpu state structure + + ;only saving registers that need to be preserved by this function + mov qword [rdi + 8], rbx + mov qword [rdi + 48], rbp + mov qword [rdi + 56], rsp + mov qword [rdi + 96], r12 + mov qword [rdi + 104], r13 + mov qword [rdi + 112], r14 + mov qword [rdi + 120], r15 + + mov qword [rdi + 136], .resume_to ;rip + mov rax, cr3 + mov qword [rdi + 144], rax ;cr3 + + push rdi + lea rdi, [rsp + 8] + call copy_syscall_stack + pop rdi + + mov qword [rdi + 152], rax ;kernel_stack_copy + mov byte [rdi + 160], 0x01 ;in_syscall + + xor al, al + ret + +.resume_to: + mov al, 0x01 + ret |