sysfs.rs 18 KB

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