Microkernel thing OS experiment (Zig ⚡)
at dev 3.0 kB view raw
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 inline fn readMSR(comptime T: type, num: u32) T { 36 return switch (@bitSizeOf(T)) { 37 32 => @bitCast(asm volatile ("rdmsr" 38 : [_] "={eax}" (-> u32), 39 : [_] "{ecx}" (num), 40 )), 41 64 => blk: { 42 var low_val: u32 = undefined; 43 var high_val: u32 = undefined; 44 asm volatile ("rdmsr" 45 : [_] "={eax}" (low_val), 46 [_] "={edx}" (high_val), 47 : [_] "{ecx}" (num), 48 ); 49 const combined_val = (@as(u64, high_val) << 32) | @as(u64, low_val); 50 break :blk @as(T, combined_val); 51 }, 52 else => @compileError("Unimplemented for type of this size"), 53 }; 54} 55 56pub inline fn writeMSR(comptime T: type, num: u32, val: T) void { 57 switch (@bitSizeOf(T)) { 58 32 => asm volatile ("wrmsr" 59 : 60 : [_] "{eax}" (val), 61 [_] "{edx}" (@as(u32, 0)), 62 [_] "{ecx}" (num), 63 ), 64 64 => { 65 const low_val: u32 = @truncate(@as(u64, val)); 66 const high_val: u32 = @truncate(@as(u64, val >> 32)); 67 asm volatile ("wrmsr" 68 : 69 : [_] "{eax}" (low_val), 70 [_] "{edx}" (high_val), 71 [_] "{ecx}" (num), 72 ); 73 }, 74 else => @compileError("Unimplemented for type of this size"), 75 } 76} 77 78pub fn MSR(comptime T: type, comptime num: u32) type { 79 return struct { 80 pub fn read() T { 81 return readMSR(T, num); 82 } 83 pub fn write(val: T) void { 84 writeMSR(T, num, val); 85 } 86 }; 87} 88 89pub const ControlRegisters = struct { 90 pub const Cr0 = ControlRegister(u64, "cr0"); 91 pub const Cr2 = ControlRegister(u64, "cr2"); 92 pub const Cr3 = ControlRegister(u64, "cr3"); 93 pub const Cr4 = ControlRegister(u64, "cr4"); 94}; 95 96pub const Segmentation = struct { 97 pub const Cs = GeneralPurpose(u16, "cs"); 98 pub const Ds = GeneralPurpose(u16, "ds"); 99 pub const Ss = GeneralPurpose(u16, "ss"); 100 pub const Es = GeneralPurpose(u16, "es"); 101 pub const Fs = GeneralPurpose(u16, "fs"); 102 pub const Gs = GeneralPurpose(u16, "gs"); 103};