Split acpi::init to perform two stage initialisation

This commit is contained in:
R Aadarsh
2026-06-27 17:47:40 +05:30
committed by Jeremy Soller
parent 6c3d5d28c6
commit a2a3df33c6
6 changed files with 73 additions and 66 deletions
+26 -13
View File
@@ -8,7 +8,10 @@ use alloc::{boxed::Box, string::String, vec::Vec};
use hashbrown::HashMap;
use spin::{Once, RwLock};
use crate::memory::{KernelMapper, PageFlags, PhysicalAddress, RmmA, RmmArch};
use crate::{
acpi::rxsdt::RxsdtIter,
memory::{KernelMapper, PageFlags, PhysicalAddress, RmmA, RmmArch},
};
use self::{hpet::Hpet, madt::Madt, rsdp::Rsdp, rsdt::Rsdt, rxsdt::Rxsdt, sdt::Sdt, xsdt::Xsdt};
@@ -78,24 +81,20 @@ pub enum RxsdtEnum {
Xsdt(Xsdt),
}
impl Rxsdt for RxsdtEnum {
fn iter(&self) -> Box<dyn Iterator<Item = PhysicalAddress>> {
fn iter(&self) -> RxsdtIter {
match self {
Self::Rsdt(rsdt) => <Rsdt as Rxsdt>::iter(rsdt),
Self::Xsdt(xsdt) => <Xsdt as Rxsdt>::iter(xsdt),
Self::Rsdt(rsdt) => rsdt.iter(),
Self::Xsdt(xsdt) => xsdt.iter(),
}
}
}
pub static RXSDT_ENUM: Once<RxsdtEnum> = Once::new();
/// Parse the ACPI tables to gather CPU, interrupt, and timer information
pub unsafe fn init(already_supplied_rsdp: Option<NonNull<u8>>) {
/// Initialses the global `RXSDT_ENUM` if RSDT or XSDT was found and maps the SDT pages.
/// It does not perform any allocations
pub unsafe fn init_before_mem(already_supplied_rsdp: Option<NonNull<u8>>) {
unsafe {
{
let mut sdt_ptrs = SDT_POINTERS.write();
*sdt_ptrs = Some(HashMap::new());
}
// Search for RSDP
let rsdp_opt = Rsdp::get_rsdp(already_supplied_rsdp);
@@ -140,6 +139,22 @@ pub unsafe fn init(already_supplied_rsdp: Option<NonNull<u8>>) {
for sdt in rxsdt.iter() {
get_sdt(sdt, &mut KernelMapper::lock_rw());
}
} else {
error!("NO RSDP FOUND");
return;
}
}
}
/// Parse the ACPI tables to gather CPU, interrupt, and timer information. The code performs allocations, so
/// it must be called only after the allocator is set up.
pub unsafe fn init_after_mem(already_supplied_rsdp: Option<NonNull<u8>>) {
if let Some(rxsdt) = RXSDT_ENUM.get() {
unsafe {
{
let mut sdt_ptrs = SDT_POINTERS.write();
*sdt_ptrs = Some(HashMap::new());
}
for sdt_address in rxsdt.iter() {
let sdt = &*(RmmA::phys_to_virt(sdt_address).data() as *const Sdt);
@@ -162,8 +177,6 @@ pub unsafe fn init(already_supplied_rsdp: Option<NonNull<u8>>) {
Hpet::init();
#[cfg(target_arch = "aarch64")]
gtdt::Gtdt::init();
} else {
error!("NO RSDP FOUND");
}
}
}
+4 -24
View File
@@ -2,6 +2,8 @@ use alloc::boxed::Box;
use core::convert::TryFrom;
use rmm::PhysicalAddress;
use crate::acpi::rxsdt::RxsdtIter;
use super::{rxsdt::Rxsdt, sdt::Sdt};
#[derive(Debug)]
@@ -24,29 +26,7 @@ impl Rsdt {
}
impl Rxsdt for Rsdt {
fn iter(&self) -> Box<dyn Iterator<Item = PhysicalAddress>> {
Box::new(RsdtIter { sdt: self.0, i: 0 })
}
}
pub struct RsdtIter {
sdt: &'static Sdt,
i: usize,
}
impl Iterator for RsdtIter {
type Item = PhysicalAddress;
fn next(&mut self) -> Option<Self::Item> {
if self.i < self.sdt.data_len() / size_of::<u32>() {
let item = unsafe {
(self.sdt.data_address() as *const u32)
.add(self.i)
.read_unaligned()
};
self.i += 1;
Some(PhysicalAddress::new(item as usize))
} else {
None
}
fn iter(&self) -> RxsdtIter {
RxsdtIter { sdt: self.0, i: 0 }
}
}
+23 -1
View File
@@ -1,6 +1,28 @@
use alloc::boxed::Box;
use rmm::PhysicalAddress;
use crate::acpi::sdt::Sdt;
pub trait Rxsdt {
fn iter(&self) -> Box<dyn Iterator<Item = PhysicalAddress>>;
fn iter(&self) -> RxsdtIter;
}
pub struct RxsdtIter {
pub sdt: &'static Sdt,
pub i: usize,
}
impl Iterator for RxsdtIter {
type Item = PhysicalAddress;
fn next(&mut self) -> Option<Self::Item> {
if self.i < self.sdt.data_len() / size_of::<u64>() {
let item = unsafe {
core::ptr::read_unaligned((self.sdt.data_address() as *const u64).add(self.i))
};
self.i += 1;
Some(PhysicalAddress::new(item as usize))
} else {
None
}
}
}
+4 -22
View File
@@ -2,6 +2,8 @@ use alloc::boxed::Box;
use core::convert::TryFrom;
use rmm::PhysicalAddress;
use crate::acpi::rxsdt::RxsdtIter;
use super::{rxsdt::Rxsdt, sdt::Sdt};
#[derive(Debug)]
@@ -24,27 +26,7 @@ impl Xsdt {
}
impl Rxsdt for Xsdt {
fn iter(&self) -> Box<dyn Iterator<Item = PhysicalAddress>> {
Box::new(XsdtIter { sdt: self.0, i: 0 })
}
}
pub struct XsdtIter {
sdt: &'static Sdt,
i: usize,
}
impl Iterator for XsdtIter {
type Item = PhysicalAddress;
fn next(&mut self) -> Option<Self::Item> {
if self.i < self.sdt.data_len() / size_of::<u64>() {
let item = unsafe {
core::ptr::read_unaligned((self.sdt.data_address() as *const u64).add(self.i))
};
self.i += 1;
Some(PhysicalAddress::new(item as usize))
} else {
None
}
fn iter(&self) -> RxsdtIter {
RxsdtIter { sdt: self.0, i: 0 }
}
}
+10 -3
View File
@@ -102,13 +102,20 @@ unsafe extern "C" fn start(args_ptr: *const KernelArgs, stack_end: usize) -> ! {
// Initialize RMM
#[cfg(target_arch = "x86")]
crate::startup::memory::init(&args, Some(0x100000), Some(0x40000000));
let bump_allocator =
crate::startup::memory::init(&args, Some(0x100000), Some(0x40000000));
#[cfg(target_arch = "x86_64")]
crate::startup::memory::init(&args, Some(0x100000), None);
let bump_allocator = crate::startup::memory::init(&args, Some(0x100000), None);
// Initialize paging
paging::init();
if cfg!(feature = "acpi") {
crate::acpi::init_before_mem(args.acpi_rsdp());
}
crate::memory::init_mm(bump_allocator);
#[cfg(target_arch = "x86_64")]
crate::arch::alternative::early_init(true);
@@ -130,7 +137,7 @@ unsafe extern "C" fn start(args_ptr: *const KernelArgs, stack_end: usize) -> ! {
// Read ACPI tables, starts APs
if cfg!(feature = "acpi") {
crate::acpi::init(args.acpi_rsdp());
crate::acpi::init_after_mem(args.acpi_rsdp());
device::init_after_acpi();
}
crate::profiling::init();
+6 -3
View File
@@ -394,7 +394,11 @@ unsafe fn map_memory<A: Arch>(areas: &[MemoryArea], mut bump_allocator: &mut Bum
}
}
pub unsafe fn init(args: &KernelArgs, low_limit: Option<usize>, high_limit: Option<usize>) {
pub unsafe fn init(
args: &KernelArgs,
low_limit: Option<usize>,
high_limit: Option<usize>,
) -> BumpAllocator<CurrentRmmArch> {
register_memory_from_kernel_args(args);
unsafe {
@@ -441,7 +445,6 @@ pub unsafe fn init(args: &KernelArgs, low_limit: Option<usize>, high_limit: Opti
// Create the physical memory map
let offset = bump_allocator.offset();
info!("Permanently used: {} KB", offset.div_ceil(KILOBYTE));
crate::memory::init_mm(bump_allocator);
bump_allocator
}
}