fadt.rs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. use crate::{
  2. sdt::{ExtendedField, SdtHeader},
  3. AcpiError,
  4. AcpiTable,
  5. GenericAddress,
  6. };
  7. #[derive(Clone, Copy, PartialEq, Eq, Debug)]
  8. pub enum PowerProfile {
  9. Unspecified,
  10. Desktop,
  11. Mobile,
  12. Workstation,
  13. EnterpriseServer,
  14. SohoServer,
  15. AppliancePc,
  16. PerformanceServer,
  17. Tablet,
  18. Reserved(u8),
  19. }
  20. /// Represents the Fixed ACPI Description Table (FADT). This table contains various fixed hardware
  21. /// details, such as the addresses of the hardware register blocks. It also contains a pointer to
  22. /// the Differentiated Definition Block (DSDT).
  23. ///
  24. /// In cases where the FADT contains both a 32-bit and 64-bit field for the same address, we should
  25. /// always prefer the 64-bit one. Only if it's zero or the CPU will not allow us to access that
  26. /// address should the 32-bit one be used.
  27. #[repr(C, packed)]
  28. pub struct Fadt {
  29. header: SdtHeader,
  30. firmware_ctrl: u32,
  31. dsdt_address: u32,
  32. // used in acpi 1.0; compatibility only, should be zero
  33. _reserved: u8,
  34. preferred_pm_profile: u8,
  35. sci_interrupt: u16,
  36. smi_cmd_port: u32,
  37. acpi_enable: u8,
  38. acpi_disable: u8,
  39. s4bios_req: u8,
  40. pstate_control: u8,
  41. pm1a_event_block: u32,
  42. pm1b_event_block: u32,
  43. pm1a_control_block: u32,
  44. pm1b_control_block: u32,
  45. pm2_control_block: u32,
  46. pm_timer_block: u32,
  47. gpe0_block: u32,
  48. gpe1_block: u32,
  49. pm1_event_length: u8,
  50. pm1_control_length: u8,
  51. pm2_control_length: u8,
  52. pm_timer_length: u8,
  53. gpe0_block_length: u8,
  54. gpe1_block_length: u8,
  55. gpe1_base: u8,
  56. c_state_control: u8,
  57. worst_c2_latency: u16,
  58. worst_c3_latency: u16,
  59. flush_size: u16,
  60. flush_stride: u16,
  61. duty_offset: u8,
  62. duty_width: u8,
  63. day_alarm: u8,
  64. month_alarm: u8,
  65. century: u8,
  66. iapc_boot_arch: u16,
  67. _reserved2: u8, // must be 0
  68. flags: u32,
  69. reset_reg: GenericAddress,
  70. reset_value: u8,
  71. arm_boot_arch: u16,
  72. fadt_minor_version: u8,
  73. x_firmware_ctrl: ExtendedField<u64, 2>,
  74. x_dsdt_address: ExtendedField<u64, 2>,
  75. x_pm1a_event_block: ExtendedField<GenericAddress, 2>,
  76. x_pm1b_event_block: ExtendedField<GenericAddress, 2>,
  77. x_pm1a_control_block: ExtendedField<GenericAddress, 2>,
  78. x_pm1b_control_block: ExtendedField<GenericAddress, 2>,
  79. x_pm2_control_block: ExtendedField<GenericAddress, 2>,
  80. x_pm_timer_block: ExtendedField<GenericAddress, 2>,
  81. x_gpe0_block: ExtendedField<GenericAddress, 2>,
  82. x_gpe1_block: ExtendedField<GenericAddress, 2>,
  83. sleep_control_reg: ExtendedField<GenericAddress, 2>,
  84. sleep_status_reg: ExtendedField<GenericAddress, 2>,
  85. hypervisor_vendor_id: ExtendedField<u64, 2>,
  86. }
  87. impl AcpiTable for Fadt {
  88. fn header(&self) -> &SdtHeader {
  89. &self.header
  90. }
  91. }
  92. impl Fadt {
  93. pub fn validate(&self) -> Result<(), AcpiError> {
  94. self.header.validate(crate::sdt::Signature::FADT)
  95. }
  96. pub fn dsdt_address(&self) -> Result<usize, AcpiError> {
  97. unsafe {
  98. self.x_dsdt_address
  99. .access(self.header.revision)
  100. .filter(|&p| p != 0)
  101. .or(Some(self.dsdt_address as u64))
  102. .filter(|p| *p != 0)
  103. .map(|p| p as usize)
  104. .ok_or(AcpiError::InvalidDsdtAddress)
  105. }
  106. }
  107. pub fn power_profile(&self) -> PowerProfile {
  108. match self.preferred_pm_profile {
  109. 0 => PowerProfile::Unspecified,
  110. 1 => PowerProfile::Desktop,
  111. 2 => PowerProfile::Mobile,
  112. 3 => PowerProfile::Workstation,
  113. 4 => PowerProfile::EnterpriseServer,
  114. 5 => PowerProfile::SohoServer,
  115. 6 => PowerProfile::AppliancePc,
  116. 7 => PowerProfile::PerformanceServer,
  117. 8 => PowerProfile::Tablet,
  118. other => PowerProfile::Reserved(other),
  119. }
  120. }
  121. }