xref: /DragonOS/kernel/src/driver/acpi/sysfs.rs (revision c635d8a9cfe25bc11779f323ef0c7d7a0f597d4a)
1 use crate::{
2     driver::{
3         acpi::acpi_manager,
4         base::{kobject::KObject, kset::KSet},
5     },
6     filesystem::{
7         sysfs::{
8             file::sysfs_emit_str, sysfs_instance, Attribute, BinAttribute, SysFSOpsSupport,
9             SYSFS_ATTR_MODE_RO,
10         },
11         vfs::syscall::ModeType,
12     },
13     libs::rwlock::RwLock,
14 };
15 use acpi::sdt::SdtHeader;
16 use alloc::{
17     string::{String, ToString},
18     sync::Arc,
19     vec::Vec,
20 };
21 use log::{debug, error, warn};
22 use system_error::SystemError;
23 
24 use super::{acpi_kset, AcpiManager};
25 
26 static mut __HOTPLUG_KSET_INSTANCE: Option<Arc<KSet>> = None;
27 static mut __ACPI_TABLES_KSET_INSTANCE: Option<Arc<KSet>> = None;
28 static mut __ACPI_TABLES_DATA_KSET_INSTANCE: Option<Arc<KSet>> = None;
29 static mut __ACPI_TABLES_DYNAMIC_KSET_INSTANCE: Option<Arc<KSet>> = None;
30 static mut __ACPI_TABLE_ATTR_LIST: Option<RwLock<Vec<Arc<AttrAcpiTable>>>> = None;
31 
32 const ACPI_MAX_TABLE_INSTANCES: usize = 999;
33 
34 #[inline(always)]
35 #[allow(dead_code)]
36 pub fn hotplug_kset() -> Arc<KSet> {
37     unsafe { __HOTPLUG_KSET_INSTANCE.clone().unwrap() }
38 }
39 
40 #[inline(always)]
41 pub fn acpi_tables_kset() -> Arc<KSet> {
42     unsafe { __ACPI_TABLES_KSET_INSTANCE.clone().unwrap() }
43 }
44 
45 #[inline(always)]
46 #[allow(dead_code)]
47 pub fn acpi_tables_data_kset() -> Arc<KSet> {
48     unsafe { __ACPI_TABLES_DATA_KSET_INSTANCE.clone().unwrap() }
49 }
50 
51 #[inline(always)]
52 #[allow(dead_code)]
53 pub fn acpi_tables_dynamic_kset() -> Arc<KSet> {
54     unsafe { __ACPI_TABLES_DYNAMIC_KSET_INSTANCE.clone().unwrap() }
55 }
56 
57 #[inline(always)]
58 fn acpi_table_attr_list() -> &'static RwLock<Vec<Arc<AttrAcpiTable>>> {
59     unsafe {
60         return __ACPI_TABLE_ATTR_LIST.as_ref().unwrap();
61     }
62 }
63 
64 impl AcpiManager {
65     pub(super) fn acpi_sysfs_init(&self) -> Result<(), SystemError> {
66         unsafe {
67             __ACPI_TABLE_ATTR_LIST = Some(RwLock::new(Vec::new()));
68         }
69         self.acpi_tables_sysfs_init()?;
70 
71         let hotplug_kset = KSet::new("hotplug".to_string());
72         hotplug_kset.register(Some(acpi_kset()))?;
73 
74         unsafe {
75             __HOTPLUG_KSET_INSTANCE = Some(hotplug_kset.clone());
76         }
77 
78         let hotplug_kobj = hotplug_kset as Arc<dyn KObject>;
79         sysfs_instance().create_file(&hotplug_kobj, &AttrForceRemove)?;
80 
81         return Ok(());
82     }
83 
84     /// 在 sysfs 中创建 ACPI 表目录
85     ///
86     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/acpi/sysfs.c?fi=acpi_sysfs_init#488
87     fn acpi_tables_sysfs_init(&self) -> Result<(), SystemError> {
88         // 创建 `/sys/firmware/acpi/tables` 目录
89         let acpi_tables_kset = KSet::new("tables".to_string());
90         acpi_tables_kset.register(Some(acpi_kset()))?;
91         unsafe {
92             __ACPI_TABLES_KSET_INSTANCE = Some(acpi_tables_kset.clone());
93         }
94 
95         // 创建 `/sys/firmware/acpi/tables/data` 目录
96         let acpi_tables_data_kset = KSet::new("data".to_string());
97         acpi_tables_data_kset.register(Some(acpi_tables_kset.clone()))?;
98         unsafe {
99             __ACPI_TABLES_DATA_KSET_INSTANCE = Some(acpi_tables_data_kset);
100         }
101 
102         // 创建 `/sys/firmware/acpi/tables/dynamic` 目录
103         let acpi_tables_dynamic_kset = KSet::new("dynamic".to_string());
104         acpi_tables_dynamic_kset.register(Some(acpi_tables_kset.clone()))?;
105         unsafe {
106             __ACPI_TABLES_DYNAMIC_KSET_INSTANCE = Some(acpi_tables_dynamic_kset);
107         }
108 
109         // todo: get acpi tables.
110         let tables = self.tables().unwrap();
111         let headers = tables.headers();
112         for header in headers {
113             debug!("ACPI header: {:?}", header);
114             let attr = AttrAcpiTable::new(&header)?;
115             acpi_table_attr_list().write().push(attr);
116             self.acpi_table_data_init(&header)?;
117         }
118 
119         return Ok(());
120     }
121 
122     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/acpi/sysfs.c?fi=acpi_sysfs_init#469
123     fn acpi_table_data_init(&self, _header: &SdtHeader) -> Result<(), SystemError> {
124         // todo!("AcpiManager::acpi_table_data_init()")
125         return Ok(());
126     }
127 }
128 
129 #[derive(Debug)]
130 struct AttrForceRemove;
131 
132 impl Attribute for AttrForceRemove {
133     fn name(&self) -> &str {
134         "force_remove"
135     }
136 
137     fn mode(&self) -> ModeType {
138         SYSFS_ATTR_MODE_RO
139     }
140 
141     fn support(&self) -> SysFSOpsSupport {
142         return SysFSOpsSupport::ATTR_SHOW;
143     }
144 
145     fn show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
146         return sysfs_emit_str(buf, "0\n");
147     }
148 }
149 
150 /// ACPI 表在 sysfs 中的属性
151 #[derive(Debug)]
152 struct AttrAcpiTable {
153     name: String,
154     filename: String,
155     instance: isize,
156     size: usize,
157 }
158 
159 impl AttrAcpiTable {
160     pub fn new(header: &SdtHeader) -> Result<Arc<Self>, SystemError> {
161         let mut r = Self {
162             name: header.signature.to_string(),
163             filename: "".to_string(),
164             instance: 0,
165             size: header.length as usize,
166         };
167 
168         for attr in acpi_table_attr_list().read().iter() {
169             if attr.name == r.name {
170                 r.instance = attr.instance;
171             }
172         }
173         // 将当前实例的序号加1
174         r.instance += 1;
175         if r.instance > ACPI_MAX_TABLE_INSTANCES as isize {
176             warn!("too many table instances. name: {}", r.name);
177             return Err(SystemError::ERANGE);
178         }
179 
180         let mut has_multiple_instances: bool = false;
181         let mut tmpcnt = 0;
182         for h in acpi_manager().tables().unwrap().headers() {
183             if h.signature == header.signature {
184                 tmpcnt += 1;
185                 if tmpcnt > 1 {
186                     has_multiple_instances = true;
187                     break;
188                 }
189             }
190         }
191 
192         if r.instance > 1 || (r.instance == 1 && has_multiple_instances) {
193             r.filename = format!("{}{}", r.name, r.instance);
194         } else {
195             r.filename = r.name.clone();
196         }
197 
198         let result = Arc::new(r);
199         sysfs_instance().create_bin_file(
200             &(acpi_tables_kset() as Arc<dyn KObject>),
201             &(result.clone() as Arc<dyn BinAttribute>),
202         )?;
203         return Ok(result);
204     }
205 }
206 
207 impl Attribute for AttrAcpiTable {
208     fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
209         return Err(SystemError::ENOSYS);
210     }
211 
212     fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
213         return Err(SystemError::ENOSYS);
214     }
215 
216     fn name(&self) -> &str {
217         return &self.filename;
218     }
219 
220     fn mode(&self) -> ModeType {
221         return ModeType::from_bits_truncate(0o400);
222     }
223 
224     fn support(&self) -> SysFSOpsSupport {
225         return SysFSOpsSupport::empty();
226     }
227 }
228 
229 impl BinAttribute for AttrAcpiTable {
230     fn support_battr(&self) -> SysFSOpsSupport {
231         return SysFSOpsSupport::BATTR_READ;
232     }
233     fn write(
234         &self,
235         _kobj: Arc<dyn KObject>,
236         _buf: &[u8],
237         _offset: usize,
238     ) -> Result<usize, SystemError> {
239         return Err(SystemError::ENOSYS);
240     }
241 
242     /// 展示 ACPI 表的内容
243     ///
244     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/acpi/sysfs.c?fi=acpi_sysfs_init#320
245     fn read(
246         &self,
247         _kobj: Arc<dyn KObject>,
248         buf: &mut [u8],
249         offset: usize,
250     ) -> Result<usize, SystemError> {
251         macro_rules! copy_data {
252             ($table:expr) => {
253                 let from = unsafe {
254                     core::slice::from_raw_parts(
255                         $table.virtual_start().as_ptr() as *const u8,
256                         $table.region_length(),
257                     )
258                 };
259                 if offset >= from.len() {
260                     return Ok(0);
261                 }
262                 let mut count = buf.len();
263                 if count > from.len() - offset {
264                     count = from.len() - offset;
265                 }
266                 buf[0..count].copy_from_slice(&from[offset..offset + count]);
267                 return Ok(count);
268             };
269         }
270 
271         macro_rules! define_struct {
272             ($name:ident) => {
273                 #[repr(transparent)]
274                 #[allow(non_snake_case)]
275                 #[allow(non_camel_case_types)]
276                 struct $name {
277                     header: SdtHeader,
278                 }
279 
280                 unsafe impl acpi::AcpiTable for $name {
281                     const SIGNATURE: acpi::sdt::Signature = acpi::sdt::Signature::$name;
282                     fn header(&self) -> &acpi::sdt::SdtHeader {
283                         return &self.header;
284                     }
285                 }
286             };
287         }
288 
289         macro_rules! handle {
290             ($name: ident, $tables: expr) => {
291                 define_struct!($name);
292                 let table = $tables.find_entire_table::<$name>().map_err(|e| {
293                     warn!(
294                         "AttrAcpiTable::read(): failed to find table. name: {}, error: {:?}",
295                         self.name, e
296                     );
297                     SystemError::ENODEV
298                 })?;
299 
300                 copy_data!(table);
301             };
302         }
303 
304         let tables = acpi_manager().tables().unwrap();
305         match self.name.as_str() {
306             "RSDT" => {
307                 handle!(RSDT, tables);
308             }
309             "XSDT" => {
310                 handle!(XSDT, tables);
311             }
312             "FACP" => {
313                 handle!(FADT, tables);
314             }
315             "HPET" => {
316                 handle!(HPET, tables);
317             }
318             "APIC" => {
319                 handle!(MADT, tables);
320             }
321             "MCFG" => {
322                 handle!(MCFG, tables);
323             }
324             "SSDT" => {
325                 handle!(SSDT, tables);
326             }
327             "BERT" => {
328                 handle!(BERT, tables);
329             }
330             "BGRT" => {
331                 handle!(BGRT, tables);
332             }
333             "CPEP" => {
334                 handle!(CPEP, tables);
335             }
336             "DSDT" => {
337                 handle!(DSDT, tables);
338             }
339             "ECDT" => {
340                 handle!(ECDT, tables);
341             }
342             "EINJ" => {
343                 handle!(EINJ, tables);
344             }
345             "ERST" => {
346                 handle!(ERST, tables);
347             }
348             "FACS" => {
349                 handle!(FACS, tables);
350             }
351             "FPDT" => {
352                 handle!(FPDT, tables);
353             }
354             "GTDT" => {
355                 handle!(GTDT, tables);
356             }
357             "HEST" => {
358                 handle!(HEST, tables);
359             }
360             "MSCT" => {
361                 handle!(MSCT, tables);
362             }
363             "MPST" => {
364                 handle!(MPST, tables);
365             }
366             "NFIT" => {
367                 handle!(NFIT, tables);
368             }
369             "PCCT" => {
370                 handle!(PCCT, tables);
371             }
372             "PHAT" => {
373                 handle!(PHAT, tables);
374             }
375             "PMTT" => {
376                 handle!(PMTT, tables);
377             }
378             "PSDT" => {
379                 handle!(PSDT, tables);
380             }
381             "RASF" => {
382                 handle!(RASF, tables);
383             }
384             "SBST" => {
385                 handle!(SBST, tables);
386             }
387             "SDEV" => {
388                 handle!(SDEV, tables);
389             }
390             "SLIT" => {
391                 handle!(SLIT, tables);
392             }
393             "SRAT" => {
394                 handle!(SRAT, tables);
395             }
396             "AEST" => {
397                 handle!(AEST, tables);
398             }
399             "BDAT" => {
400                 handle!(BDAT, tables);
401             }
402             "CDIT" => {
403                 handle!(CDIT, tables);
404             }
405             "CEDT" => {
406                 handle!(CEDT, tables);
407             }
408             "CRAT" => {
409                 handle!(CRAT, tables);
410             }
411             "CSRT" => {
412                 handle!(CSRT, tables);
413             }
414             "DBGP" => {
415                 handle!(DBGP, tables);
416             }
417             "DBG2" => {
418                 handle!(DBG2, tables);
419             }
420             "DMAR" => {
421                 handle!(DMAR, tables);
422             }
423             "DRTM" => {
424                 handle!(DRTM, tables);
425             }
426             "ETDT" => {
427                 handle!(ETDT, tables);
428             }
429             "IBFT" => {
430                 handle!(IBFT, tables);
431             }
432             "IORT" => {
433                 handle!(IORT, tables);
434             }
435             "IVRS" => {
436                 handle!(IVRS, tables);
437             }
438             "LPIT" => {
439                 handle!(LPIT, tables);
440             }
441             "MCHI" => {
442                 handle!(MCHI, tables);
443             }
444             "MPAM" => {
445                 handle!(MPAM, tables);
446             }
447             "MSDM" => {
448                 handle!(MSDM, tables);
449             }
450             "PRMT" => {
451                 handle!(PRMT, tables);
452             }
453             "RGRT" => {
454                 handle!(RGRT, tables);
455             }
456             "SDEI" => {
457                 handle!(SDEI, tables);
458             }
459             "SLIC" => {
460                 handle!(SLIC, tables);
461             }
462             "SPCR" => {
463                 handle!(SPCR, tables);
464             }
465             "SPMI" => {
466                 handle!(SPMI, tables);
467             }
468             "STAO" => {
469                 handle!(STAO, tables);
470             }
471             "SVKL" => {
472                 handle!(SVKL, tables);
473             }
474             "TCPA" => {
475                 handle!(TCPA, tables);
476             }
477             "TPM2" => {
478                 handle!(TPM2, tables);
479             }
480             "UEFI" => {
481                 handle!(UEFI, tables);
482             }
483             "WAET" => {
484                 handle!(WAET, tables);
485             }
486             "WDAT" => {
487                 handle!(WDAT, tables);
488             }
489             "WDRT" => {
490                 handle!(WDRT, tables);
491             }
492             "WPBT" => {
493                 handle!(WPBT, tables);
494             }
495             "WSMT" => {
496                 handle!(WSMT, tables);
497             }
498             "XENV" => {
499                 handle!(XENV, tables);
500             }
501 
502             _ => {
503                 error!("AttrAcpiTable::read(): unknown table. name: {}", self.name);
504                 return Err(SystemError::ENODEV);
505             }
506         };
507     }
508 
509     fn size(&self) -> usize {
510         return self.size;
511     }
512 }
513