From 4d5d36d44eca33d9a56dfeb11c7cab2ff646dcd7 Mon Sep 17 00:00:00 2001 From: R Aadarsh Date: Sun, 5 Jul 2026 19:58:41 +0530 Subject: [PATCH] Extract code that is common to both x86 and ARM to `srat::init` --- src/acpi/srat/aarch64.rs | 70 ++++++++++++++++------------------------ src/acpi/srat/mod.rs | 53 ++++++++++++++++++++++++++---- src/acpi/srat/x86.rs | 67 ++++++++++++-------------------------- 3 files changed, 93 insertions(+), 97 deletions(-) diff --git a/src/acpi/srat/aarch64.rs b/src/acpi/srat/aarch64.rs index 4cd126ccb3..fd37e13a71 100644 --- a/src/acpi/srat/aarch64.rs +++ b/src/acpi/srat/aarch64.rs @@ -9,50 +9,36 @@ use crate::{ numa::{self, assign_memory_id, assign_node_id, NumaMemory}, }; -pub fn init_srat( - allocator: &mut BumpAllocator, - srat: &Srat, -) -> (&'static [u32], &'static [u32], &'static [NumaMemory]) { - let dom_node_map_ptr = allocator - .allocate(FrameCount::new( - round_up_pages(numa::MAX_DOMAINS * size_of::()) / PAGE_SIZE, - )) - .expect("Failed to allocate pages for domain-node-map") - .data(); +pub fn init_srat(dom_node_map: &mut [u32], cpus: &mut [u32], mem: &mut [NumaMemory], srat: &Srat) { + let mut cpu_count = 0; + let mut memory_count = 0; - let va = crate::memory::RmmA::phys_to_virt(PhysicalAddress::new(dom_node_map_ptr)).data(); - let dom_node_map_ptr = va.data() as *mut u32; - - // occupies 521 bytes - let dom_node_map = unsafe { slice::from_raw_parts_mut(dom_node_map_ptr, numa::MAX_DOMAINS) }; - - // occupies 512 bytes - let cpus = unsafe { - slice::from_raw_parts_mut( - dom_node_map_ptr.add(numa::MAX_DOMAINS as usize * size_of::()), - MAX_CPU_COUNT as usize, - ) - }; - - // remaining 3072 bytes: can accomodate 128 Mem entries - let mem = unsafe { - slice::from_raw_parts_mut( - dom_node_map_ptr - .add(numa::MAX_DOMAINS) - .add(MAX_CPU_COUNT as usize) as *mut NumaMemory, - numa::MAX_DOMAINS * size_of::(), - ) - }; - - cpus.fill(u32::MAX); - dom_node_map.fill(u32::MAX); - mem.fill(NumaMemory { - start: 0, - length: 0, - node_id: 0, - _pad: [0; 4], + srat.into_iter().for_each(|e| match e { + SratEntry::GiccAffinity(gicc_affinity) => { + if gicc_affinity.flags & 1 != 0 { + cpu_count += 1 + } + } + SratEntry::MemoryAffinity(memory_affinity) => { + if memory_affinity.flags & 1 != 0 && memory_affinity.flags & (1 << 1) == 0 { + memory_count += 1 + } + } + _ => (), }); + assert!( + memory_count <= numa::MAX_DOMAINS, + "Found {} memory blocks while only a maximum of {} are supported", + memory_count, + numa::MAX_DOMAINS + ); + + assert!( + cpu_count <= cpu_set::MAX_CPU_COUNT, + "Found more number of CPUs than supported" + ); + for affinity in srat { match affinity { SratEntry::MemoryAffinity(memory_affinity) => { @@ -100,6 +86,4 @@ pub fn init_srat( _ => continue, } } - - (dom_node_map, cpus, mem) } diff --git a/src/acpi/srat/mod.rs b/src/acpi/srat/mod.rs index d613f2c1aa..0768a78e9e 100644 --- a/src/acpi/srat/mod.rs +++ b/src/acpi/srat/mod.rs @@ -1,13 +1,16 @@ //! See +use core::slice; + use hashbrown::HashMap; -use rmm::{Arch, BumpAllocator}; +use rmm::{Arch, BumpAllocator, FrameAllocator}; use spin::once::Once; use crate::{ acpi::{find_sdt, get_sdt_signature, rxsdt::Rxsdt, sdt::Sdt, srat, RXSDT_ENUM}, + cpu_set::MAX_CPU_COUNT, find_one_sdt, memory, - numa::NumaMemory, + numa::{self, NumaMemory}, }; #[cfg(target_arch = "aarch64")] @@ -27,17 +30,53 @@ pub struct Srat { pub fn init( allocator: &mut BumpAllocator, map: &Once<&'static [u32]>, - cpus: &Once<&'static [u32]>, + once_cpus: &Once<&'static [u32]>, mem: &Once<&'static [NumaMemory]>, ) { + let dom_node_map = allocator + .allocate(rmm::FrameCount::new(1)) + .expect("Failed to allocate memory for storing NUMA info"); + + let dom_node_map_ptr = + unsafe { crate::memory::RmmA::phys_to_virt(dom_node_map).data() as *mut u32 }; + + // Occupies 512 bytes (1/8th of a page) + let dom_node_map: &'static mut [u32] = + unsafe { slice::from_raw_parts_mut(dom_node_map_ptr, numa::MAX_DOMAINS) }; + + // occupies 512 bytes (1/8th of a page) + let cpus: &'static mut [u32] = unsafe { + slice::from_raw_parts_mut( + dom_node_map_ptr.add(numa::MAX_DOMAINS) as *mut u32, + MAX_CPU_COUNT as usize, + ) + }; + + // total occupied till now: 1024 bytes, remaining 3072 bytes, can accomodate 128 memory entries + let memories: &'static mut [NumaMemory] = unsafe { + slice::from_raw_parts_mut( + cpus.as_ptr().add(numa::MAX_DOMAINS) as *mut NumaMemory, + numa::MAX_DOMAINS, + ) + }; + + dom_node_map.fill(u32::MAX); + cpus.fill(u32::MAX); + memories.fill(NumaMemory { + start: 0, + length: 0, + node_id: 0, + _pad: [0; 4], + }); + if let Some(rxsdt) = RXSDT_ENUM.get() { for sdt_addr in rxsdt.iter() { let sdt = unsafe { &*(memory::RmmA::phys_to_virt(sdt_addr).data() as *const Sdt) }; if &sdt.signature == b"SRAT" { - let (a, b, c) = arch::init_srat(allocator, &Srat::new(sdt)); - map.call_once(|| a); - cpus.call_once(|| b); - mem.call_once(|| c); + arch::init_srat(dom_node_map, cpus, memories, &Srat::new(sdt)); + map.call_once(|| dom_node_map); + once_cpus.call_once(|| cpus); + mem.call_once(|| memories); return; } } diff --git a/src/acpi/srat/x86.rs b/src/acpi/srat/x86.rs index 78bb835ec9..f67407db25 100644 --- a/src/acpi/srat/x86.rs +++ b/src/acpi/srat/x86.rs @@ -18,30 +18,31 @@ fn to_single_int(high: &[u8; 3], low: u8) -> u32 { u32::from_le_bytes(high_and_low) } -pub fn init_srat( - allocator: &mut BumpAllocator, +pub fn init_srat( + dom_node_map: &mut [u32], + cpus: &mut [u32], + memories: &mut [NumaMemory], srat: &Srat, -) -> (&'static [u32], &'static [u32], &'static [NumaMemory]) { - let dom_node_map = allocator - .allocate(rmm::FrameCount::new( - memory::round_up_pages(numa::MAX_DOMAINS * size_of::()) / PAGE_SIZE, - )) - .expect("Failed to allocate memory for storing NUMA info"); - - let dom_node_map_ptr = - unsafe { crate::memory::RmmA::phys_to_virt(dom_node_map).data() as *mut u32 }; - // Occupies 512 bytes (1/8th of a page) - let dom_node_map: &'static mut [u32] = - unsafe { slice::from_raw_parts_mut(dom_node_map_ptr, numa::MAX_DOMAINS) }; - dom_node_map.fill(u32::MAX); - +) { let mut cpu_count = 0; let mut memory_count = 0; srat.into_iter().for_each(|e| match e { - SratEntry::LegacyProcessorLocalAffinity(legacy_processor_local_affinity) => cpu_count += 1, - SratEntry::MemoryAffinity(memory_affinity) => memory_count += 1, - SratEntry::ProcessorLocalAffinity(processor_local_affinity) => todo!(), + SratEntry::LegacyProcessorLocalAffinity(legacy_processor_local_affinity) => { + if legacy_processor_local_affinity.flags & 1 != 0 { + cpu_count += 1 + } + } + SratEntry::MemoryAffinity(memory_affinity) => { + if memory_affinity.flags & 1 != 0 && memory_affinity.flags & (1 << 1) == 0 { + memory_count += 1 + } + } + SratEntry::ProcessorLocalAffinity(processor_local_affinity) => { + if processor_local_affinity.flags & 1 != 0 { + cpu_count += 1 + } + } _ => (), }); @@ -57,32 +58,6 @@ pub fn init_srat( "Found more number of CPUs than supported" ); - // occupies 512 bytes (1/8th of a page) - let cpus: &'static mut [u32] = unsafe { - slice::from_raw_parts_mut( - dom_node_map_ptr.add(numa::MAX_DOMAINS) as *mut u32, - numa::MAX_DOMAINS, - ) - }; - - cpus.fill(u32::MAX); - - // total occupied till now: 1024 bytes, remaining 3072 bytes, can accomodate 128 memory entries - - let memories: &'static mut [NumaMemory] = unsafe { - slice::from_raw_parts_mut( - cpus.as_ptr().add(numa::MAX_DOMAINS) as *mut NumaMemory, - numa::MAX_DOMAINS, - ) - }; - - memories.fill(NumaMemory { - start: 0, - length: 0, - node_id: 0, - _pad: [0; 4], - }); - for affinity in srat { match affinity { SratEntry::LegacyProcessorLocalAffinity(legacy_processor_local_affinity) => { @@ -145,6 +120,4 @@ pub fn init_srat( _ => continue, } } - - (dom_node_map, cpus, memories) }