1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
//! SYSCALL/SYSRET implementation - Invocation mechanism using MSRs
const entry = @import("../asm/entry.zig");
const gdt = @import("../boot/gdt/gdt.zig");
const handler = @import("handler.zig");
const int = @import("../utils/types/int.zig");
const msr_const = @import("../common/constants/msr.zig");
const msr = @import("../asm/msr.zig");
const ptr = @import("../utils/types/ptr.zig");
const tss = @import("../boot/tss/tss.zig");
const SYSRET_USER_BASE_OFFSET: u64 = 16;
const SyscallContext = packed struct {
rax: u64,
rbx: u64,
rcx: u64,
rdx: u64,
rsi: u64,
rdi: u64,
rbp: u64,
r8: u64,
r9: u64,
r10: u64,
r11: u64,
r12: u64,
r13: u64,
r14: u64,
r15: u64,
user_cs: u64,
user_rip: u64,
user_ss: u64,
user_rflags: u64,
user_rsp: u64,
};
pub fn init() void {
const kernel_cs = int.u64_of(gdt.KERNEL_CODE);
const user_base = int.u64_of(gdt.USER_CODE) - SYSRET_USER_BASE_OFFSET;
const star_value =
(kernel_cs << msr_const.STAR_KERNEL_CS_SHIFT) |
(user_base << msr_const.STAR_USER_BASE_SHIFT);
msr.write(msr_const.IA32_STAR, star_value);
msr.write(msr_const.IA32_LSTAR, entry.get_entry_address());
msr.write(msr_const.IA32_FMASK, msr_const.FMASK_IF);
const efer = msr.read(msr_const.IA32_EFER);
msr.write(msr_const.IA32_EFER, efer | msr_const.EFER_SCE);
}
export fn handle_syscall(ctx_ptr: u64) void {
const regs = ptr.of(SyscallContext, ctx_ptr);
var ctx = handler.InvocationContext{
.rax = regs.rax,
.rbx = regs.rbx,
.rcx = regs.rcx,
.rdx = regs.rdx,
.rsi = regs.rsi,
.rdi = regs.rdi,
.rbp = regs.rbp,
.rsp = regs.user_rsp,
.r8 = regs.r8,
.r9 = regs.r9,
.r10 = regs.r10,
.r11 = regs.r11,
.r12 = regs.r12,
.r13 = regs.r13,
.r14 = regs.r14,
.r15 = regs.r15,
.rip = regs.user_rip,
.rflags = regs.user_rflags,
.cs = regs.user_cs,
.ss = regs.user_ss,
};
handler.handle(&ctx);
regs.rax = ctx.rax;
}
export fn get_kernel_stack() u64 {
return tss.get_kernel_stack();
}
|