Files
nt-lite/code/kernel/ke_syscall.asm
T

172 lines
5.1 KiB
NASM

; ke_syscall.asm - INT 0x40 kernel entry (MASM64)
;
; On entry the CPU has pushed (ring-3 -> ring-0 transition):
; SS, RSP, RFLAGS, CS, RIP (on the kernel stack via TSS.RSP0)
; RAX = syscall number
; RCX, RDX, R8, R9 = args 0-3 (MS x64)
; R10, R11 = args 4-5 (our extension)
EXTERN KeSyscallDispatch:PROC
.CODE
KeSyscallEntry PROC
sub rsp, 8 ; 16-byte align the stack frame
; We need to allocate 32 bytes for shadow space, plus 24 bytes for
; the 3 stack arguments (a3, a4, a5), plus 8 bytes of padding to keep
; the stack 16-byte aligned. Total = 64.
sub rsp, 64
; Place the 5th, 6th, and 7th arguments onto the stack for KeSyscallDispatch
mov [rsp + 32], r9 ; a3
mov [rsp + 40], r10 ; a4
mov [rsp + 48], r11 ; a5
; Shift the first 4 registers down one slot
mov r9, r8 ; a2
mov r8, rdx ; a1
mov rdx, rcx ; a0
mov rcx, rax ; nr (syscall number)
; Call the C dispatcher
call KeSyscallDispatch
add rsp, 72 ; Clean up (64 + 8)
iretq
KeSyscallEntry ENDP
; ---------------------------------------------------------------------------
; Fault stubs - thin wrappers that collect the CPU exception frame and
; forward to KeFaultDispatch (C), which handles both kernel panics and
; user-process bugchecks.
;
; KeFaultDispatch signature (MS x64):
; void KeFaultDispatch(int vector, // rcx
; UINT64 rip, // rdx
; UINT64 errCode, // r8
; UINT64 cr2, // r9
; UINT64 cs) // [rsp+20h] (5th arg, on stack)
; ---------------------------------------------------------------------------
EXTERN KeFaultDispatch:PROC
; Allocation for a 5-argument call (MS x64):
; 32 bytes shadow space (0x00..0x1F)
; 8 bytes for 5th arg (0x20..0x27)
; Total = 0x28 bytes.
; After "and rsp,-16" rsp%16==0; sub 0x28 (40) → rsp%16==8,
; so the subsequent "call" push makes rsp 16-byte aligned at callee entry. ✓
FAULT_FRAME_SIZE EQU 28h
; ---------------------------------------------------------
; Divide Error (#0) - NO error code pushed by CPU
; Exception frame at entry: [rsp]=RIP [rsp+8]=CS [rsp+16]=RFLAGS
; ---------------------------------------------------------
KeFaultDE PROC
mov rdx, [rsp] ; Arg2: rip
xor r8, r8 ; Arg3: errCode = 0 (no error code for #DE)
xor r9, r9 ; Arg4: cr2 = 0 (not a page fault)
mov r10, [rsp+8] ; cs (save before we clobber rsp)
mov ecx, 0 ; Arg1: vector = 0
and rsp, -16
sub rsp, FAULT_FRAME_SIZE
mov [rsp+20h], r10 ; Arg5: cs
call KeFaultDispatch ; _Noreturn - never returns
KeFaultDE ENDP
; ---------------------------------------------------------
; General Protection Fault (#13) - error code pushed by CPU
; Exception frame at entry: [rsp]=ErrCode [rsp+8]=RIP [rsp+16]=CS
; ---------------------------------------------------------
KeFaultGP PROC
mov r8, [rsp] ; Arg3: errCode
mov rdx, [rsp+8] ; Arg2: rip
xor r9, r9 ; Arg4: cr2 = 0 (not a page fault)
mov r10, [rsp+16] ; cs
mov ecx, 13 ; Arg1: vector = 13
and rsp, -16
sub rsp, FAULT_FRAME_SIZE
mov [rsp+20h], r10 ; Arg5: cs
call KeFaultDispatch
KeFaultGP ENDP
; ---------------------------------------------------------
; Page Fault (#14) - error code pushed by CPU
; Exception frame at entry: [rsp]=ErrCode [rsp+8]=RIP [rsp+16]=CS
; ---------------------------------------------------------
KeFaultPF PROC
mov r8, [rsp] ; Arg3: errCode
mov rdx, [rsp+8] ; Arg2: rip
mov r9, cr2 ; Arg4: cr2 (faulting virtual address)
mov r10, [rsp+16] ; cs
mov ecx, 14 ; Arg1: vector = 14
and rsp, -16
sub rsp, FAULT_FRAME_SIZE
mov [rsp+20h], r10 ; Arg5: cs
call KeFaultDispatch
KeFaultPF ENDP
EXTERN KeIrqDispatch:PROC
IrqStub MACRO num
PUBLIC KeIrqStub&num
KeIrqStub&num PROC
push rax
mov al, num
jmp KeIrqCommon
KeIrqStub&num ENDP
ENDM
IrqStub 0
IrqStub 1
IrqStub 2
IrqStub 3
IrqStub 4
IrqStub 5
IrqStub 6
IrqStub 7
IrqStub 8
IrqStub 9
IrqStub 10
IrqStub 11
IrqStub 12
IrqStub 13
IrqStub 14
IrqStub 15
IrqStub 16
IrqStub 17
IrqStub 18
IrqStub 19
IrqStub 20
IrqStub 21
IrqStub 22
IrqStub 23
KeIrqCommon PROC
; al = irq number, rax saved on stack
; Build a minimal calling-convention-safe frame
push rcx
push rdx
push r8
push r9
push r10
push r11
movzx ecx, al ; first arg = irq number (rcx, Win64 ABI)
sub rsp, 32 ; shadow space
call KeIrqDispatch
add rsp, 32
pop r11
pop r10
pop r9
pop r8
pop rdx
pop rcx
pop rax
iretq
KeIrqCommon ENDP
END