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