xref: /DragonOS/kernel/src/driver/acpi/mod.rs (revision 7eda31b2f07c6ef41dc0d2bd13051f0fce5e5976)
17ae679ddSLoGin use core::{fmt::Debug, ptr::NonNull};
27ae679ddSLoGin 
37ae679ddSLoGin use acpi::AcpiHandler;
4*7eda31b2SLoGin use alloc::{string::ToString, sync::Arc};
57ae679ddSLoGin 
67ae679ddSLoGin use crate::{
7*7eda31b2SLoGin     driver::base::firmware::sys_firmware_kset,
87ae679ddSLoGin     kinfo,
9*7eda31b2SLoGin     libs::align::{page_align_down, page_align_up},
107ae679ddSLoGin     mm::{
117ae679ddSLoGin         mmio_buddy::{mmio_pool, MMIOSpaceGuard},
127ae679ddSLoGin         PhysAddr, VirtAddr,
137ae679ddSLoGin     },
14*7eda31b2SLoGin     syscall::SystemError,
157ae679ddSLoGin };
167ae679ddSLoGin 
17*7eda31b2SLoGin use super::base::kset::KSet;
18*7eda31b2SLoGin 
19*7eda31b2SLoGin extern crate acpi;
20*7eda31b2SLoGin 
21a03c4f9dSLoGin pub mod bus;
227ae679ddSLoGin mod c_adapter;
2306d5e247SLoGin pub mod glue;
247ae679ddSLoGin pub mod old;
25*7eda31b2SLoGin mod sysfs;
267ae679ddSLoGin 
277ae679ddSLoGin static mut __ACPI_TABLE: Option<acpi::AcpiTables<AcpiHandlerImpl>> = None;
28*7eda31b2SLoGin /// `/sys/firmware/acpi`的kset
29*7eda31b2SLoGin static mut ACPI_KSET_INSTANCE: Option<Arc<KSet>> = None;
307ae679ddSLoGin 
31a03c4f9dSLoGin #[inline(always)]
32a03c4f9dSLoGin pub fn acpi_manager() -> &'static AcpiManager {
33a03c4f9dSLoGin     &AcpiManager
34a03c4f9dSLoGin }
35a03c4f9dSLoGin 
36*7eda31b2SLoGin #[inline(always)]
37*7eda31b2SLoGin pub fn acpi_kset() -> Arc<KSet> {
38*7eda31b2SLoGin     unsafe { ACPI_KSET_INSTANCE.clone().unwrap() }
39*7eda31b2SLoGin }
40*7eda31b2SLoGin 
417ae679ddSLoGin #[derive(Debug)]
427ae679ddSLoGin pub struct AcpiManager;
437ae679ddSLoGin 
447ae679ddSLoGin impl AcpiManager {
45*7eda31b2SLoGin     /// 初始化ACPI
46*7eda31b2SLoGin     ///
47*7eda31b2SLoGin     /// ## 参数
48*7eda31b2SLoGin     ///
49*7eda31b2SLoGin     /// - `rsdp_paddr`: RSDP的物理地址
50*7eda31b2SLoGin     ///
51*7eda31b2SLoGin     ///
52*7eda31b2SLoGin     /// ## 参考资料
53*7eda31b2SLoGin     ///
54*7eda31b2SLoGin     /// https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/acpi/bus.c#1390
55*7eda31b2SLoGin     pub fn init(&self, rsdp_paddr: PhysAddr) -> Result<(), SystemError> {
567ae679ddSLoGin         kinfo!("Initializing Acpi Manager...");
57*7eda31b2SLoGin 
58*7eda31b2SLoGin         // 初始化`/sys/firmware/acpi`的kset
59*7eda31b2SLoGin         let kset = KSet::new("acpi".to_string());
60*7eda31b2SLoGin         kset.register(Some(sys_firmware_kset()))?;
61*7eda31b2SLoGin         unsafe {
62*7eda31b2SLoGin             ACPI_KSET_INSTANCE = Some(kset.clone());
63*7eda31b2SLoGin         }
64*7eda31b2SLoGin         self.map_tables(rsdp_paddr)?;
65*7eda31b2SLoGin         self.bus_init()?;
66*7eda31b2SLoGin         kinfo!("Acpi Manager initialized.");
67*7eda31b2SLoGin         return Ok(());
68*7eda31b2SLoGin     }
69*7eda31b2SLoGin 
70*7eda31b2SLoGin     fn map_tables(&self, rsdp_paddr: PhysAddr) -> Result<(), SystemError> {
717ae679ddSLoGin         let acpi_table: acpi::AcpiTables<AcpiHandlerImpl> =
72*7eda31b2SLoGin             unsafe { acpi::AcpiTables::from_rsdp(AcpiHandlerImpl, rsdp_paddr.data()) }.map_err(
73*7eda31b2SLoGin                 |e| {
74*7eda31b2SLoGin                     kerror!("acpi_init(): failed to parse acpi tables, error: {:?}", e);
75*7eda31b2SLoGin                     SystemError::ENOMEM
76*7eda31b2SLoGin                 },
77*7eda31b2SLoGin             )?;
787ae679ddSLoGin 
797ae679ddSLoGin         unsafe {
807ae679ddSLoGin             __ACPI_TABLE = Some(acpi_table);
817ae679ddSLoGin         }
82*7eda31b2SLoGin 
83*7eda31b2SLoGin         return Ok(());
847ae679ddSLoGin     }
857ae679ddSLoGin 
867ae679ddSLoGin     #[allow(dead_code)]
87*7eda31b2SLoGin     pub fn tables(&self) -> Option<&'static acpi::AcpiTables<AcpiHandlerImpl>> {
887ae679ddSLoGin         unsafe { __ACPI_TABLE.as_ref() }
897ae679ddSLoGin     }
907ae679ddSLoGin }
917ae679ddSLoGin 
927ae679ddSLoGin #[derive(Debug, Clone, Copy)]
937ae679ddSLoGin pub struct AcpiHandlerImpl;
947ae679ddSLoGin 
957ae679ddSLoGin impl AcpiHandler for AcpiHandlerImpl {
967ae679ddSLoGin     unsafe fn map_physical_region<T>(
977ae679ddSLoGin         &self,
987ae679ddSLoGin         physical_address: usize,
997ae679ddSLoGin         size: usize,
1007ae679ddSLoGin     ) -> acpi::PhysicalMapping<Self, T> {
1017ae679ddSLoGin         let offset = physical_address - page_align_down(physical_address);
1027ae679ddSLoGin         let size_fix = page_align_up(size + offset);
1037ae679ddSLoGin 
1047ae679ddSLoGin         let mmio_guard = mmio_pool()
1057ae679ddSLoGin             .create_mmio(size_fix)
1067ae679ddSLoGin             .expect("AcpiHandlerImpl::map_physical_region(): failed to create mmio");
1077ae679ddSLoGin 
1087ae679ddSLoGin         mmio_guard
1097ae679ddSLoGin             .map_phys(PhysAddr::new(page_align_down(physical_address)), size_fix)
1107ae679ddSLoGin             .expect("AcpiHandlerImpl::map_physical_region(): failed to map phys");
1117ae679ddSLoGin         let virtual_start = mmio_guard.vaddr().data() + offset;
1127ae679ddSLoGin 
1137ae679ddSLoGin         let virtual_start = NonNull::new(virtual_start as *mut T).unwrap();
1147ae679ddSLoGin 
1157ae679ddSLoGin         let result: acpi::PhysicalMapping<AcpiHandlerImpl, T> = acpi::PhysicalMapping::new(
1167ae679ddSLoGin             physical_address,
1177ae679ddSLoGin             virtual_start,
1187ae679ddSLoGin             size,
1197ae679ddSLoGin             mmio_guard.size(),
1207ae679ddSLoGin             AcpiHandlerImpl,
1217ae679ddSLoGin         );
1227ae679ddSLoGin 
1237ae679ddSLoGin         MMIOSpaceGuard::leak(mmio_guard);
1247ae679ddSLoGin 
1257ae679ddSLoGin         return result;
1267ae679ddSLoGin     }
1277ae679ddSLoGin 
1287ae679ddSLoGin     fn unmap_physical_region<T>(region: &acpi::PhysicalMapping<Self, T>) {
1297ae679ddSLoGin         let mmio_guard = unsafe {
1307ae679ddSLoGin             MMIOSpaceGuard::from_raw(
1317ae679ddSLoGin                 VirtAddr::new(page_align_down(
1327ae679ddSLoGin                     region.virtual_start().as_ref() as *const T as usize
1337ae679ddSLoGin                 )),
1347ae679ddSLoGin                 region.mapped_length(),
1357ae679ddSLoGin                 true,
1367ae679ddSLoGin             )
1377ae679ddSLoGin         };
1387ae679ddSLoGin         drop(mmio_guard);
1397ae679ddSLoGin     }
1407ae679ddSLoGin }
141