diff --git a/src/arch/amd64/root.zig b/src/arch/amd64/root.zig index 8a69adc..d653bcf 100644 --- a/src/arch/amd64/root.zig +++ b/src/arch/amd64/root.zig @@ -110,6 +110,12 @@ pub inline fn wrmsr(msr: Msr, value: u64) void { ); } +pub inline fn rdgsbase() usize { + return asm volatile ("rdgsbase %[ret]" + : [ret] "=r" (-> usize), + ); +} + pub inline fn invlpg(addr: u64) void { asm volatile ("invlpg (%[addr])" : @@ -204,7 +210,7 @@ pub const Cr4 = packed struct(u64) { osxmmEex: bool, umip: bool, la57: bool, - reserved: u4, + reserved: u3, fsgsbase: bool, pcide: bool, osxsave: bool, @@ -213,16 +219,17 @@ pub const Cr4 = packed struct(u64) { smap: bool, pke: bool, cet: bool, + reserved2: u40, }; -pub inline fn read_cr(comptime n: u2) u64 { +pub inline fn read_cr(comptime n: u8) u64 { comptime std.debug.assert(n != 1); return asm volatile (std.fmt.comptimePrint("mov %%cr{}, %[ret]", .{n}) : [ret] "=r" (-> u64), ); } -pub inline fn write_cr(comptime n: u2, value: u64) void { +pub inline fn write_cr(comptime n: u8, value: u64) void { comptime std.debug.assert(n != 1); asm volatile (std.fmt.comptimePrint("mov %[value], %%cr{}", .{n}) : diff --git a/src/kern/amd64/impl.zig b/src/kern/amd64/impl.zig index df673b1..835ce5d 100644 --- a/src/kern/amd64/impl.zig +++ b/src/kern/amd64/impl.zig @@ -12,6 +12,8 @@ pub const Cpu = struct { percpu_offset: usize, }; +pub var cpu_self_offset: usize linksection(b.percpu) = 0; + pub const ThreadContext = struct { rdi: u64, rsi: u64, @@ -104,7 +106,6 @@ pub const ThreadContext = struct { inline fn percpu_ptr_for(variable: anytype, cpu: u32) @TypeOf(variable) { _ = cpu; // TODO @panic("TODO percpu_ptr_for"); - // return @ptrFromInt(@intFromPtr(variable) +% cpu.impl.percpu_offset); } @@ -113,7 +114,12 @@ pub inline fn percpu_ptr_other(variable: anytype, id: u32) @TypeOf(variable) { } pub inline fn percpu_ptr(variable: anytype) @TypeOf(variable) { - @panic("TODO percpu_ptr"); + const offset = asm volatile ("mov %%gs:(%[self]), %[out]" + : [out] "=r" (-> u64), + : [self] "r" (&cpu_self_offset), + ); + + return @ptrFromInt(offset +% @intFromPtr(variable)); } pub inline fn set_hardware_ipl(ipl: ke.Ipl) void { diff --git a/src/kern/amd64/init.zig b/src/kern/amd64/init.zig index c46ff95..bd9c7a7 100644 --- a/src/kern/amd64/init.zig +++ b/src/kern/amd64/init.zig @@ -33,5 +33,6 @@ pub fn early_init() linksection(b.init) void { int.init(); - asm volatile ("int3"); + // Enable Per-CPU data for this CPU + amd64.wrmsr(.GsBase, 0); }