123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- use core::sync::atomic::{fence, Ordering};
- use alloc::{string::ToString, sync::Arc};
- use bitmap::{traits::BitMapOps, StaticBitmap};
- use system_error::SystemError;
- use crate::{
- arch::{interrupt::TrapFrame, time::riscv_time_base_freq, CurrentIrqArch, CurrentTimeArch},
- driver::base::device::DeviceId,
- exception::{
- irqdata::{IrqHandlerData, IrqLineStatus},
- irqdesc::{
- irq_desc_manager, IrqDesc, IrqFlowHandler, IrqHandleFlags, IrqHandler, IrqReturn,
- },
- manage::irq_manager,
- InterruptArch, IrqNumber,
- },
- libs::spinlock::SpinLock,
- mm::percpu::PerCpu,
- process::ProcessManager,
- smp::core::smp_get_processor_id,
- time::TimeArch,
- };
- pub struct RiscVSbiTimer;
- static SBI_TIMER_INIT_BMP: SpinLock<StaticBitmap<{ PerCpu::MAX_CPU_NUM as usize }>> =
- SpinLock::new(StaticBitmap::new());
- static mut INTERVAL_CNT: usize = 0;
- impl RiscVSbiTimer {
- pub const TIMER_IRQ: IrqNumber = IrqNumber::from(5);
- fn handle_irq(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
- // 更新下一次中断时间
- // kdebug!(
- // "riscv_sbi_timer: handle_irq: cpu_id: {}, time: {}",
- // smp_get_processor_id().data(),
- // CurrentTimeArch::get_cycles() as u64
- // );
- sbi_rt::set_timer(CurrentTimeArch::get_cycles() as u64 + unsafe { INTERVAL_CNT } as u64);
- ProcessManager::update_process_times(trap_frame.is_from_user());
- Ok(())
- }
- fn enable() {
- unsafe { riscv::register::sie::set_stimer() };
- }
- fn disable() {
- unsafe { riscv::register::sie::clear_stimer() };
- }
- }
- /// riscv 初始化本地调度时钟源
- #[inline(never)]
- pub fn riscv_sbi_timer_init_local() {
- assert_eq!(CurrentIrqArch::is_irq_enabled(), false);
- if unsafe { INTERVAL_CNT } == 0 {
- // todo: 将来正式实现时,需要除以HZ
- let new = riscv_time_base_freq() / 3;
- if new == 0 {
- panic!("riscv_sbi_timer_init: failed to get timebase-frequency");
- }
- unsafe {
- INTERVAL_CNT = new;
- }
- }
- let mut guard = SBI_TIMER_INIT_BMP.lock();
- // 如果已经初始化过了,直接返回。或者cpu id不存在
- if guard
- .get(smp_get_processor_id().data() as usize)
- .unwrap_or(true)
- {
- return;
- }
- irq_manager()
- .request_irq(
- RiscVSbiTimer::TIMER_IRQ,
- "riscv_clocksource".to_string(),
- &RiscvSbiTimerHandler,
- IrqHandleFlags::IRQF_SHARED | IrqHandleFlags::IRQF_PERCPU,
- Some(DeviceId::new(Some("riscv sbi timer"), None).unwrap()),
- )
- .expect("Apic timer init failed");
- // 设置第一次中断
- sbi_rt::set_timer(CurrentTimeArch::get_cycles() as u64);
- RiscVSbiTimer::enable();
- guard
- .set(smp_get_processor_id().data() as usize, true)
- .unwrap();
- }
- #[inline(never)]
- pub fn riscv_sbi_timer_irq_desc_init() {
- let desc = irq_desc_manager().lookup(RiscVSbiTimer::TIMER_IRQ).unwrap();
- desc.modify_status(IrqLineStatus::IRQ_LEVEL, IrqLineStatus::empty());
- desc.set_handler(&RiscvSbiTimerIrqFlowHandler);
- }
- #[derive(Debug)]
- struct RiscvSbiTimerHandler;
- impl IrqHandler for RiscvSbiTimerHandler {
- fn handle(
- &self,
- _irq: IrqNumber,
- _static_data: Option<&dyn IrqHandlerData>,
- _dynamic_data: Option<Arc<dyn IrqHandlerData>>,
- ) -> Result<IrqReturn, SystemError> {
- // empty (只是为了让编译通过,不会被调用到。真正的处理函数在 RiscvSbiTimerIrqFlowHandler 中)
- Ok(IrqReturn::NotHandled)
- }
- }
- #[derive(Debug)]
- struct RiscvSbiTimerIrqFlowHandler;
- impl IrqFlowHandler for RiscvSbiTimerIrqFlowHandler {
- fn handle(&self, _irq_desc: &Arc<IrqDesc>, trap_frame: &mut TrapFrame) {
- RiscVSbiTimer::handle_irq(trap_frame).unwrap();
- fence(Ordering::SeqCst)
- }
- }
|