fadt.rs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. use crate::{sdt::SdtHeader, Acpi, AcpiError, AcpiHandler, GenericAddress, PhysicalMapping};
  2. /// Represents the Fixed ACPI Description Table (FADT). This table contains various fixed hardware
  3. /// details, such as the addresses of the hardware register blocks. It also contains a pointer to
  4. /// the Differentiated Definition Block (DSDT).
  5. ///
  6. /// In cases where the FADT contains both a 32-bit and 64-bit field for the same address, we should
  7. /// always prefer the 64-bit one. Only if it's zero or the CPU will not allow us to access that
  8. /// address should the 32-bit one be used.
  9. #[repr(C, packed)]
  10. pub struct Fadt {
  11. header: SdtHeader,
  12. firmware_ctrl: u32,
  13. dsdt_address: u32,
  14. // used in acpi 1.0; compatibility only, should be zero
  15. reserved: u8,
  16. preferred_pm_profile: u8,
  17. sci_interrupt: u16,
  18. smi_cmd_port: u32,
  19. acpi_enable: u8,
  20. acpi_disable: u8,
  21. s4bios_req: u8,
  22. pstate_control: u8,
  23. pm1a_event_block: u32,
  24. pm1b_event_block: u32,
  25. pm1a_control_block: u32,
  26. pm1b_control_block: u32,
  27. pm2_control_block: u32,
  28. pm_timer_block: u32,
  29. gpe0_block: u32,
  30. gpe1_block: u32,
  31. pm1_event_length: u8,
  32. pm1_control_length: u8,
  33. pm2_control_length: u8,
  34. pm_timer_length: u8,
  35. gpe0_block_length: u8,
  36. gpe1_block_length: u8,
  37. gpe1_base: u8,
  38. c_state_control: u8,
  39. worst_c2_latency: u16,
  40. worst_c3_latency: u16,
  41. flush_size: u16,
  42. flush_stride: u16,
  43. duty_offset: u8,
  44. duty_width: u8,
  45. day_alarm: u8,
  46. month_alarm: u8,
  47. century: u8,
  48. iapc_boot_arch: u16,
  49. reserved2: u8, // must be 0
  50. flags: u32,
  51. reset_reg: GenericAddress,
  52. reset_value: u8,
  53. arm_boot_arch: u16,
  54. fadt_minor_version: u8,
  55. x_firmware_control: u64,
  56. x_dsdt_address: u64,
  57. x_pm1a_event_block: GenericAddress,
  58. x_pm1b_event_block: GenericAddress,
  59. x_pm1a_control_block: GenericAddress,
  60. x_pm1b_control_block: GenericAddress,
  61. x_pm2_control_block: GenericAddress,
  62. x_pm_timer_block: GenericAddress,
  63. x_gpe0_block: GenericAddress,
  64. x_gpe1_block: GenericAddress,
  65. sleep_control_reg: GenericAddress,
  66. sleep_status_reg: GenericAddress,
  67. hypervisor_vendor_id: u64,
  68. }
  69. pub(crate) fn parse_fadt<H>(
  70. acpi: &mut Acpi,
  71. handler: &mut H,
  72. mapping: &PhysicalMapping<Fadt>,
  73. ) -> Result<(), AcpiError>
  74. where
  75. H: AcpiHandler,
  76. {
  77. let fadt = &*mapping;
  78. fadt.header.validate(b"FACP")?;
  79. // TODO more generic typesafe way of accessing the x_ fields
  80. acpi.dsdt_address = Some(if fadt.header.revision() > 1 && fadt.x_dsdt_address != 0 {
  81. fadt.x_dsdt_address as usize
  82. } else {
  83. fadt.dsdt_address as usize
  84. });
  85. Ok(())
  86. }