From 67b5d6ea184c432b21b3f07649ec3ba150a1d350 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Wed, 17 Mar 2021 15:20:53 +0200 Subject: cpuid: show manufacturer and model --- src/cpu/cpu.cc | 35 ++++++++++++++++++++ src/cpu/cpu.h | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 src/cpu/cpu.cc create mode 100644 src/cpu/cpu.h (limited to 'src/cpu') diff --git a/src/cpu/cpu.cc b/src/cpu/cpu.cc new file mode 100644 index 0000000..0c9403f --- /dev/null +++ b/src/cpu/cpu.cc @@ -0,0 +1,35 @@ +#include "cpu.h" +#include + +static_assert(sizeof(CPU::features_t) == 2 * sizeof(uint32_t)); + +CPU::CPU() { + static_assert(sizeof(CPU::version_t) == sizeof(uint32_t)); + struct { + uint32_t d; + uint32_t c; + uint32_t b; + uint32_t a; + } __attribute__((packed)) r; + size_t highest_param = 0; + + for (int i = 0; i <= highest_param; ++i) { + asm volatile("cpuid" : "=a"(r.a), "=b"(r.b), "=c"(r.c), "=d"(r.d) : "a"(i)); + + switch (i) { + case 0: + highest_param = static_cast(r.a); + memcpy(&m_manufacturer[0], &r.b, sizeof(r.b)); + memcpy(&m_manufacturer[4], &r.d, sizeof(r.d)); + memcpy(&m_manufacturer[8], &r.c, sizeof(r.c)); + break; + case 1: + memcpy(&m_info, &r.a, sizeof(r.a)); + memcpy(&m_features, &r.d, sizeof(CPU::features_t)); + break; + default: + return; + } + } + +} diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h new file mode 100644 index 0000000..2dc9cbe --- /dev/null +++ b/src/cpu/cpu.h @@ -0,0 +1,101 @@ +#pragma once + +#include + +class CPU { +public: + struct features_t { + bool fpu : 1 = false; // onboard x87 fpu + bool vme : 1 = false; // virtual 8086 mode + bool de : 1 = false; // debugging extensions + bool pse : 1 = false; // page size extension + bool tsc : 1 = false; // time stamp counter + bool msr : 1 = false; // model specific registers + bool pae : 1 = false; // physical address extension + bool mce : 1 = false; // machine check exception + bool cx8 : 1 = false; // compare and swap instruction + bool apic : 1 = false; // onboard apic + bool __r0 : 1 = false; + bool sep : 1 = false; // sysenter and sysexit + bool mtrr : 1 = false; // memory type range registers + bool pge : 1 = false; // page global enable bit + bool mca : 1 = false; // machine check architecture + bool cmov : 1 = false; // conditional move + bool pat : 1 = false; // page attribute table + bool pse36 : 1 = false; // 36-bit page size extension + bool psn : 1 = false; // processor serial number + bool clfsh : 1 = false; // clflish + bool __r1 : 1 = false; + bool ds : 1 = false; // debug store + bool acpi : 1 = false; // onboard thermal control for acpi + bool mmx : 1 = false; // mmx extension + bool fxsr : 1 = false; // fxsave, fxrestor + bool sse : 1 = false; // sse extension + bool sse2 : 1 = false; // sse2 extension + bool ss : 1 = false; // cpu cache implements self-snoop + bool htt : 1 = false; // hyper-threading + bool tm : 1 = false; // thermal monitor auto-limits temperature + bool ia64 : 1 = false; // ia64 processor emulating x86 + bool pbe : 1 = false; // pending break enable + + bool sse3 : 1 = false; // sse3 extension + bool pclmulqdq : 1 = false; // pclmulqdq + bool dtes64 : 1 = false; // 64-bit debug store + bool monitor : 1 = false; // monitor and mwait instructions (sse3) + bool ds_cpl : 1 = false; // CPL qualified debug store + bool vmx : 1 = false; // virtual machine extensions + bool smx : 1 = false; // safer mode extensions + bool est : 1 = false; // enahnced speedstep + bool tm2 : 1 = false; // thermal monitor 2 + bool ssse3 : 1 = false; // supplemental sse3 + bool cnxt_id : 1 = false; // L1 context ID + bool sdbg : 1 = false; // Silicon Debug interface + bool fma : 1 = false; // fused multiply-add + bool cx16 : 1 = false; // cmpxchg16b instruction + bool xtpr : 1 = false; // can disable sending task priority messages + bool pdcm : 1 = false; // perfom and debug capability + bool __r2 : 1 = false; + bool pcid : 1 = false; // process context identifiers + bool dca : 1 = false; // direct cache access for DMA writes + bool sse41 : 1 = false; // sse 4.1 + bool sse42 : 1 = false; // sse 4.2 + bool x2apic : 1 = false; // x2APIX + bool movbe : 1 = false; // movbe instruction + bool popcnt : 1 = false; // popcnt instruction + bool tsc_deadline : 1 = false; // apic implements one-shot operation using tsc deadline + bool aes : 1 = false; // aes instruction set + bool xsave : 1 = false; // xsave, xrestor, xsetbv, xgetbv + bool oxsave : 1 = false; // xsave enabled by OS + bool avx : 1 = false; // advanced vector extensions + bool f16c : 1 = false; // f16c fp feature + bool rdrnd : 1 = false; // rdrand + bool hypervisor : 1 = false; // hypervisor present + } __attribute__((packed)); + + CPU(); + ~CPU() = default; + + const char* manufacturer() const { return m_manufacturer; } + uint8_t family() const { return m_info.family == 15 ? m_info.family + m_info.family_ex : m_info.family; } + uint8_t model() const { + return (m_info.model == 6 || m_info.model == 15) ? (static_cast(m_info.model_ex << 4) + m_info.model) + : m_info.model; + } + uint8_t stepping() const { return m_info.stepping; } + auto features() const { return m_features; } + +private: + char m_manufacturer[13] = {'\0'}; + struct version_t { + uint8_t stepping : 4 = 0; + uint8_t model : 4 = 0; + uint8_t family : 4 = 0; + uint8_t type : 2 = 0; + uint8_t reserved_1 : 2 = 0; + uint8_t model_ex : 4 = 0; + uint8_t family_ex : 8 = 0; + uint8_t reserved_2 : 4 = 0; + } __attribute__((packed)) m_info; + + features_t m_features; +}; -- cgit v1.2.1