From 63d1171ffbfb9027f5a38f3c827fb352d72f7c9d Mon Sep 17 00:00:00 2001 From: R Aadarsh Date: Thu, 11 Jun 2026 21:11:38 +0530 Subject: [PATCH] Initial commit --- src/acpi/mod.rs | 1 + src/acpi/srat/aarch64.rs | 0 src/acpi/srat/mod.rs | 130 +++++++++++++++++++++++++++++++++++++++ src/acpi/srat/x86.rs | 3 + src/main.rs | 3 + src/numa.rs | 14 +++++ src/percpu.rs | 5 ++ 7 files changed, 156 insertions(+) create mode 100644 src/acpi/srat/aarch64.rs create mode 100644 src/acpi/srat/mod.rs create mode 100644 src/acpi/srat/x86.rs create mode 100644 src/numa.rs diff --git a/src/acpi/mod.rs b/src/acpi/mod.rs index 786621b48c..2f8d0549cb 100644 --- a/src/acpi/mod.rs +++ b/src/acpi/mod.rs @@ -22,6 +22,7 @@ mod rxsdt; pub mod sdt; #[cfg(target_arch = "aarch64")] mod spcr; +mod srat; mod xsdt; unsafe fn map_linearly(addr: PhysicalAddress, len: usize, mapper: &mut crate::memory::PageMapper) { diff --git a/src/acpi/srat/aarch64.rs b/src/acpi/srat/aarch64.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/acpi/srat/mod.rs b/src/acpi/srat/mod.rs new file mode 100644 index 0000000000..10355907ce --- /dev/null +++ b/src/acpi/srat/mod.rs @@ -0,0 +1,130 @@ +//! See + +use crate::{ + acpi::{find_sdt, sdt::Sdt, srat}, + find_one_sdt, +}; + +#[cfg(target_arch = "aarch64")] +#[path = "aarch64.rs"] +mod arch; + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +#[path = "x86.rs"] +mod arch; + +#[repr(C, packed)] +pub struct Srat { + sdt: &'static Sdt, + entries: usize, +} + +impl Srat { + pub fn init() { + let srat = Self::new(find_one_sdt!("SRAT")); + arch::init_srat(&srat); + } + + pub fn new(sdt: &'static Sdt) -> Self { + Self { + sdt, + entries: sdt.data_address() + 16, + } + } +} + +struct SratIter<'a> { + i: u32, + srat: &'a Srat, +} + +impl<'a> Iterator for SratIter<'a> { + type Item = SratEntry; + + fn next(&mut self) -> Option { + while self.i < self.srat.sdt.length { + let entry = (self.srat.entries + self.i as usize) as *const u8; + + return Some(match unsafe { *entry } { + 0 => SratEntry::LegacyProcessorLocalAffinity(unsafe { + *(entry.add(2) as *const LegacyProcessorLocalAffinity) + }), + + 1 => SratEntry::MemoryAffinity(unsafe { *(entry.add(2) as *const MemoryAffinity) }), + 2 => SratEntry::ProcessorLocalAffinity(unsafe { + *(entry.add(4) as *const ProcessorLocalAffinity) + }), + 3 => SratEntry::GiccAffinity(unsafe { *(entry.add(2) as *const GiccAffinity) }), + 4 => SratEntry::GicItsAffinity(unsafe { *(entry.add(2) as *const GicItsAffinity) }), + // ignore Generic Initiator Affinity + 5 => { + self.i += 1; + continue; + } + _ => panic!("Unknown value in Srat"), + }); + } + None + } +} + +enum SratEntry { + LegacyProcessorLocalAffinity(LegacyProcessorLocalAffinity), + MemoryAffinity(MemoryAffinity), + ProcessorLocalAffinity(ProcessorLocalAffinity), + GiccAffinity(GiccAffinity), + GicItsAffinity(GicItsAffinity), + // unimplemented: Generic Initiator Affinity; our current focus is only on memory and cpus +} + +#[repr(C, packed)] +#[derive(Clone, Copy)] +/// For legacy xAPIC systems +struct LegacyProcessorLocalAffinity { + proximity_domain_low: u8, + apic_id: u8, + flags: u32, + sapic_id: u8, + proximity_domain_high: [u8; 3], + clock_domain: u32, +} + +#[repr(C, packed)] +#[derive(Clone, Copy)] +struct MemoryAffinity { + proximity_domain: u32, + _reserved0: u16, + base_address_low: u32, + base_address_high: u32, + length_low: u32, + length_high: u32, + _reserved1: u32, + flags: u32, +} + +#[repr(C, packed)] +#[derive(Clone, Copy)] +/// For x2APIC systems +struct ProcessorLocalAffinity { + proximity_domain: u32, + x2apic_id: u32, + flags: u32, + clock_domain: u32, +} + +#[repr(C, packed)] +#[derive(Clone, Copy)] +struct GiccAffinity { + proximity_domain: u32, + processor_uid: u32, + flags: u32, + clock_domain: u32, +} + +#[repr(C, packed)] +#[derive(Clone, Copy)] +struct GicItsAffinity { + proximity_domain: u32, + _reserved: u16, + its_domain: u32, +} diff --git a/src/acpi/srat/x86.rs b/src/acpi/srat/x86.rs new file mode 100644 index 0000000000..7c14abe07b --- /dev/null +++ b/src/acpi/srat/x86.rs @@ -0,0 +1,3 @@ +use crate::acpi::srat::Srat; + +pub fn init_srat(srat: &Srat) {} diff --git a/src/main.rs b/src/main.rs index 41577273ac..8380e02f94 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,6 +68,9 @@ mod log; /// Memory management mod memory; +/// NUMA support +mod numa; + /// Panic mod panic; diff --git a/src/numa.rs b/src/numa.rs new file mode 100644 index 0000000000..d3978aa152 --- /dev/null +++ b/src/numa.rs @@ -0,0 +1,14 @@ +use crate::{ + cpu_set::LogicalCpuId, + sync::{Mutex, L0}, +}; +use alloc::{sync::Arc, vec::Vec}; + +pub static NUMA_NODES: Mutex>> = Mutex::new(Vec::new()); + +pub struct NumaMemory; + +pub struct NumaNode { + cpus: Vec, + memory: Vec, +} diff --git a/src/percpu.rs b/src/percpu.rs index f93fa40f3e..c388b90d5f 100644 --- a/src/percpu.rs +++ b/src/percpu.rs @@ -19,6 +19,7 @@ use crate::{ }, cpu_set::{LogicalCpuId, MAX_CPU_COUNT}, cpu_stats::{CpuStats, CpuStatsData}, + numa::NumaNode, ptrace::Session, syscall::debug::SyscallDebugInfo, }; @@ -49,6 +50,8 @@ pub struct PercpuBlock { pub misc_arch_info: crate::arch::device::ArchPercpuMisc, pub stats: CpuStats, + + pub numa_node: Option>, } static ALL_PERCPU_BLOCKS: [AtomicPtr; MAX_CPU_COUNT as usize] = @@ -201,6 +204,8 @@ impl PercpuBlock { misc_arch_info: ArchPercpuMisc::default(), stats: CpuStats::default(), + + numa_node: None, } } }