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