summaryrefslogtreecommitdiff
path: root/kernel/source/application.asm
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/source/application.asm')
-rw-r--r--kernel/source/application.asm171
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