1*cc5feaf6SJomo use core::{fmt::Debug, hint::spin_loop, ptr::NonNull}; 27ae679ddSLoGin 3*cc5feaf6SJomo use acpi::{AcpiHandler, AcpiTables, PlatformInfo}; 47eda31b2SLoGin use alloc::{string::ToString, sync::Arc}; 57ae679ddSLoGin 67ae679ddSLoGin use crate::{ 7*cc5feaf6SJomo arch::MMArch, 87eda31b2SLoGin driver::base::firmware::sys_firmware_kset, 97ae679ddSLoGin kinfo, 10*cc5feaf6SJomo libs::align::{page_align_down, page_align_up, AlignedBox}, 117ae679ddSLoGin mm::{ 127ae679ddSLoGin mmio_buddy::{mmio_pool, MMIOSpaceGuard}, 13*cc5feaf6SJomo MemoryManagementArch, PhysAddr, VirtAddr, 147ae679ddSLoGin }, 157eda31b2SLoGin syscall::SystemError, 167ae679ddSLoGin }; 177ae679ddSLoGin 187eda31b2SLoGin use super::base::kset::KSet; 197eda31b2SLoGin 207eda31b2SLoGin extern crate acpi; 217eda31b2SLoGin 22a03c4f9dSLoGin pub mod bus; 237ae679ddSLoGin mod c_adapter; 2406d5e247SLoGin pub mod glue; 25fbe6becdSLoGin pub mod pmtmr; 267eda31b2SLoGin mod sysfs; 277ae679ddSLoGin 287ae679ddSLoGin static mut __ACPI_TABLE: Option<acpi::AcpiTables<AcpiHandlerImpl>> = None; 297eda31b2SLoGin /// `/sys/firmware/acpi`的kset 307eda31b2SLoGin static mut ACPI_KSET_INSTANCE: Option<Arc<KSet>> = None; 317ae679ddSLoGin 32*cc5feaf6SJomo static mut RSDP_TMP_BOX: Option<AlignedBox<[u8; 4096], 4096>> = None; 33*cc5feaf6SJomo 34a03c4f9dSLoGin #[inline(always)] 35a03c4f9dSLoGin pub fn acpi_manager() -> &'static AcpiManager { 36a03c4f9dSLoGin &AcpiManager 37a03c4f9dSLoGin } 38a03c4f9dSLoGin 397eda31b2SLoGin #[inline(always)] 407eda31b2SLoGin pub fn acpi_kset() -> Arc<KSet> { 417eda31b2SLoGin unsafe { ACPI_KSET_INSTANCE.clone().unwrap() } 427eda31b2SLoGin } 437eda31b2SLoGin 447ae679ddSLoGin #[derive(Debug)] 457ae679ddSLoGin pub struct AcpiManager; 467ae679ddSLoGin 477ae679ddSLoGin impl AcpiManager { 487eda31b2SLoGin /// 初始化ACPI 497eda31b2SLoGin /// 507eda31b2SLoGin /// ## 参数 517eda31b2SLoGin /// 52*cc5feaf6SJomo /// - `rsdp_vaddr1`: RSDP(v1)的虚拟地址 53*cc5feaf6SJomo /// - `rsdp_vaddr2`: RSDP(v2)的虚拟地址 547eda31b2SLoGin /// 557eda31b2SLoGin /// 567eda31b2SLoGin /// ## 参考资料 577eda31b2SLoGin /// 587eda31b2SLoGin /// https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/acpi/bus.c#1390 59*cc5feaf6SJomo pub fn init(&self, rsdp_vaddr1: u64, rsdp_vaddr2: u64) -> Result<(), SystemError> { 607ae679ddSLoGin kinfo!("Initializing Acpi Manager..."); 617eda31b2SLoGin 627eda31b2SLoGin // 初始化`/sys/firmware/acpi`的kset 637eda31b2SLoGin let kset = KSet::new("acpi".to_string()); 647eda31b2SLoGin kset.register(Some(sys_firmware_kset()))?; 657eda31b2SLoGin unsafe { 667eda31b2SLoGin ACPI_KSET_INSTANCE = Some(kset.clone()); 677eda31b2SLoGin } 68*cc5feaf6SJomo self.map_tables(rsdp_vaddr1, rsdp_vaddr2)?; 697eda31b2SLoGin self.bus_init()?; 707eda31b2SLoGin kinfo!("Acpi Manager initialized."); 717eda31b2SLoGin return Ok(()); 727eda31b2SLoGin } 737eda31b2SLoGin 74*cc5feaf6SJomo fn map_tables(&self, rsdp_vaddr1: u64, rsdp_vaddr2: u64) -> Result<(), SystemError> { 75*cc5feaf6SJomo let rsdp_paddr1 = Self::rsdp_paddr(rsdp_vaddr1); 76*cc5feaf6SJomo let res1 = unsafe { acpi::AcpiTables::from_rsdp(AcpiHandlerImpl, rsdp_paddr1.data()) }; 77*cc5feaf6SJomo let e1; 78*cc5feaf6SJomo match res1 { 79*cc5feaf6SJomo // 如果rsdpv1能够获取到acpi_table,则就用该表,不用rsdpv2了 80*cc5feaf6SJomo Ok(acpi_table) => { 81*cc5feaf6SJomo Self::set_acpi_table(acpi_table); 82*cc5feaf6SJomo return Ok(()); 83*cc5feaf6SJomo } 84*cc5feaf6SJomo Err(e) => { 85*cc5feaf6SJomo e1 = e; 86*cc5feaf6SJomo Self::drop_rsdp_tmp_box(); 87*cc5feaf6SJomo } 88*cc5feaf6SJomo } 897ae679ddSLoGin 90*cc5feaf6SJomo let rsdp_paddr2 = Self::rsdp_paddr(rsdp_vaddr2); 91*cc5feaf6SJomo let res2 = unsafe { acpi::AcpiTables::from_rsdp(AcpiHandlerImpl, rsdp_paddr2.data()) }; 92*cc5feaf6SJomo match res2 { 93*cc5feaf6SJomo Ok(acpi_table) => { 94*cc5feaf6SJomo Self::set_acpi_table(acpi_table); 95*cc5feaf6SJomo } 96*cc5feaf6SJomo // 如果rsdpv1和rsdpv2都无法获取到acpi_table,说明有问题,打印报错信息后进入死循环 97*cc5feaf6SJomo Err(e2) => { 98*cc5feaf6SJomo kerror!("acpi_init(): failed to parse acpi tables, error: (rsdpv1: {:?}) or (rsdpv2: {:?})", e1, e2); 99*cc5feaf6SJomo Self::drop_rsdp_tmp_box(); 100*cc5feaf6SJomo loop { 101*cc5feaf6SJomo spin_loop(); 102*cc5feaf6SJomo } 103*cc5feaf6SJomo } 1047ae679ddSLoGin } 1057eda31b2SLoGin 1067eda31b2SLoGin return Ok(()); 1077ae679ddSLoGin } 1087ae679ddSLoGin 109*cc5feaf6SJomo /// 通过RSDP虚拟地址获取RSDP物理地址 110*cc5feaf6SJomo /// 111*cc5feaf6SJomo /// ## 参数 112*cc5feaf6SJomo /// 113*cc5feaf6SJomo /// - `rsdp_vaddr`: RSDP的虚拟地址 114*cc5feaf6SJomo /// 115*cc5feaf6SJomo /// ## 返回值 116*cc5feaf6SJomo /// 117*cc5feaf6SJomo /// RSDP物理地址 118*cc5feaf6SJomo fn rsdp_paddr(rsdp_vaddr: u64) -> PhysAddr { 119*cc5feaf6SJomo unsafe { 120*cc5feaf6SJomo RSDP_TMP_BOX = Some(AlignedBox::new_zeroed().expect("rs_acpi_init(): failed to alloc")) 121*cc5feaf6SJomo }; 122*cc5feaf6SJomo let size = core::mem::size_of::<acpi::rsdp::Rsdp>(); 123*cc5feaf6SJomo let tmp_data = 124*cc5feaf6SJomo unsafe { core::slice::from_raw_parts(rsdp_vaddr as usize as *const u8, size) }; 125*cc5feaf6SJomo unsafe { RSDP_TMP_BOX.as_mut().unwrap()[0..size].copy_from_slice(tmp_data) }; 126*cc5feaf6SJomo let rsdp_paddr = unsafe { 127*cc5feaf6SJomo MMArch::virt_2_phys(VirtAddr::new( 128*cc5feaf6SJomo RSDP_TMP_BOX.as_ref().unwrap().as_ptr() as usize 129*cc5feaf6SJomo )) 130*cc5feaf6SJomo .unwrap() 131*cc5feaf6SJomo }; 132*cc5feaf6SJomo 133*cc5feaf6SJomo return rsdp_paddr; 134*cc5feaf6SJomo } 135*cc5feaf6SJomo 136*cc5feaf6SJomo fn set_acpi_table(acpi_table: AcpiTables<AcpiHandlerImpl>) { 137*cc5feaf6SJomo unsafe { 138*cc5feaf6SJomo __ACPI_TABLE = Some(acpi_table); 139*cc5feaf6SJomo } 140*cc5feaf6SJomo } 141*cc5feaf6SJomo 142*cc5feaf6SJomo fn drop_rsdp_tmp_box() { 143*cc5feaf6SJomo unsafe { 144*cc5feaf6SJomo RSDP_TMP_BOX = None; 145*cc5feaf6SJomo } 146*cc5feaf6SJomo } 147*cc5feaf6SJomo 1487ae679ddSLoGin #[allow(dead_code)] 1497eda31b2SLoGin pub fn tables(&self) -> Option<&'static acpi::AcpiTables<AcpiHandlerImpl>> { 1507ae679ddSLoGin unsafe { __ACPI_TABLE.as_ref() } 1517ae679ddSLoGin } 152d7f5742aSLoGin 153d7f5742aSLoGin /// 从acpi获取平台的信息 154d7f5742aSLoGin /// 155d7f5742aSLoGin /// 包括: 156d7f5742aSLoGin /// 157d7f5742aSLoGin /// - PowerProfile 158d7f5742aSLoGin /// - InterruptModel 159d7f5742aSLoGin /// - ProcessorInfo 160d7f5742aSLoGin /// - PmTimer 161d7f5742aSLoGin pub fn platform_info(&self) -> Option<PlatformInfo<'_, alloc::alloc::Global>> { 162d7f5742aSLoGin let r = self.tables()?.platform_info(); 163d7f5742aSLoGin if let Err(ref e) = r { 164d7f5742aSLoGin kerror!( 165d7f5742aSLoGin "AcpiManager::platform_info(): failed to get platform info, error: {:?}", 166d7f5742aSLoGin e 167d7f5742aSLoGin ); 168d7f5742aSLoGin return None; 169d7f5742aSLoGin } 170d7f5742aSLoGin 171d7f5742aSLoGin return Some(r.unwrap()); 172d7f5742aSLoGin } 1737ae679ddSLoGin } 1747ae679ddSLoGin 1757ae679ddSLoGin #[derive(Debug, Clone, Copy)] 1767ae679ddSLoGin pub struct AcpiHandlerImpl; 1777ae679ddSLoGin 1787ae679ddSLoGin impl AcpiHandler for AcpiHandlerImpl { 1797ae679ddSLoGin unsafe fn map_physical_region<T>( 1807ae679ddSLoGin &self, 1817ae679ddSLoGin physical_address: usize, 1827ae679ddSLoGin size: usize, 1837ae679ddSLoGin ) -> acpi::PhysicalMapping<Self, T> { 1847ae679ddSLoGin let offset = physical_address - page_align_down(physical_address); 1857ae679ddSLoGin let size_fix = page_align_up(size + offset); 1867ae679ddSLoGin 1877ae679ddSLoGin let mmio_guard = mmio_pool() 1887ae679ddSLoGin .create_mmio(size_fix) 1897ae679ddSLoGin .expect("AcpiHandlerImpl::map_physical_region(): failed to create mmio"); 1907ae679ddSLoGin 1917ae679ddSLoGin mmio_guard 1927ae679ddSLoGin .map_phys(PhysAddr::new(page_align_down(physical_address)), size_fix) 1937ae679ddSLoGin .expect("AcpiHandlerImpl::map_physical_region(): failed to map phys"); 1947ae679ddSLoGin let virtual_start = mmio_guard.vaddr().data() + offset; 1957ae679ddSLoGin 1967ae679ddSLoGin let virtual_start = NonNull::new(virtual_start as *mut T).unwrap(); 1977ae679ddSLoGin 1987ae679ddSLoGin let result: acpi::PhysicalMapping<AcpiHandlerImpl, T> = acpi::PhysicalMapping::new( 1997ae679ddSLoGin physical_address, 2007ae679ddSLoGin virtual_start, 2017ae679ddSLoGin size, 2027ae679ddSLoGin mmio_guard.size(), 2037ae679ddSLoGin AcpiHandlerImpl, 2047ae679ddSLoGin ); 2057ae679ddSLoGin 2067ae679ddSLoGin MMIOSpaceGuard::leak(mmio_guard); 2077ae679ddSLoGin 2087ae679ddSLoGin return result; 2097ae679ddSLoGin } 2107ae679ddSLoGin 2117ae679ddSLoGin fn unmap_physical_region<T>(region: &acpi::PhysicalMapping<Self, T>) { 2127ae679ddSLoGin let mmio_guard = unsafe { 2137ae679ddSLoGin MMIOSpaceGuard::from_raw( 2147ae679ddSLoGin VirtAddr::new(page_align_down( 2157ae679ddSLoGin region.virtual_start().as_ref() as *const T as usize 2167ae679ddSLoGin )), 2177ae679ddSLoGin region.mapped_length(), 2187ae679ddSLoGin true, 2197ae679ddSLoGin ) 2207ae679ddSLoGin }; 2217ae679ddSLoGin drop(mmio_guard); 2227ae679ddSLoGin } 2237ae679ddSLoGin } 224