xref: /DragonOS/kernel/src/driver/acpi/mod.rs (revision cc5feaf67b914ecf701abcba70c01da149755491)
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