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