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)] 35 pub fn hotplug_kset() -> Arc<KSet> { 36 unsafe { __HOTPLUG_KSET_INSTANCE.clone().unwrap() } 37 } 38 39 #[inline(always)] 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)] 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)] 52 pub fn acpi_tables_dynamic_kset() -> Arc<KSet> { 53 unsafe { __ACPI_TABLES_DYNAMIC_KSET_INSTANCE.clone().unwrap() } 54 } 55 56 #[inline(always)] 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 { 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 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 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 { 132 fn name(&self) -> &str { 133 "force_remove" 134 } 135 136 fn mode(&self) -> ModeType { 137 SYSFS_ATTR_MODE_RO 138 } 139 140 fn support(&self) -> SysFSOpsSupport { 141 return SysFSOpsSupport::ATTR_SHOW; 142 } 143 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 { 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 { 207 fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> { 208 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 209 } 210 211 fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> { 212 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 213 } 214 215 fn name(&self) -> &str { 216 return &self.filename; 217 } 218 219 fn mode(&self) -> ModeType { 220 return ModeType::from_bits_truncate(0o400); 221 } 222 223 fn support(&self) -> SysFSOpsSupport { 224 return SysFSOpsSupport::empty(); 225 } 226 } 227 228 impl BinAttribute for AttrAcpiTable { 229 fn support_battr(&self) -> SysFSOpsSupport { 230 return SysFSOpsSupport::BATTR_READ; 231 } 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 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 509 fn size(&self) -> usize { 510 return self.size; 511 } 512 } 513