⚠️ VeridianOS Kernel Documentation - This is low-level kernel code. All functions are unsafe unless explicitly marked otherwise. no_std

veridian_kernel/arch/x86_64/
msr.rs

1//! Model-Specific Register (MSR) read/write primitives.
2//!
3//! Extracted from `apic.rs` so that other modules (e.g. `pat.rs`) can
4//! access MSRs without duplicating inline assembly.
5
6/// Read a 64-bit Model-Specific Register.
7pub fn rdmsr(msr: u32) -> u64 {
8    let (low, high): (u32, u32);
9    // SAFETY: RDMSR reads the MSR specified by ECX. The caller passes a
10    // well-known MSR address. This is a privileged, read-only operation
11    // with no side effects beyond returning the MSR value.
12    unsafe {
13        core::arch::asm!(
14            "rdmsr",
15            in("ecx") msr,
16            out("eax") low,
17            out("edx") high,
18            options(nomem, nostack, preserves_flags),
19        );
20    }
21    (low as u64) | ((high as u64) << 32)
22}
23
24/// Write a 64-bit value to a Model-Specific Register.
25pub fn wrmsr(msr: u32, value: u64) {
26    let low = value as u32;
27    let high = (value >> 32) as u32;
28    // SAFETY: WRMSR writes to the MSR specified by ECX. The caller passes a
29    // well-known MSR address and a valid value. This is a privileged operation
30    // that modifies CPU configuration.
31    unsafe {
32        core::arch::asm!(
33            "wrmsr",
34            in("ecx") msr,
35            in("eax") low,
36            in("edx") high,
37            options(nomem, nostack, preserves_flags),
38        );
39    }
40}
41
42/// Translate a physical address to its virtual address using the
43/// bootloader's physical memory mapping.
44///
45/// The bootloader maps all physical memory at a dynamic offset in the
46/// higher-half virtual address space. MMIO regions like the Local APIC
47/// (0xFEE0_0000) and I/O APIC (0xFEC0_0000) are not identity-mapped,
48/// so we must add the physical memory offset to access them.
49///
50/// Returns `None` if boot info or the physical memory offset is unavailable.
51pub fn phys_to_virt(phys: usize) -> Option<usize> {
52    // SAFETY: BOOT_INFO is a static mut written once during early boot
53    // (before any concurrency) and read-only afterwards. We are in
54    // single-threaded kernel init context.
55    #[allow(static_mut_refs)]
56    let boot_info = unsafe { crate::arch::x86_64::boot::BOOT_INFO.as_ref()? };
57    let offset = boot_info.physical_memory_offset.into_option()?;
58    Some(offset as usize + phys)
59}