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