From a34f179d8455ae6627da858bfbf549b488149a11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Gr=C3=A9goire?= Date: Tue, 14 Apr 2026 22:21:36 -0400 Subject: [PATCH] refactor(amd64): rework MSR handling --- src/arch/amd64/root.zig | 26 ++++++++++++++++++++++---- src/kern/amd64/init.zig | 2 +- src/platform/pc/pvclock.zig | 2 +- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/arch/amd64/root.zig b/src/arch/amd64/root.zig index f1629ab..fa34bca 100644 --- a/src/arch/amd64/root.zig +++ b/src/arch/amd64/root.zig @@ -6,6 +6,7 @@ pub const name = "amd64"; pub const Msr = enum(u32) { /// IA32_APIC_BASE LapicBase = 0x1B, + X2ApicBase = 0x800, /// IA32_FS_BASE FsBase = 0xC000_0100, /// IA32_GS_BASE @@ -20,6 +21,7 @@ pub const Msr = enum(u32) { LStar = 0xC000_0082, /// MSR_KVM_SYSTEM_TIME_NEW KvmSystemTimeNew = 0x4B564D01, + _, }; pub const IrqFrame = extern struct { @@ -92,26 +94,34 @@ pub inline fn inl(port: u16) u32 { ); } -pub inline fn rdmsr(msr: Msr) u64 { +pub inline fn rdmsr(msr: u32) u64 { var low: u32 = undefined; var high: u32 = undefined; asm volatile ("rdmsr" : [low] "={eax}" (low), [high] "={edx}" (high), - : [msr] "{ecx}" (@intFromEnum(msr)), + : [msr] "{ecx}" (msr), ); return @as(u64, high) << 32 | low; } -pub inline fn wrmsr(msr: Msr, value: u64) void { +pub inline fn wrmsr(msr: u32, value: u64) void { asm volatile ("wrmsr" : : [low] "{eax}" (@as(u32, @truncate(value))), [high] "{edx}" (@as(u32, @truncate(value >> 32))), - [msr] "{ecx}" (@intFromEnum(msr)), + [msr] "{ecx}" (msr), ); } +pub inline fn read_msr(comptime msr: Msr) u64 { + return rdmsr(@intFromEnum(msr)); +} + +pub inline fn write_msr(comptime msr: Msr, value: u64) void { + wrmsr(@intFromEnum(msr), value); +} + pub inline fn rdgsbase() usize { return asm volatile ("rdgsbase %[ret]" : [ret] "=r" (-> usize), @@ -630,6 +640,14 @@ pub const Idtr = extern struct { base: usize align(1), }; +pub fn sidtr() Idtr { + var idtr: Idtr = undefined; + asm volatile ("sidt %[idtr]" + : [idtr] "={memory}" (idtr), + ); + return idtr; +} + pub const IdtEntry = extern struct { offset_low: u16 align(1), selector: u16 align(1), diff --git a/src/kern/amd64/init.zig b/src/kern/amd64/init.zig index bd9c7a7..4f3837e 100644 --- a/src/kern/amd64/init.zig +++ b/src/kern/amd64/init.zig @@ -34,5 +34,5 @@ pub fn early_init() linksection(b.init) void { int.init(); // Enable Per-CPU data for this CPU - amd64.wrmsr(.GsBase, 0); + amd64.write_msr(.GsBase, 0); } diff --git a/src/platform/pc/pvclock.zig b/src/platform/pc/pvclock.zig index 2ebb0cd..50bf77a 100644 --- a/src/platform/pc/pvclock.zig +++ b/src/platform/pc/pvclock.zig @@ -33,7 +33,7 @@ pub fn init() linksection(b.init) void { const page = mm.phys.alloc(); pvclock = @ptrFromInt(mm.p2v(page)); - amd64.wrmsr(.KvmSystemTimeNew, page | 1); + amd64.write_msr(.KvmSystemTimeNew, page | 1); time_at_boot = read_pvclock();