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};