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}
25
26const FeaturesEcx = packed struct(u32) {
27 _reserved0: u23,
28 tsc_deadline: bool,
29 _reserved1: u8,
30};
31
32pub inline fn cpuid(leaf: u32, sub: u32) DefaultResults {
33 var eax: u32 = undefined;
34 var ebx: u32 = undefined;
35 var edx: u32 = undefined;
36 var ecx: u32 = undefined;
37
38 asm volatile (
39 \\cpuid
40 : [eax] "={eax}" (eax),
41 [ebx] "={ebx}" (ebx),
42 [edx] "={edx}" (edx),
43 [ecx] "={ecx}" (ecx),
44 : [leaf] "{eax}" (leaf),
45 [sub] "{ecx}" (sub),
46 );
47
48 return .{
49 .eax = eax,
50 .ebx = ebx,
51 .ecx = ecx,
52 .edx = edx,
53 };
54}
55
56pub const DefaultResults = struct {
57 eax: u32 = 0,
58 ebx: u32 = 0,
59 edx: u32 = 0,
60 ecx: u32 = 0,
61};