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

123 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 r15
push r14
push r13
push r12
push r11
push 0
push r9
push r8
push rbp
push 0
push 0
push 0
push rcx
push rbx
push rax
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 rsi, 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 rbx
pop rbx ; 2x rbx to discard rax
pop rcx
pop rdx
pop rsi
pop rdi
pop rbp
pop r8
pop r9
pop r10
pop r11
pop r12
pop r13
pop r14
pop r15
; pop the error code and 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