Skip to content
Snippets Groups Projects
Commit 4f90a0f5 authored by wartman4404's avatar wartman4404
Browse files

Write hpet timer 0 twice to set accumulator and period

This allows booting with implementations that require them to be set separately.
Also, check for the availability of legacy-replacement mode and periodic interrupts before using hpet
parent 083c444a
No related branches found
No related tags found
1 merge request!74Write hpet timer twice
...@@ -11,20 +11,39 @@ static CAPABILITY_OFFSET: usize = 0x00; ...@@ -11,20 +11,39 @@ static CAPABILITY_OFFSET: usize = 0x00;
static GENERAL_CONFIG_OFFSET: usize = 0x10; static GENERAL_CONFIG_OFFSET: usize = 0x10;
// static GENERAL_INTERRUPT_OFFSET: usize = 0x20; // static GENERAL_INTERRUPT_OFFSET: usize = 0x20;
// static MAIN_COUNTER_OFFSET: usize = 0xF0; // static MAIN_COUNTER_OFFSET: usize = 0xF0;
// static NUM_TIMER_CAP_MASK: u64 = 0x0f00;
static LEG_RT_CAP: u64 = 0x8000;
static T0_CONFIG_CAPABILITY_OFFSET: usize = 0x100; static T0_CONFIG_CAPABILITY_OFFSET: usize = 0x100;
static T0_COMPARATOR_OFFSET: usize = 0x108; static T0_COMPARATOR_OFFSET: usize = 0x108;
pub unsafe fn init(hpet: &mut Hpet) { static PER_INT_CAP: u64 = 0x10;
let counter_clk_period_fs = hpet.base_address.read_u64(CAPABILITY_OFFSET) >> 32;
pub unsafe fn init(hpet: &mut Hpet) -> bool {
let capability = hpet.base_address.read_u64(CAPABILITY_OFFSET);
if capability & LEG_RT_CAP == 0 {
return false;
}
let counter_clk_period_fs = capability >> 32;
let desired_fs_period: u64 = 2_250_286 * 1_000_000; let desired_fs_period: u64 = 2_250_286 * 1_000_000;
let clk_periods_per_kernel_tick: u64 = desired_fs_period / counter_clk_period_fs; let clk_periods_per_kernel_tick: u64 = desired_fs_period / counter_clk_period_fs;
let enable_word: u64 = hpet.base_address.read_u64(GENERAL_CONFIG_OFFSET) | LEG_RT_CNF | ENABLE_CNF; let t0_capabilities = hpet.base_address.read_u64(T0_CONFIG_CAPABILITY_OFFSET);
hpet.base_address.write_u64(GENERAL_CONFIG_OFFSET, enable_word); if t0_capabilities & PER_INT_CAP == 0 {
// Enable interrupts from the HPET return false;
}
let t0_config_word: u64 = TN_VAL_SET_CNF | TN_TYPE_CNF | TN_INT_ENB_CNF; let t0_config_word: u64 = TN_VAL_SET_CNF | TN_TYPE_CNF | TN_INT_ENB_CNF;
hpet.base_address.write_u64(T0_CONFIG_CAPABILITY_OFFSET, t0_config_word); hpet.base_address.write_u64(T0_CONFIG_CAPABILITY_OFFSET, t0_config_word);
hpet.base_address.write_u64(T0_COMPARATOR_OFFSET, clk_periods_per_kernel_tick); hpet.base_address.write_u64(T0_COMPARATOR_OFFSET, clk_periods_per_kernel_tick);
// set accumulator value
hpet.base_address.write_u64(T0_COMPARATOR_OFFSET, clk_periods_per_kernel_tick);
// set interval
let enable_word: u64 = hpet.base_address.read_u64(GENERAL_CONFIG_OFFSET) | LEG_RT_CNF | ENABLE_CNF;
hpet.base_address.write_u64(GENERAL_CONFIG_OFFSET, enable_word);
// Enable interrupts from the HPET
true
} }
...@@ -16,9 +16,12 @@ pub unsafe fn init(active_table: &mut ActivePageTable){ ...@@ -16,9 +16,12 @@ pub unsafe fn init(active_table: &mut ActivePageTable){
pub unsafe fn init_noncore() { pub unsafe fn init_noncore() {
{ {
if let Some(ref mut hpet) = *ACPI_TABLE.hpet.write() { let using_hpet = if let Some(ref mut hpet) = *ACPI_TABLE.hpet.write() {
hpet::init(hpet); hpet::init(hpet)
} else { } else {
false
};
if !using_hpet {
pit::init(); pit::init();
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment