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 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 53 fn enable() { 54 unsafe { riscv::register::sie::set_stimer() }; 55 } 56 57 #[allow(dead_code)] 58 fn disable() { 59 unsafe { riscv::register::sie::clear_stimer() }; 60 } 61 } 62 63 /// riscv 初始化本地调度时钟源 64 #[inline(never)] 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)] 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 { 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 { 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