Microkernel thing OS experiment (Zig ⚡)
1pub fn ControlRegister(comptime T: type, comptime reg: []const u8) type { 2 return struct { 3 pub fn read() T { 4 return asm volatile ("mov %%" ++ reg ++ ", %[output]" 5 : [output] "=r" (-> T), 6 ); 7 } 8 9 pub fn write(value: T) void { 10 asm volatile ("mov %[input], %%" ++ reg 11 : 12 : [input] "r" (value), 13 ); 14 } 15 }; 16} 17 18pub fn GeneralPurpose(comptime T: type, comptime reg: []const u8) type { 19 return struct { 20 pub fn read() T { 21 return asm volatile ("mov %%" ++ reg ++ ", %[output]" 22 : [output] "=r" (-> T), 23 ); 24 } 25 26 pub fn write(value: T) void { 27 asm volatile ("mov %[input], %%" ++ reg 28 : 29 : [input] "r" (value), 30 ); 31 } 32 }; 33} 34 35pub fn MSR(comptime T: type, comptime num: u32) type { 36 return struct { 37 pub fn read() T { 38 // TODO: switch on bit size to allow custom structs 39 switch (T) { 40 u32 => return asm volatile ("rdmsr" 41 : [_] "={eax}" (-> u32), 42 : [_] "{ecx}" (num), 43 ), 44 u64 => { 45 var low_val: u32 = undefined; 46 var high_val: u32 = undefined; 47 asm volatile ("rdmsr" 48 : [_] "={eax}" (low_val), 49 [_] "={edx}" (high_val), 50 : [_] "{ecx}" (num), 51 ); 52 return (@as(u64, high_val) << 32) | @as(u64, low_val); 53 }, 54 else => @compileError("Unimplemented for type"), 55 } 56 } 57 pub fn write(value: T) void { 58 switch (T) { 59 u32 => asm volatile ("wrmsr" 60 : 61 : [_] "{eax}" (value), 62 [_] "{edx}" (@as(u32, 0)), 63 [_] "{ecx}" (num), 64 ), 65 u64 => { 66 const low_val: u32 = @truncate(value); 67 const high_val: u32 = @truncate(value >> 32); 68 asm volatile ("wrmsr" 69 : 70 : [_] "{eax}" (low_val), 71 [_] "{edx}" (high_val), 72 [_] "{ecx}" (num), 73 ); 74 }, 75 else => @compileError("Unimplemented for type"), 76 } 77 } 78 }; 79} 80 81pub const ControlRegisters = struct { 82 pub const Cr0 = ControlRegister(u64, "cr0"); 83 pub const Cr2 = ControlRegister(u64, "cr2"); 84 pub const Cr3 = ControlRegister(u64, "cr3"); 85 pub const Cr4 = ControlRegister(u64, "cr4"); 86}; 87 88pub const Segmentation = struct { 89 pub const Cs = GeneralPurpose(u16, "cs"); 90 pub const Ds = GeneralPurpose(u16, "ds"); 91 pub const Ss = GeneralPurpose(u16, "ss"); 92 pub const Es = GeneralPurpose(u16, "es"); 93 pub const Fs = GeneralPurpose(u16, "fs"); 94 pub const Gs = GeneralPurpose(u16, "gs"); 95};