> ## Documentation Index
> Fetch the complete documentation index at: https://kernel.mvhcloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# CPU Driver: x86 CPUID, FPU, MSR, and Thermal in MVH Kernel

> MVH Kernel's CPU drivers handle CPUID detection, FPU/SSE/AVX setup, MSR access, hardware RNG, and Intel DTS or AMD northbridge/SMN temperature readings.

The CPU subsystem in MVH Kernel is composed of five cooperating drivers that together fully characterize, initialize, and expose the x86\_64 processor at boot. On startup, the kernel queries CPUID to identify the vendor, brand string, family/model/stepping, and every feature flag it needs. It then initializes the FPU and extended state (SSE, XSAVE, AVX, AVX-512F) based on the capabilities that CPUID reports, enables the applicable security features (NX, SMEP, SMAP, UMIP, supervisor write protection), and probes the available thermal sensor backend. All of this information is surfaced through the `cpuinfo` and `features` shell commands.

## Drivers in This Subsystem

| Driver ID                         | Responsibility                                                                   |
| --------------------------------- | -------------------------------------------------------------------------------- |
| `x86-cpuid`                       | Vendor, brand, family/model/stepping, feature flag enumeration                   |
| `x86-fpu-xsave`                   | FPU, SSE, XSAVE, AVX, and AVX-512F state initialization                          |
| `x86-msr-rng`                     | Hardware RNG via RDRAND; capability-guarded MSR read/write access                |
| `intel-dts-temperature`           | Intel Digital Thermal Sensor temperature via MSRs                                |
| `amd-northbridge-smn-temperature` | AMD Tctl temperature — northbridge (families 10h–16h) and SMN (families 17h–1Ah) |

## CPUID Detection

`cpu_init()` issues CPUID leaves to populate a `cpu_info_t` and a `cpu_capabilities_t` for every subsequent kernel subsystem to consume. The following information is retrieved at boot:

* **Vendor string** — e.g., `GenuineIntel` or `AuthenticAMD` (via `cpu_vendor()`)
* **Brand string** — human-readable model name, up to 48 characters (via `cpu_brand()`)
* **Family, model, and stepping** — computed from the extended family/model fields in CPUID leaf 1
* **APIC ID and logical CPU count** — reported by CPUID; MVH Kernel currently runs on a single boot processor
* **Cache geometry** — L1 data, L1 instruction, L2, and L3 sizes in KiB, plus cache line size in bytes
* **TSC frequency** — computed at boot and stored in `tsc_hz`
* **Microcode revision** — read from MSR `0x8B` when the MSR capability is present

## FPU, SSE, and AVX Initialization

The `x86-fpu-xsave` driver runs after CPUID detection and enables each SIMD tier only when the corresponding capability flag is set:

<Steps>
  <Step title="FPU">
    Sets CR0.MP and clears CR0.EM and CR0.TS to enable the x87 FPU. Required for any floating-point operation.
  </Step>

  <Step title="SSE / SSE2">
    Sets CR4.OSFXSR and CR4.OSXMMEXCPT. SSE2 is always present on x86\_64 but the driver confirms the flags before enabling.
  </Step>

  <Step title="XSAVE">
    Sets CR4.OSXSAVE when the `xsave` capability is present. This is the prerequisite for any extended state (AVX, AVX-512).
  </Step>

  <Step title="AVX">
    Enables the YMM state component in the XCR0 register when the `avx` capability is present.
  </Step>

  <Step title="AVX-512F">
    Enables the ZMM, opmask, and hi-ZMM state components in XCR0 when the `avx512f` capability is present.
  </Step>
</Steps>

The `xsave_bytes` field in `cpu_info_t` reports the size of the XSAVE area in bytes as returned by CPUID leaf `0xD`.

## Security State Initialization

After the FPU is initialized, the kernel enables all available hardware security features:

| Feature                     | Register | Effect                                                      |
| --------------------------- | -------- | ----------------------------------------------------------- |
| Supervisor write protection | CR0.WP   | Prevents kernel-mode writes to read-only pages              |
| NX (No-Execute)             | EFER.NXE | Enforces non-executable data pages                          |
| SMEP                        | CR4.SMEP | Prevents kernel execution of user-mode pages                |
| SMAP                        | CR4.SMAP | Prevents kernel access to user-mode pages without STAC/CLAC |
| UMIP                        | CR4.UMIP | Blocks userspace from executing SGDT, SIDT, SLDT, SMSW, STR |

Each feature is only enabled when the matching capability flag is set. `cpu_get_security_state()` returns the live state for all five flags.

## Hardware RNG

The `x86-msr-rng` driver exposes `cpu_random64()`, which issues the `RDRAND` instruction to generate a hardware-backed 64-bit random number. The function is capability-guarded: it checks the `rdrand` flag in `cpu_capabilities_t` before executing the instruction and returns `0` (failure) if the processor does not support RDRAND.

```c theme={null}
uint64_t value;
if (cpu_random64(&value)) {
    // value contains a hardware-generated random number
}
```

`RDSEED` capability detection is also present in `cpu_capabilities_t` (`rdseed` flag) for future use.

## MSR Access

The `x86-msr-rng` driver also provides capability-guarded MSR primitives:

```c theme={null}
uint8_t cpu_rdmsr(uint32_t msr, uint64_t *value); // Returns 1 on success, 0 if MSR not available
void    cpu_wrmsr(uint32_t msr, uint64_t value);   // Write MSR (only call when msr capability is set)
```

Before calling either function, confirm that the `msr` flag in `cpu_capabilities_t` is set. Calling `cpu_wrmsr` on a processor that does not support MSRs will fault.

## Temperature Backends

The kernel probes for a thermal backend in priority order and stores the result in `cpu_info_t`. The `temperature_available` flag indicates whether a reading was obtained. When no supported backend is detected — such as when running inside QEMU without thermal emulation — the driver reports the temperature as unavailable and sets `temperature_celsius` to a sentinel value rather than crashing.

<AccordionGroup>
  <Accordion title="Intel Digital Thermal Sensor (DTS)">
    Used on supported Intel processors. The driver reads MSR `0x19C` (IA32\_THERM\_STATUS) and MSR `0x1A2` (MSR\_TEMPERATURE\_TARGET) to compute the package temperature from the thermal margin. Reported in both `temperature_celsius` and `temperature_millicelsius`. The `temperature_source` string is set to `"Intel DTS/MSR"`.
  </Accordion>

  <Accordion title="AMD Northbridge (Families 10h–16h)">
    Used on AMD processors from families 10h through 16h. The driver reads the Tctl register from the northbridge PCI device (bus 0, device 24, function 3, offset `0xA4`) and converts the raw value to degrees Celsius. The `temperature_source` string is set to `"AMD northbridge Tctl"`.
  </Accordion>

  <Accordion title="AMD SMN (Families 17h–1Ah)">
    Used on AMD Zen-architecture processors (families 17h through 1Ah). The driver accesses the System Management Network (SMN) via PCI indirect registers to read THM::CUR\_TEMP and converts the Tctl value to degrees Celsius. The `temperature_source` string is set to `"AMD SMN Tctl"`.
  </Accordion>
</AccordionGroup>

All backends validate the raw value against a sane range before reporting. Out-of-range readings are discarded and the temperature is reported as unavailable.

## Data Structures

### `cpu_info_t`

```c theme={null}
typedef struct {
    uint32_t family;                  // CPU family (extended)
    uint32_t model;                   // CPU model (extended)
    uint32_t stepping;                // CPU stepping
    uint32_t apic_id;                 // Local APIC ID of the boot processor
    uint32_t logical_cpus;            // Logical CPU count reported by CPUID
    uint32_t cache_line_bytes;        // Cache line size in bytes
    uint32_t l1_data_kib;             // L1 data cache size in KiB
    uint32_t l1_instruction_kib;      // L1 instruction cache size in KiB
    uint32_t l2_kib;                  // L2 cache size in KiB
    uint32_t l3_kib;                  // L3 cache size in KiB
    uint32_t xsave_bytes;             // XSAVE area size in bytes
    uint32_t microcode;               // Microcode revision (when available)
    uint64_t tsc_hz;                  // TSC frequency in Hz
    uint64_t local_apic_base;         // Local APIC base address from IA32_APIC_BASE MSR
    uint8_t  local_apic_enabled;      // 1 if the local APIC is enabled
    uint8_t  x2apic_enabled;          // 1 if x2APIC mode is active
    uint8_t  microcode_available;     // 1 if the microcode revision was read successfully
    uint8_t  temperature_available;   // 1 if a temperature backend is active
    int32_t  temperature_celsius;     // Current temperature in whole degrees Celsius
    int32_t  temperature_millicelsius;// Current temperature in millidegrees Celsius
    const char *temperature_source;  // Name of the active temperature backend
} cpu_info_t;
```

### `cpu_capabilities_t`

```c theme={null}
typedef struct {
    uint8_t fpu;           // x87 FPU present
    uint8_t sse;           // SSE supported
    uint8_t sse2;          // SSE2 supported
    uint8_t avx;           // AVX supported
    uint8_t avx2;          // AVX2 supported
    uint8_t avx512f;       // AVX-512 Foundation supported
    uint8_t xsave;         // XSAVE/XRSTOR supported
    uint8_t osxsave;       // XSAVE enabled in CR4 (OS support confirmed)
    uint8_t msr;           // RDMSR/WRMSR supported
    uint8_t apic;          // Local APIC present
    uint8_t x2apic;        // x2APIC supported
    uint8_t tsc;           // Time Stamp Counter present
    uint8_t invariant_tsc; // Invariant TSC (non-stop TSC across P/C-states)
    uint8_t rdrand;        // RDRAND hardware RNG supported
    uint8_t rdseed;        // RDSEED supported
    uint8_t mtrr;          // Memory Type Range Registers present
    uint8_t pat;           // Page Attribute Table supported
    uint8_t nx;            // No-Execute bit supported (EFER.NXE)
    uint8_t smep;          // Supervisor Mode Execution Prevention
    uint8_t smap;          // Supervisor Mode Access Prevention
    uint8_t umip;          // User-Mode Instruction Prevention
} cpu_capabilities_t;
```

### `cpu_security_state_t`

```c theme={null}
typedef struct {
    uint8_t write_protect; // CR0.WP — supervisor write protection active
    uint8_t nx;            // EFER.NXE — NX enforcement active
    uint8_t smep;          // CR4.SMEP active
    uint8_t smap;          // CR4.SMAP active
    uint8_t umip;          // CR4.UMIP active
} cpu_security_state_t;
```

## Shell Commands

| Command    | Output                                                                                                  |
| ---------- | ------------------------------------------------------------------------------------------------------- |
| `cpuinfo`  | Full `cpu_info_t` dump: vendor, brand, family/model/stepping, APIC, caches, TSC, temperature, microcode |
| `features` | Full `cpu_capabilities_t` dump plus enabled kernel support status for each feature                      |

## Full API Reference

```c theme={null}
void     cpu_init(void);                              // Initialize CPU subsystem, populate info/capabilities
void     cpu_vendor(char *vendor);                    // Write null-terminated vendor string (≥ 13 bytes)
void     cpu_brand(char *brand);                      // Write null-terminated brand string (≥ 49 bytes)
uint32_t cpu_logical_count(void);                     // Return logical CPU count from CPUID
uint32_t cpu_feature_ecx(void);                       // Raw CPUID leaf 1 ECX feature flags
uint32_t cpu_feature_edx(void);                       // Raw CPUID leaf 1 EDX feature flags
uint32_t cpu_extended_feature_edx(void);              // Raw CPUID leaf 0x80000001 EDX extended flags
void     cpu_get_info(cpu_info_t *info);              // Populate a cpu_info_t struct
void     cpu_get_capabilities(cpu_capabilities_t *c); // Populate a cpu_capabilities_t struct
void     cpu_get_security_state(cpu_security_state_t *s); // Populate a cpu_security_state_t struct
uint64_t cpu_read_tsc(void);                          // Read the Time Stamp Counter (RDTSC)
uint8_t  cpu_random64(uint64_t *value);               // Generate a hardware RNG value via RDRAND
uint8_t  cpu_rdmsr(uint32_t msr, uint64_t *value);    // Read an MSR; returns 1 on success
void     cpu_wrmsr(uint32_t msr, uint64_t value);     // Write an MSR
```
