Microkernel thing OS experiment (Zig ⚡)
1// Do all the needed CPUID calls here, and store the info for later use
2const std = @import("std");
3const arch = @import("../root.zig");
4
5pub const captured = struct {
6 pub var vendor_str: [12]u8 = undefined;
7};
8pub fn init() void {
9 capture_vendor_str();
10 capture_cpu_features();
11}
12
13fn capture_vendor_str() void {
14 const res = cpuid(0, 0);
15 @memcpy(captured.vendor_str[0..4], std.mem.asBytes(&res.ebx));
16 @memcpy(captured.vendor_str[4..8], std.mem.asBytes(&res.edx));
17 @memcpy(captured.vendor_str[8..12], std.mem.asBytes(&res.ecx));
18}
19
20fn capture_cpu_features() void {
21 const res = cpuid(1, 0);
22 const feat_ecx: FeaturesEcx = @bitCast(res.ecx);
23 arch.interrupts.apic.tsc_deadline_available = feat_ecx.tsc_deadline;
24 arch.interrupts.apic.has_x2apic = feat_ecx.x2apic;
25}
26
27const FeaturesEcx = packed struct(u32) {
28 sse3: bool,
29 pclmulqdq: bool,
30 dtes64: bool,
31 monitor: bool,
32 ds_cpl: bool,
33 vmx: bool,
34 smx: bool,
35 est: bool,
36 tm2: bool,
37 ssse3: bool,
38 cnxt_id: bool,
39 sdbg: bool,
40 fma: bool,
41 cx16: bool,
42 xtpr: bool,
43 pdcm: bool,
44 _reserved0: bool,
45 pcid: bool,
46 dca: bool,
47 sse4_1: bool,
48 sse4_2: bool,
49 x2apic: bool,
50 movbe: bool,
51 popcnt: bool,
52 tsc_deadline: bool,
53 aesni: bool,
54 xsave: bool,
55 osxsave: bool,
56 avx: bool,
57 f16c: bool,
58 rdrand: bool,
59 hypervisor: bool,
60};
61
62pub inline fn cpuid(leaf: u32, sub: u32) DefaultResults {
63 var eax: u32 = undefined;
64 var ebx: u32 = undefined;
65 var edx: u32 = undefined;
66 var ecx: u32 = undefined;
67
68 asm volatile (
69 \\cpuid
70 : [eax] "={eax}" (eax),
71 [ebx] "={ebx}" (ebx),
72 [edx] "={edx}" (edx),
73 [ecx] "={ecx}" (ecx),
74 : [leaf] "{eax}" (leaf),
75 [sub] "{ecx}" (sub),
76 );
77
78 return .{
79 .eax = eax,
80 .ebx = ebx,
81 .ecx = ecx,
82 .edx = edx,
83 };
84}
85
86pub const DefaultResults = struct {
87 eax: u32 = 0,
88 ebx: u32 = 0,
89 edx: u32 = 0,
90 ecx: u32 = 0,
91};