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