xref: /DragonOS/kernel/src/driver/clocksource/timer_riscv.rs (revision af097f9f4b317337fe74aaa5070c34a14b8635fd)
1 use core::sync::atomic::{compiler_fence, fence, Ordering};
2 
3 use alloc::{string::ToString, sync::Arc};
4 use bitmap::{traits::BitMapOps, StaticBitmap};
5 use system_error::SystemError;
6 
7 use crate::{
8     arch::{interrupt::TrapFrame, time::riscv_time_base_freq, CurrentIrqArch, CurrentTimeArch},
9     driver::{
10         base::device::DeviceId,
11         irqchip::riscv_intc::{riscv_intc_assicate_irq, riscv_intc_hwirq_to_virq},
12     },
13     exception::{
14         irqdata::{IrqHandlerData, IrqLineStatus},
15         irqdesc::{
16             irq_desc_manager, IrqDesc, IrqFlowHandler, IrqHandleFlags, IrqHandler, IrqReturn,
17         },
18         manage::irq_manager,
19         HardwareIrqNumber, InterruptArch, IrqNumber,
20     },
21     libs::spinlock::SpinLock,
22     mm::percpu::PerCpu,
23     smp::core::smp_get_processor_id,
24     time::{
25         clocksource::HZ, tick_common::tick_handle_periodic, timer::try_raise_timer_softirq,
26         TimeArch,
27     },
28 };
29 
30 pub struct RiscVSbiTimer;
31 
32 static SBI_TIMER_INIT_BMP: SpinLock<StaticBitmap<{ PerCpu::MAX_CPU_NUM as usize }>> =
33     SpinLock::new(StaticBitmap::new());
34 
35 static mut INTERVAL_CNT: usize = 0;
36 
37 impl RiscVSbiTimer {
38     pub const TIMER_IRQ: HardwareIrqNumber = HardwareIrqNumber::new(5);
39 
handle_irq(trap_frame: &mut TrapFrame) -> Result<(), SystemError>40     fn handle_irq(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
41         // 更新下一次中断时间
42         // debug!(
43         //     "riscv_sbi_timer: handle_irq: cpu_id: {}, time: {}",
44         //     smp_get_processor_id().data(),
45         //     CurrentTimeArch::get_cycles() as u64
46         // );
47         tick_handle_periodic(trap_frame);
48         compiler_fence(Ordering::SeqCst);
49         sbi_rt::set_timer(CurrentTimeArch::get_cycles() as u64 + unsafe { INTERVAL_CNT } as u64);
50         Ok(())
51     }
52 
enable()53     fn enable() {
54         unsafe { riscv::register::sie::set_stimer() };
55     }
56 
57     #[allow(dead_code)]
disable()58     fn disable() {
59         unsafe { riscv::register::sie::clear_stimer() };
60     }
61 }
62 
63 /// riscv 初始化本地调度时钟源
64 #[inline(never)]
riscv_sbi_timer_init_local()65 pub fn riscv_sbi_timer_init_local() {
66     assert_eq!(CurrentIrqArch::is_irq_enabled(), false);
67 
68     if unsafe { INTERVAL_CNT } == 0 {
69         let new = riscv_time_base_freq() / HZ as usize;
70         if new == 0 {
71             panic!("riscv_sbi_timer_init: failed to get timebase-frequency");
72         }
73         unsafe {
74             INTERVAL_CNT = new;
75         }
76     }
77 
78     let mut guard = SBI_TIMER_INIT_BMP.lock();
79     // 如果已经初始化过了,直接返回。或者cpu id不存在
80     if guard
81         .get(smp_get_processor_id().data() as usize)
82         .unwrap_or(true)
83     {
84         return;
85     }
86 
87     irq_manager()
88         .request_irq(
89             riscv_intc_hwirq_to_virq(RiscVSbiTimer::TIMER_IRQ).unwrap(),
90             "riscv_clocksource".to_string(),
91             &RiscvSbiTimerHandler,
92             IrqHandleFlags::IRQF_SHARED | IrqHandleFlags::IRQF_PERCPU,
93             Some(DeviceId::new(Some("riscv sbi timer"), None).unwrap()),
94         )
95         .expect("Apic timer init failed");
96 
97     // 设置第一次中断
98     sbi_rt::set_timer(CurrentTimeArch::get_cycles() as u64);
99 
100     RiscVSbiTimer::enable();
101     guard
102         .set(smp_get_processor_id().data() as usize, true)
103         .unwrap();
104 }
105 
106 #[inline(never)]
riscv_sbi_timer_irq_desc_init()107 pub fn riscv_sbi_timer_irq_desc_init() {
108     let virq = riscv_intc_assicate_irq(RiscVSbiTimer::TIMER_IRQ).unwrap();
109     let desc = irq_desc_manager().lookup(virq).unwrap();
110 
111     desc.modify_status(IrqLineStatus::IRQ_LEVEL, IrqLineStatus::empty());
112     desc.set_handler(&RiscvSbiTimerIrqFlowHandler);
113 }
114 
115 #[derive(Debug)]
116 struct RiscvSbiTimerHandler;
117 
118 impl IrqHandler for RiscvSbiTimerHandler {
handle( &self, _irq: IrqNumber, _static_data: Option<&dyn IrqHandlerData>, _dynamic_data: Option<Arc<dyn IrqHandlerData>>, ) -> Result<IrqReturn, SystemError>119     fn handle(
120         &self,
121         _irq: IrqNumber,
122         _static_data: Option<&dyn IrqHandlerData>,
123         _dynamic_data: Option<Arc<dyn IrqHandlerData>>,
124     ) -> Result<IrqReturn, SystemError> {
125         // empty (只是为了让编译通过,不会被调用到。真正的处理函数在 RiscvSbiTimerIrqFlowHandler 中)
126         Ok(IrqReturn::NotHandled)
127     }
128 }
129 
130 #[derive(Debug)]
131 struct RiscvSbiTimerIrqFlowHandler;
132 
133 impl IrqFlowHandler for RiscvSbiTimerIrqFlowHandler {
handle(&self, _irq_desc: &Arc<IrqDesc>, trap_frame: &mut TrapFrame)134     fn handle(&self, _irq_desc: &Arc<IrqDesc>, trap_frame: &mut TrapFrame) {
135         RiscVSbiTimer::handle_irq(trap_frame).unwrap();
136         fence(Ordering::SeqCst)
137     }
138 }
139