17ae679ddSLoGin use core::{fmt::Debug, ptr::NonNull}; 27ae679ddSLoGin 37ae679ddSLoGin use acpi::AcpiHandler; 47ae679ddSLoGin 57ae679ddSLoGin use crate::{ 67ae679ddSLoGin kinfo, 77ae679ddSLoGin libs::{ 87ae679ddSLoGin align::{page_align_down, page_align_up}, 97ae679ddSLoGin once::Once, 107ae679ddSLoGin }, 117ae679ddSLoGin mm::{ 127ae679ddSLoGin mmio_buddy::{mmio_pool, MMIOSpaceGuard}, 137ae679ddSLoGin PhysAddr, VirtAddr, 147ae679ddSLoGin }, 157ae679ddSLoGin }; 167ae679ddSLoGin 17*a03c4f9dSLoGin pub mod bus; 187ae679ddSLoGin mod c_adapter; 1906d5e247SLoGin pub mod glue; 207ae679ddSLoGin pub mod old; 217ae679ddSLoGin 227ae679ddSLoGin extern crate acpi; 237ae679ddSLoGin 247ae679ddSLoGin static mut __ACPI_TABLE: Option<acpi::AcpiTables<AcpiHandlerImpl>> = None; 257ae679ddSLoGin 26*a03c4f9dSLoGin #[inline(always)] 27*a03c4f9dSLoGin pub fn acpi_manager() -> &'static AcpiManager { 28*a03c4f9dSLoGin &AcpiManager 29*a03c4f9dSLoGin } 30*a03c4f9dSLoGin 317ae679ddSLoGin #[derive(Debug)] 327ae679ddSLoGin pub struct AcpiManager; 337ae679ddSLoGin 347ae679ddSLoGin impl AcpiManager { 357ae679ddSLoGin pub fn init(rsdp_paddr: PhysAddr) { 367ae679ddSLoGin static INIT: Once = Once::new(); 377ae679ddSLoGin INIT.call_once(|| { 387ae679ddSLoGin kinfo!("Initializing Acpi Manager..."); 397ae679ddSLoGin let acpi_table: acpi::AcpiTables<AcpiHandlerImpl> = 407ae679ddSLoGin unsafe { acpi::AcpiTables::from_rsdp(AcpiHandlerImpl, rsdp_paddr.data()) } 417ae679ddSLoGin .unwrap_or_else(|e| { 427ae679ddSLoGin panic!("acpi_init(): failed to parse acpi tables, error: {:?}", e) 437ae679ddSLoGin }); 447ae679ddSLoGin 457ae679ddSLoGin unsafe { 467ae679ddSLoGin __ACPI_TABLE = Some(acpi_table); 477ae679ddSLoGin } 487ae679ddSLoGin kinfo!("Acpi Manager initialized."); 497ae679ddSLoGin }); 507ae679ddSLoGin } 517ae679ddSLoGin 527ae679ddSLoGin #[allow(dead_code)] 537ae679ddSLoGin pub fn tables() -> Option<&'static acpi::AcpiTables<AcpiHandlerImpl>> { 547ae679ddSLoGin unsafe { __ACPI_TABLE.as_ref() } 557ae679ddSLoGin } 567ae679ddSLoGin } 577ae679ddSLoGin 587ae679ddSLoGin #[derive(Debug, Clone, Copy)] 597ae679ddSLoGin pub struct AcpiHandlerImpl; 607ae679ddSLoGin 617ae679ddSLoGin impl AcpiHandler for AcpiHandlerImpl { 627ae679ddSLoGin unsafe fn map_physical_region<T>( 637ae679ddSLoGin &self, 647ae679ddSLoGin physical_address: usize, 657ae679ddSLoGin size: usize, 667ae679ddSLoGin ) -> acpi::PhysicalMapping<Self, T> { 677ae679ddSLoGin let offset = physical_address - page_align_down(physical_address); 687ae679ddSLoGin let size_fix = page_align_up(size + offset); 697ae679ddSLoGin 707ae679ddSLoGin let mmio_guard = mmio_pool() 717ae679ddSLoGin .create_mmio(size_fix) 727ae679ddSLoGin .expect("AcpiHandlerImpl::map_physical_region(): failed to create mmio"); 737ae679ddSLoGin 747ae679ddSLoGin mmio_guard 757ae679ddSLoGin .map_phys(PhysAddr::new(page_align_down(physical_address)), size_fix) 767ae679ddSLoGin .expect("AcpiHandlerImpl::map_physical_region(): failed to map phys"); 777ae679ddSLoGin let virtual_start = mmio_guard.vaddr().data() + offset; 787ae679ddSLoGin 797ae679ddSLoGin let virtual_start = NonNull::new(virtual_start as *mut T).unwrap(); 807ae679ddSLoGin 817ae679ddSLoGin let result: acpi::PhysicalMapping<AcpiHandlerImpl, T> = acpi::PhysicalMapping::new( 827ae679ddSLoGin physical_address, 837ae679ddSLoGin virtual_start, 847ae679ddSLoGin size, 857ae679ddSLoGin mmio_guard.size(), 867ae679ddSLoGin AcpiHandlerImpl, 877ae679ddSLoGin ); 887ae679ddSLoGin 897ae679ddSLoGin MMIOSpaceGuard::leak(mmio_guard); 907ae679ddSLoGin 917ae679ddSLoGin return result; 927ae679ddSLoGin } 937ae679ddSLoGin 947ae679ddSLoGin fn unmap_physical_region<T>(region: &acpi::PhysicalMapping<Self, T>) { 957ae679ddSLoGin let mmio_guard = unsafe { 967ae679ddSLoGin MMIOSpaceGuard::from_raw( 977ae679ddSLoGin VirtAddr::new(page_align_down( 987ae679ddSLoGin region.virtual_start().as_ref() as *const T as usize 997ae679ddSLoGin )), 1007ae679ddSLoGin region.mapped_length(), 1017ae679ddSLoGin true, 1027ae679ddSLoGin ) 1037ae679ddSLoGin }; 1047ae679ddSLoGin drop(mmio_guard); 1057ae679ddSLoGin } 1067ae679ddSLoGin } 107