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 system_error::SystemError;
22
23 use super::{acpi_kset, AcpiManager};
24
25 static mut __HOTPLUG_KSET_INSTANCE: Option<Arc<KSet>> = None;
26 static mut __ACPI_TABLES_KSET_INSTANCE: Option<Arc<KSet>> = None;
27 static mut __ACPI_TABLES_DATA_KSET_INSTANCE: Option<Arc<KSet>> = None;
28 static mut __ACPI_TABLES_DYNAMIC_KSET_INSTANCE: Option<Arc<KSet>> = None;
29 static mut __ACPI_TABLE_ATTR_LIST: Option<RwLock<Vec<Arc<AttrAcpiTable>>>> = None;
30
31 const ACPI_MAX_TABLE_INSTANCES: usize = 999;
32
33 #[inline(always)]
34 #[allow(dead_code)]
hotplug_kset() -> Arc<KSet>35 pub fn hotplug_kset() -> Arc<KSet> {
36 unsafe { __HOTPLUG_KSET_INSTANCE.clone().unwrap() }
37 }
38
39 #[inline(always)]
acpi_tables_kset() -> Arc<KSet>40 pub fn acpi_tables_kset() -> Arc<KSet> {
41 unsafe { __ACPI_TABLES_KSET_INSTANCE.clone().unwrap() }
42 }
43
44 #[inline(always)]
45 #[allow(dead_code)]
acpi_tables_data_kset() -> Arc<KSet>46 pub fn acpi_tables_data_kset() -> Arc<KSet> {
47 unsafe { __ACPI_TABLES_DATA_KSET_INSTANCE.clone().unwrap() }
48 }
49
50 #[inline(always)]
51 #[allow(dead_code)]
acpi_tables_dynamic_kset() -> Arc<KSet>52 pub fn acpi_tables_dynamic_kset() -> Arc<KSet> {
53 unsafe { __ACPI_TABLES_DYNAMIC_KSET_INSTANCE.clone().unwrap() }
54 }
55
56 #[inline(always)]
acpi_table_attr_list() -> &'static RwLock<Vec<Arc<AttrAcpiTable>>>57 fn acpi_table_attr_list() -> &'static RwLock<Vec<Arc<AttrAcpiTable>>> {
58 unsafe {
59 return __ACPI_TABLE_ATTR_LIST.as_ref().unwrap();
60 }
61 }
62
63 impl AcpiManager {
acpi_sysfs_init(&self) -> Result<(), SystemError>64 pub(super) fn acpi_sysfs_init(&self) -> Result<(), SystemError> {
65 unsafe {
66 __ACPI_TABLE_ATTR_LIST = Some(RwLock::new(Vec::new()));
67 }
68 self.acpi_tables_sysfs_init()?;
69
70 let hotplug_kset = KSet::new("hotplug".to_string());
71 hotplug_kset.register(Some(acpi_kset()))?;
72
73 unsafe {
74 __HOTPLUG_KSET_INSTANCE = Some(hotplug_kset.clone());
75 }
76
77 let hotplug_kobj = hotplug_kset as Arc<dyn KObject>;
78 sysfs_instance().create_file(&hotplug_kobj, &AttrForceRemove)?;
79
80 return Ok(());
81 }
82
83 /// 在 sysfs 中创建 ACPI 表目录
84 ///
85 /// 参考 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>86 fn acpi_tables_sysfs_init(&self) -> Result<(), SystemError> {
87 // 创建 `/sys/firmware/acpi/tables` 目录
88 let acpi_tables_kset = KSet::new("tables".to_string());
89 acpi_tables_kset.register(Some(acpi_kset()))?;
90 unsafe {
91 __ACPI_TABLES_KSET_INSTANCE = Some(acpi_tables_kset.clone());
92 }
93
94 // 创建 `/sys/firmware/acpi/tables/data` 目录
95 let acpi_tables_data_kset = KSet::new("data".to_string());
96 acpi_tables_data_kset.register(Some(acpi_tables_kset.clone()))?;
97 unsafe {
98 __ACPI_TABLES_DATA_KSET_INSTANCE = Some(acpi_tables_data_kset);
99 }
100
101 // 创建 `/sys/firmware/acpi/tables/dynamic` 目录
102 let acpi_tables_dynamic_kset = KSet::new("dynamic".to_string());
103 acpi_tables_dynamic_kset.register(Some(acpi_tables_kset.clone()))?;
104 unsafe {
105 __ACPI_TABLES_DYNAMIC_KSET_INSTANCE = Some(acpi_tables_dynamic_kset);
106 }
107
108 // todo: get acpi tables.
109 let tables = self.tables().unwrap();
110 let headers = tables.headers();
111 for header in headers {
112 kdebug!("ACPI header: {:?}", header);
113 let attr = AttrAcpiTable::new(&header)?;
114 acpi_table_attr_list().write().push(attr);
115 self.acpi_table_data_init(&header)?;
116 }
117
118 return Ok(());
119 }
120
121 /// 参考 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>122 fn acpi_table_data_init(&self, _header: &SdtHeader) -> Result<(), SystemError> {
123 // todo!("AcpiManager::acpi_table_data_init()")
124 return Ok(());
125 }
126 }
127
128 #[derive(Debug)]
129 struct AttrForceRemove;
130
131 impl Attribute for AttrForceRemove {
name(&self) -> &str132 fn name(&self) -> &str {
133 "force_remove"
134 }
135
mode(&self) -> ModeType136 fn mode(&self) -> ModeType {
137 SYSFS_ATTR_MODE_RO
138 }
139
support(&self) -> SysFSOpsSupport140 fn support(&self) -> SysFSOpsSupport {
141 return SysFSOpsSupport::ATTR_SHOW;
142 }
143
show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>144 fn show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
145 return sysfs_emit_str(buf, "0\n");
146 }
147 }
148
149 /// ACPI 表在 sysfs 中的属性
150 #[derive(Debug)]
151 struct AttrAcpiTable {
152 name: String,
153 filename: String,
154 instance: isize,
155 size: usize,
156 }
157
158 impl AttrAcpiTable {
new(header: &SdtHeader) -> Result<Arc<Self>, SystemError>159 pub fn new(header: &SdtHeader) -> Result<Arc<Self>, SystemError> {
160 let mut r = Self {
161 name: header.signature.to_string(),
162 filename: "".to_string(),
163 instance: 0,
164 size: header.length as usize,
165 };
166
167 for attr in acpi_table_attr_list().read().iter() {
168 if attr.name == r.name {
169 r.instance = attr.instance;
170 }
171 }
172 // 将当前实例的序号加1
173 r.instance += 1;
174 if r.instance > ACPI_MAX_TABLE_INSTANCES as isize {
175 kwarn!("too many table instances. name: {}", r.name);
176 return Err(SystemError::ERANGE);
177 }
178
179 let mut has_multiple_instances: bool = false;
180 let mut tmpcnt = 0;
181 for h in acpi_manager().tables().unwrap().headers() {
182 if h.signature == header.signature {
183 tmpcnt += 1;
184 if tmpcnt > 1 {
185 has_multiple_instances = true;
186 break;
187 }
188 }
189 }
190
191 if r.instance > 1 || (r.instance == 1 && has_multiple_instances) {
192 r.filename = format!("{}{}", r.name, r.instance);
193 } else {
194 r.filename = r.name.clone();
195 }
196
197 let result = Arc::new(r);
198 sysfs_instance().create_bin_file(
199 &(acpi_tables_kset() as Arc<dyn KObject>),
200 &(result.clone() as Arc<dyn BinAttribute>),
201 )?;
202 return Ok(result);
203 }
204 }
205
206 impl Attribute for AttrAcpiTable {
show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError>207 fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
208 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
209 }
210
store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError>211 fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
212 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
213 }
214
name(&self) -> &str215 fn name(&self) -> &str {
216 return &self.filename;
217 }
218
mode(&self) -> ModeType219 fn mode(&self) -> ModeType {
220 return ModeType::from_bits_truncate(0o400);
221 }
222
support(&self) -> SysFSOpsSupport223 fn support(&self) -> SysFSOpsSupport {
224 return SysFSOpsSupport::empty();
225 }
226 }
227
228 impl BinAttribute for AttrAcpiTable {
support_battr(&self) -> SysFSOpsSupport229 fn support_battr(&self) -> SysFSOpsSupport {
230 return SysFSOpsSupport::BATTR_READ;
231 }
write( &self, _kobj: Arc<dyn KObject>, _buf: &[u8], _offset: usize, ) -> Result<usize, SystemError>232 fn write(
233 &self,
234 _kobj: Arc<dyn KObject>,
235 _buf: &[u8],
236 _offset: usize,
237 ) -> Result<usize, SystemError> {
238 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
239 }
240
241 /// 展示 ACPI 表的内容
242 ///
243 /// 参考 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>244 fn read(
245 &self,
246 _kobj: Arc<dyn KObject>,
247 buf: &mut [u8],
248 offset: usize,
249 ) -> Result<usize, SystemError> {
250 macro_rules! copy_data {
251 ($table:expr) => {
252 let from = unsafe {
253 core::slice::from_raw_parts(
254 $table.virtual_start().as_ptr() as *const u8,
255 $table.region_length(),
256 )
257 };
258 if offset >= from.len() {
259 return Ok(0);
260 }
261 let mut count = buf.len();
262 if count > from.len() - offset {
263 count = from.len() - offset;
264 }
265 buf[0..count].copy_from_slice(&from[offset..offset + count]);
266 return Ok(count);
267 };
268 }
269
270 macro_rules! define_struct {
271 ($name:ident) => {
272 #[repr(transparent)]
273 #[allow(non_snake_case)]
274 #[allow(non_camel_case_types)]
275 struct $name {
276 header: SdtHeader,
277 }
278
279 unsafe impl acpi::AcpiTable for $name {
280 const SIGNATURE: acpi::sdt::Signature = acpi::sdt::Signature::$name;
281 fn header(&self) -> &acpi::sdt::SdtHeader {
282 return &self.header;
283 }
284 }
285 };
286 }
287
288 macro_rules! handle {
289 ($name: ident, $tables: expr) => {
290 define_struct!($name);
291 let table = $tables.find_entire_table::<$name>().map_err(|e| {
292 kwarn!(
293 "AttrAcpiTable::read(): failed to find table. name: {}, error: {:?}",
294 self.name,
295 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 kerror!("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