Extract code that is common to both x86 and ARM to srat::init

This commit is contained in:
R Aadarsh
2026-07-05 19:58:41 +05:30
parent 35340a80c4
commit 4d5d36d44e
3 changed files with 93 additions and 97 deletions
+27 -43
View File
@@ -9,50 +9,36 @@ use crate::{
numa::{self, assign_memory_id, assign_node_id, NumaMemory},
};
pub fn init_srat<A: Arch>(
allocator: &mut BumpAllocator<A>,
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::<u32>()) / 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::<u32>()),
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::<NumaMemory>(),
)
};
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<A: Arch>(
_ => continue,
}
}
(dom_node_map, cpus, mem)
}
+46 -7
View File
@@ -1,13 +1,16 @@
//! See <https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#system-resource-affinity-table-srat>
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<A: Arch>(
allocator: &mut BumpAllocator<A>,
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;
}
}
+20 -47
View File
@@ -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<A: Arch>(
allocator: &mut BumpAllocator<A>,
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::<u32>()) / 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<A: Arch>(
"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<A: Arch>(
_ => continue,
}
}
(dom_node_map, cpus, memories)
}