Extract code that is common to both x86 and ARM to srat::init
This commit is contained in:
+27
-43
@@ -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
@@ -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
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user