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::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::{ 23 clocksource::HZ, 24 jiffies::NSEC_PER_JIFFY, 25 timer::{try_raise_timer_softirq, update_timer_jiffies}, 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 /// 已经过去的纳秒数 38 /// 39 /// 0号核心用这个值来更新墙上时钟,他只能被0号核心访问 40 static mut HART0_NSEC_PASSED: usize = 0; 41 /// hart0上一次更新墙上时钟的时间 42 static mut HART0_LAST_UPDATED: u64 = 0; 43 44 impl RiscVSbiTimer { 45 pub const TIMER_IRQ: IrqNumber = IrqNumber::from(5); 46 47 fn handle_irq(trap_frame: &mut TrapFrame) -> Result<(), SystemError> { 48 // 更新下一次中断时间 49 // kdebug!( 50 // "riscv_sbi_timer: handle_irq: cpu_id: {}, time: {}", 51 // smp_get_processor_id().data(), 52 // CurrentTimeArch::get_cycles() as u64 53 // ); 54 ProcessManager::update_process_times(trap_frame.is_from_user()); 55 Self::update_nsec_passed_and_walltime(); 56 sbi_rt::set_timer(CurrentTimeArch::get_cycles() as u64 + unsafe { INTERVAL_CNT } as u64); 57 Ok(()) 58 } 59 60 fn enable() { 61 unsafe { riscv::register::sie::set_stimer() }; 62 } 63 64 #[allow(dead_code)] 65 fn disable() { 66 unsafe { riscv::register::sie::clear_stimer() }; 67 } 68 69 fn update_nsec_passed_and_walltime() { 70 if smp_get_processor_id().data() != 0 { 71 return; 72 } 73 74 let cycles = CurrentTimeArch::get_cycles() as u64; 75 let nsec_passed = 76 CurrentTimeArch::cycles2ns((cycles - unsafe { HART0_LAST_UPDATED }) as usize); 77 unsafe { 78 HART0_LAST_UPDATED = cycles; 79 HART0_NSEC_PASSED += nsec_passed; 80 } 81 82 let jiffies = unsafe { HART0_NSEC_PASSED } / NSEC_PER_JIFFY as usize; 83 unsafe { HART0_NSEC_PASSED %= NSEC_PER_JIFFY as usize }; 84 85 update_timer_jiffies( 86 jiffies as u64, 87 (jiffies * NSEC_PER_JIFFY as usize / 1000) as i64, 88 ); 89 try_raise_timer_softirq(); 90 compiler_fence(Ordering::SeqCst); 91 } 92 } 93 94 /// riscv 初始化本地调度时钟源 95 #[inline(never)] 96 pub fn riscv_sbi_timer_init_local() { 97 assert_eq!(CurrentIrqArch::is_irq_enabled(), false); 98 99 if unsafe { INTERVAL_CNT } == 0 { 100 let new = riscv_time_base_freq() / HZ as usize; 101 if new == 0 { 102 panic!("riscv_sbi_timer_init: failed to get timebase-frequency"); 103 } 104 unsafe { 105 INTERVAL_CNT = new; 106 } 107 } 108 109 let mut guard = SBI_TIMER_INIT_BMP.lock(); 110 // 如果已经初始化过了,直接返回。或者cpu id不存在 111 if guard 112 .get(smp_get_processor_id().data() as usize) 113 .unwrap_or(true) 114 { 115 return; 116 } 117 118 irq_manager() 119 .request_irq( 120 RiscVSbiTimer::TIMER_IRQ, 121 "riscv_clocksource".to_string(), 122 &RiscvSbiTimerHandler, 123 IrqHandleFlags::IRQF_SHARED | IrqHandleFlags::IRQF_PERCPU, 124 Some(DeviceId::new(Some("riscv sbi timer"), None).unwrap()), 125 ) 126 .expect("Apic timer init failed"); 127 128 // 设置第一次中断 129 sbi_rt::set_timer(CurrentTimeArch::get_cycles() as u64); 130 131 RiscVSbiTimer::enable(); 132 guard 133 .set(smp_get_processor_id().data() as usize, true) 134 .unwrap(); 135 } 136 137 #[inline(never)] 138 pub fn riscv_sbi_timer_irq_desc_init() { 139 let desc = irq_desc_manager().lookup(RiscVSbiTimer::TIMER_IRQ).unwrap(); 140 141 desc.modify_status(IrqLineStatus::IRQ_LEVEL, IrqLineStatus::empty()); 142 desc.set_handler(&RiscvSbiTimerIrqFlowHandler); 143 } 144 145 #[derive(Debug)] 146 struct RiscvSbiTimerHandler; 147 148 impl IrqHandler for RiscvSbiTimerHandler { 149 fn handle( 150 &self, 151 _irq: IrqNumber, 152 _static_data: Option<&dyn IrqHandlerData>, 153 _dynamic_data: Option<Arc<dyn IrqHandlerData>>, 154 ) -> Result<IrqReturn, SystemError> { 155 // empty (只是为了让编译通过,不会被调用到。真正的处理函数在 RiscvSbiTimerIrqFlowHandler 中) 156 Ok(IrqReturn::NotHandled) 157 } 158 } 159 160 #[derive(Debug)] 161 struct RiscvSbiTimerIrqFlowHandler; 162 163 impl IrqFlowHandler for RiscvSbiTimerIrqFlowHandler { 164 fn handle(&self, _irq_desc: &Arc<IrqDesc>, trap_frame: &mut TrapFrame) { 165 RiscVSbiTimer::handle_irq(trap_frame).unwrap(); 166 fence(Ordering::SeqCst) 167 } 168 } 169