1 use core::{fmt::Debug, ptr::NonNull}; 2 3 use acpi::{AcpiHandler, AcpiTables, PlatformInfo}; 4 use alloc::{string::ToString, sync::Arc}; 5 use log::{error, info}; 6 7 use crate::{ 8 arch::MMArch, 9 driver::base::firmware::sys_firmware_kset, 10 init::{boot::BootloaderAcpiArg, boot_params}, 11 libs::align::{page_align_down, page_align_up, AlignedBox}, 12 mm::{ 13 mmio_buddy::{mmio_pool, MMIOSpaceGuard}, 14 MemoryManagementArch, PhysAddr, VirtAddr, 15 }, 16 }; 17 use system_error::SystemError; 18 19 use super::base::kset::KSet; 20 21 extern crate acpi; 22 23 pub mod bus; 24 pub mod glue; 25 pub mod pmtmr; 26 mod sysfs; 27 28 static mut __ACPI_TABLE: Option<acpi::AcpiTables<AcpiHandlerImpl>> = None; 29 /// `/sys/firmware/acpi`的kset 30 static mut ACPI_KSET_INSTANCE: Option<Arc<KSet>> = None; 31 32 static mut RSDP_TMP_BOX: Option<AlignedBox<[u8; 4096], 4096>> = None; 33 34 #[inline(always)] 35 pub fn acpi_manager() -> &'static AcpiManager { 36 &AcpiManager 37 } 38 39 #[inline(always)] 40 pub fn acpi_kset() -> Arc<KSet> { 41 unsafe { ACPI_KSET_INSTANCE.clone().unwrap() } 42 } 43 44 #[derive(Debug)] 45 pub struct AcpiManager; 46 47 impl AcpiManager { 48 /// 初始化ACPI 49 /// 50 /// ## 参数 51 /// 52 /// - `rsdp_vaddr1`: RSDP(v1)的虚拟地址 53 /// - `rsdp_vaddr2`: RSDP(v2)的虚拟地址 54 /// 55 /// 56 /// ## 参考资料 57 /// 58 /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/acpi/bus.c#1390 59 fn init(&self) -> Result<(), SystemError> { 60 info!("Initializing Acpi Manager..."); 61 62 // 初始化`/sys/firmware/acpi`的kset 63 let kset = KSet::new("acpi".to_string()); 64 kset.register(Some(sys_firmware_kset()))?; 65 unsafe { 66 ACPI_KSET_INSTANCE = Some(kset.clone()); 67 } 68 let acpi_args = boot_params().read().acpi; 69 if let BootloaderAcpiArg::NotProvided = acpi_args { 70 error!("acpi_init(): ACPI not provided by bootloader"); 71 return Err(SystemError::ENODEV); 72 } 73 74 self.map_tables(acpi_args)?; 75 self.bus_init()?; 76 info!("Acpi Manager initialized."); 77 return Ok(()); 78 } 79 80 fn map_tables(&self, acpi_args: BootloaderAcpiArg) -> Result<(), SystemError> { 81 let table_paddr: PhysAddr = match acpi_args { 82 BootloaderAcpiArg::Rsdt(rsdpv1) => Self::rsdp_paddr(&rsdpv1), 83 BootloaderAcpiArg::Xsdt(rsdpv2) => Self::rsdp_paddr(&rsdpv2), 84 BootloaderAcpiArg::Rsdp(rsdp) => rsdp, 85 _ => { 86 error!( 87 "AcpiManager::map_tables(): unsupported acpi_args: {:?}", 88 acpi_args 89 ); 90 return Err(SystemError::ENODEV); 91 } 92 }; 93 let res = unsafe { acpi::AcpiTables::from_rsdp(AcpiHandlerImpl, table_paddr.data()) }; 94 match res { 95 Ok(acpi_table) => { 96 Self::set_acpi_table(acpi_table); 97 return Ok(()); 98 } 99 Err(e) => { 100 error!( 101 "AcpiManager::map_tables(): failed to map tables, error: {:?}", 102 e 103 ); 104 Self::drop_rsdp_tmp_box(); 105 return Err(SystemError::ENODEV); 106 } 107 } 108 } 109 110 /// 通过RSDP虚拟地址获取RSDP物理地址 111 /// 112 /// ## 参数 113 /// 114 /// - `rsdp_vaddr`: RSDP的虚拟地址 115 /// 116 /// ## 返回值 117 /// 118 /// RSDP物理地址 119 fn rsdp_paddr(rsdp_instance: &acpi::rsdp::Rsdp) -> PhysAddr { 120 unsafe { 121 RSDP_TMP_BOX = Some(AlignedBox::new_zeroed().expect("rs_acpi_init(): failed to alloc")) 122 }; 123 124 let size = core::mem::size_of::<acpi::rsdp::Rsdp>(); 125 let tmp_data = unsafe { 126 core::slice::from_raw_parts( 127 rsdp_instance as *const acpi::rsdp::Rsdp as usize as *const u8, 128 size, 129 ) 130 }; 131 unsafe { RSDP_TMP_BOX.as_mut().unwrap()[0..size].copy_from_slice(tmp_data) }; 132 let rsdp_paddr = unsafe { 133 MMArch::virt_2_phys(VirtAddr::new( 134 RSDP_TMP_BOX.as_ref().unwrap().as_ptr() as usize 135 )) 136 .unwrap() 137 }; 138 139 return rsdp_paddr; 140 } 141 142 fn set_acpi_table(acpi_table: AcpiTables<AcpiHandlerImpl>) { 143 unsafe { 144 __ACPI_TABLE = Some(acpi_table); 145 } 146 } 147 148 fn drop_rsdp_tmp_box() { 149 unsafe { 150 RSDP_TMP_BOX = None; 151 } 152 } 153 154 #[allow(dead_code)] 155 pub fn tables(&self) -> Option<&'static acpi::AcpiTables<AcpiHandlerImpl>> { 156 unsafe { __ACPI_TABLE.as_ref() } 157 } 158 159 /// 从acpi获取平台的信息 160 /// 161 /// 包括: 162 /// 163 /// - PowerProfile 164 /// - InterruptModel 165 /// - ProcessorInfo 166 /// - PmTimer 167 pub fn platform_info(&self) -> Option<PlatformInfo<'_, alloc::alloc::Global>> { 168 let r = self.tables()?.platform_info(); 169 if let Err(ref e) = r { 170 error!( 171 "AcpiManager::platform_info(): failed to get platform info, error: {:?}", 172 e 173 ); 174 return None; 175 } 176 177 return Some(r.unwrap()); 178 } 179 } 180 181 #[derive(Debug, Clone, Copy)] 182 pub struct AcpiHandlerImpl; 183 184 impl AcpiHandler for AcpiHandlerImpl { 185 unsafe fn map_physical_region<T>( 186 &self, 187 physical_address: usize, 188 size: usize, 189 ) -> acpi::PhysicalMapping<Self, T> { 190 let offset = physical_address - page_align_down(physical_address); 191 let size_fix = page_align_up(size + offset); 192 193 let mmio_guard = mmio_pool() 194 .create_mmio(size_fix) 195 .expect("AcpiHandlerImpl::map_physical_region(): failed to create mmio"); 196 197 mmio_guard 198 .map_phys(PhysAddr::new(page_align_down(physical_address)), size_fix) 199 .expect("AcpiHandlerImpl::map_physical_region(): failed to map phys"); 200 let virtual_start = mmio_guard.vaddr().data() + offset; 201 202 let virtual_start = NonNull::new(virtual_start as *mut T).unwrap(); 203 204 let result: acpi::PhysicalMapping<AcpiHandlerImpl, T> = acpi::PhysicalMapping::new( 205 physical_address, 206 virtual_start, 207 size, 208 mmio_guard.size(), 209 AcpiHandlerImpl, 210 ); 211 212 MMIOSpaceGuard::leak(mmio_guard); 213 214 return result; 215 } 216 217 fn unmap_physical_region<T>(region: &acpi::PhysicalMapping<Self, T>) { 218 let mmio_guard = unsafe { 219 MMIOSpaceGuard::from_raw( 220 VirtAddr::new(page_align_down( 221 region.virtual_start().as_ref() as *const T as usize 222 )), 223 region.mapped_length(), 224 true, 225 ) 226 }; 227 drop(mmio_guard); 228 } 229 } 230 231 #[inline(never)] 232 pub fn acpi_init() -> Result<(), SystemError> { 233 #[cfg(target_arch = "x86_64")] 234 { 235 acpi_manager().init() 236 } 237 238 #[cfg(not(target_arch = "x86_64"))] 239 { 240 log::warn!("acpi_init(): unsupported arch"); 241 return Ok(()); 242 } 243 } 244