#![no_std]
#![feature(allocator_api)]
#![forbid(stable_features, unsafe_op_in_unsafe_fn)]
#![deny(
clippy::debug_assert_with_mut_call,
clippy::float_arithmetic,
clippy::as_conversions
)]
#![warn(
clippy::cargo,
clippy::pedantic,
clippy::undocumented_unsafe_blocks,
clippy::semicolon_inside_block,
clippy::semicolon_if_nothing_returned
)]
#![allow(
dead_code,
clippy::missing_const_for_fn,
clippy::needless_for_each,
clippy::if_not_else
)]
mod sys;
use core::ptr::NonNull;
pub type PhysicalAddress = u64;
pub type LogicalAddress = NonNull<u8>;
pub trait AcpiHandler: Send + Sync {
fn initialize(&self);
fn terminate(&self);
fn get_root_address(&self) -> PhysicalAddress;
fn map_memory(&self, physical_address: PhysicalAddress, size: usize) -> Option<LogicalAddress>;
fn unmap_memory(&self, logical_address: LogicalAddress, size: usize);
fn get_physical_address(&self, logical_address: LogicalAddress) -> PhysicalAddress;
fn allocate(&self, size: usize) -> Option<LogicalAddress>;
fn deallocate(&self, logical_address: LogicalAddress);
fn is_memory_readable(&self, logical_address: LogicalAddress, length: usize) -> bool;
fn is_memory_writable(&self, logical_address: LogicalAddress, length: usize) -> bool;
}
pub static OS_LAYER: spin::Once<&'static dyn AcpiHandler> = spin::Once::new();
pub fn install(handler: &'static impl AcpiHandler) {
debug_assert!(
!OS_LAYER.is_completed(),
"`acpica_sys::install` has been called more than once; this is likely an error"
);
OS_LAYER.call_once(|| handler);
}
fn get_os_layer() -> &'static dyn AcpiHandler {
*OS_LAYER
.get()
.expect("ACPICA OS layer has not been installed")
}
#[cfg(target_arch = "x86")]
pub fn find_root_pointer() -> PhysicalAddress {
let mut address: usize;
let exception_code = unsafe { sys::AcpiFindRootPointer(&mut address) };
match exception_code {
sys::ExceptionCode::OK => address,
sys::ExceptionCode::NO_MEMORY => panic!("insufficient dynamic memory"),
sys::ExceptionCode::NOT_FOUND => panic!("valid RSDP could not be located"),
}
}