diff --git a/src/arch/x86_64/device/local_apic.rs b/src/arch/x86_64/device/local_apic.rs index 38a8e1cc217d0c1a2e54991a6a90b65a55ec58e6..e878c12d1b8cc80c881d0450d6432651c5362045 100644 --- a/src/arch/x86_64/device/local_apic.rs +++ b/src/arch/x86_64/device/local_apic.rs @@ -6,7 +6,6 @@ use x86::msr::*; use crate::memory::Frame; use crate::paging::{ActivePageTable, PhysicalAddress, Page, VirtualAddress}; use crate::paging::entry::EntryFlags; -use crate::{interrupt, time}; pub static mut LOCAL_APIC: LocalApic = LocalApic { address: 0, @@ -212,89 +211,6 @@ impl LocalApic { let vector = 49u32; self.set_lvt_error(vector); } - unsafe fn setup_timer(&mut self) -> Result<(), NoFreqInfo> { - // TODO: Get the correct frequency, use the local apic timer instead of the PIT. - let cpuid = CpuId::new(); - let hardcoded_frequency_in_hz = cpuid.get_tsc_info().map(|tsc| { - if tsc.numerator() != 0 { - // The core crystal clock frequency, in hertz. - Some(tsc.tsc_frequency()) - } else { None } - }).or_else(|| { - cpuid.get_processor_frequency_info().map(|freq| { - let bus_freq = freq.bus_frequency(); - if bus_freq != 0 { - Some(u64::from(bus_freq) * 1_000_000) - } else { None } - }) - }).flatten(); - - let frequency_in_hz = hardcoded_frequency_in_hz.unwrap_or_else(|| { - let (numer, denom) = self.determine_freq(); - let quotient = numer / denom; - quotient as u64 - }); - - let most_suitable_divider = most_suitable_divider(frequency_in_hz); - - println!("FREQUENCY: {}", frequency_in_hz); - println!("MOST_SUIT_DIV: {}", most_suitable_divider); - - let div_conf_value = most_suitable_divider; // divide by 128 - self.set_div_conf(div_conf_value.into()); - - let init_count_value = 1_000_000; - self.set_init_count(init_count_value); - - let lvt_timer_value = ((LvtTimerMode::Periodic as u32) << 17) | 48u32; - self.set_lvt_timer(lvt_timer_value); - - Ok(()) - } - - /// Determine the APIC timer frequency, if the info wasn't already retrieved directly from the - /// CPU. - unsafe fn determine_freq(&mut self) -> (u128, u128) { - let old_time = time::monotonic(); - let (old_time_s, old_time_ns) = old_time; - - super::super::idt::IDT[32].set_func(super::super::interrupt::irq::calib_pit); - - self.set_div_conf(0b1011); // divide by 1 - self.set_lvt_timer((LvtTimerMode::OneShot as u32) << 17 | 48); - - // enable both the apic timer and the pit timer simultaneously - interrupt::enable_and_nop(); - - self.set_init_count(0xFFFF_FFFF); - - let mut time; - - 'halt: loop { - time = time::monotonic(); - if time.0 > old_time_s || time.1 - old_time_ns > 10_000_000 { - break 'halt; - } - x86::halt(); - } - - let (time_s, time_ns) = time; - - let lvt_timer = self.lvt_timer(); - self.set_lvt_timer(lvt_timer | 1 << 16); - - let current_count = self.cur_count(); - - let lvt_timer_difference = 0xFFFF_FFFF - current_count; - let (s_difference, ns_difference) = (time_s - old_time_s, time_ns - old_time_ns); - - let freq_numer = u128::from(lvt_timer_difference) * 1_000_000_000; // multiply with a billion since we're dividing by nanoseconds. - let freq_denom_in_s = u128::from(s_difference) * 1_000_000_000 + u128::from(ns_difference); - - super::super::idt::IDT[32].set_func(super::super::interrupt::irq::pit); - - (freq_numer, freq_denom_in_s) - } } #[repr(u8)] @@ -303,30 +219,3 @@ pub enum LvtTimerMode { Periodic = 0b01, TscDeadline = 0b10, } - -/// Find the most suitable divider configuration value, which is useful if the reported frequency -/// is way too high to actually be useful. -fn most_suitable_divider(freq: u64) -> u8 { - // the current scheduler switches process about every 40 µs, with 4 µs per tick. - let quotient = (freq * 1000) / 2_000_000_000; - if quotient == 0 { - // the frequency is way to low, so the pit should be used - println!("Suboptimal APIC timer frequency"); - 0b1011 // divide by 1 - } else if quotient == 1 { - // the frequency closely matches the requested frequency, so use divider 1 - 0b1011 - } else if quotient < 4 { - 0b0000 // divider 2 - } else if quotient < 8 { - 0b0001 // divider 4 - } else if quotient < 16 { - 0b0010 // divider 8 - } else if quotient < 32 { - 0b0011 // divider 16 - } else if quotient < 64 { - 0b1001 // divider 64 - } else { - 0b1010 // divider 128 - } -} diff --git a/src/scheme/irq.rs b/src/scheme/irq.rs index b3784e610d2aca2f9969076361901719f529117f..18ee836fce0904a096460c77b935f354ff2350fa 100644 --- a/src/scheme/irq.rs +++ b/src/scheme/irq.rs @@ -43,7 +43,7 @@ pub extern fn irq_trigger(irq: u8) { let guard = HANDLES.read(); if let Some(handles) = guard.as_ref() { - for (fd, (_, handle_irq)) in handles.iter().filter_map(|(fd, handle)| Some((fd, handle.as_irq_handle()?))).filter(|&(_, (_, handle_irq))| handle_irq == irq) { + for (fd, _) in handles.iter().filter_map(|(fd, handle)| Some((fd, handle.as_irq_handle()?))).filter(|&(_, (_, handle_irq))| handle_irq == irq) { event::trigger(IRQ_SCHEME_ID.load(Ordering::SeqCst), *fd, EVENT_READ); } } else {