xref: /DragonOS/kernel/src/driver/acpi/mod.rs (revision 91e9d4ab55ef960f57a1b6287bc523ca4341f67a)
1cc5feaf6SJomo use core::{fmt::Debug, hint::spin_loop, ptr::NonNull};
27ae679ddSLoGin 
3cc5feaf6SJomo use acpi::{AcpiHandler, AcpiTables, PlatformInfo};
47eda31b2SLoGin use alloc::{string::ToString, sync::Arc};
57ae679ddSLoGin 
67ae679ddSLoGin use crate::{
7cc5feaf6SJomo     arch::MMArch,
87eda31b2SLoGin     driver::base::firmware::sys_firmware_kset,
97ae679ddSLoGin     kinfo,
10cc5feaf6SJomo     libs::align::{page_align_down, page_align_up, AlignedBox},
117ae679ddSLoGin     mm::{
127ae679ddSLoGin         mmio_buddy::{mmio_pool, MMIOSpaceGuard},
13cc5feaf6SJomo         MemoryManagementArch, PhysAddr, VirtAddr,
147ae679ddSLoGin     },
157ae679ddSLoGin };
16*91e9d4abSLoGin use system_error::SystemError;
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 
32cc5feaf6SJomo static mut RSDP_TMP_BOX: Option<AlignedBox<[u8; 4096], 4096>> = None;
33cc5feaf6SJomo 
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     ///
52cc5feaf6SJomo     /// - `rsdp_vaddr1`: RSDP(v1)的虚拟地址
53cc5feaf6SJomo     /// - `rsdp_vaddr2`: RSDP(v2)的虚拟地址
547eda31b2SLoGin     ///
557eda31b2SLoGin     ///
567eda31b2SLoGin     /// ## 参考资料
577eda31b2SLoGin     ///
587eda31b2SLoGin     /// https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/acpi/bus.c#1390
59cc5feaf6SJomo     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         }
68cc5feaf6SJomo         self.map_tables(rsdp_vaddr1, rsdp_vaddr2)?;
697eda31b2SLoGin         self.bus_init()?;
707eda31b2SLoGin         kinfo!("Acpi Manager initialized.");
717eda31b2SLoGin         return Ok(());
727eda31b2SLoGin     }
737eda31b2SLoGin 
74cc5feaf6SJomo     fn map_tables(&self, rsdp_vaddr1: u64, rsdp_vaddr2: u64) -> Result<(), SystemError> {
75cc5feaf6SJomo         let rsdp_paddr1 = Self::rsdp_paddr(rsdp_vaddr1);
76cc5feaf6SJomo         let res1 = unsafe { acpi::AcpiTables::from_rsdp(AcpiHandlerImpl, rsdp_paddr1.data()) };
77cc5feaf6SJomo         let e1;
78cc5feaf6SJomo         match res1 {
79cc5feaf6SJomo             // 如果rsdpv1能够获取到acpi_table,则就用该表,不用rsdpv2了
80cc5feaf6SJomo             Ok(acpi_table) => {
81cc5feaf6SJomo                 Self::set_acpi_table(acpi_table);
82cc5feaf6SJomo                 return Ok(());
83cc5feaf6SJomo             }
84cc5feaf6SJomo             Err(e) => {
85cc5feaf6SJomo                 e1 = e;
86cc5feaf6SJomo                 Self::drop_rsdp_tmp_box();
87cc5feaf6SJomo             }
88cc5feaf6SJomo         }
897ae679ddSLoGin 
90cc5feaf6SJomo         let rsdp_paddr2 = Self::rsdp_paddr(rsdp_vaddr2);
91cc5feaf6SJomo         let res2 = unsafe { acpi::AcpiTables::from_rsdp(AcpiHandlerImpl, rsdp_paddr2.data()) };
92cc5feaf6SJomo         match res2 {
93cc5feaf6SJomo             Ok(acpi_table) => {
94cc5feaf6SJomo                 Self::set_acpi_table(acpi_table);
95cc5feaf6SJomo             }
96cc5feaf6SJomo             // 如果rsdpv1和rsdpv2都无法获取到acpi_table,说明有问题,打印报错信息后进入死循环
97cc5feaf6SJomo             Err(e2) => {
98cc5feaf6SJomo                 kerror!("acpi_init(): failed to parse acpi tables, error: (rsdpv1: {:?}) or (rsdpv2: {:?})", e1, e2);
99cc5feaf6SJomo                 Self::drop_rsdp_tmp_box();
100cc5feaf6SJomo                 loop {
101cc5feaf6SJomo                     spin_loop();
102cc5feaf6SJomo                 }
103cc5feaf6SJomo             }
1047ae679ddSLoGin         }
1057eda31b2SLoGin 
1067eda31b2SLoGin         return Ok(());
1077ae679ddSLoGin     }
1087ae679ddSLoGin 
109cc5feaf6SJomo     /// 通过RSDP虚拟地址获取RSDP物理地址
110cc5feaf6SJomo     ///
111cc5feaf6SJomo     /// ## 参数
112cc5feaf6SJomo     ///
113cc5feaf6SJomo     /// - `rsdp_vaddr`: RSDP的虚拟地址
114cc5feaf6SJomo     ///
115cc5feaf6SJomo     /// ## 返回值
116cc5feaf6SJomo     ///
117cc5feaf6SJomo     /// RSDP物理地址
118cc5feaf6SJomo     fn rsdp_paddr(rsdp_vaddr: u64) -> PhysAddr {
119cc5feaf6SJomo         unsafe {
120cc5feaf6SJomo             RSDP_TMP_BOX = Some(AlignedBox::new_zeroed().expect("rs_acpi_init(): failed to alloc"))
121cc5feaf6SJomo         };
122cc5feaf6SJomo         let size = core::mem::size_of::<acpi::rsdp::Rsdp>();
123cc5feaf6SJomo         let tmp_data =
124cc5feaf6SJomo             unsafe { core::slice::from_raw_parts(rsdp_vaddr as usize as *const u8, size) };
125cc5feaf6SJomo         unsafe { RSDP_TMP_BOX.as_mut().unwrap()[0..size].copy_from_slice(tmp_data) };
126cc5feaf6SJomo         let rsdp_paddr = unsafe {
127cc5feaf6SJomo             MMArch::virt_2_phys(VirtAddr::new(
128cc5feaf6SJomo                 RSDP_TMP_BOX.as_ref().unwrap().as_ptr() as usize
129cc5feaf6SJomo             ))
130cc5feaf6SJomo             .unwrap()
131cc5feaf6SJomo         };
132cc5feaf6SJomo 
133cc5feaf6SJomo         return rsdp_paddr;
134cc5feaf6SJomo     }
135cc5feaf6SJomo 
136cc5feaf6SJomo     fn set_acpi_table(acpi_table: AcpiTables<AcpiHandlerImpl>) {
137cc5feaf6SJomo         unsafe {
138cc5feaf6SJomo             __ACPI_TABLE = Some(acpi_table);
139cc5feaf6SJomo         }
140cc5feaf6SJomo     }
141cc5feaf6SJomo 
142cc5feaf6SJomo     fn drop_rsdp_tmp_box() {
143cc5feaf6SJomo         unsafe {
144cc5feaf6SJomo             RSDP_TMP_BOX = None;
145cc5feaf6SJomo         }
146cc5feaf6SJomo     }
147cc5feaf6SJomo 
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