-
-
Notifications
You must be signed in to change notification settings - Fork 141
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
340 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#[cfg(target_arch = "riscv64")] | ||
pub mod timer_riscv; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
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(); | ||
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) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
pub mod acpi; | ||
pub mod base; | ||
pub mod block; | ||
pub mod clocksource; | ||
pub mod disk; | ||
pub mod firmware; | ||
pub mod input; | ||
|
Oops, something went wrong.