1*70a4e555SLoGin use core::cell::RefCell; 2*70a4e555SLoGin 3*70a4e555SLoGin use crate::arch::driver::tsc::TSCManager; 4*70a4e555SLoGin use crate::include::bindings::bindings::APIC_TIMER_IRQ_NUM; 5*70a4e555SLoGin 6*70a4e555SLoGin use crate::kdebug; 7*70a4e555SLoGin use crate::mm::percpu::PerCpu; 8*70a4e555SLoGin use crate::sched::core::sched_update_jiffies; 9*70a4e555SLoGin use crate::smp::core::smp_get_processor_id; 10*70a4e555SLoGin use crate::syscall::SystemError; 11*70a4e555SLoGin pub use drop; 12*70a4e555SLoGin use x86::cpuid::cpuid; 13*70a4e555SLoGin use x86::msr::{wrmsr, IA32_X2APIC_DIV_CONF, IA32_X2APIC_INIT_COUNT}; 14*70a4e555SLoGin 15*70a4e555SLoGin use super::xapic::XApicOffset; 16*70a4e555SLoGin use super::{CurrentApic, LVTRegister, LocalAPIC, LVT}; 17*70a4e555SLoGin 18*70a4e555SLoGin static mut LOCAL_APIC_TIMERS: [RefCell<LocalApicTimer>; PerCpu::MAX_CPU_NUM] = 19*70a4e555SLoGin [const { RefCell::new(LocalApicTimer::new()) }; PerCpu::MAX_CPU_NUM]; 20*70a4e555SLoGin 21*70a4e555SLoGin #[inline(always)] 22*70a4e555SLoGin pub(super) fn local_apic_timer_instance(cpu_id: u32) -> core::cell::Ref<'static, LocalApicTimer> { 23*70a4e555SLoGin unsafe { LOCAL_APIC_TIMERS[cpu_id as usize].borrow() } 24*70a4e555SLoGin } 25*70a4e555SLoGin 26*70a4e555SLoGin #[inline(always)] 27*70a4e555SLoGin pub(super) fn local_apic_timer_instance_mut( 28*70a4e555SLoGin cpu_id: u32, 29*70a4e555SLoGin ) -> core::cell::RefMut<'static, LocalApicTimer> { 30*70a4e555SLoGin unsafe { LOCAL_APIC_TIMERS[cpu_id as usize].borrow_mut() } 31*70a4e555SLoGin } 32*70a4e555SLoGin 33*70a4e555SLoGin /// 初始化BSP的APIC定时器 34*70a4e555SLoGin /// 35*70a4e555SLoGin fn init_bsp_apic_timer() { 36*70a4e555SLoGin kdebug!("init_bsp_apic_timer"); 37*70a4e555SLoGin assert!(smp_get_processor_id() == 0); 38*70a4e555SLoGin let mut local_apic_timer = local_apic_timer_instance_mut(0); 39*70a4e555SLoGin local_apic_timer.init( 40*70a4e555SLoGin LocalApicTimerMode::Periodic, 41*70a4e555SLoGin LocalApicTimer::periodic_default_initial_count(), 42*70a4e555SLoGin LocalApicTimer::DIVISOR as u32, 43*70a4e555SLoGin ); 44*70a4e555SLoGin kdebug!("init_bsp_apic_timer done"); 45*70a4e555SLoGin } 46*70a4e555SLoGin 47*70a4e555SLoGin fn init_ap_apic_timer() { 48*70a4e555SLoGin kdebug!("init_ap_apic_timer"); 49*70a4e555SLoGin let cpu_id = smp_get_processor_id(); 50*70a4e555SLoGin assert!(cpu_id != 0); 51*70a4e555SLoGin 52*70a4e555SLoGin let mut local_apic_timer = local_apic_timer_instance_mut(cpu_id); 53*70a4e555SLoGin local_apic_timer.init( 54*70a4e555SLoGin LocalApicTimerMode::Periodic, 55*70a4e555SLoGin LocalApicTimer::periodic_default_initial_count(), 56*70a4e555SLoGin LocalApicTimer::DIVISOR as u32, 57*70a4e555SLoGin ); 58*70a4e555SLoGin kdebug!("init_ap_apic_timer done"); 59*70a4e555SLoGin } 60*70a4e555SLoGin 61*70a4e555SLoGin pub(super) struct LocalApicTimerIntrController; 62*70a4e555SLoGin 63*70a4e555SLoGin impl LocalApicTimerIntrController { 64*70a4e555SLoGin pub(super) fn install(&self, _irq_num: u8) { 65*70a4e555SLoGin kdebug!("LocalApicTimerIntrController::install"); 66*70a4e555SLoGin if smp_get_processor_id() == 0 { 67*70a4e555SLoGin init_bsp_apic_timer(); 68*70a4e555SLoGin } else { 69*70a4e555SLoGin init_ap_apic_timer(); 70*70a4e555SLoGin } 71*70a4e555SLoGin } 72*70a4e555SLoGin 73*70a4e555SLoGin pub(super) fn uninstall(&self) { 74*70a4e555SLoGin let cpu_id = smp_get_processor_id(); 75*70a4e555SLoGin let local_apic_timer = local_apic_timer_instance(cpu_id); 76*70a4e555SLoGin local_apic_timer.stop_current(); 77*70a4e555SLoGin } 78*70a4e555SLoGin 79*70a4e555SLoGin pub(super) fn enable(&self) { 80*70a4e555SLoGin kdebug!("LocalApicTimerIntrController::enable"); 81*70a4e555SLoGin let cpu_id = smp_get_processor_id(); 82*70a4e555SLoGin let mut local_apic_timer = local_apic_timer_instance_mut(cpu_id); 83*70a4e555SLoGin local_apic_timer.start_current(); 84*70a4e555SLoGin } 85*70a4e555SLoGin 86*70a4e555SLoGin pub(super) fn disable(&self) { 87*70a4e555SLoGin let cpu_id = smp_get_processor_id(); 88*70a4e555SLoGin let local_apic_timer = local_apic_timer_instance_mut(cpu_id); 89*70a4e555SLoGin local_apic_timer.stop_current(); 90*70a4e555SLoGin } 91*70a4e555SLoGin } 92*70a4e555SLoGin 93*70a4e555SLoGin #[derive(Debug, Copy, Clone)] 94*70a4e555SLoGin pub struct LocalApicTimer { 95*70a4e555SLoGin mode: LocalApicTimerMode, 96*70a4e555SLoGin /// IntialCount 97*70a4e555SLoGin initial_count: u64, 98*70a4e555SLoGin divisor: u32, 99*70a4e555SLoGin /// 是否已经触发(oneshot模式) 100*70a4e555SLoGin triggered: bool, 101*70a4e555SLoGin } 102*70a4e555SLoGin 103*70a4e555SLoGin #[derive(Debug, Copy, Clone)] 104*70a4e555SLoGin #[repr(u32)] 105*70a4e555SLoGin pub enum LocalApicTimerMode { 106*70a4e555SLoGin Oneshot = 0, 107*70a4e555SLoGin Periodic = 1, 108*70a4e555SLoGin Deadline = 2, 109*70a4e555SLoGin } 110*70a4e555SLoGin 111*70a4e555SLoGin impl LocalApicTimer { 112*70a4e555SLoGin /// 定时器中断的间隔 113*70a4e555SLoGin pub const INTERVAL_MS: u64 = 5; 114*70a4e555SLoGin pub const DIVISOR: u64 = 3; 115*70a4e555SLoGin 116*70a4e555SLoGin /// IoApicManager 初值为0或false 117*70a4e555SLoGin pub const fn new() -> Self { 118*70a4e555SLoGin LocalApicTimer { 119*70a4e555SLoGin mode: LocalApicTimerMode::Periodic, 120*70a4e555SLoGin initial_count: 0, 121*70a4e555SLoGin divisor: 0, 122*70a4e555SLoGin triggered: false, 123*70a4e555SLoGin } 124*70a4e555SLoGin } 125*70a4e555SLoGin 126*70a4e555SLoGin /// 周期模式下的默认初始值 127*70a4e555SLoGin pub fn periodic_default_initial_count() -> u64 { 128*70a4e555SLoGin let cpu_khz = TSCManager::cpu_khz(); 129*70a4e555SLoGin 130*70a4e555SLoGin // 疑惑:这里使用khz吗? 131*70a4e555SLoGin // 我觉得应该是hz,但是由于旧的代码是测量出initcnt的,而不是计算的 132*70a4e555SLoGin // 然后我发现使用hz会导致计算出来的initcnt太大,导致系统卡顿,而khz的却能跑 133*70a4e555SLoGin let count = cpu_khz * Self::INTERVAL_MS / (1000 * Self::DIVISOR); 134*70a4e555SLoGin return count; 135*70a4e555SLoGin } 136*70a4e555SLoGin 137*70a4e555SLoGin /// Init this manager. 138*70a4e555SLoGin /// 139*70a4e555SLoGin /// At this time, it does nothing. 140*70a4e555SLoGin fn init(&mut self, mode: LocalApicTimerMode, initial_count: u64, divisor: u32) { 141*70a4e555SLoGin self.stop_current(); 142*70a4e555SLoGin self.triggered = false; 143*70a4e555SLoGin match mode { 144*70a4e555SLoGin LocalApicTimerMode::Periodic => self.install_periodic_mode(initial_count, divisor), 145*70a4e555SLoGin LocalApicTimerMode::Oneshot => todo!(), 146*70a4e555SLoGin LocalApicTimerMode::Deadline => todo!(), 147*70a4e555SLoGin } 148*70a4e555SLoGin } 149*70a4e555SLoGin 150*70a4e555SLoGin fn install_periodic_mode(&mut self, initial_count: u64, divisor: u32) { 151*70a4e555SLoGin kdebug!( 152*70a4e555SLoGin "install_periodic_mode: initial_count = {}, divisor = {}", 153*70a4e555SLoGin initial_count, 154*70a4e555SLoGin divisor 155*70a4e555SLoGin ); 156*70a4e555SLoGin self.mode = LocalApicTimerMode::Periodic; 157*70a4e555SLoGin self.set_divisor(divisor); 158*70a4e555SLoGin self.set_initial_cnt(initial_count); 159*70a4e555SLoGin self.setup_lvt(APIC_TIMER_IRQ_NUM as u8, true, LocalApicTimerMode::Periodic); 160*70a4e555SLoGin } 161*70a4e555SLoGin 162*70a4e555SLoGin fn setup_lvt(&mut self, vector: u8, mask: bool, mode: LocalApicTimerMode) { 163*70a4e555SLoGin let mode: u32 = mode as u32; 164*70a4e555SLoGin let data = (mode << 17) | (vector as u32) | (if mask { 1 << 16 } else { 0 }); 165*70a4e555SLoGin let lvt = LVT::new(LVTRegister::Timer, data).unwrap(); 166*70a4e555SLoGin 167*70a4e555SLoGin CurrentApic.set_lvt(lvt); 168*70a4e555SLoGin } 169*70a4e555SLoGin 170*70a4e555SLoGin fn set_divisor(&mut self, divisor: u32) { 171*70a4e555SLoGin self.divisor = divisor; 172*70a4e555SLoGin CurrentApic.set_timer_divisor(divisor as u32); 173*70a4e555SLoGin } 174*70a4e555SLoGin 175*70a4e555SLoGin fn set_initial_cnt(&mut self, initial_count: u64) { 176*70a4e555SLoGin self.initial_count = initial_count; 177*70a4e555SLoGin CurrentApic.set_timer_initial_count(initial_count); 178*70a4e555SLoGin } 179*70a4e555SLoGin 180*70a4e555SLoGin fn start_current(&mut self) { 181*70a4e555SLoGin let mut lvt = CurrentApic.read_lvt(LVTRegister::Timer); 182*70a4e555SLoGin lvt.set_mask(false); 183*70a4e555SLoGin CurrentApic.set_lvt(lvt); 184*70a4e555SLoGin } 185*70a4e555SLoGin 186*70a4e555SLoGin fn stop_current(&self) { 187*70a4e555SLoGin let mut lvt = CurrentApic.read_lvt(LVTRegister::Timer); 188*70a4e555SLoGin lvt.set_mask(true); 189*70a4e555SLoGin CurrentApic.set_lvt(lvt); 190*70a4e555SLoGin } 191*70a4e555SLoGin 192*70a4e555SLoGin /// 检查是否支持TSC-Deadline 193*70a4e555SLoGin /// 194*70a4e555SLoGin /// 此函数调用cpuid,请避免多次调用此函数。 195*70a4e555SLoGin /// 如果支持TSC-Deadline模式,则除非TSC为常数,否则不会启用该模式。 196*70a4e555SLoGin #[allow(dead_code)] 197*70a4e555SLoGin pub fn is_deadline_mode_supported(&self) -> bool { 198*70a4e555SLoGin let res = cpuid!(1); 199*70a4e555SLoGin return (res.ecx & (1 << 24)) != 0; 200*70a4e555SLoGin } 201*70a4e555SLoGin 202*70a4e555SLoGin pub(super) fn handle_irq() -> Result<(), SystemError> { 203*70a4e555SLoGin sched_update_jiffies(); 204*70a4e555SLoGin return Ok(()); 205*70a4e555SLoGin } 206*70a4e555SLoGin } 207*70a4e555SLoGin 208*70a4e555SLoGin impl TryFrom<u8> for LocalApicTimerMode { 209*70a4e555SLoGin type Error = SystemError; 210*70a4e555SLoGin 211*70a4e555SLoGin fn try_from(value: u8) -> Result<Self, Self::Error> { 212*70a4e555SLoGin match value { 213*70a4e555SLoGin 0b00 => { 214*70a4e555SLoGin return Ok(LocalApicTimerMode::Oneshot); 215*70a4e555SLoGin } 216*70a4e555SLoGin 0b01 => { 217*70a4e555SLoGin return Ok(LocalApicTimerMode::Periodic); 218*70a4e555SLoGin } 219*70a4e555SLoGin 0b10 => { 220*70a4e555SLoGin return Ok(LocalApicTimerMode::Deadline); 221*70a4e555SLoGin } 222*70a4e555SLoGin _ => { 223*70a4e555SLoGin return Err(SystemError::EINVAL); 224*70a4e555SLoGin } 225*70a4e555SLoGin } 226*70a4e555SLoGin } 227*70a4e555SLoGin } 228*70a4e555SLoGin 229*70a4e555SLoGin impl CurrentApic { 230*70a4e555SLoGin fn set_timer_divisor(&self, divisor: u32) { 231*70a4e555SLoGin if self.x2apic_enabled() { 232*70a4e555SLoGin unsafe { wrmsr(IA32_X2APIC_DIV_CONF, divisor.into()) }; 233*70a4e555SLoGin } else { 234*70a4e555SLoGin unsafe { 235*70a4e555SLoGin self.write_xapic_register( 236*70a4e555SLoGin XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_CLKDIV, 237*70a4e555SLoGin divisor.into(), 238*70a4e555SLoGin ) 239*70a4e555SLoGin }; 240*70a4e555SLoGin } 241*70a4e555SLoGin } 242*70a4e555SLoGin 243*70a4e555SLoGin fn set_timer_initial_count(&self, initial_count: u64) { 244*70a4e555SLoGin if self.x2apic_enabled() { 245*70a4e555SLoGin unsafe { 246*70a4e555SLoGin wrmsr(IA32_X2APIC_INIT_COUNT.into(), initial_count); 247*70a4e555SLoGin } 248*70a4e555SLoGin } else { 249*70a4e555SLoGin unsafe { 250*70a4e555SLoGin self.write_xapic_register( 251*70a4e555SLoGin XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_INITIAL_COUNT_REG, 252*70a4e555SLoGin initial_count as u32, 253*70a4e555SLoGin ) 254*70a4e555SLoGin }; 255*70a4e555SLoGin } 256*70a4e555SLoGin } 257*70a4e555SLoGin } 258