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