os-k/kaleid/kernel/ke/syscall.asm

124 lines
3.5 KiB
NASM

;=----------------------------------------------------------------------------=;
; OS on Kaleid ;
; ;
; Desc: System call & userspace related functions ;
; ;
; ;
; Copyright © 2018-2021 The OS/K Team ;
; ;
; This file is part of OS/K. ;
; ;
; OS/K is free software: you can redistribute it and/or modify ;
; it under the terms of the GNU General Public License as published by ;
; the Free Software Foundation, either version 3 of the License, or ;
; (at your option) any later version. ;
; ;
; OS/K is distributed in the hope that it will be useful, ;
; but WITHOUT ANY WARRANTY; without even the implied warranty of ;
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;
; GNU General Public License for more details. ;
; ;
; You should have received a copy of the GNU General Public License ;
; along with OS/K. If not, see <https://www.gnu.org/licenses/>. ;
;=----------------------------------------------------------------------------=;
[BITS 64]
%include "kaleid/kernel/ke/cpuf.inc"
global KeJumpToUserspace
global KeSyscall
global syscallPreHandler
extern _KeSyscallHandler
;;
;; System call pre-handler
;;
syscallPreHandler:
push rax ; rax
push rbx
push rcx
push 0 ; rdx
push 0 ; rsi
push 0 ; rdi
push rbp
push r8
push r9
push 0 ; r10
push r11
push r12
push r13
push r14
push r15
mov rax, cr8
push rax
mov rax, cr4
push rax
mov rax, cr3
push rax
mov rax, cr2
push rax
mov rax, cr0
push rax
mov rcx, 0xC0000080
rdmsr
push rax
; Call the C routine to dispatch interrupts
cld ; DF must be cleared by the caller
mov r8, rsp ; First argument points to the processor state
mov rbp, 0 ; Terminate stack traces here
call _KeSyscallHandler
; pop the control registers
add rsp, 48
; pop registers except return value
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rbp
pop rdi
pop rsi
pop rdx
pop rcx
pop rbx
; pop rax without overwriting
add rsp, 8
; pop the error code, interrupt id
add rsp, 16
iretq
;;
;; To get ring3 code running
;;
KeJumpToUserspace:
; rdi = user args
; rsi = entry point in user space
; rdx = user space stack
; Build a fake iret frame
push QWORD 0x23 ; Selector 0x20 (User Data) + RPL 3
push rdx ; User space stack
push QWORD 0x202 ; rflags = interrupt enable + reserved bit
push QWORD 0x1B ; Selector 0x18 (User Code) + RPL 3
push rsi ; Entry point in user space
iretq
;;
;; Syscall trigger
;;
KeSyscall:
int 0x80
ret