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::mm::percpu::PerCpu;
1570a4e555SLoGin use crate::smp::core::smp_get_processor_id;
16e2841179SLoGin use crate::smp::cpu::ProcessorId;
17be8cdf4bSLoGin use crate::time::clocksource::HZ;
18af097f9fS黄铭涛 use crate::time::tick_common::tick_handle_periodic;
19e2841179SLoGin use alloc::string::ToString;
20e2841179SLoGin use alloc::sync::Arc;
2170a4e555SLoGin pub use drop;
222eab6dd7S曾俊 use log::debug;
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)]
local_apic_timer_instance( cpu_id: ProcessorId, ) -> core::cell::Ref<'static, LocalApicTimer>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)]
local_apic_timer_instance_mut( cpu_id: ProcessorId, ) -> core::cell::RefMut<'static, LocalApicTimer>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 {
handle( &self, _irq: IrqNumber, _static_data: Option<&dyn IrqHandlerData>, _dynamic_data: Option<Arc<dyn IrqHandlerData>>, ) -> Result<IrqReturn, SystemError>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 {
handle(&self, _irq_desc: &Arc<IrqDesc>, trap_frame: &mut TrapFrame)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
apic_timer_init()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)]
local_apic_timer_irq_desc_init()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 ///
init_bsp_apic_timer()10770a4e555SLoGin fn init_bsp_apic_timer() {
1082eab6dd7S曾俊 debug!("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 );
1162eab6dd7S曾俊 debug!("init_bsp_apic_timer done");
11770a4e555SLoGin }
11870a4e555SLoGin
init_ap_apic_timer()11970a4e555SLoGin fn init_ap_apic_timer() {
1202eab6dd7S曾俊 debug!("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 );
1302eab6dd7S曾俊 debug!("init_ap_apic_timer done");
13170a4e555SLoGin }
13270a4e555SLoGin
13370a4e555SLoGin pub(super) struct LocalApicTimerIntrController;
13470a4e555SLoGin
13570a4e555SLoGin impl LocalApicTimerIntrController {
install(&self)136e2841179SLoGin pub(super) fn install(&self) {
1372eab6dd7S曾俊 debug!("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)]
uninstall(&self)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
enable(&self)15270a4e555SLoGin pub(super) fn enable(&self) {
1532eab6dd7S曾俊 debug!("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
159*bd70d2d1SLoGin #[allow(dead_code)]
disable(&self)16070a4e555SLoGin pub(super) fn disable(&self) {
16170a4e555SLoGin let cpu_id = smp_get_processor_id();
16270a4e555SLoGin let local_apic_timer = local_apic_timer_instance_mut(cpu_id);
16370a4e555SLoGin local_apic_timer.stop_current();
16470a4e555SLoGin }
16570a4e555SLoGin }
16670a4e555SLoGin
16770a4e555SLoGin #[derive(Debug, Copy, Clone)]
16870a4e555SLoGin pub struct LocalApicTimer {
16970a4e555SLoGin mode: LocalApicTimerMode,
17070a4e555SLoGin /// IntialCount
17170a4e555SLoGin initial_count: u64,
17270a4e555SLoGin divisor: u32,
17370a4e555SLoGin /// 是否已经触发(oneshot模式)
17470a4e555SLoGin triggered: bool,
17570a4e555SLoGin }
17670a4e555SLoGin
17770a4e555SLoGin #[derive(Debug, Copy, Clone)]
17870a4e555SLoGin #[repr(u32)]
17970a4e555SLoGin pub enum LocalApicTimerMode {
18070a4e555SLoGin Oneshot = 0,
18170a4e555SLoGin Periodic = 1,
18270a4e555SLoGin Deadline = 2,
18370a4e555SLoGin }
18470a4e555SLoGin
18570a4e555SLoGin impl LocalApicTimer {
18670a4e555SLoGin /// 定时器中断的间隔
187b5b571e0SLoGin pub const INTERVAL_MS: u64 = 1000 / HZ;
1880d6cf65aSLoGin pub const DIVISOR: u64 = 4;
18970a4e555SLoGin
19070a4e555SLoGin /// IoApicManager 初值为0或false
new() -> Self19170a4e555SLoGin pub const fn new() -> Self {
19270a4e555SLoGin LocalApicTimer {
19370a4e555SLoGin mode: LocalApicTimerMode::Periodic,
19470a4e555SLoGin initial_count: 0,
19570a4e555SLoGin divisor: 0,
19670a4e555SLoGin triggered: false,
19770a4e555SLoGin }
19870a4e555SLoGin }
19970a4e555SLoGin
20070a4e555SLoGin /// 周期模式下的默认初始值
periodic_default_initial_count() -> u6420170a4e555SLoGin pub fn periodic_default_initial_count() -> u64 {
20270a4e555SLoGin let cpu_khz = TSCManager::cpu_khz();
20370a4e555SLoGin
20470a4e555SLoGin // 疑惑:这里使用khz吗?
20570a4e555SLoGin // 我觉得应该是hz,但是由于旧的代码是测量出initcnt的,而不是计算的
20670a4e555SLoGin // 然后我发现使用hz会导致计算出来的initcnt太大,导致系统卡顿,而khz的却能跑
2070d6cf65aSLoGin let count = cpu_khz * Self::INTERVAL_MS / (Self::DIVISOR);
20870a4e555SLoGin return count;
20970a4e555SLoGin }
21070a4e555SLoGin
21170a4e555SLoGin /// Init this manager.
21270a4e555SLoGin ///
21370a4e555SLoGin /// At this time, it does nothing.
init(&mut self, mode: LocalApicTimerMode, initial_count: u64, divisor: u32)21470a4e555SLoGin fn init(&mut self, mode: LocalApicTimerMode, initial_count: u64, divisor: u32) {
21570a4e555SLoGin self.stop_current();
21670a4e555SLoGin self.triggered = false;
21770a4e555SLoGin match mode {
21870a4e555SLoGin LocalApicTimerMode::Periodic => self.install_periodic_mode(initial_count, divisor),
21970a4e555SLoGin LocalApicTimerMode::Oneshot => todo!(),
22070a4e555SLoGin LocalApicTimerMode::Deadline => todo!(),
22170a4e555SLoGin }
22270a4e555SLoGin }
22370a4e555SLoGin
install_periodic_mode(&mut self, initial_count: u64, divisor: u32)22470a4e555SLoGin fn install_periodic_mode(&mut self, initial_count: u64, divisor: u32) {
2252eab6dd7S曾俊 debug!(
22670a4e555SLoGin "install_periodic_mode: initial_count = {}, divisor = {}",
2272eab6dd7S曾俊 initial_count, 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 );
236236e88d5SLoGin self.set_initial_cnt(initial_count);
23770a4e555SLoGin }
23870a4e555SLoGin
setup_lvt(&mut self, vector: u8, mask: bool, mode: LocalApicTimerMode)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
set_divisor(&mut self, divisor: u32)24770a4e555SLoGin fn set_divisor(&mut self, divisor: u32) {
24870a4e555SLoGin self.divisor = divisor;
249b5b571e0SLoGin CurrentApic.set_timer_divisor(divisor);
25070a4e555SLoGin }
25170a4e555SLoGin
set_initial_cnt(&mut self, initial_count: u64)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
start_current(&mut self)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
stop_current(&self)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)]
is_deadline_mode_supported(&self) -> bool27470a4e555SLoGin pub fn is_deadline_mode_supported(&self) -> bool {
27570a4e555SLoGin let res = cpuid!(1);
27670a4e555SLoGin return (res.ecx & (1 << 24)) != 0;
27770a4e555SLoGin }
27870a4e555SLoGin
handle_irq(trap_frame: &TrapFrame) -> Result<IrqReturn, SystemError>279f0c87a89SGnoCiYeH pub(super) fn handle_irq(trap_frame: &TrapFrame) -> Result<IrqReturn, SystemError> {
280f0c87a89SGnoCiYeH // sched_update_jiffies();
281af097f9fS黄铭涛 tick_handle_periodic(trap_frame);
282e2841179SLoGin return Ok(IrqReturn::Handled);
28370a4e555SLoGin }
28470a4e555SLoGin }
28570a4e555SLoGin
28670a4e555SLoGin impl TryFrom<u8> for LocalApicTimerMode {
28770a4e555SLoGin type Error = SystemError;
28870a4e555SLoGin
try_from(value: u8) -> Result<Self, Self::Error>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 {
set_timer_divisor(&self, divisor: u32)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
set_timer_initial_count(&self, initial_count: u64)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