aboutsummaryrefslogtreecommitdiff
path: root/mirai.old/invocations/syscall.zig
diff options
context:
space:
mode:
Diffstat (limited to 'mirai.old/invocations/syscall.zig')
-rw-r--r--mirai.old/invocations/syscall.zig85
1 files changed, 85 insertions, 0 deletions
diff --git a/mirai.old/invocations/syscall.zig b/mirai.old/invocations/syscall.zig
new file mode 100644
index 0000000..73a7b68
--- /dev/null
+++ b/mirai.old/invocations/syscall.zig
@@ -0,0 +1,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();
+}