> ## 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 API — CPUID, Capabilities, Security State, and RNG

> Reference for the MVH Kernel CPU API: cpu_get_info, cpu_get_capabilities, cpu_get_security_state, cpu_read_tsc, cpu_random64, cpu_rdmsr, cpu_wrmsr.

The CPU API exposes CPUID-based processor detection, structured capability querying, active security feature inspection, Time Stamp Counter (TSC) reading, hardware random number generation via RDRAND, and Model-Specific Register (MSR) access. After calling `cpu_init`, you can query detailed information about the processor topology, cache hierarchy, supported instruction sets, and the security mitigations that the kernel has enabled in hardware control registers.

## Structures

### `cpu_info_t`

A comprehensive snapshot of processor identity and topology. Filled by `cpu_get_info`.

```c theme={null}
typedef struct {
    uint32_t    family;
    uint32_t    model;
    uint32_t    stepping;
    uint32_t    apic_id;
    uint32_t    logical_cpus;
    uint32_t    cache_line_bytes;
    uint32_t    l1_data_kib;
    uint32_t    l1_instruction_kib;
    uint32_t    l2_kib;
    uint32_t    l3_kib;
    uint32_t    xsave_bytes;
    uint32_t    microcode;
    uint64_t    tsc_hz;
    uint64_t    local_apic_base;
    uint8_t     local_apic_enabled;
    uint8_t     x2apic_enabled;
    uint8_t     microcode_available;
    uint8_t     temperature_available;
    int32_t     temperature_celsius;
    int32_t     temperature_millicelsius;
    const char *temperature_source;
} cpu_info_t;
```

<ResponseField name="family" type="uint32_t">
  Processor family number from CPUID leaf 1 (extended family included).
</ResponseField>

<ResponseField name="model" type="uint32_t">
  Processor model number from CPUID leaf 1 (extended model included).
</ResponseField>

<ResponseField name="stepping" type="uint32_t">
  Processor stepping (revision) identifier.
</ResponseField>

<ResponseField name="apic_id" type="uint32_t">
  Local APIC ID of the bootstrap processor, as reported by CPUID leaf 1.
</ResponseField>

<ResponseField name="logical_cpus" type="uint32_t">
  Number of logical CPU threads reported by CPUID.
</ResponseField>

<ResponseField name="cache_line_bytes" type="uint32_t">
  Cache line size in bytes (typically `64`).
</ResponseField>

<ResponseField name="l1_data_kib" type="uint32_t">
  L1 data cache size in kibibytes.
</ResponseField>

<ResponseField name="l1_instruction_kib" type="uint32_t">
  L1 instruction cache size in kibibytes.
</ResponseField>

<ResponseField name="l2_kib" type="uint32_t">
  L2 unified cache size in kibibytes.
</ResponseField>

<ResponseField name="l3_kib" type="uint32_t">
  L3 unified cache size in kibibytes. `0` if no L3 cache is present.
</ResponseField>

<ResponseField name="xsave_bytes" type="uint32_t">
  Size in bytes of the XSAVE area, as reported by CPUID leaf `0xD`. `0` if XSAVE is not supported.
</ResponseField>

<ResponseField name="microcode" type="uint32_t">
  Current microcode revision read from MSR `0x8B`. Only valid when `microcode_available` is `1`.
</ResponseField>

<ResponseField name="tsc_hz" type="uint64_t">
  Calibrated TSC frequency in Hz. `0` if the frequency could not be determined.
</ResponseField>

<ResponseField name="local_apic_base" type="uint64_t">
  Physical base address of the local APIC MMIO region, read from the `IA32_APIC_BASE` MSR.
</ResponseField>

<ResponseField name="local_apic_enabled" type="uint8_t">
  `1` if the local APIC is enabled in the `IA32_APIC_BASE` MSR, `0` otherwise.
</ResponseField>

<ResponseField name="x2apic_enabled" type="uint8_t">
  `1` if x2APIC mode is currently active, `0` otherwise.
</ResponseField>

<ResponseField name="microcode_available" type="uint8_t">
  `1` if the microcode revision was successfully read from MSR `0x8B`, `0` otherwise.
</ResponseField>

<ResponseField name="temperature_available" type="uint8_t">
  `1` if a CPU temperature reading is available, `0` otherwise.
</ResponseField>

<ResponseField name="temperature_celsius" type="int32_t">
  Current CPU temperature in whole degrees Celsius. Only valid when `temperature_available` is `1`.
</ResponseField>

<ResponseField name="temperature_millicelsius" type="int32_t">
  Current CPU temperature in millidegrees Celsius for higher precision. Only valid when `temperature_available` is `1`.
</ResponseField>

<ResponseField name="temperature_source" type="const char *">
  Static string identifying the temperature source (e.g., `"MSR_THERM_STATUS"`). Only valid when `temperature_available` is `1`.
</ResponseField>

***

### `cpu_capabilities_t`

A flat set of boolean flags describing which processor features are available. Filled by `cpu_get_capabilities`.

```c theme={null}
typedef struct {
    uint8_t fpu;
    uint8_t sse;
    uint8_t sse2;
    uint8_t avx;
    uint8_t avx2;
    uint8_t avx512f;
    uint8_t xsave;
    uint8_t osxsave;
    uint8_t msr;
    uint8_t apic;
    uint8_t x2apic;
    uint8_t tsc;
    uint8_t invariant_tsc;
    uint8_t rdrand;
    uint8_t rdseed;
    uint8_t mtrr;
    uint8_t pat;
    uint8_t nx;
    uint8_t smep;
    uint8_t smap;
    uint8_t umip;
} cpu_capabilities_t;
```

Every field is `1` if the feature is present and usable, `0` if absent.

<ResponseField name="fpu" type="uint8_t">x87 FPU on-chip.</ResponseField>
<ResponseField name="sse" type="uint8_t">SSE (Streaming SIMD Extensions).</ResponseField>
<ResponseField name="sse2" type="uint8_t">SSE2.</ResponseField>
<ResponseField name="avx" type="uint8_t">AVX (256-bit SIMD).</ResponseField>
<ResponseField name="avx2" type="uint8_t">AVX2 integer 256-bit SIMD.</ResponseField>
<ResponseField name="avx512f" type="uint8_t">AVX-512 Foundation.</ResponseField>
<ResponseField name="xsave" type="uint8_t">XSAVE/XRSTOR extended state save.</ResponseField>
<ResponseField name="osxsave" type="uint8_t">OS has set CR4.OSXSAVE, enabling AVX state save.</ResponseField>
<ResponseField name="msr" type="uint8_t">Model-Specific Registers (RDMSR/WRMSR) available. Required before calling `cpu_rdmsr` or `cpu_wrmsr`.</ResponseField>
<ResponseField name="apic" type="uint8_t">Local APIC present and enabled.</ResponseField>
<ResponseField name="x2apic" type="uint8_t">x2APIC mode supported.</ResponseField>
<ResponseField name="tsc" type="uint8_t">Time Stamp Counter (RDTSC) available.</ResponseField>
<ResponseField name="invariant_tsc" type="uint8_t">Invariant TSC — TSC rate does not change with CPU frequency scaling.</ResponseField>
<ResponseField name="rdrand" type="uint8_t">RDRAND hardware RNG instruction available.</ResponseField>
<ResponseField name="rdseed" type="uint8_t">RDSEED hardware entropy instruction available.</ResponseField>
<ResponseField name="mtrr" type="uint8_t">Memory Type Range Registers.</ResponseField>
<ResponseField name="pat" type="uint8_t">Page Attribute Table.</ResponseField>
<ResponseField name="nx" type="uint8_t">No-Execute (NX/XD) bit in page tables.</ResponseField>
<ResponseField name="smep" type="uint8_t">Supervisor Mode Execution Prevention (SMEP).</ResponseField>
<ResponseField name="smap" type="uint8_t">Supervisor Mode Access Prevention (SMAP).</ResponseField>
<ResponseField name="umip" type="uint8_t">User Mode Instruction Prevention (UMIP).</ResponseField>

***

### `cpu_security_state_t`

Reports which security mitigations are currently **active** in hardware control registers. Filled by `cpu_get_security_state`.

```c theme={null}
typedef struct {
    uint8_t write_protect;
    uint8_t nx;
    uint8_t smep;
    uint8_t smap;
    uint8_t umip;
} cpu_security_state_t;
```

Each field is `1` if the mitigation is enabled in the relevant control register right now, `0` otherwise.

<ResponseField name="write_protect" type="uint8_t">
  CR0.WP is set — the kernel cannot write to read-only pages in supervisor mode.
</ResponseField>

<ResponseField name="nx" type="uint8_t">
  `EFER.NXE` is set — the NX/XD page table bit is active and enforced by hardware.
</ResponseField>

<ResponseField name="smep" type="uint8_t">
  CR4.SMEP is set — the CPU refuses to execute user-mode pages in supervisor mode.
</ResponseField>

<ResponseField name="smap" type="uint8_t">
  CR4.SMAP is set — the kernel cannot access user-mode pages without explicitly setting the AC flag.
</ResponseField>

<ResponseField name="umip" type="uint8_t">
  CR4.UMIP is set — privileged instructions such as SGDT and SIDT fault if executed in user mode.
</ResponseField>

***

## Functions

### `cpu_init`

Initialize the CPU driver: run CPUID detection, enable the FPU/SSE state, and activate available security features in the control registers.

```c theme={null}
void cpu_init(void);
```

Call this once during kernel initialization before using any other `cpu_*` function.

***

### `cpu_vendor`

Fill a caller-supplied buffer with the null-terminated CPU vendor identification string.

```c theme={null}
void cpu_vendor(char *vendor);
```

<ParamField path="vendor" type="char *" required>
  Buffer to receive the vendor string. Must be at least 13 bytes (12 characters plus a null terminator). Common values are `"GenuineIntel"` and `"AuthenticAMD"`.
</ParamField>

***

### `cpu_brand`

Fill a caller-supplied buffer with the null-terminated CPU brand string.

```c theme={null}
void cpu_brand(char *brand);
```

<ParamField path="brand" type="char *" required>
  Buffer to receive the brand string. Must be at least 49 bytes (48 characters plus a null terminator). Example: `"Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz"`.
</ParamField>

***

### `cpu_logical_count`

Return the number of logical CPU threads as reported by CPUID.

```c theme={null}
uint32_t cpu_logical_count(void);
```

<ResponseField name="return" type="uint32_t">
  Number of logical processors. On a single-core system without Hyper-Threading this is `1`.
</ResponseField>

***

### `cpu_feature_ecx`

Return the raw CPUID feature flags from leaf 1, register ECX.

```c theme={null}
uint32_t cpu_feature_ecx(void);
```

<ResponseField name="return" type="uint32_t">
  Raw ECX value from CPUID leaf `0x1`. Consult the Intel or AMD SDM for individual bit definitions. Prefer `cpu_get_capabilities` for portable feature testing.
</ResponseField>

***

### `cpu_feature_edx`

Return the raw CPUID feature flags from leaf 1, register EDX.

```c theme={null}
uint32_t cpu_feature_edx(void);
```

<ResponseField name="return" type="uint32_t">
  Raw EDX value from CPUID leaf `0x1`. Prefer `cpu_get_capabilities` for portable feature testing.
</ResponseField>

***

### `cpu_extended_feature_edx`

Return the raw extended CPUID feature flags from leaf `0x80000001`, register EDX.

```c theme={null}
uint32_t cpu_extended_feature_edx(void);
```

<ResponseField name="return" type="uint32_t">
  Raw EDX value from CPUID leaf `0x80000001`. Contains flags such as NX (bit 20) and Long Mode (bit 29). Prefer `cpu_get_capabilities` for portable feature testing.
</ResponseField>

***

### `cpu_get_info`

Fill a `cpu_info_t` struct with a complete snapshot of processor identity, topology, cache sizes, and thermal state.

```c theme={null}
void cpu_get_info(cpu_info_t *info);
```

<ParamField path="info" type="cpu_info_t *" required>
  Pointer to a caller-allocated `cpu_info_t` struct that receives all processor information. All fields are written on return.
</ParamField>

***

### `cpu_get_capabilities`

Fill a `cpu_capabilities_t` struct with boolean flags for every detectable processor feature.

```c theme={null}
void cpu_get_capabilities(cpu_capabilities_t *capabilities);
```

<ParamField path="capabilities" type="cpu_capabilities_t *" required>
  Pointer to a caller-allocated `cpu_capabilities_t` struct. All fields are written on return.
</ParamField>

***

### `cpu_get_security_state`

Fill a `cpu_security_state_t` struct describing which security mitigations are currently active in hardware control registers.

```c theme={null}
void cpu_get_security_state(cpu_security_state_t *state);
```

<ParamField path="state" type="cpu_security_state_t *" required>
  Pointer to a caller-allocated `cpu_security_state_t` struct. All fields are written on return.
</ParamField>

***

### `cpu_read_tsc`

Read the processor Time Stamp Counter (TSC) and return its 64-bit value.

```c theme={null}
uint64_t cpu_read_tsc(void);
```

<ResponseField name="return" type="uint64_t">
  Current TSC value. Monotonically increasing on processors with an invariant TSC (`cpu_capabilities_t.invariant_tsc == 1`). Use `cpu_info_t.tsc_hz` to convert ticks to wall time.
</ResponseField>

***

### `cpu_random64`

Generate a 64-bit hardware random number using the RDRAND instruction.

```c theme={null}
uint8_t cpu_random64(uint64_t *value);
```

<ParamField path="value" type="uint64_t *" required>
  Pointer to a `uint64_t` that receives the random value on success. Not modified if the function returns `0`.
</ParamField>

<ResponseField name="return" type="uint8_t">
  `1` on success. `0` if RDRAND is not available on this processor (`cpu_capabilities_t.rdrand == 0`) or if the hardware entropy pool is exhausted after the maximum retry count.
</ResponseField>

***

### `cpu_rdmsr`

Read a Model-Specific Register (MSR).

```c theme={null}
uint8_t cpu_rdmsr(uint32_t msr, uint64_t *value);
```

<ParamField path="msr" type="uint32_t" required>
  MSR address to read. Consult the Intel or AMD SDM for valid MSR addresses.
</ParamField>

<ParamField path="value" type="uint64_t *" required>
  Pointer to a `uint64_t` that receives the MSR value on success.
</ParamField>

<ResponseField name="return" type="uint8_t">
  `1` on success. `0` if MSR access is not available (`cpu_capabilities_t.msr == 0`).
</ResponseField>

***

### `cpu_wrmsr`

Write a value to a Model-Specific Register (MSR).

```c theme={null}
void cpu_wrmsr(uint32_t msr, uint64_t value);
```

<ParamField path="msr" type="uint32_t" required>
  MSR address to write.
</ParamField>

<ParamField path="value" type="uint64_t" required>
  64-bit value to write into the MSR.
</ParamField>

<Warning>
  Always check `cpu_capabilities_t.msr` before calling `cpu_rdmsr` or `cpu_wrmsr`. Executing RDMSR or WRMSR on a processor that does not support MSRs, or using an invalid MSR address, causes a General Protection Fault (#GP) and triggers a kernel panic via `exception_dispatch`. Writing an incorrect value to a sensitive MSR (such as `IA32_EFER` or `IA32_APIC_BASE`) can render the system unbootable.
</Warning>

***

## Example

```c theme={null}
#include "mvh/cpu.h"
#include <stdint.h>

void inspect_cpu(void) {
    /* Initialize CPU detection */
    cpu_init();

    /* Read identity and topology */
    cpu_info_t info;
    cpu_get_info(&info);

    /* info.family, info.model, info.stepping  */
    /* info.tsc_hz — TSC frequency in Hz        */
    /* info.l2_kib, info.l3_kib — cache sizes  */
    (void)info;

    /* Read capabilities */
    cpu_capabilities_t caps;
    cpu_get_capabilities(&caps);

    if (caps.avx2) {
        /* AVX2 is available — use 256-bit SIMD paths */
    }

    /* Check active security mitigations */
    cpu_security_state_t sec;
    cpu_get_security_state(&sec);

    /* sec.smep, sec.smap, sec.nx, sec.write_protect, sec.umip */
    (void)sec;

    /* Generate a hardware random number (requires RDRAND) */
    if (caps.rdrand) {
        uint64_t random_value = 0;
        if (cpu_random64(&random_value)) {
            /* random_value contains a fresh hardware-generated random number */
            (void)random_value;
        }
    }

    /* Read an MSR only when supported */
    if (caps.msr) {
        uint64_t efer = 0;
        cpu_rdmsr(0xC0000080, &efer); /* IA32_EFER */
        (void)efer;
    }
}
```
