123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- use crate::{
- address::RawGenericAddress,
- sdt::{SdtHeader, Signature},
- AcpiError,
- AcpiHandler,
- AcpiTable,
- AcpiTables,
- };
- use bit_field::BitField;
- #[derive(Debug)]
- pub enum PageProtection {
- None,
- /// Access to the rest of the 4KiB, relative to the base address, will not generate a fault.
- Protected4K,
- /// Access to the rest of the 64KiB, relative to the base address, will not generate a fault.
- Protected64K,
- Other,
- }
- /// Information about the High Precision Event Timer (HPET)
- #[derive(Debug)]
- pub struct HpetInfo {
- // TODO(3.0.0): unpack these fields directly, and get rid of methods
- pub event_timer_block_id: u32,
- pub base_address: usize,
- pub hpet_number: u8,
- /// The minimum number of clock ticks that can be set without losing interrupts (for timers in Periodic Mode)
- pub clock_tick_unit: u16,
- pub page_protection: PageProtection,
- }
- impl HpetInfo {
- pub fn new<H>(tables: &AcpiTables<H>) -> Result<HpetInfo, AcpiError>
- where
- H: AcpiHandler,
- {
- let hpet = tables.find_table::<HpetTable>()?;
- // Make sure the HPET is in system memory
- assert_eq!(hpet.base_address.address_space, 0);
- Ok(HpetInfo {
- event_timer_block_id: hpet.event_timer_block_id,
- base_address: hpet.base_address.address as usize,
- hpet_number: hpet.hpet_number,
- clock_tick_unit: hpet.clock_tick_unit,
- page_protection: match hpet.page_protection_and_oem.get_bits(0..4) {
- 0 => PageProtection::None,
- 1 => PageProtection::Protected4K,
- 2 => PageProtection::Protected64K,
- 3..=15 => PageProtection::Other,
- _ => unreachable!(),
- },
- })
- }
- pub fn hardware_rev(&self) -> u8 {
- self.event_timer_block_id.get_bits(0..8) as u8
- }
- pub fn num_comparators(&self) -> u8 {
- self.event_timer_block_id.get_bits(8..13) as u8 + 1
- }
- pub fn main_counter_is_64bits(&self) -> bool {
- self.event_timer_block_id.get_bit(13)
- }
- pub fn legacy_irq_capable(&self) -> bool {
- self.event_timer_block_id.get_bit(15)
- }
- pub fn pci_vendor_id(&self) -> u16 {
- self.event_timer_block_id.get_bits(16..32) as u16
- }
- }
- #[repr(C, packed)]
- #[derive(Debug, Clone, Copy)]
- pub struct HpetTable {
- /// The contents of the HPET's 'General Capabilities and ID register'
- header: SdtHeader,
- event_timer_block_id: u32,
- base_address: RawGenericAddress,
- hpet_number: u8,
- clock_tick_unit: u16,
- /// Bits `0..4` specify the page protection guarantee. Bits `4..8` are reserved for OEM attributes.
- page_protection_and_oem: u8,
- }
- /// ### Safety: Implementation properly represents a valid HPET table.
- unsafe impl AcpiTable for HpetTable {
- const SIGNATURE: Signature = Signature::HPET;
- fn header(&self) -> &SdtHeader {
- &self.header
- }
- }
|