17ae679ddSLoGin use core::{fmt::Debug, ptr::NonNull}; 27ae679ddSLoGin 37ae679ddSLoGin use acpi::AcpiHandler; 4*7eda31b2SLoGin use alloc::{string::ToString, sync::Arc}; 57ae679ddSLoGin 67ae679ddSLoGin use crate::{ 7*7eda31b2SLoGin driver::base::firmware::sys_firmware_kset, 87ae679ddSLoGin kinfo, 9*7eda31b2SLoGin libs::align::{page_align_down, page_align_up}, 107ae679ddSLoGin mm::{ 117ae679ddSLoGin mmio_buddy::{mmio_pool, MMIOSpaceGuard}, 127ae679ddSLoGin PhysAddr, VirtAddr, 137ae679ddSLoGin }, 14*7eda31b2SLoGin syscall::SystemError, 157ae679ddSLoGin }; 167ae679ddSLoGin 17*7eda31b2SLoGin use super::base::kset::KSet; 18*7eda31b2SLoGin 19*7eda31b2SLoGin extern crate acpi; 20*7eda31b2SLoGin 21a03c4f9dSLoGin pub mod bus; 227ae679ddSLoGin mod c_adapter; 2306d5e247SLoGin pub mod glue; 247ae679ddSLoGin pub mod old; 25*7eda31b2SLoGin mod sysfs; 267ae679ddSLoGin 277ae679ddSLoGin static mut __ACPI_TABLE: Option<acpi::AcpiTables<AcpiHandlerImpl>> = None; 28*7eda31b2SLoGin /// `/sys/firmware/acpi`的kset 29*7eda31b2SLoGin static mut ACPI_KSET_INSTANCE: Option<Arc<KSet>> = None; 307ae679ddSLoGin 31a03c4f9dSLoGin #[inline(always)] 32a03c4f9dSLoGin pub fn acpi_manager() -> &'static AcpiManager { 33a03c4f9dSLoGin &AcpiManager 34a03c4f9dSLoGin } 35a03c4f9dSLoGin 36*7eda31b2SLoGin #[inline(always)] 37*7eda31b2SLoGin pub fn acpi_kset() -> Arc<KSet> { 38*7eda31b2SLoGin unsafe { ACPI_KSET_INSTANCE.clone().unwrap() } 39*7eda31b2SLoGin } 40*7eda31b2SLoGin 417ae679ddSLoGin #[derive(Debug)] 427ae679ddSLoGin pub struct AcpiManager; 437ae679ddSLoGin 447ae679ddSLoGin impl AcpiManager { 45*7eda31b2SLoGin /// 初始化ACPI 46*7eda31b2SLoGin /// 47*7eda31b2SLoGin /// ## 参数 48*7eda31b2SLoGin /// 49*7eda31b2SLoGin /// - `rsdp_paddr`: RSDP的物理地址 50*7eda31b2SLoGin /// 51*7eda31b2SLoGin /// 52*7eda31b2SLoGin /// ## 参考资料 53*7eda31b2SLoGin /// 54*7eda31b2SLoGin /// https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/acpi/bus.c#1390 55*7eda31b2SLoGin pub fn init(&self, rsdp_paddr: PhysAddr) -> Result<(), SystemError> { 567ae679ddSLoGin kinfo!("Initializing Acpi Manager..."); 57*7eda31b2SLoGin 58*7eda31b2SLoGin // 初始化`/sys/firmware/acpi`的kset 59*7eda31b2SLoGin let kset = KSet::new("acpi".to_string()); 60*7eda31b2SLoGin kset.register(Some(sys_firmware_kset()))?; 61*7eda31b2SLoGin unsafe { 62*7eda31b2SLoGin ACPI_KSET_INSTANCE = Some(kset.clone()); 63*7eda31b2SLoGin } 64*7eda31b2SLoGin self.map_tables(rsdp_paddr)?; 65*7eda31b2SLoGin self.bus_init()?; 66*7eda31b2SLoGin kinfo!("Acpi Manager initialized."); 67*7eda31b2SLoGin return Ok(()); 68*7eda31b2SLoGin } 69*7eda31b2SLoGin 70*7eda31b2SLoGin fn map_tables(&self, rsdp_paddr: PhysAddr) -> Result<(), SystemError> { 717ae679ddSLoGin let acpi_table: acpi::AcpiTables<AcpiHandlerImpl> = 72*7eda31b2SLoGin unsafe { acpi::AcpiTables::from_rsdp(AcpiHandlerImpl, rsdp_paddr.data()) }.map_err( 73*7eda31b2SLoGin |e| { 74*7eda31b2SLoGin kerror!("acpi_init(): failed to parse acpi tables, error: {:?}", e); 75*7eda31b2SLoGin SystemError::ENOMEM 76*7eda31b2SLoGin }, 77*7eda31b2SLoGin )?; 787ae679ddSLoGin 797ae679ddSLoGin unsafe { 807ae679ddSLoGin __ACPI_TABLE = Some(acpi_table); 817ae679ddSLoGin } 82*7eda31b2SLoGin 83*7eda31b2SLoGin return Ok(()); 847ae679ddSLoGin } 857ae679ddSLoGin 867ae679ddSLoGin #[allow(dead_code)] 87*7eda31b2SLoGin pub fn tables(&self) -> Option<&'static acpi::AcpiTables<AcpiHandlerImpl>> { 887ae679ddSLoGin unsafe { __ACPI_TABLE.as_ref() } 897ae679ddSLoGin } 907ae679ddSLoGin } 917ae679ddSLoGin 927ae679ddSLoGin #[derive(Debug, Clone, Copy)] 937ae679ddSLoGin pub struct AcpiHandlerImpl; 947ae679ddSLoGin 957ae679ddSLoGin impl AcpiHandler for AcpiHandlerImpl { 967ae679ddSLoGin unsafe fn map_physical_region<T>( 977ae679ddSLoGin &self, 987ae679ddSLoGin physical_address: usize, 997ae679ddSLoGin size: usize, 1007ae679ddSLoGin ) -> acpi::PhysicalMapping<Self, T> { 1017ae679ddSLoGin let offset = physical_address - page_align_down(physical_address); 1027ae679ddSLoGin let size_fix = page_align_up(size + offset); 1037ae679ddSLoGin 1047ae679ddSLoGin let mmio_guard = mmio_pool() 1057ae679ddSLoGin .create_mmio(size_fix) 1067ae679ddSLoGin .expect("AcpiHandlerImpl::map_physical_region(): failed to create mmio"); 1077ae679ddSLoGin 1087ae679ddSLoGin mmio_guard 1097ae679ddSLoGin .map_phys(PhysAddr::new(page_align_down(physical_address)), size_fix) 1107ae679ddSLoGin .expect("AcpiHandlerImpl::map_physical_region(): failed to map phys"); 1117ae679ddSLoGin let virtual_start = mmio_guard.vaddr().data() + offset; 1127ae679ddSLoGin 1137ae679ddSLoGin let virtual_start = NonNull::new(virtual_start as *mut T).unwrap(); 1147ae679ddSLoGin 1157ae679ddSLoGin let result: acpi::PhysicalMapping<AcpiHandlerImpl, T> = acpi::PhysicalMapping::new( 1167ae679ddSLoGin physical_address, 1177ae679ddSLoGin virtual_start, 1187ae679ddSLoGin size, 1197ae679ddSLoGin mmio_guard.size(), 1207ae679ddSLoGin AcpiHandlerImpl, 1217ae679ddSLoGin ); 1227ae679ddSLoGin 1237ae679ddSLoGin MMIOSpaceGuard::leak(mmio_guard); 1247ae679ddSLoGin 1257ae679ddSLoGin return result; 1267ae679ddSLoGin } 1277ae679ddSLoGin 1287ae679ddSLoGin fn unmap_physical_region<T>(region: &acpi::PhysicalMapping<Self, T>) { 1297ae679ddSLoGin let mmio_guard = unsafe { 1307ae679ddSLoGin MMIOSpaceGuard::from_raw( 1317ae679ddSLoGin VirtAddr::new(page_align_down( 1327ae679ddSLoGin region.virtual_start().as_ref() as *const T as usize 1337ae679ddSLoGin )), 1347ae679ddSLoGin region.mapped_length(), 1357ae679ddSLoGin true, 1367ae679ddSLoGin ) 1377ae679ddSLoGin }; 1387ae679ddSLoGin drop(mmio_guard); 1397ae679ddSLoGin } 1407ae679ddSLoGin } 141