|
@@ -1,9 +1,31 @@
|
|
|
-use crate::{sdt::SdtHeader, AcpiError, GenericAddress, PhysicalMapping};
|
|
|
+use crate::{sdt::SdtHeader, Acpi, AcpiError, GenericAddress, PhysicalMapping};
|
|
|
+use bit_field::BitField;
|
|
|
+
|
|
|
+#[derive(Debug)]
|
|
|
+pub enum PageProtection {
|
|
|
+ None,
|
|
|
+ /// Access to the adjacent 3KB to the base address will not generate a fault.
|
|
|
+ Protected_4K,
|
|
|
+ /// Access to the adjacent 64KB to the base address will not generate a fault.
|
|
|
+ Protected_64K,
|
|
|
+ Other,
|
|
|
+}
|
|
|
+
|
|
|
+/// Information about the High Precision Event Timer
|
|
|
+#[derive(Debug)]
|
|
|
+pub struct HpetInfo {
|
|
|
+ event_timer_block_id: u32,
|
|
|
+ base_address: usize,
|
|
|
+ hpet_number: u8,
|
|
|
+ /// The minimum number of clock ticks that can be set without losing interrupts (for timers in
|
|
|
+ /// Periodic Mode)
|
|
|
+ clock_tick_unit: u16,
|
|
|
+ page_protection: PageProtection,
|
|
|
+}
|
|
|
|
|
|
#[repr(C, packed)]
|
|
|
-pub struct Hpet {
|
|
|
+pub(crate) struct HpetTable {
|
|
|
header: SdtHeader,
|
|
|
-
|
|
|
event_timer_block_id: u32,
|
|
|
base_address: GenericAddress,
|
|
|
hpet_number: u8,
|
|
@@ -11,8 +33,30 @@ pub struct Hpet {
|
|
|
page_protection_oem: u8,
|
|
|
}
|
|
|
|
|
|
-pub fn parse_hpet(mapping: &PhysicalMapping<Hpet>) -> Result<(), AcpiError> {
|
|
|
+pub(crate) fn parse_hpet(
|
|
|
+ acpi: &mut Acpi,
|
|
|
+ mapping: &PhysicalMapping<HpetTable>,
|
|
|
+) -> Result<(), AcpiError> {
|
|
|
(*mapping).header.validate(b"HPET")?;
|
|
|
+ let hpet = &*mapping;
|
|
|
+
|
|
|
+ // Make sure the HPET's in system memory
|
|
|
+ assert_eq!(hpet.base_address.address_space, 0);
|
|
|
+
|
|
|
+ info!("HPET address: {:#?}", hpet.base_address);
|
|
|
+ acpi.hpet = Some(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_oem.get_bits(0..5) {
|
|
|
+ 0 => PageProtection::None,
|
|
|
+ 1 => PageProtection::Protected_4K,
|
|
|
+ 2 => PageProtection::Protected_64K,
|
|
|
+ 3..=15 => PageProtection::Other,
|
|
|
+ _ => unreachable!(),
|
|
|
+ },
|
|
|
+ });
|
|
|
|
|
|
Ok(())
|
|
|
}
|