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)]
hotplug_kset() -> Arc<KSet>36 pub fn hotplug_kset() -> Arc<KSet> {
37 unsafe { __HOTPLUG_KSET_INSTANCE.clone().unwrap() }
38 }
39
40 #[inline(always)]
acpi_tables_kset() -> Arc<KSet>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)]
acpi_tables_data_kset() -> Arc<KSet>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)]
acpi_tables_dynamic_kset() -> Arc<KSet>53 pub fn acpi_tables_dynamic_kset() -> Arc<KSet> {
54 unsafe { __ACPI_TABLES_DYNAMIC_KSET_INSTANCE.clone().unwrap() }
55 }
56
57 #[inline(always)]
acpi_table_attr_list() -> &'static RwLock<Vec<Arc<AttrAcpiTable>>>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 {
acpi_sysfs_init(&self) -> Result<(), SystemError>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
acpi_tables_sysfs_init(&self) -> Result<(), SystemError>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
acpi_table_data_init(&self, _header: &SdtHeader) -> Result<(), SystemError>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 {
name(&self) -> &str133 fn name(&self) -> &str {
134 "force_remove"
135 }
136
mode(&self) -> ModeType137 fn mode(&self) -> ModeType {
138 SYSFS_ATTR_MODE_RO
139 }
140
support(&self) -> SysFSOpsSupport141 fn support(&self) -> SysFSOpsSupport {
142 return SysFSOpsSupport::ATTR_SHOW;
143 }
144
show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>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 {
new(header: &SdtHeader) -> Result<Arc<Self>, SystemError>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 {
show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError>208 fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
209 return Err(SystemError::ENOSYS);
210 }
211
store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError>212 fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
213 return Err(SystemError::ENOSYS);
214 }
215
name(&self) -> &str216 fn name(&self) -> &str {
217 return &self.filename;
218 }
219
mode(&self) -> ModeType220 fn mode(&self) -> ModeType {
221 return ModeType::from_bits_truncate(0o400);
222 }
223
support(&self) -> SysFSOpsSupport224 fn support(&self) -> SysFSOpsSupport {
225 return SysFSOpsSupport::empty();
226 }
227 }
228
229 impl BinAttribute for AttrAcpiTable {
support_battr(&self) -> SysFSOpsSupport230 fn support_battr(&self) -> SysFSOpsSupport {
231 return SysFSOpsSupport::BATTR_READ;
232 }
write( &self, _kobj: Arc<dyn KObject>, _buf: &[u8], _offset: usize, ) -> Result<usize, SystemError>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
read( &self, _kobj: Arc<dyn KObject>, buf: &mut [u8], offset: usize, ) -> Result<usize, SystemError>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
size(&self) -> usize509 fn size(&self) -> usize {
510 return self.size;
511 }
512 }
513