xref: /DragonOS/kernel/src/driver/acpi/mod.rs (revision 2b7818e80e00fcfe4d03533f587cc125ea5e4bec)
1*2b7818e8SLoGin use core::{fmt::Debug, ptr::NonNull};
27ae679ddSLoGin 
3cc5feaf6SJomo use acpi::{AcpiHandler, AcpiTables, PlatformInfo};
47eda31b2SLoGin use alloc::{string::ToString, sync::Arc};
52eab6dd7S曾俊 use log::{error, info};
67ae679ddSLoGin 
77ae679ddSLoGin use crate::{
8cc5feaf6SJomo     arch::MMArch,
97eda31b2SLoGin     driver::base::firmware::sys_firmware_kset,
10*2b7818e8SLoGin     init::{boot::BootloaderAcpiArg, boot_params},
11cc5feaf6SJomo     libs::align::{page_align_down, page_align_up, AlignedBox},
127ae679ddSLoGin     mm::{
137ae679ddSLoGin         mmio_buddy::{mmio_pool, MMIOSpaceGuard},
14cc5feaf6SJomo         MemoryManagementArch, PhysAddr, VirtAddr,
157ae679ddSLoGin     },
167ae679ddSLoGin };
1791e9d4abSLoGin use system_error::SystemError;
187ae679ddSLoGin 
197eda31b2SLoGin use super::base::kset::KSet;
207eda31b2SLoGin 
217eda31b2SLoGin extern crate acpi;
227eda31b2SLoGin 
23a03c4f9dSLoGin pub mod bus;
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 
32cc5feaf6SJomo static mut RSDP_TMP_BOX: Option<AlignedBox<[u8; 4096], 4096>> = None;
33cc5feaf6SJomo 
34a03c4f9dSLoGin #[inline(always)]
acpi_manager() -> &'static AcpiManager35a03c4f9dSLoGin pub fn acpi_manager() -> &'static AcpiManager {
36a03c4f9dSLoGin     &AcpiManager
37a03c4f9dSLoGin }
38a03c4f9dSLoGin 
397eda31b2SLoGin #[inline(always)]
acpi_kset() -> Arc<KSet>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     ///
52cc5feaf6SJomo     /// - `rsdp_vaddr1`: RSDP(v1)的虚拟地址
53cc5feaf6SJomo     /// - `rsdp_vaddr2`: RSDP(v2)的虚拟地址
547eda31b2SLoGin     ///
557eda31b2SLoGin     ///
567eda31b2SLoGin     /// ## 参考资料
577eda31b2SLoGin     ///
58e7071df6SLoGin     /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/acpi/bus.c#1390
init(&self) -> Result<(), SystemError>59*2b7818e8SLoGin     fn init(&self) -> Result<(), SystemError> {
602eab6dd7S曾俊         info!("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*2b7818e8SLoGin         let acpi_args = boot_params().read().acpi;
69*2b7818e8SLoGin         if let BootloaderAcpiArg::NotProvided = acpi_args {
70*2b7818e8SLoGin             error!("acpi_init(): ACPI not provided by bootloader");
71*2b7818e8SLoGin             return Err(SystemError::ENODEV);
72*2b7818e8SLoGin         }
73*2b7818e8SLoGin 
74*2b7818e8SLoGin         self.map_tables(acpi_args)?;
757eda31b2SLoGin         self.bus_init()?;
762eab6dd7S曾俊         info!("Acpi Manager initialized.");
777eda31b2SLoGin         return Ok(());
787eda31b2SLoGin     }
797eda31b2SLoGin 
map_tables(&self, acpi_args: BootloaderAcpiArg) -> Result<(), SystemError>80*2b7818e8SLoGin     fn map_tables(&self, acpi_args: BootloaderAcpiArg) -> Result<(), SystemError> {
81*2b7818e8SLoGin         let table_paddr: PhysAddr = match acpi_args {
82*2b7818e8SLoGin             BootloaderAcpiArg::Rsdt(rsdpv1) => Self::rsdp_paddr(&rsdpv1),
83*2b7818e8SLoGin             BootloaderAcpiArg::Xsdt(rsdpv2) => Self::rsdp_paddr(&rsdpv2),
84*2b7818e8SLoGin             _ => {
85*2b7818e8SLoGin                 error!(
86*2b7818e8SLoGin                     "AcpiManager::map_tables(): unsupported acpi_args: {:?}",
87*2b7818e8SLoGin                     acpi_args
88*2b7818e8SLoGin                 );
89*2b7818e8SLoGin                 return Err(SystemError::ENODEV);
90*2b7818e8SLoGin             }
91*2b7818e8SLoGin         };
92*2b7818e8SLoGin         let res = unsafe { acpi::AcpiTables::from_rsdp(AcpiHandlerImpl, table_paddr.data()) };
93*2b7818e8SLoGin         match res {
94cc5feaf6SJomo             Ok(acpi_table) => {
95cc5feaf6SJomo                 Self::set_acpi_table(acpi_table);
96cc5feaf6SJomo                 return Ok(());
97cc5feaf6SJomo             }
98cc5feaf6SJomo             Err(e) => {
99*2b7818e8SLoGin                 error!(
100*2b7818e8SLoGin                     "AcpiManager::map_tables(): failed to map tables, error: {:?}",
101*2b7818e8SLoGin                     e
102*2b7818e8SLoGin                 );
103cc5feaf6SJomo                 Self::drop_rsdp_tmp_box();
104*2b7818e8SLoGin                 return Err(SystemError::ENODEV);
105cc5feaf6SJomo             }
106cc5feaf6SJomo         }
1077ae679ddSLoGin     }
1087ae679ddSLoGin 
109cc5feaf6SJomo     /// 通过RSDP虚拟地址获取RSDP物理地址
110cc5feaf6SJomo     ///
111cc5feaf6SJomo     /// ## 参数
112cc5feaf6SJomo     ///
113cc5feaf6SJomo     /// - `rsdp_vaddr`: RSDP的虚拟地址
114cc5feaf6SJomo     ///
115cc5feaf6SJomo     /// ## 返回值
116cc5feaf6SJomo     ///
117cc5feaf6SJomo     /// RSDP物理地址
rsdp_paddr(rsdp_instance: &acpi::rsdp::Rsdp) -> PhysAddr118*2b7818e8SLoGin     fn rsdp_paddr(rsdp_instance: &acpi::rsdp::Rsdp) -> PhysAddr {
119cc5feaf6SJomo         unsafe {
120cc5feaf6SJomo             RSDP_TMP_BOX = Some(AlignedBox::new_zeroed().expect("rs_acpi_init(): failed to alloc"))
121cc5feaf6SJomo         };
122*2b7818e8SLoGin 
123cc5feaf6SJomo         let size = core::mem::size_of::<acpi::rsdp::Rsdp>();
124*2b7818e8SLoGin         let tmp_data = unsafe {
125*2b7818e8SLoGin             core::slice::from_raw_parts(
126*2b7818e8SLoGin                 rsdp_instance as *const acpi::rsdp::Rsdp as usize as *const u8,
127*2b7818e8SLoGin                 size,
128*2b7818e8SLoGin             )
129*2b7818e8SLoGin         };
130cc5feaf6SJomo         unsafe { RSDP_TMP_BOX.as_mut().unwrap()[0..size].copy_from_slice(tmp_data) };
131cc5feaf6SJomo         let rsdp_paddr = unsafe {
132cc5feaf6SJomo             MMArch::virt_2_phys(VirtAddr::new(
133cc5feaf6SJomo                 RSDP_TMP_BOX.as_ref().unwrap().as_ptr() as usize
134cc5feaf6SJomo             ))
135cc5feaf6SJomo             .unwrap()
136cc5feaf6SJomo         };
137cc5feaf6SJomo 
138cc5feaf6SJomo         return rsdp_paddr;
139cc5feaf6SJomo     }
140cc5feaf6SJomo 
set_acpi_table(acpi_table: AcpiTables<AcpiHandlerImpl>)141cc5feaf6SJomo     fn set_acpi_table(acpi_table: AcpiTables<AcpiHandlerImpl>) {
142cc5feaf6SJomo         unsafe {
143cc5feaf6SJomo             __ACPI_TABLE = Some(acpi_table);
144cc5feaf6SJomo         }
145cc5feaf6SJomo     }
146cc5feaf6SJomo 
drop_rsdp_tmp_box()147cc5feaf6SJomo     fn drop_rsdp_tmp_box() {
148cc5feaf6SJomo         unsafe {
149cc5feaf6SJomo             RSDP_TMP_BOX = None;
150cc5feaf6SJomo         }
151cc5feaf6SJomo     }
152cc5feaf6SJomo 
1537ae679ddSLoGin     #[allow(dead_code)]
tables(&self) -> Option<&'static acpi::AcpiTables<AcpiHandlerImpl>>1547eda31b2SLoGin     pub fn tables(&self) -> Option<&'static acpi::AcpiTables<AcpiHandlerImpl>> {
1557ae679ddSLoGin         unsafe { __ACPI_TABLE.as_ref() }
1567ae679ddSLoGin     }
157d7f5742aSLoGin 
158d7f5742aSLoGin     /// 从acpi获取平台的信息
159d7f5742aSLoGin     ///
160d7f5742aSLoGin     /// 包括:
161d7f5742aSLoGin     ///
162d7f5742aSLoGin     /// - PowerProfile
163d7f5742aSLoGin     /// - InterruptModel
164d7f5742aSLoGin     /// - ProcessorInfo
165d7f5742aSLoGin     /// - PmTimer
platform_info(&self) -> Option<PlatformInfo<'_, alloc::alloc::Global>>166d7f5742aSLoGin     pub fn platform_info(&self) -> Option<PlatformInfo<'_, alloc::alloc::Global>> {
167d7f5742aSLoGin         let r = self.tables()?.platform_info();
168d7f5742aSLoGin         if let Err(ref e) = r {
1692eab6dd7S曾俊             error!(
170d7f5742aSLoGin                 "AcpiManager::platform_info(): failed to get platform info, error: {:?}",
171d7f5742aSLoGin                 e
172d7f5742aSLoGin             );
173d7f5742aSLoGin             return None;
174d7f5742aSLoGin         }
175d7f5742aSLoGin 
176d7f5742aSLoGin         return Some(r.unwrap());
177d7f5742aSLoGin     }
1787ae679ddSLoGin }
1797ae679ddSLoGin 
1807ae679ddSLoGin #[derive(Debug, Clone, Copy)]
1817ae679ddSLoGin pub struct AcpiHandlerImpl;
1827ae679ddSLoGin 
1837ae679ddSLoGin impl AcpiHandler for AcpiHandlerImpl {
map_physical_region<T>( &self, physical_address: usize, size: usize, ) -> acpi::PhysicalMapping<Self, T>1847ae679ddSLoGin     unsafe fn map_physical_region<T>(
1857ae679ddSLoGin         &self,
1867ae679ddSLoGin         physical_address: usize,
1877ae679ddSLoGin         size: usize,
1887ae679ddSLoGin     ) -> acpi::PhysicalMapping<Self, T> {
1897ae679ddSLoGin         let offset = physical_address - page_align_down(physical_address);
1907ae679ddSLoGin         let size_fix = page_align_up(size + offset);
1917ae679ddSLoGin 
1927ae679ddSLoGin         let mmio_guard = mmio_pool()
1937ae679ddSLoGin             .create_mmio(size_fix)
1947ae679ddSLoGin             .expect("AcpiHandlerImpl::map_physical_region(): failed to create mmio");
1957ae679ddSLoGin 
1967ae679ddSLoGin         mmio_guard
1977ae679ddSLoGin             .map_phys(PhysAddr::new(page_align_down(physical_address)), size_fix)
1987ae679ddSLoGin             .expect("AcpiHandlerImpl::map_physical_region(): failed to map phys");
1997ae679ddSLoGin         let virtual_start = mmio_guard.vaddr().data() + offset;
2007ae679ddSLoGin 
2017ae679ddSLoGin         let virtual_start = NonNull::new(virtual_start as *mut T).unwrap();
2027ae679ddSLoGin 
2037ae679ddSLoGin         let result: acpi::PhysicalMapping<AcpiHandlerImpl, T> = acpi::PhysicalMapping::new(
2047ae679ddSLoGin             physical_address,
2057ae679ddSLoGin             virtual_start,
2067ae679ddSLoGin             size,
2077ae679ddSLoGin             mmio_guard.size(),
2087ae679ddSLoGin             AcpiHandlerImpl,
2097ae679ddSLoGin         );
2107ae679ddSLoGin 
2117ae679ddSLoGin         MMIOSpaceGuard::leak(mmio_guard);
2127ae679ddSLoGin 
2137ae679ddSLoGin         return result;
2147ae679ddSLoGin     }
2157ae679ddSLoGin 
unmap_physical_region<T>(region: &acpi::PhysicalMapping<Self, T>)2167ae679ddSLoGin     fn unmap_physical_region<T>(region: &acpi::PhysicalMapping<Self, T>) {
2177ae679ddSLoGin         let mmio_guard = unsafe {
2187ae679ddSLoGin             MMIOSpaceGuard::from_raw(
2197ae679ddSLoGin                 VirtAddr::new(page_align_down(
2207ae679ddSLoGin                     region.virtual_start().as_ref() as *const T as usize
2217ae679ddSLoGin                 )),
2227ae679ddSLoGin                 region.mapped_length(),
2237ae679ddSLoGin                 true,
2247ae679ddSLoGin             )
2257ae679ddSLoGin         };
2267ae679ddSLoGin         drop(mmio_guard);
2277ae679ddSLoGin     }
2287ae679ddSLoGin }
229*2b7818e8SLoGin 
230*2b7818e8SLoGin #[inline(never)]
acpi_init() -> Result<(), SystemError>231*2b7818e8SLoGin pub fn acpi_init() -> Result<(), SystemError> {
232*2b7818e8SLoGin     #[cfg(target_arch = "x86_64")]
233*2b7818e8SLoGin     {
234*2b7818e8SLoGin         acpi_manager().init()
235*2b7818e8SLoGin     }
236*2b7818e8SLoGin 
237*2b7818e8SLoGin     #[cfg(not(target_arch = "x86_64"))]
238*2b7818e8SLoGin     {
239*2b7818e8SLoGin         log::warn!("acpi_init(): unsupported arch");
240*2b7818e8SLoGin         return Ok(());
241*2b7818e8SLoGin     }
242*2b7818e8SLoGin }
243