1use crate::{
2 address::RawGenericAddress,
3 sdt::{SdtHeader, Signature},
4 AcpiError,
5 AcpiHandler,
6 AcpiTable,
7 AcpiTables,
8};
9use bit_field::BitField;
10
11#[derive(Debug)]
12pub enum PageProtection {
13 None,
14 Protected4K,
16 Protected64K,
18 Other,
19}
20
21#[derive(Debug)]
23pub struct HpetInfo {
24 pub event_timer_block_id: u32,
26 pub base_address: usize,
27 pub hpet_number: u8,
28 pub clock_tick_unit: u16,
30 pub page_protection: PageProtection,
31}
32
33impl HpetInfo {
34 pub fn new<H>(tables: &AcpiTables<H>) -> Result<HpetInfo, AcpiError>
35 where
36 H: AcpiHandler,
37 {
38 let hpet = tables.find_table::<HpetTable>()?;
39
40 assert_eq!(hpet.base_address.address_space, 0);
42
43 Ok(HpetInfo {
44 event_timer_block_id: hpet.event_timer_block_id,
45 base_address: hpet.base_address.address as usize,
46 hpet_number: hpet.hpet_number,
47 clock_tick_unit: hpet.clock_tick_unit,
48 page_protection: match hpet.page_protection_and_oem.get_bits(0..4) {
49 0 => PageProtection::None,
50 1 => PageProtection::Protected4K,
51 2 => PageProtection::Protected64K,
52 3..=15 => PageProtection::Other,
53 _ => unreachable!(),
54 },
55 })
56 }
57
58 pub fn hardware_rev(&self) -> u8 {
59 self.event_timer_block_id.get_bits(0..8) as u8
60 }
61
62 pub fn num_comparators(&self) -> u8 {
63 self.event_timer_block_id.get_bits(8..13) as u8 + 1
64 }
65
66 pub fn main_counter_is_64bits(&self) -> bool {
67 self.event_timer_block_id.get_bit(13)
68 }
69
70 pub fn legacy_irq_capable(&self) -> bool {
71 self.event_timer_block_id.get_bit(15)
72 }
73
74 pub fn pci_vendor_id(&self) -> u16 {
75 self.event_timer_block_id.get_bits(16..32) as u16
76 }
77}
78
79#[repr(C, packed)]
80#[derive(Debug, Clone, Copy)]
81pub struct HpetTable {
82 header: SdtHeader,
84 event_timer_block_id: u32,
85 base_address: RawGenericAddress,
86 hpet_number: u8,
87 clock_tick_unit: u16,
88 page_protection_and_oem: u8,
90}
91
92unsafe impl AcpiTable for HpetTable {
94 const SIGNATURE: Signature = Signature::HPET;
95
96 fn header(&self) -> &SdtHeader {
97 &self.header
98 }
99}