hpet.rs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. use crate::{sdt::SdtHeader, AcpiError, AcpiHandler, AcpiTable, AcpiTables, GenericAddress};
  2. use bit_field::BitField;
  3. #[derive(Debug)]
  4. pub enum PageProtection {
  5. None,
  6. /// Access to the adjacent 3KB to the base address will not generate a fault.
  7. Protected4K,
  8. /// Access to the adjacent 64KB to the base address will not generate a fault.
  9. Protected64K,
  10. Other,
  11. }
  12. /// Information about the High Precision Event Timer
  13. #[derive(Debug)]
  14. pub struct HpetInfo {
  15. pub event_timer_block_id: u32,
  16. pub base_address: usize,
  17. pub hpet_number: u8,
  18. /// The minimum number of clock ticks that can be set without losing interrupts (for timers in Periodic Mode)
  19. pub clock_tick_unit: u16,
  20. pub page_protection: PageProtection,
  21. }
  22. impl HpetInfo {
  23. pub fn new<H>(tables: &AcpiTables<H>) -> Result<HpetInfo, AcpiError>
  24. where
  25. H: AcpiHandler,
  26. {
  27. let hpet = unsafe {
  28. tables
  29. .get_sdt::<HpetTable>(crate::sdt::Signature::HPET)?
  30. .ok_or(AcpiError::TableMissing(crate::sdt::Signature::HPET))?
  31. };
  32. // Make sure the HPET's in system memory
  33. assert_eq!(hpet.base_address.address_space, 0);
  34. Ok(HpetInfo {
  35. event_timer_block_id: hpet.event_timer_block_id,
  36. base_address: hpet.base_address.address as usize,
  37. hpet_number: hpet.hpet_number,
  38. clock_tick_unit: hpet.clock_tick_unit,
  39. page_protection: match hpet.page_protection_oem.get_bits(0..5) {
  40. 0 => PageProtection::None,
  41. 1 => PageProtection::Protected4K,
  42. 2 => PageProtection::Protected64K,
  43. 3..=15 => PageProtection::Other,
  44. _ => unreachable!(),
  45. },
  46. })
  47. }
  48. }
  49. #[repr(C, packed)]
  50. pub(crate) struct HpetTable {
  51. header: SdtHeader,
  52. event_timer_block_id: u32,
  53. base_address: GenericAddress,
  54. hpet_number: u8,
  55. clock_tick_unit: u16,
  56. page_protection_oem: u8,
  57. }
  58. impl AcpiTable for HpetTable {
  59. fn header(&self) -> &SdtHeader {
  60. &self.header
  61. }
  62. }