170a4e555SLoGin use core::cell::RefCell; 2f0c87a89SGnoCiYeH use core::sync::atomic::{fence, Ordering}; 370a4e555SLoGin 470a4e555SLoGin use crate::arch::driver::tsc::TSCManager; 5e2841179SLoGin use crate::arch::interrupt::TrapFrame; 6e2841179SLoGin use crate::driver::base::device::DeviceId; 7e2841179SLoGin use crate::exception::irqdata::{IrqHandlerData, IrqLineStatus}; 8e2841179SLoGin use crate::exception::irqdesc::{ 9e2841179SLoGin irq_desc_manager, IrqDesc, IrqFlowHandler, IrqHandleFlags, IrqHandler, IrqReturn, 10e2841179SLoGin }; 11e2841179SLoGin use crate::exception::manage::irq_manager; 12e2841179SLoGin use crate::exception::IrqNumber; 1370a4e555SLoGin 1470a4e555SLoGin use crate::kdebug; 1570a4e555SLoGin use crate::mm::percpu::PerCpu; 16f0c87a89SGnoCiYeH use crate::process::ProcessManager; 1770a4e555SLoGin use crate::smp::core::smp_get_processor_id; 18e2841179SLoGin use crate::smp::cpu::ProcessorId; 19be8cdf4bSLoGin use crate::time::clocksource::HZ; 20e2841179SLoGin use alloc::string::ToString; 21e2841179SLoGin use alloc::sync::Arc; 2270a4e555SLoGin pub use drop; 2391e9d4abSLoGin use system_error::SystemError; 2470a4e555SLoGin use x86::cpuid::cpuid; 2570a4e555SLoGin use x86::msr::{wrmsr, IA32_X2APIC_DIV_CONF, IA32_X2APIC_INIT_COUNT}; 2670a4e555SLoGin 27e2841179SLoGin use super::lapic_vector::local_apic_chip; 2870a4e555SLoGin use super::xapic::XApicOffset; 2970a4e555SLoGin use super::{CurrentApic, LVTRegister, LocalAPIC, LVT}; 3070a4e555SLoGin 31e2841179SLoGin pub const APIC_TIMER_IRQ_NUM: IrqNumber = IrqNumber::new(151); 3270a4e555SLoGin 33e2841179SLoGin static mut LOCAL_APIC_TIMERS: [RefCell<LocalApicTimer>; PerCpu::MAX_CPU_NUM as usize] = 34e2841179SLoGin [const { RefCell::new(LocalApicTimer::new()) }; PerCpu::MAX_CPU_NUM as usize]; 35e2841179SLoGin 36e2841179SLoGin #[allow(dead_code)] 3770a4e555SLoGin #[inline(always)] 38e2841179SLoGin pub(super) fn local_apic_timer_instance( 39e2841179SLoGin cpu_id: ProcessorId, 40e2841179SLoGin ) -> core::cell::Ref<'static, LocalApicTimer> { 41e2841179SLoGin unsafe { LOCAL_APIC_TIMERS[cpu_id.data() as usize].borrow() } 4270a4e555SLoGin } 4370a4e555SLoGin 4470a4e555SLoGin #[inline(always)] 4570a4e555SLoGin pub(super) fn local_apic_timer_instance_mut( 46e2841179SLoGin cpu_id: ProcessorId, 4770a4e555SLoGin ) -> core::cell::RefMut<'static, LocalApicTimer> { 48e2841179SLoGin unsafe { LOCAL_APIC_TIMERS[cpu_id.data() as usize].borrow_mut() } 49e2841179SLoGin } 50e2841179SLoGin 51e2841179SLoGin #[derive(Debug)] 52e2841179SLoGin struct LocalApicTimerHandler; 53e2841179SLoGin 54e2841179SLoGin impl IrqHandler for LocalApicTimerHandler { 55e2841179SLoGin fn handle( 56e2841179SLoGin &self, 57e2841179SLoGin _irq: IrqNumber, 58e2841179SLoGin _static_data: Option<&dyn IrqHandlerData>, 59e2841179SLoGin _dynamic_data: Option<Arc<dyn IrqHandlerData>>, 60e2841179SLoGin ) -> Result<IrqReturn, SystemError> { 61e2841179SLoGin // empty (只是为了让编译通过,不会被调用到。真正的处理函数在LocalApicTimerIrqFlowHandler中) 62e2841179SLoGin Ok(IrqReturn::NotHandled) 63e2841179SLoGin } 64e2841179SLoGin } 65e2841179SLoGin 66e2841179SLoGin #[derive(Debug)] 67e2841179SLoGin struct LocalApicTimerIrqFlowHandler; 68e2841179SLoGin 69e2841179SLoGin impl IrqFlowHandler for LocalApicTimerIrqFlowHandler { 70f0c87a89SGnoCiYeH fn handle(&self, _irq_desc: &Arc<IrqDesc>, trap_frame: &mut TrapFrame) { 71f0c87a89SGnoCiYeH LocalApicTimer::handle_irq(trap_frame).ok(); 72e2841179SLoGin CurrentApic.send_eoi(); 73f0c87a89SGnoCiYeH fence(Ordering::SeqCst) 74e2841179SLoGin } 75e2841179SLoGin } 76e2841179SLoGin 77e2841179SLoGin pub fn apic_timer_init() { 78e2841179SLoGin irq_manager() 79e2841179SLoGin .request_irq( 80e2841179SLoGin APIC_TIMER_IRQ_NUM, 81e2841179SLoGin "LocalApic".to_string(), 82e2841179SLoGin &LocalApicTimerHandler, 83e2841179SLoGin IrqHandleFlags::IRQF_SHARED | IrqHandleFlags::IRQF_PERCPU, 84e2841179SLoGin Some(DeviceId::new(Some("lapic timer"), None).unwrap()), 85e2841179SLoGin ) 86e2841179SLoGin .expect("Apic timer init failed"); 87e2841179SLoGin 88e2841179SLoGin LocalApicTimerIntrController.install(); 89e2841179SLoGin LocalApicTimerIntrController.enable(); 90e2841179SLoGin } 91e2841179SLoGin 92e2841179SLoGin /// 初始化本地APIC定时器的中断描述符 93e2841179SLoGin #[inline(never)] 94e2841179SLoGin pub(super) fn local_apic_timer_irq_desc_init() { 95e2841179SLoGin let desc = irq_desc_manager().lookup(APIC_TIMER_IRQ_NUM).unwrap(); 96e2841179SLoGin let irq_data: Arc<crate::exception::irqdata::IrqData> = desc.irq_data(); 97e2841179SLoGin let mut chip_info_guard = irq_data.chip_info_write_irqsave(); 98e2841179SLoGin chip_info_guard.set_chip(Some(local_apic_chip().clone())); 99e2841179SLoGin 100e2841179SLoGin desc.modify_status(IrqLineStatus::IRQ_LEVEL, IrqLineStatus::empty()); 101e2841179SLoGin drop(chip_info_guard); 102e2841179SLoGin desc.set_handler(&LocalApicTimerIrqFlowHandler); 10370a4e555SLoGin } 10470a4e555SLoGin 10570a4e555SLoGin /// 初始化BSP的APIC定时器 10670a4e555SLoGin /// 10770a4e555SLoGin fn init_bsp_apic_timer() { 10870a4e555SLoGin kdebug!("init_bsp_apic_timer"); 109e2841179SLoGin assert!(smp_get_processor_id().data() == 0); 110e2841179SLoGin let mut local_apic_timer = local_apic_timer_instance_mut(ProcessorId::new(0)); 11170a4e555SLoGin local_apic_timer.init( 11270a4e555SLoGin LocalApicTimerMode::Periodic, 11370a4e555SLoGin LocalApicTimer::periodic_default_initial_count(), 11470a4e555SLoGin LocalApicTimer::DIVISOR as u32, 11570a4e555SLoGin ); 11670a4e555SLoGin kdebug!("init_bsp_apic_timer done"); 11770a4e555SLoGin } 11870a4e555SLoGin 11970a4e555SLoGin fn init_ap_apic_timer() { 12070a4e555SLoGin kdebug!("init_ap_apic_timer"); 12170a4e555SLoGin let cpu_id = smp_get_processor_id(); 122e2841179SLoGin assert!(cpu_id.data() != 0); 12370a4e555SLoGin 12470a4e555SLoGin let mut local_apic_timer = local_apic_timer_instance_mut(cpu_id); 12570a4e555SLoGin local_apic_timer.init( 12670a4e555SLoGin LocalApicTimerMode::Periodic, 12770a4e555SLoGin LocalApicTimer::periodic_default_initial_count(), 12870a4e555SLoGin LocalApicTimer::DIVISOR as u32, 12970a4e555SLoGin ); 13070a4e555SLoGin kdebug!("init_ap_apic_timer done"); 13170a4e555SLoGin } 13270a4e555SLoGin 13370a4e555SLoGin pub(super) struct LocalApicTimerIntrController; 13470a4e555SLoGin 13570a4e555SLoGin impl LocalApicTimerIntrController { 136e2841179SLoGin pub(super) fn install(&self) { 13770a4e555SLoGin kdebug!("LocalApicTimerIntrController::install"); 138e2841179SLoGin if smp_get_processor_id().data() == 0 { 13970a4e555SLoGin init_bsp_apic_timer(); 14070a4e555SLoGin } else { 14170a4e555SLoGin init_ap_apic_timer(); 14270a4e555SLoGin } 14370a4e555SLoGin } 14470a4e555SLoGin 145e2841179SLoGin #[allow(dead_code)] 14670a4e555SLoGin pub(super) fn uninstall(&self) { 14770a4e555SLoGin let cpu_id = smp_get_processor_id(); 14870a4e555SLoGin let local_apic_timer = local_apic_timer_instance(cpu_id); 14970a4e555SLoGin local_apic_timer.stop_current(); 15070a4e555SLoGin } 15170a4e555SLoGin 15270a4e555SLoGin pub(super) fn enable(&self) { 15370a4e555SLoGin kdebug!("LocalApicTimerIntrController::enable"); 15470a4e555SLoGin let cpu_id = smp_get_processor_id(); 15570a4e555SLoGin let mut local_apic_timer = local_apic_timer_instance_mut(cpu_id); 15670a4e555SLoGin local_apic_timer.start_current(); 15770a4e555SLoGin } 15870a4e555SLoGin 15970a4e555SLoGin pub(super) fn disable(&self) { 16070a4e555SLoGin let cpu_id = smp_get_processor_id(); 16170a4e555SLoGin let local_apic_timer = local_apic_timer_instance_mut(cpu_id); 16270a4e555SLoGin local_apic_timer.stop_current(); 16370a4e555SLoGin } 16470a4e555SLoGin } 16570a4e555SLoGin 16670a4e555SLoGin #[derive(Debug, Copy, Clone)] 16770a4e555SLoGin pub struct LocalApicTimer { 16870a4e555SLoGin mode: LocalApicTimerMode, 16970a4e555SLoGin /// IntialCount 17070a4e555SLoGin initial_count: u64, 17170a4e555SLoGin divisor: u32, 17270a4e555SLoGin /// 是否已经触发(oneshot模式) 17370a4e555SLoGin triggered: bool, 17470a4e555SLoGin } 17570a4e555SLoGin 17670a4e555SLoGin #[derive(Debug, Copy, Clone)] 17770a4e555SLoGin #[repr(u32)] 17870a4e555SLoGin pub enum LocalApicTimerMode { 17970a4e555SLoGin Oneshot = 0, 18070a4e555SLoGin Periodic = 1, 18170a4e555SLoGin Deadline = 2, 18270a4e555SLoGin } 18370a4e555SLoGin 18470a4e555SLoGin impl LocalApicTimer { 18570a4e555SLoGin /// 定时器中断的间隔 186b5b571e0SLoGin pub const INTERVAL_MS: u64 = 1000 / HZ; 1870d6cf65aSLoGin pub const DIVISOR: u64 = 4; 18870a4e555SLoGin 18970a4e555SLoGin /// IoApicManager 初值为0或false 19070a4e555SLoGin pub const fn new() -> Self { 19170a4e555SLoGin LocalApicTimer { 19270a4e555SLoGin mode: LocalApicTimerMode::Periodic, 19370a4e555SLoGin initial_count: 0, 19470a4e555SLoGin divisor: 0, 19570a4e555SLoGin triggered: false, 19670a4e555SLoGin } 19770a4e555SLoGin } 19870a4e555SLoGin 19970a4e555SLoGin /// 周期模式下的默认初始值 20070a4e555SLoGin pub fn periodic_default_initial_count() -> u64 { 20170a4e555SLoGin let cpu_khz = TSCManager::cpu_khz(); 20270a4e555SLoGin 20370a4e555SLoGin // 疑惑:这里使用khz吗? 20470a4e555SLoGin // 我觉得应该是hz,但是由于旧的代码是测量出initcnt的,而不是计算的 20570a4e555SLoGin // 然后我发现使用hz会导致计算出来的initcnt太大,导致系统卡顿,而khz的却能跑 2060d6cf65aSLoGin let count = cpu_khz * Self::INTERVAL_MS / (Self::DIVISOR); 20770a4e555SLoGin return count; 20870a4e555SLoGin } 20970a4e555SLoGin 21070a4e555SLoGin /// Init this manager. 21170a4e555SLoGin /// 21270a4e555SLoGin /// At this time, it does nothing. 21370a4e555SLoGin fn init(&mut self, mode: LocalApicTimerMode, initial_count: u64, divisor: u32) { 21470a4e555SLoGin self.stop_current(); 21570a4e555SLoGin self.triggered = false; 21670a4e555SLoGin match mode { 21770a4e555SLoGin LocalApicTimerMode::Periodic => self.install_periodic_mode(initial_count, divisor), 21870a4e555SLoGin LocalApicTimerMode::Oneshot => todo!(), 21970a4e555SLoGin LocalApicTimerMode::Deadline => todo!(), 22070a4e555SLoGin } 22170a4e555SLoGin } 22270a4e555SLoGin 22370a4e555SLoGin fn install_periodic_mode(&mut self, initial_count: u64, divisor: u32) { 22470a4e555SLoGin kdebug!( 22570a4e555SLoGin "install_periodic_mode: initial_count = {}, divisor = {}", 22670a4e555SLoGin initial_count, 22770a4e555SLoGin divisor 22870a4e555SLoGin ); 22970a4e555SLoGin self.mode = LocalApicTimerMode::Periodic; 23070a4e555SLoGin self.set_divisor(divisor); 231e2841179SLoGin self.setup_lvt( 232e2841179SLoGin APIC_TIMER_IRQ_NUM.data() as u8, 233e2841179SLoGin true, 234e2841179SLoGin LocalApicTimerMode::Periodic, 235e2841179SLoGin ); 236*236e88d5SLoGin self.set_initial_cnt(initial_count); 23770a4e555SLoGin } 23870a4e555SLoGin 23970a4e555SLoGin fn setup_lvt(&mut self, vector: u8, mask: bool, mode: LocalApicTimerMode) { 24070a4e555SLoGin let mode: u32 = mode as u32; 24170a4e555SLoGin let data = (mode << 17) | (vector as u32) | (if mask { 1 << 16 } else { 0 }); 24270a4e555SLoGin let lvt = LVT::new(LVTRegister::Timer, data).unwrap(); 24370a4e555SLoGin 24470a4e555SLoGin CurrentApic.set_lvt(lvt); 24570a4e555SLoGin } 24670a4e555SLoGin 24770a4e555SLoGin fn set_divisor(&mut self, divisor: u32) { 24870a4e555SLoGin self.divisor = divisor; 249b5b571e0SLoGin CurrentApic.set_timer_divisor(divisor); 25070a4e555SLoGin } 25170a4e555SLoGin 25270a4e555SLoGin fn set_initial_cnt(&mut self, initial_count: u64) { 25370a4e555SLoGin self.initial_count = initial_count; 25470a4e555SLoGin CurrentApic.set_timer_initial_count(initial_count); 25570a4e555SLoGin } 25670a4e555SLoGin 25770a4e555SLoGin fn start_current(&mut self) { 25870a4e555SLoGin let mut lvt = CurrentApic.read_lvt(LVTRegister::Timer); 25970a4e555SLoGin lvt.set_mask(false); 26070a4e555SLoGin CurrentApic.set_lvt(lvt); 26170a4e555SLoGin } 26270a4e555SLoGin 26370a4e555SLoGin fn stop_current(&self) { 26470a4e555SLoGin let mut lvt = CurrentApic.read_lvt(LVTRegister::Timer); 26570a4e555SLoGin lvt.set_mask(true); 26670a4e555SLoGin CurrentApic.set_lvt(lvt); 26770a4e555SLoGin } 26870a4e555SLoGin 26970a4e555SLoGin /// 检查是否支持TSC-Deadline 27070a4e555SLoGin /// 27170a4e555SLoGin /// 此函数调用cpuid,请避免多次调用此函数。 27270a4e555SLoGin /// 如果支持TSC-Deadline模式,则除非TSC为常数,否则不会启用该模式。 27370a4e555SLoGin #[allow(dead_code)] 27470a4e555SLoGin pub fn is_deadline_mode_supported(&self) -> bool { 27570a4e555SLoGin let res = cpuid!(1); 27670a4e555SLoGin return (res.ecx & (1 << 24)) != 0; 27770a4e555SLoGin } 27870a4e555SLoGin 279f0c87a89SGnoCiYeH pub(super) fn handle_irq(trap_frame: &TrapFrame) -> Result<IrqReturn, SystemError> { 280f0c87a89SGnoCiYeH // sched_update_jiffies(); 281f0c87a89SGnoCiYeH ProcessManager::update_process_times(trap_frame.is_from_user()); 282e2841179SLoGin return Ok(IrqReturn::Handled); 28370a4e555SLoGin } 28470a4e555SLoGin } 28570a4e555SLoGin 28670a4e555SLoGin impl TryFrom<u8> for LocalApicTimerMode { 28770a4e555SLoGin type Error = SystemError; 28870a4e555SLoGin 28970a4e555SLoGin fn try_from(value: u8) -> Result<Self, Self::Error> { 29070a4e555SLoGin match value { 29170a4e555SLoGin 0b00 => { 29270a4e555SLoGin return Ok(LocalApicTimerMode::Oneshot); 29370a4e555SLoGin } 29470a4e555SLoGin 0b01 => { 29570a4e555SLoGin return Ok(LocalApicTimerMode::Periodic); 29670a4e555SLoGin } 29770a4e555SLoGin 0b10 => { 29870a4e555SLoGin return Ok(LocalApicTimerMode::Deadline); 29970a4e555SLoGin } 30070a4e555SLoGin _ => { 30170a4e555SLoGin return Err(SystemError::EINVAL); 30270a4e555SLoGin } 30370a4e555SLoGin } 30470a4e555SLoGin } 30570a4e555SLoGin } 30670a4e555SLoGin 30770a4e555SLoGin impl CurrentApic { 30870a4e555SLoGin fn set_timer_divisor(&self, divisor: u32) { 30970a4e555SLoGin if self.x2apic_enabled() { 31070a4e555SLoGin unsafe { wrmsr(IA32_X2APIC_DIV_CONF, divisor.into()) }; 31170a4e555SLoGin } else { 31270a4e555SLoGin unsafe { 313b5b571e0SLoGin self.write_xapic_register(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_CLKDIV, divisor) 31470a4e555SLoGin }; 31570a4e555SLoGin } 31670a4e555SLoGin } 31770a4e555SLoGin 31870a4e555SLoGin fn set_timer_initial_count(&self, initial_count: u64) { 31970a4e555SLoGin if self.x2apic_enabled() { 32070a4e555SLoGin unsafe { 321b5b571e0SLoGin wrmsr(IA32_X2APIC_INIT_COUNT, initial_count); 32270a4e555SLoGin } 32370a4e555SLoGin } else { 32470a4e555SLoGin unsafe { 32570a4e555SLoGin self.write_xapic_register( 32670a4e555SLoGin XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_INITIAL_COUNT_REG, 32770a4e555SLoGin initial_count as u32, 32870a4e555SLoGin ) 32970a4e555SLoGin }; 33070a4e555SLoGin } 33170a4e555SLoGin } 33270a4e555SLoGin } 333