diff --git a/ostd/src/arch/riscv/mod.rs b/ostd/src/arch/riscv/mod.rs index cddeae567..b8d521831 100644 --- a/ostd/src/arch/riscv/mod.rs +++ b/ostd/src/arch/riscv/mod.rs @@ -48,14 +48,14 @@ pub(crate) unsafe fn late_init_on_bsp() { // SAFETY: This is called before any IPI-related operation is performed. unsafe { irq::ipi::init() }; - // SAFETY: We're on the BSP and we're ready to boot all APs. - unsafe { crate::boot::smp::boot_all_aps() }; - // SAFETY: This function is called once and at most once at a proper timing // in the boot context of the BSP, with no timer-related operations having // been performed. unsafe { timer::init() }; + // SAFETY: We're on the BSP and we're ready to boot all APs. + unsafe { crate::boot::smp::boot_all_aps() }; + // SAFETY: // 1. All the system device memory have been removed from the builder. // 2. RISC-V platforms do not have port I/O. @@ -82,6 +82,9 @@ pub(crate) unsafe fn init_on_ap() { // SAFETY: This is called before any IPI-related operation is performed. unsafe { irq::ipi::init_current_hart() }; + + // SAFETY: The caller ensures that this function is only called once here. + unsafe { timer::init_current_hart() }; } /// Returns the frequency of TSC. The unit is Hz. diff --git a/ostd/src/arch/riscv/timer/mod.rs b/ostd/src/arch/riscv/timer/mod.rs index cd38386ad..14a85a2d1 100644 --- a/ostd/src/arch/riscv/timer/mod.rs +++ b/ostd/src/arch/riscv/timer/mod.rs @@ -26,8 +26,8 @@ static TIMER_INTERVAL: AtomicU64 = AtomicU64::new(0); /// # Safety /// /// This function is safe to call on the following conditions: -/// 1. It is called once and at most once at a proper timing in the boot context. -/// 2. It is called before any other public functions of this module is called. +/// 1. It is called once and at most once at a proper timing in the boot context. +/// 2. It is called before any other public functions of this module is called. pub(super) unsafe fn init() { TIMEBASE_FREQ.store( DEVICE_TREE @@ -60,6 +60,16 @@ pub(super) unsafe fn init() { timer_irq }); + // SAFETY: The caller ensures that this is only called once on the boot hart. + unsafe { init_current_hart() }; +} + +/// Initializes the timer on the current hart. +/// +/// # Safety +/// +/// This function must be called in a hart that hasn't called this function. +pub(super) unsafe fn init_current_hart() { set_next_timer(); // SAFETY: Accessing the `sie` CSR to enable the timer interrupt is safe // here because this function is only called during timer initialization,