xref: /DragonOS/kernel/src/driver/acpi/sysfs.rs (revision 196b75dc17b5cc2ed84301bce776e496ddfe1ed1)
17eda31b2SLoGin use crate::{
27eda31b2SLoGin     driver::{
37eda31b2SLoGin         acpi::acpi_manager,
47eda31b2SLoGin         base::{kobject::KObject, kset::KSet},
57eda31b2SLoGin     },
67eda31b2SLoGin     filesystem::{
7*196b75dcSLoGin         sysfs::{
8*196b75dcSLoGin             file::sysfs_emit_str, sysfs_instance, Attribute, BinAttribute, SysFSOpsSupport,
9*196b75dcSLoGin             SYSFS_ATTR_MODE_RO,
10*196b75dcSLoGin         },
117eda31b2SLoGin         vfs::syscall::ModeType,
127eda31b2SLoGin     },
137eda31b2SLoGin     libs::rwlock::RwLock,
147eda31b2SLoGin };
1591e9d4abSLoGin use acpi::sdt::SdtHeader;
1691e9d4abSLoGin use alloc::{
1791e9d4abSLoGin     string::{String, ToString},
1891e9d4abSLoGin     sync::Arc,
1991e9d4abSLoGin     vec::Vec,
2091e9d4abSLoGin };
2191e9d4abSLoGin use system_error::SystemError;
227eda31b2SLoGin 
237eda31b2SLoGin use super::{acpi_kset, AcpiManager};
247eda31b2SLoGin 
257eda31b2SLoGin static mut __HOTPLUG_KSET_INSTANCE: Option<Arc<KSet>> = None;
267eda31b2SLoGin static mut __ACPI_TABLES_KSET_INSTANCE: Option<Arc<KSet>> = None;
277eda31b2SLoGin static mut __ACPI_TABLES_DATA_KSET_INSTANCE: Option<Arc<KSet>> = None;
287eda31b2SLoGin static mut __ACPI_TABLES_DYNAMIC_KSET_INSTANCE: Option<Arc<KSet>> = None;
297eda31b2SLoGin static mut __ACPI_TABLE_ATTR_LIST: Option<RwLock<Vec<Arc<AttrAcpiTable>>>> = None;
307eda31b2SLoGin 
317eda31b2SLoGin const ACPI_MAX_TABLE_INSTANCES: usize = 999;
327eda31b2SLoGin 
337eda31b2SLoGin #[inline(always)]
347eda31b2SLoGin #[allow(dead_code)]
357eda31b2SLoGin pub fn hotplug_kset() -> Arc<KSet> {
367eda31b2SLoGin     unsafe { __HOTPLUG_KSET_INSTANCE.clone().unwrap() }
377eda31b2SLoGin }
387eda31b2SLoGin 
397eda31b2SLoGin #[inline(always)]
407eda31b2SLoGin pub fn acpi_tables_kset() -> Arc<KSet> {
417eda31b2SLoGin     unsafe { __ACPI_TABLES_KSET_INSTANCE.clone().unwrap() }
427eda31b2SLoGin }
437eda31b2SLoGin 
447eda31b2SLoGin #[inline(always)]
457eda31b2SLoGin #[allow(dead_code)]
467eda31b2SLoGin pub fn acpi_tables_data_kset() -> Arc<KSet> {
477eda31b2SLoGin     unsafe { __ACPI_TABLES_DATA_KSET_INSTANCE.clone().unwrap() }
487eda31b2SLoGin }
497eda31b2SLoGin 
507eda31b2SLoGin #[inline(always)]
517eda31b2SLoGin #[allow(dead_code)]
527eda31b2SLoGin pub fn acpi_tables_dynamic_kset() -> Arc<KSet> {
537eda31b2SLoGin     unsafe { __ACPI_TABLES_DYNAMIC_KSET_INSTANCE.clone().unwrap() }
547eda31b2SLoGin }
557eda31b2SLoGin 
567eda31b2SLoGin #[inline(always)]
577eda31b2SLoGin fn acpi_table_attr_list() -> &'static RwLock<Vec<Arc<AttrAcpiTable>>> {
587eda31b2SLoGin     unsafe {
597eda31b2SLoGin         return __ACPI_TABLE_ATTR_LIST.as_ref().unwrap();
607eda31b2SLoGin     }
617eda31b2SLoGin }
627eda31b2SLoGin 
637eda31b2SLoGin impl AcpiManager {
647eda31b2SLoGin     pub(super) fn acpi_sysfs_init(&self) -> Result<(), SystemError> {
657eda31b2SLoGin         unsafe {
667eda31b2SLoGin             __ACPI_TABLE_ATTR_LIST = Some(RwLock::new(Vec::new()));
677eda31b2SLoGin         }
687eda31b2SLoGin         self.acpi_tables_sysfs_init()?;
697eda31b2SLoGin 
707eda31b2SLoGin         let hotplug_kset = KSet::new("hotplug".to_string());
717eda31b2SLoGin         hotplug_kset.register(Some(acpi_kset()))?;
727eda31b2SLoGin 
737eda31b2SLoGin         unsafe {
747eda31b2SLoGin             __HOTPLUG_KSET_INSTANCE = Some(hotplug_kset.clone());
757eda31b2SLoGin         }
767eda31b2SLoGin 
777eda31b2SLoGin         let hotplug_kobj = hotplug_kset as Arc<dyn KObject>;
787eda31b2SLoGin         sysfs_instance().create_file(&hotplug_kobj, &AttrForceRemove)?;
797eda31b2SLoGin 
807eda31b2SLoGin         return Ok(());
817eda31b2SLoGin     }
827eda31b2SLoGin 
837eda31b2SLoGin     /// 在 sysfs 中创建 ACPI 表目录
847eda31b2SLoGin     ///
85e7071df6SLoGin     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/acpi/sysfs.c?fi=acpi_sysfs_init#488
867eda31b2SLoGin     fn acpi_tables_sysfs_init(&self) -> Result<(), SystemError> {
877eda31b2SLoGin         // 创建 `/sys/firmware/acpi/tables` 目录
887eda31b2SLoGin         let acpi_tables_kset = KSet::new("tables".to_string());
897eda31b2SLoGin         acpi_tables_kset.register(Some(acpi_kset()))?;
907eda31b2SLoGin         unsafe {
917eda31b2SLoGin             __ACPI_TABLES_KSET_INSTANCE = Some(acpi_tables_kset.clone());
927eda31b2SLoGin         }
937eda31b2SLoGin 
947eda31b2SLoGin         // 创建 `/sys/firmware/acpi/tables/data` 目录
957eda31b2SLoGin         let acpi_tables_data_kset = KSet::new("data".to_string());
967eda31b2SLoGin         acpi_tables_data_kset.register(Some(acpi_tables_kset.clone()))?;
977eda31b2SLoGin         unsafe {
987eda31b2SLoGin             __ACPI_TABLES_DATA_KSET_INSTANCE = Some(acpi_tables_data_kset);
997eda31b2SLoGin         }
1007eda31b2SLoGin 
1017eda31b2SLoGin         // 创建 `/sys/firmware/acpi/tables/dynamic` 目录
1027eda31b2SLoGin         let acpi_tables_dynamic_kset = KSet::new("dynamic".to_string());
1037eda31b2SLoGin         acpi_tables_dynamic_kset.register(Some(acpi_tables_kset.clone()))?;
1047eda31b2SLoGin         unsafe {
1057eda31b2SLoGin             __ACPI_TABLES_DYNAMIC_KSET_INSTANCE = Some(acpi_tables_dynamic_kset);
1067eda31b2SLoGin         }
1077eda31b2SLoGin 
1087eda31b2SLoGin         // todo: get acpi tables.
1097eda31b2SLoGin         let tables = self.tables().unwrap();
1107eda31b2SLoGin         let headers = tables.headers();
1117eda31b2SLoGin         for header in headers {
1127eda31b2SLoGin             kdebug!("ACPI header: {:?}", header);
1137eda31b2SLoGin             let attr = AttrAcpiTable::new(&header)?;
1147eda31b2SLoGin             acpi_table_attr_list().write().push(attr);
1157eda31b2SLoGin             self.acpi_table_data_init(&header)?;
1167eda31b2SLoGin         }
1177eda31b2SLoGin 
1187eda31b2SLoGin         return Ok(());
1197eda31b2SLoGin     }
1207eda31b2SLoGin 
121e7071df6SLoGin     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/acpi/sysfs.c?fi=acpi_sysfs_init#469
1227eda31b2SLoGin     fn acpi_table_data_init(&self, _header: &SdtHeader) -> Result<(), SystemError> {
1237eda31b2SLoGin         // todo!("AcpiManager::acpi_table_data_init()")
1247eda31b2SLoGin         return Ok(());
1257eda31b2SLoGin     }
1267eda31b2SLoGin }
1277eda31b2SLoGin 
1287eda31b2SLoGin #[derive(Debug)]
1297eda31b2SLoGin struct AttrForceRemove;
1307eda31b2SLoGin 
1317eda31b2SLoGin impl Attribute for AttrForceRemove {
1327eda31b2SLoGin     fn name(&self) -> &str {
1337eda31b2SLoGin         "force_remove"
1347eda31b2SLoGin     }
1357eda31b2SLoGin 
1367eda31b2SLoGin     fn mode(&self) -> ModeType {
137*196b75dcSLoGin         SYSFS_ATTR_MODE_RO
1387eda31b2SLoGin     }
1397eda31b2SLoGin 
1407eda31b2SLoGin     fn support(&self) -> SysFSOpsSupport {
141*196b75dcSLoGin         return SysFSOpsSupport::ATTR_SHOW;
1427eda31b2SLoGin     }
1437eda31b2SLoGin 
1447eda31b2SLoGin     fn show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
1457eda31b2SLoGin         return sysfs_emit_str(buf, "0\n");
1467eda31b2SLoGin     }
1477eda31b2SLoGin }
1487eda31b2SLoGin 
1497eda31b2SLoGin /// ACPI 表在 sysfs 中的属性
1507eda31b2SLoGin #[derive(Debug)]
1517eda31b2SLoGin struct AttrAcpiTable {
1527eda31b2SLoGin     name: String,
1537eda31b2SLoGin     filename: String,
1547eda31b2SLoGin     instance: isize,
1557eda31b2SLoGin     size: usize,
1567eda31b2SLoGin }
1577eda31b2SLoGin 
1587eda31b2SLoGin impl AttrAcpiTable {
1597eda31b2SLoGin     pub fn new(header: &SdtHeader) -> Result<Arc<Self>, SystemError> {
1607eda31b2SLoGin         let mut r = Self {
1617eda31b2SLoGin             name: header.signature.to_string(),
1627eda31b2SLoGin             filename: "".to_string(),
1637eda31b2SLoGin             instance: 0,
1647eda31b2SLoGin             size: header.length as usize,
1657eda31b2SLoGin         };
1667eda31b2SLoGin 
1677eda31b2SLoGin         for attr in acpi_table_attr_list().read().iter() {
1687eda31b2SLoGin             if attr.name == r.name {
1697eda31b2SLoGin                 r.instance = attr.instance;
1707eda31b2SLoGin             }
1717eda31b2SLoGin         }
1727eda31b2SLoGin         // 将当前实例的序号加1
1737eda31b2SLoGin         r.instance += 1;
1747eda31b2SLoGin         if r.instance > ACPI_MAX_TABLE_INSTANCES as isize {
1757eda31b2SLoGin             kwarn!("too many table instances. name: {}", r.name);
1767eda31b2SLoGin             return Err(SystemError::ERANGE);
1777eda31b2SLoGin         }
1787eda31b2SLoGin 
1797eda31b2SLoGin         let mut has_multiple_instances: bool = false;
1807eda31b2SLoGin         let mut tmpcnt = 0;
1817eda31b2SLoGin         for h in acpi_manager().tables().unwrap().headers() {
1827eda31b2SLoGin             if h.signature == header.signature {
1837eda31b2SLoGin                 tmpcnt += 1;
1847eda31b2SLoGin                 if tmpcnt > 1 {
1857eda31b2SLoGin                     has_multiple_instances = true;
1867eda31b2SLoGin                     break;
1877eda31b2SLoGin                 }
1887eda31b2SLoGin             }
1897eda31b2SLoGin         }
1907eda31b2SLoGin 
1917eda31b2SLoGin         if r.instance > 1 || (r.instance == 1 && has_multiple_instances) {
1927eda31b2SLoGin             r.filename = format!("{}{}", r.name, r.instance);
1937eda31b2SLoGin         } else {
1947eda31b2SLoGin             r.filename = r.name.clone();
1957eda31b2SLoGin         }
1967eda31b2SLoGin 
1977eda31b2SLoGin         let result = Arc::new(r);
1987eda31b2SLoGin         sysfs_instance().create_bin_file(
1997eda31b2SLoGin             &(acpi_tables_kset() as Arc<dyn KObject>),
2007eda31b2SLoGin             &(result.clone() as Arc<dyn BinAttribute>),
2017eda31b2SLoGin         )?;
2027eda31b2SLoGin         return Ok(result);
2037eda31b2SLoGin     }
2047eda31b2SLoGin }
2057eda31b2SLoGin 
2067eda31b2SLoGin impl Attribute for AttrAcpiTable {
2077eda31b2SLoGin     fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
2087eda31b2SLoGin         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
2097eda31b2SLoGin     }
2107eda31b2SLoGin 
2117eda31b2SLoGin     fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
2127eda31b2SLoGin         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
2137eda31b2SLoGin     }
2147eda31b2SLoGin 
2157eda31b2SLoGin     fn name(&self) -> &str {
2167eda31b2SLoGin         return &self.filename;
2177eda31b2SLoGin     }
2187eda31b2SLoGin 
2197eda31b2SLoGin     fn mode(&self) -> ModeType {
2207eda31b2SLoGin         return ModeType::from_bits_truncate(0o400);
2217eda31b2SLoGin     }
2227eda31b2SLoGin 
2237eda31b2SLoGin     fn support(&self) -> SysFSOpsSupport {
2247eda31b2SLoGin         return SysFSOpsSupport::empty();
2257eda31b2SLoGin     }
2267eda31b2SLoGin }
2277eda31b2SLoGin 
2287eda31b2SLoGin impl BinAttribute for AttrAcpiTable {
2297eda31b2SLoGin     fn support_battr(&self) -> SysFSOpsSupport {
230*196b75dcSLoGin         return SysFSOpsSupport::BATTR_READ;
2317eda31b2SLoGin     }
2327eda31b2SLoGin     fn write(
2337eda31b2SLoGin         &self,
2347eda31b2SLoGin         _kobj: Arc<dyn KObject>,
2357eda31b2SLoGin         _buf: &[u8],
2367eda31b2SLoGin         _offset: usize,
2377eda31b2SLoGin     ) -> Result<usize, SystemError> {
2387eda31b2SLoGin         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
2397eda31b2SLoGin     }
2407eda31b2SLoGin 
2417eda31b2SLoGin     /// 展示 ACPI 表的内容
2427eda31b2SLoGin     ///
243e7071df6SLoGin     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/acpi/sysfs.c?fi=acpi_sysfs_init#320
2447eda31b2SLoGin     fn read(
2457eda31b2SLoGin         &self,
2467eda31b2SLoGin         _kobj: Arc<dyn KObject>,
2477eda31b2SLoGin         buf: &mut [u8],
2487eda31b2SLoGin         offset: usize,
2497eda31b2SLoGin     ) -> Result<usize, SystemError> {
2507eda31b2SLoGin         macro_rules! copy_data {
2517eda31b2SLoGin             ($table:expr) => {
2527eda31b2SLoGin                 let from = unsafe {
2537eda31b2SLoGin                     core::slice::from_raw_parts(
2547eda31b2SLoGin                         $table.virtual_start().as_ptr() as *const u8,
2557eda31b2SLoGin                         $table.region_length(),
2567eda31b2SLoGin                     )
2577eda31b2SLoGin                 };
2587eda31b2SLoGin                 if offset >= from.len() {
2597eda31b2SLoGin                     return Ok(0);
2607eda31b2SLoGin                 }
2617eda31b2SLoGin                 let mut count = buf.len();
2627eda31b2SLoGin                 if count > from.len() - offset {
2637eda31b2SLoGin                     count = from.len() - offset;
2647eda31b2SLoGin                 }
2657eda31b2SLoGin                 buf[0..count].copy_from_slice(&from[offset..offset + count]);
2667eda31b2SLoGin                 return Ok(count);
2677eda31b2SLoGin             };
2687eda31b2SLoGin         }
2697eda31b2SLoGin 
2707eda31b2SLoGin         macro_rules! define_struct {
2717eda31b2SLoGin             ($name:ident) => {
2727eda31b2SLoGin                 #[repr(transparent)]
2737eda31b2SLoGin                 #[allow(non_snake_case)]
2747eda31b2SLoGin                 #[allow(non_camel_case_types)]
2757eda31b2SLoGin                 struct $name {
2767eda31b2SLoGin                     header: SdtHeader,
2777eda31b2SLoGin                 }
2787eda31b2SLoGin 
2797eda31b2SLoGin                 unsafe impl acpi::AcpiTable for $name {
2807eda31b2SLoGin                     const SIGNATURE: acpi::sdt::Signature = acpi::sdt::Signature::$name;
2817eda31b2SLoGin                     fn header(&self) -> &acpi::sdt::SdtHeader {
2827eda31b2SLoGin                         return &self.header;
2837eda31b2SLoGin                     }
2847eda31b2SLoGin                 }
2857eda31b2SLoGin             };
2867eda31b2SLoGin         }
2877eda31b2SLoGin 
2887eda31b2SLoGin         macro_rules! handle {
2897eda31b2SLoGin             ($name: ident, $tables: expr) => {
2907eda31b2SLoGin                 define_struct!($name);
2917eda31b2SLoGin                 let table = $tables.find_entire_table::<$name>().map_err(|e| {
2927eda31b2SLoGin                     kwarn!(
2937eda31b2SLoGin                         "AttrAcpiTable::read(): failed to find table. name: {}, error: {:?}",
2947eda31b2SLoGin                         self.name,
2957eda31b2SLoGin                         e
2967eda31b2SLoGin                     );
2977eda31b2SLoGin                     SystemError::ENODEV
2987eda31b2SLoGin                 })?;
2997eda31b2SLoGin 
3007eda31b2SLoGin                 copy_data!(table);
3017eda31b2SLoGin             };
3027eda31b2SLoGin         }
3037eda31b2SLoGin 
3047eda31b2SLoGin         let tables = acpi_manager().tables().unwrap();
3057eda31b2SLoGin         match self.name.as_str() {
3067eda31b2SLoGin             "RSDT" => {
3077eda31b2SLoGin                 handle!(RSDT, tables);
3087eda31b2SLoGin             }
3097eda31b2SLoGin             "XSDT" => {
3107eda31b2SLoGin                 handle!(XSDT, tables);
3117eda31b2SLoGin             }
3127eda31b2SLoGin             "FACP" => {
3137eda31b2SLoGin                 handle!(FADT, tables);
3147eda31b2SLoGin             }
3157eda31b2SLoGin             "HPET" => {
3167eda31b2SLoGin                 handle!(HPET, tables);
3177eda31b2SLoGin             }
3187eda31b2SLoGin             "APIC" => {
3197eda31b2SLoGin                 handle!(MADT, tables);
3207eda31b2SLoGin             }
3217eda31b2SLoGin             "MCFG" => {
3227eda31b2SLoGin                 handle!(MCFG, tables);
3237eda31b2SLoGin             }
3247eda31b2SLoGin             "SSDT" => {
3257eda31b2SLoGin                 handle!(SSDT, tables);
3267eda31b2SLoGin             }
3277eda31b2SLoGin             "BERT" => {
3287eda31b2SLoGin                 handle!(BERT, tables);
3297eda31b2SLoGin             }
3307eda31b2SLoGin             "BGRT" => {
3317eda31b2SLoGin                 handle!(BGRT, tables);
3327eda31b2SLoGin             }
3337eda31b2SLoGin             "CPEP" => {
3347eda31b2SLoGin                 handle!(CPEP, tables);
3357eda31b2SLoGin             }
3367eda31b2SLoGin             "DSDT" => {
3377eda31b2SLoGin                 handle!(DSDT, tables);
3387eda31b2SLoGin             }
3397eda31b2SLoGin             "ECDT" => {
3407eda31b2SLoGin                 handle!(ECDT, tables);
3417eda31b2SLoGin             }
3427eda31b2SLoGin             "EINJ" => {
3437eda31b2SLoGin                 handle!(EINJ, tables);
3447eda31b2SLoGin             }
3457eda31b2SLoGin             "ERST" => {
3467eda31b2SLoGin                 handle!(ERST, tables);
3477eda31b2SLoGin             }
3487eda31b2SLoGin             "FACS" => {
3497eda31b2SLoGin                 handle!(FACS, tables);
3507eda31b2SLoGin             }
3517eda31b2SLoGin             "FPDT" => {
3527eda31b2SLoGin                 handle!(FPDT, tables);
3537eda31b2SLoGin             }
3547eda31b2SLoGin             "GTDT" => {
3557eda31b2SLoGin                 handle!(GTDT, tables);
3567eda31b2SLoGin             }
3577eda31b2SLoGin             "HEST" => {
3587eda31b2SLoGin                 handle!(HEST, tables);
3597eda31b2SLoGin             }
3607eda31b2SLoGin             "MSCT" => {
3617eda31b2SLoGin                 handle!(MSCT, tables);
3627eda31b2SLoGin             }
3637eda31b2SLoGin             "MPST" => {
3647eda31b2SLoGin                 handle!(MPST, tables);
3657eda31b2SLoGin             }
3667eda31b2SLoGin             "NFIT" => {
3677eda31b2SLoGin                 handle!(NFIT, tables);
3687eda31b2SLoGin             }
3697eda31b2SLoGin             "PCCT" => {
3707eda31b2SLoGin                 handle!(PCCT, tables);
3717eda31b2SLoGin             }
3727eda31b2SLoGin             "PHAT" => {
3737eda31b2SLoGin                 handle!(PHAT, tables);
3747eda31b2SLoGin             }
3757eda31b2SLoGin             "PMTT" => {
3767eda31b2SLoGin                 handle!(PMTT, tables);
3777eda31b2SLoGin             }
3787eda31b2SLoGin             "PSDT" => {
3797eda31b2SLoGin                 handle!(PSDT, tables);
3807eda31b2SLoGin             }
3817eda31b2SLoGin             "RASF" => {
3827eda31b2SLoGin                 handle!(RASF, tables);
3837eda31b2SLoGin             }
3847eda31b2SLoGin             "SBST" => {
3857eda31b2SLoGin                 handle!(SBST, tables);
3867eda31b2SLoGin             }
3877eda31b2SLoGin             "SDEV" => {
3887eda31b2SLoGin                 handle!(SDEV, tables);
3897eda31b2SLoGin             }
3907eda31b2SLoGin             "SLIT" => {
3917eda31b2SLoGin                 handle!(SLIT, tables);
3927eda31b2SLoGin             }
3937eda31b2SLoGin             "SRAT" => {
3947eda31b2SLoGin                 handle!(SRAT, tables);
3957eda31b2SLoGin             }
3967eda31b2SLoGin             "AEST" => {
3977eda31b2SLoGin                 handle!(AEST, tables);
3987eda31b2SLoGin             }
3997eda31b2SLoGin             "BDAT" => {
4007eda31b2SLoGin                 handle!(BDAT, tables);
4017eda31b2SLoGin             }
4027eda31b2SLoGin             "CDIT" => {
4037eda31b2SLoGin                 handle!(CDIT, tables);
4047eda31b2SLoGin             }
4057eda31b2SLoGin             "CEDT" => {
4067eda31b2SLoGin                 handle!(CEDT, tables);
4077eda31b2SLoGin             }
4087eda31b2SLoGin             "CRAT" => {
4097eda31b2SLoGin                 handle!(CRAT, tables);
4107eda31b2SLoGin             }
4117eda31b2SLoGin             "CSRT" => {
4127eda31b2SLoGin                 handle!(CSRT, tables);
4137eda31b2SLoGin             }
4147eda31b2SLoGin             "DBGP" => {
4157eda31b2SLoGin                 handle!(DBGP, tables);
4167eda31b2SLoGin             }
4177eda31b2SLoGin             "DBG2" => {
4187eda31b2SLoGin                 handle!(DBG2, tables);
4197eda31b2SLoGin             }
4207eda31b2SLoGin             "DMAR" => {
4217eda31b2SLoGin                 handle!(DMAR, tables);
4227eda31b2SLoGin             }
4237eda31b2SLoGin             "DRTM" => {
4247eda31b2SLoGin                 handle!(DRTM, tables);
4257eda31b2SLoGin             }
4267eda31b2SLoGin             "ETDT" => {
4277eda31b2SLoGin                 handle!(ETDT, tables);
4287eda31b2SLoGin             }
4297eda31b2SLoGin             "IBFT" => {
4307eda31b2SLoGin                 handle!(IBFT, tables);
4317eda31b2SLoGin             }
4327eda31b2SLoGin             "IORT" => {
4337eda31b2SLoGin                 handle!(IORT, tables);
4347eda31b2SLoGin             }
4357eda31b2SLoGin             "IVRS" => {
4367eda31b2SLoGin                 handle!(IVRS, tables);
4377eda31b2SLoGin             }
4387eda31b2SLoGin             "LPIT" => {
4397eda31b2SLoGin                 handle!(LPIT, tables);
4407eda31b2SLoGin             }
4417eda31b2SLoGin             "MCHI" => {
4427eda31b2SLoGin                 handle!(MCHI, tables);
4437eda31b2SLoGin             }
4447eda31b2SLoGin             "MPAM" => {
4457eda31b2SLoGin                 handle!(MPAM, tables);
4467eda31b2SLoGin             }
4477eda31b2SLoGin             "MSDM" => {
4487eda31b2SLoGin                 handle!(MSDM, tables);
4497eda31b2SLoGin             }
4507eda31b2SLoGin             "PRMT" => {
4517eda31b2SLoGin                 handle!(PRMT, tables);
4527eda31b2SLoGin             }
4537eda31b2SLoGin             "RGRT" => {
4547eda31b2SLoGin                 handle!(RGRT, tables);
4557eda31b2SLoGin             }
4567eda31b2SLoGin             "SDEI" => {
4577eda31b2SLoGin                 handle!(SDEI, tables);
4587eda31b2SLoGin             }
4597eda31b2SLoGin             "SLIC" => {
4607eda31b2SLoGin                 handle!(SLIC, tables);
4617eda31b2SLoGin             }
4627eda31b2SLoGin             "SPCR" => {
4637eda31b2SLoGin                 handle!(SPCR, tables);
4647eda31b2SLoGin             }
4657eda31b2SLoGin             "SPMI" => {
4667eda31b2SLoGin                 handle!(SPMI, tables);
4677eda31b2SLoGin             }
4687eda31b2SLoGin             "STAO" => {
4697eda31b2SLoGin                 handle!(STAO, tables);
4707eda31b2SLoGin             }
4717eda31b2SLoGin             "SVKL" => {
4727eda31b2SLoGin                 handle!(SVKL, tables);
4737eda31b2SLoGin             }
4747eda31b2SLoGin             "TCPA" => {
4757eda31b2SLoGin                 handle!(TCPA, tables);
4767eda31b2SLoGin             }
4777eda31b2SLoGin             "TPM2" => {
4787eda31b2SLoGin                 handle!(TPM2, tables);
4797eda31b2SLoGin             }
4807eda31b2SLoGin             "UEFI" => {
4817eda31b2SLoGin                 handle!(UEFI, tables);
4827eda31b2SLoGin             }
4837eda31b2SLoGin             "WAET" => {
4847eda31b2SLoGin                 handle!(WAET, tables);
4857eda31b2SLoGin             }
4867eda31b2SLoGin             "WDAT" => {
4877eda31b2SLoGin                 handle!(WDAT, tables);
4887eda31b2SLoGin             }
4897eda31b2SLoGin             "WDRT" => {
4907eda31b2SLoGin                 handle!(WDRT, tables);
4917eda31b2SLoGin             }
4927eda31b2SLoGin             "WPBT" => {
4937eda31b2SLoGin                 handle!(WPBT, tables);
4947eda31b2SLoGin             }
4957eda31b2SLoGin             "WSMT" => {
4967eda31b2SLoGin                 handle!(WSMT, tables);
4977eda31b2SLoGin             }
4987eda31b2SLoGin             "XENV" => {
4997eda31b2SLoGin                 handle!(XENV, tables);
5007eda31b2SLoGin             }
5017eda31b2SLoGin 
5027eda31b2SLoGin             _ => {
5037eda31b2SLoGin                 kerror!("AttrAcpiTable::read(): unknown table. name: {}", self.name);
5047eda31b2SLoGin                 return Err(SystemError::ENODEV);
5057eda31b2SLoGin             }
5067eda31b2SLoGin         };
5077eda31b2SLoGin     }
5087eda31b2SLoGin 
5097eda31b2SLoGin     fn size(&self) -> usize {
5107eda31b2SLoGin         return self.size;
5117eda31b2SLoGin     }
5127eda31b2SLoGin }
513