Skip to main content

strat9_kernel/acpi/
slit.rs

1//! Support for the SLIT ACPI table (System Locality Information Table).
2//! Provides information about NUMA node distances.
3//!
4//! Reference: ACPI spec 2.0+
5
6use super::sdt::Sdt;
7use zerocopy::FromBytes;
8
9pub const SLIT_SIGNATURE: &[u8; 4] = b"SLIT";
10
11/// SLIT ACPI table structure
12#[derive(Clone, Copy, Debug, FromBytes)]
13#[repr(C, packed)]
14pub struct Slit {
15    pub header: Sdt,
16    pub locality_count: u64,
17    // Followed by locality_count * locality_count bytes of distance data
18}
19
20impl Slit {
21    /// Finds the SLIT and returns a reference to it.
22    pub fn get() -> Option<&'static Slit> {
23        unsafe { super::find_table(SLIT_SIGNATURE).map(|ptr| &*(ptr as *const Slit)) }
24    }
25
26    /// Get number of system localities (NUMA nodes)
27    pub fn num_localities(&self) -> u64 {
28        self.locality_count
29    }
30
31    /// Get distance between two localities
32    /// Returns 255 if indices are out of bounds
33    pub fn distance(&self, from: u64, to: u64) -> u8 {
34        if from >= self.locality_count || to >= self.locality_count {
35            return 255;
36        }
37
38        let offset = core::mem::size_of::<Slit>();
39        let index = (from * self.locality_count + to) as usize;
40        let ptr = unsafe { (self as *const Slit as *const u8).add(offset + index) };
41
42        unsafe { core::ptr::read_volatile(ptr) }
43    }
44
45    /// Get all distances for a locality
46    pub fn locality_distances(&self, from: u64) -> Option<&[u8]> {
47        if from >= self.locality_count {
48            return None;
49        }
50
51        let offset = core::mem::size_of::<Slit>();
52        let start = offset + (from * self.locality_count) as usize;
53        let len = self.locality_count as usize;
54
55        let ptr = unsafe { (self as *const Slit as *const u8).add(start) };
56
57        Some(unsafe { core::slice::from_raw_parts(ptr, len) })
58    }
59}
60
61/// Default distance value (same locality)
62pub const DISTANCE_LOCAL: u8 = 10;
63
64/// Default distance value (different locality)
65pub const DISTANCE_REMOTE: u8 = 20;