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 177ae679ddSLoGin mod c_adapter; 18*06d5e247SLoGin pub mod glue; 197ae679ddSLoGin pub mod old; 207ae679ddSLoGin 217ae679ddSLoGin extern crate acpi; 227ae679ddSLoGin 237ae679ddSLoGin static mut __ACPI_TABLE: Option<acpi::AcpiTables<AcpiHandlerImpl>> = None; 247ae679ddSLoGin 257ae679ddSLoGin #[derive(Debug)] 267ae679ddSLoGin pub struct AcpiManager; 277ae679ddSLoGin 287ae679ddSLoGin impl AcpiManager { 297ae679ddSLoGin pub fn init(rsdp_paddr: PhysAddr) { 307ae679ddSLoGin static INIT: Once = Once::new(); 317ae679ddSLoGin INIT.call_once(|| { 327ae679ddSLoGin kinfo!("Initializing Acpi Manager..."); 337ae679ddSLoGin let acpi_table: acpi::AcpiTables<AcpiHandlerImpl> = 347ae679ddSLoGin unsafe { acpi::AcpiTables::from_rsdp(AcpiHandlerImpl, rsdp_paddr.data()) } 357ae679ddSLoGin .unwrap_or_else(|e| { 367ae679ddSLoGin panic!("acpi_init(): failed to parse acpi tables, error: {:?}", e) 377ae679ddSLoGin }); 387ae679ddSLoGin 397ae679ddSLoGin unsafe { 407ae679ddSLoGin __ACPI_TABLE = Some(acpi_table); 417ae679ddSLoGin } 427ae679ddSLoGin kinfo!("Acpi Manager initialized."); 437ae679ddSLoGin }); 447ae679ddSLoGin } 457ae679ddSLoGin 467ae679ddSLoGin #[allow(dead_code)] 477ae679ddSLoGin pub fn tables() -> Option<&'static acpi::AcpiTables<AcpiHandlerImpl>> { 487ae679ddSLoGin unsafe { __ACPI_TABLE.as_ref() } 497ae679ddSLoGin } 507ae679ddSLoGin } 517ae679ddSLoGin 527ae679ddSLoGin #[derive(Debug, Clone, Copy)] 537ae679ddSLoGin pub struct AcpiHandlerImpl; 547ae679ddSLoGin 557ae679ddSLoGin impl AcpiHandler for AcpiHandlerImpl { 567ae679ddSLoGin unsafe fn map_physical_region<T>( 577ae679ddSLoGin &self, 587ae679ddSLoGin physical_address: usize, 597ae679ddSLoGin size: usize, 607ae679ddSLoGin ) -> acpi::PhysicalMapping<Self, T> { 617ae679ddSLoGin let offset = physical_address - page_align_down(physical_address); 627ae679ddSLoGin let size_fix = page_align_up(size + offset); 637ae679ddSLoGin 647ae679ddSLoGin let mmio_guard = mmio_pool() 657ae679ddSLoGin .create_mmio(size_fix) 667ae679ddSLoGin .expect("AcpiHandlerImpl::map_physical_region(): failed to create mmio"); 677ae679ddSLoGin 687ae679ddSLoGin mmio_guard 697ae679ddSLoGin .map_phys(PhysAddr::new(page_align_down(physical_address)), size_fix) 707ae679ddSLoGin .expect("AcpiHandlerImpl::map_physical_region(): failed to map phys"); 717ae679ddSLoGin let virtual_start = mmio_guard.vaddr().data() + offset; 727ae679ddSLoGin 737ae679ddSLoGin let virtual_start = NonNull::new(virtual_start as *mut T).unwrap(); 747ae679ddSLoGin 757ae679ddSLoGin let result: acpi::PhysicalMapping<AcpiHandlerImpl, T> = acpi::PhysicalMapping::new( 767ae679ddSLoGin physical_address, 777ae679ddSLoGin virtual_start, 787ae679ddSLoGin size, 797ae679ddSLoGin mmio_guard.size(), 807ae679ddSLoGin AcpiHandlerImpl, 817ae679ddSLoGin ); 827ae679ddSLoGin 837ae679ddSLoGin MMIOSpaceGuard::leak(mmio_guard); 847ae679ddSLoGin 857ae679ddSLoGin return result; 867ae679ddSLoGin } 877ae679ddSLoGin 887ae679ddSLoGin fn unmap_physical_region<T>(region: &acpi::PhysicalMapping<Self, T>) { 897ae679ddSLoGin let mmio_guard = unsafe { 907ae679ddSLoGin MMIOSpaceGuard::from_raw( 917ae679ddSLoGin VirtAddr::new(page_align_down( 927ae679ddSLoGin region.virtual_start().as_ref() as *const T as usize 937ae679ddSLoGin )), 947ae679ddSLoGin region.mapped_length(), 957ae679ddSLoGin true, 967ae679ddSLoGin ) 977ae679ddSLoGin }; 987ae679ddSLoGin drop(mmio_guard); 997ae679ddSLoGin } 1007ae679ddSLoGin } 101