Pārlūkot izejas kodu

feat(hal): add timer interrupt enable

Heinz 7 mēneši atpakaļ
vecāks
revīzija
7280c46efb

+ 4 - 0
crates/eonix_hal/src/arch/riscv64/bootstrap.rs

@@ -8,6 +8,7 @@ use crate::{
         cpu::CPU,
         fdt::{init_dtb_and_fdt, FdtExt},
         mm::{ArchPhysAccess, FreeRam, PageAttribute64, GLOBAL_PAGE_TABLE},
+        interrupt::enable_timer_interrupt,
     },
     bootstrap::BootStrapData,
     mm::{ArchMemory, ArchPagingMode, BasicPageAlloc, BasicPageAllocRef, ScopedAllocator},
@@ -221,6 +222,9 @@ fn setup_cpu(alloc: impl PageAlloc, hart_id: usize) {
             .as_mut()
             .set_kernel_tp(PercpuArea::get_for(cpu.cpuid()).unwrap().cast());
     }
+
+    // set current hart's mtimecmp registerAdd commentMore actions
+    enable_timer_interrupt();
 }
 
 /// TODO

+ 5 - 0
crates/eonix_hal/src/arch/riscv64/config.rs

@@ -41,6 +41,11 @@ pub mod platform {
         pub const CLINT_MSIP_OFFSET: usize = 0x0000; // Machine-mode Software Interrupt Pending (MSIP)
         pub const CLINT_MTIMECMP_OFFSET: usize = 0x4000; // Machine-mode Timer Compare (MTIMECMP)
         pub const CLINT_MTIME_OFFSET: usize = 0xBFF8;
+        // TODO: this should get in fdt
         pub const CPU_FREQ_HZ: u64 = 10_000_000;
     }
 }
+
+pub mod time {
+    pub const INTERRUPTS_PER_SECOND: usize = 100;
+}

+ 4 - 2
crates/eonix_hal/src/arch/riscv64/cpu.rs

@@ -2,7 +2,7 @@ use super::{
     interrupt::InterruptControl,
     trap::{setup_trap, TRAP_SCRATCH},
 };
-use crate::arch::fdt::{FdtExt, FDT};
+use crate::arch::{fdt::{FdtExt, FDT}, time::set_next_timer};
 use core::{arch::asm, pin::Pin, ptr::NonNull};
 use eonix_preempt::PreemptGuard;
 use eonix_sync_base::LazyLock;
@@ -79,7 +79,9 @@ impl CPU {
     }
 
     pub fn end_of_interrupt(self: Pin<&mut Self>) {
-        todo!()
+        // TODO: only timer interrupt should do this, here may need to change 
+        // if some other interrupt need send end signal
+        set_next_timer();
     }
 
     pub fn local() -> PreemptGuard<Pin<&'static mut Self>> {

+ 8 - 0
crates/eonix_hal/src/arch/riscv64/interrupt/mod.rs

@@ -1,6 +1,9 @@
 use core::pin::Pin;
 
+use crate::arch::time;
+
 use super::config::platform::virt::*;
+use riscv::register::sie;
 use riscv_peripheral::{
     aclint::{Clint, CLINT},
     plic::{Plic, PLIC},
@@ -38,3 +41,8 @@ impl InterruptControl {
 
     pub fn init(self: Pin<&mut Self>) {}
 }
+
+pub fn enable_timer_interrupt() {
+    unsafe { sie::set_stimer() };
+    time::set_next_timer();
+}

+ 1 - 0
crates/eonix_hal/src/arch/riscv64/mod.rs

@@ -9,3 +9,4 @@ pub mod fpu;
 pub mod interrupt;
 pub mod mm;
 pub mod trap;
+pub mod time;

+ 18 - 0
crates/eonix_hal/src/arch/riscv64/time.rs

@@ -0,0 +1,18 @@
+use riscv::register::time;
+use super::config::{
+    platform::virt::CPU_FREQ_HZ,
+    time::INTERRUPTS_PER_SECOND
+};
+
+pub fn get_time() -> usize {
+    time::read()
+}
+
+pub fn set_timer(times: usize) {
+    let time = (get_time() + times * CPU_FREQ_HZ as usize / INTERRUPTS_PER_SECOND) as u64;
+    sbi::legacy::set_timer(time);
+}
+
+pub fn set_next_timer() {
+    set_timer(1);
+}