timer_riscv.rs 3.9 KB

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