diff options
Diffstat (limited to 'mirai/asm/cpuid.zig')
| -rw-r--r-- | mirai/asm/cpuid.zig | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/mirai/asm/cpuid.zig b/mirai/asm/cpuid.zig new file mode 100644 index 0000000..6367b42 --- /dev/null +++ b/mirai/asm/cpuid.zig @@ -0,0 +1,58 @@ +//! CPUID Operations + +pub const CpuidResult = struct { + eax: u32, + ebx: u32, + ecx: u32, + edx: u32, +}; + +/// Execute CPUID instruction with given leaf +pub inline fn cpuid(leaf: u32) CpuidResult { + var eax: u32 = undefined; + var ebx: u32 = undefined; + var ecx: u32 = undefined; + var edx: u32 = undefined; + + asm volatile ("cpuid" + : [eax] "={eax}" (eax), + [ebx] "={ebx}" (ebx), + [ecx] "={ecx}" (ecx), + [edx] "={edx}" (edx), + : [leaf] "{eax}" (leaf), + ); + + return CpuidResult{ + .eax = eax, + .ebx = ebx, + .ecx = ecx, + .edx = edx, + }; +} + +/// Get maximum extended CPUID leaf +pub inline fn get_max_extended() u32 { + return cpuid(0x80000000).eax; +} + +/// Check if extended brand string is supported +pub inline fn has_brand_string() bool { + return get_max_extended() >= 0x80000004; +} + +/// Get CPU brand string (48 bytes) +pub fn get_brand_string(buffer: *[48]u8) void { + var pos: usize = 0; + + inline for ([_]u32{ 0x80000002, 0x80000003, 0x80000004 }) |leaf| { + const result = cpuid(leaf); + + inline for ([_]u32{ result.eax, result.ebx, result.ecx, result.edx }) |reg| { + buffer[pos] = @truncate(reg); + buffer[pos + 1] = @truncate(reg >> 8); + buffer[pos + 2] = @truncate(reg >> 16); + buffer[pos + 3] = @truncate(reg >> 24); + pos += 4; + } + } +} |
