1*7ae679ddSLoGin use core::{fmt::Debug, ptr::NonNull}; 2*7ae679ddSLoGin 3*7ae679ddSLoGin use acpi::AcpiHandler; 4*7ae679ddSLoGin 5*7ae679ddSLoGin use crate::{ 6*7ae679ddSLoGin kinfo, 7*7ae679ddSLoGin libs::{ 8*7ae679ddSLoGin align::{page_align_down, page_align_up}, 9*7ae679ddSLoGin once::Once, 10*7ae679ddSLoGin }, 11*7ae679ddSLoGin mm::{ 12*7ae679ddSLoGin mmio_buddy::{mmio_pool, MMIOSpaceGuard}, 13*7ae679ddSLoGin PhysAddr, VirtAddr, 14*7ae679ddSLoGin }, 15*7ae679ddSLoGin }; 16*7ae679ddSLoGin 17*7ae679ddSLoGin mod c_adapter; 18*7ae679ddSLoGin pub mod old; 19*7ae679ddSLoGin 20*7ae679ddSLoGin extern crate acpi; 21*7ae679ddSLoGin 22*7ae679ddSLoGin static mut __ACPI_TABLE: Option<acpi::AcpiTables<AcpiHandlerImpl>> = None; 23*7ae679ddSLoGin 24*7ae679ddSLoGin #[derive(Debug)] 25*7ae679ddSLoGin pub struct AcpiManager; 26*7ae679ddSLoGin 27*7ae679ddSLoGin impl AcpiManager { 28*7ae679ddSLoGin pub fn init(rsdp_paddr: PhysAddr) { 29*7ae679ddSLoGin static INIT: Once = Once::new(); 30*7ae679ddSLoGin INIT.call_once(|| { 31*7ae679ddSLoGin kinfo!("Initializing Acpi Manager..."); 32*7ae679ddSLoGin let acpi_table: acpi::AcpiTables<AcpiHandlerImpl> = 33*7ae679ddSLoGin unsafe { acpi::AcpiTables::from_rsdp(AcpiHandlerImpl, rsdp_paddr.data()) } 34*7ae679ddSLoGin .unwrap_or_else(|e| { 35*7ae679ddSLoGin panic!("acpi_init(): failed to parse acpi tables, error: {:?}", e) 36*7ae679ddSLoGin }); 37*7ae679ddSLoGin 38*7ae679ddSLoGin unsafe { 39*7ae679ddSLoGin __ACPI_TABLE = Some(acpi_table); 40*7ae679ddSLoGin } 41*7ae679ddSLoGin kinfo!("Acpi Manager initialized."); 42*7ae679ddSLoGin }); 43*7ae679ddSLoGin } 44*7ae679ddSLoGin 45*7ae679ddSLoGin #[allow(dead_code)] 46*7ae679ddSLoGin pub fn tables() -> Option<&'static acpi::AcpiTables<AcpiHandlerImpl>> { 47*7ae679ddSLoGin unsafe { __ACPI_TABLE.as_ref() } 48*7ae679ddSLoGin } 49*7ae679ddSLoGin } 50*7ae679ddSLoGin 51*7ae679ddSLoGin #[derive(Debug, Clone, Copy)] 52*7ae679ddSLoGin pub struct AcpiHandlerImpl; 53*7ae679ddSLoGin 54*7ae679ddSLoGin impl AcpiHandler for AcpiHandlerImpl { 55*7ae679ddSLoGin unsafe fn map_physical_region<T>( 56*7ae679ddSLoGin &self, 57*7ae679ddSLoGin physical_address: usize, 58*7ae679ddSLoGin size: usize, 59*7ae679ddSLoGin ) -> acpi::PhysicalMapping<Self, T> { 60*7ae679ddSLoGin let offset = physical_address - page_align_down(physical_address); 61*7ae679ddSLoGin let size_fix = page_align_up(size + offset); 62*7ae679ddSLoGin 63*7ae679ddSLoGin let mmio_guard = mmio_pool() 64*7ae679ddSLoGin .create_mmio(size_fix) 65*7ae679ddSLoGin .expect("AcpiHandlerImpl::map_physical_region(): failed to create mmio"); 66*7ae679ddSLoGin 67*7ae679ddSLoGin mmio_guard 68*7ae679ddSLoGin .map_phys(PhysAddr::new(page_align_down(physical_address)), size_fix) 69*7ae679ddSLoGin .expect("AcpiHandlerImpl::map_physical_region(): failed to map phys"); 70*7ae679ddSLoGin let virtual_start = mmio_guard.vaddr().data() + offset; 71*7ae679ddSLoGin 72*7ae679ddSLoGin let virtual_start = NonNull::new(virtual_start as *mut T).unwrap(); 73*7ae679ddSLoGin 74*7ae679ddSLoGin let result: acpi::PhysicalMapping<AcpiHandlerImpl, T> = acpi::PhysicalMapping::new( 75*7ae679ddSLoGin physical_address, 76*7ae679ddSLoGin virtual_start, 77*7ae679ddSLoGin size, 78*7ae679ddSLoGin mmio_guard.size(), 79*7ae679ddSLoGin AcpiHandlerImpl, 80*7ae679ddSLoGin ); 81*7ae679ddSLoGin 82*7ae679ddSLoGin MMIOSpaceGuard::leak(mmio_guard); 83*7ae679ddSLoGin 84*7ae679ddSLoGin return result; 85*7ae679ddSLoGin } 86*7ae679ddSLoGin 87*7ae679ddSLoGin fn unmap_physical_region<T>(region: &acpi::PhysicalMapping<Self, T>) { 88*7ae679ddSLoGin let mmio_guard = unsafe { 89*7ae679ddSLoGin MMIOSpaceGuard::from_raw( 90*7ae679ddSLoGin VirtAddr::new(page_align_down( 91*7ae679ddSLoGin region.virtual_start().as_ref() as *const T as usize 92*7ae679ddSLoGin )), 93*7ae679ddSLoGin region.mapped_length(), 94*7ae679ddSLoGin true, 95*7ae679ddSLoGin ) 96*7ae679ddSLoGin }; 97*7ae679ddSLoGin drop(mmio_guard); 98*7ae679ddSLoGin } 99*7ae679ddSLoGin } 100