pub fn ControlRegister(comptime T: type, comptime reg: []const u8) type { return struct { pub fn read() T { return asm volatile ("mov %%" ++ reg ++ ", %[output]" : [output] "=r" (-> T), ); } pub fn write(value: T) void { asm volatile ("mov %[input], %%" ++ reg : : [input] "r" (value), ); } }; } pub fn GeneralPurpose(comptime T: type, comptime reg: []const u8) type { return struct { pub fn read() T { return asm volatile ("mov %%" ++ reg ++ ", %[output]" : [output] "=r" (-> T), ); } pub fn write(value: T) void { asm volatile ("mov %[input], %%" ++ reg : : [input] "r" (value), ); } }; } pub fn MSR(comptime T: type, comptime num: u32) type { return struct { pub fn read() T { // TODO: switch on bit size to allow custom structs switch (T) { u32 => return asm volatile ("rdmsr" : [_] "={eax}" (-> u32), : [_] "{ecx}" (num), ), u64 => { var low_val: u32 = undefined; var high_val: u32 = undefined; asm volatile ("rdmsr" : [_] "={eax}" (low_val), [_] "={edx}" (high_val), : [_] "{ecx}" (num), ); return (@as(u64, high_val) << 32) | @as(u64, low_val); }, else => @compileError("Unimplemented for type"), } } pub fn write(value: T) void { switch (T) { u32 => asm volatile ("wrmsr" : : [_] "{eax}" (value), [_] "{edx}" (@as(u32, 0)), [_] "{ecx}" (num), ), u64 => { const low_val: u32 = @truncate(value); const high_val: u32 = @truncate(value >> 32); asm volatile ("wrmsr" : : [_] "{eax}" (low_val), [_] "{edx}" (high_val), [_] "{ecx}" (num), ); }, else => @compileError("Unimplemented for type"), } } }; } pub const ControlRegisters = struct { pub const Cr0 = ControlRegister(u64, "cr0"); pub const Cr2 = ControlRegister(u64, "cr2"); pub const Cr3 = ControlRegister(u64, "cr3"); pub const Cr4 = ControlRegister(u64, "cr4"); }; pub const Segmentation = struct { pub const Cs = GeneralPurpose(u16, "cs"); pub const Ds = GeneralPurpose(u16, "ds"); pub const Ss = GeneralPurpose(u16, "ss"); pub const Es = GeneralPurpose(u16, "es"); pub const Fs = GeneralPurpose(u16, "fs"); pub const Gs = GeneralPurpose(u16, "gs"); };