Prechádzať zdrojové kódy

arch, la: setup timer and timer interrupt on bootstrap

Setup an 1ms periodic timer on boostrap. Write the corresponding MSR to
clear and setup the next timer on interrupt.

(cherry picked from commit c46300c164962352e78b318e6e5c3f23a5d9dd72)
Signed-off-by: greatbridf <greatbridf@icloud.com>
greatbridf 6 mesiacov pred
rodič
commit
287bb545c5

+ 11 - 1
crates/eonix_hal/src/arch/loongarch64/bootstrap.rs

@@ -25,6 +25,9 @@ use eonix_mm::{
     paging::{Page, PageAccess, PageAlloc, PAGE_SIZE, PFN},
 };
 use eonix_percpu::PercpuArea;
+use loongArch64::register::ecfg;
+use loongArch64::register::ecfg::LineBasedInterrupt;
+use loongArch64::register::tcfg;
 use loongArch64::register::{euen, pgdl};
 
 #[unsafe(link_section = ".bootstrap.stack")]
@@ -264,7 +267,14 @@ fn setup_cpu(alloc: impl PageAlloc, hart_id: usize) {
         )
     }
 
-    // todo!("set_next_timer()");
+    let timer_frequency = loongArch64::time::get_timer_freq();
+
+    // 1ms periodic timer.
+    tcfg::set_init_val(timer_frequency / 1_000);
+    tcfg::set_periodic(true);
+    tcfg::set_en(true);
+
+    ecfg::set_lie(LineBasedInterrupt::all());
 }
 
 /// TODO

+ 2 - 1
crates/eonix_hal/src/arch/loongarch64/trap/trap_context.rs

@@ -8,6 +8,7 @@ use eonix_mm::address::VAddr;
 use loongArch64::register::{
     badv,
     estat::{Estat, Exception, Interrupt, Trap},
+    ticlr,
 };
 
 #[repr(C)]
@@ -145,7 +146,7 @@ impl RawTrapContext for TrapContext {
         match self.estat.cause() {
             Trap::Interrupt(Interrupt::Timer) => TrapType::Timer {
                 callback: |handler| {
-                    todo!("set_next_timer()");
+                    ticlr::clear_timer_interrupt();
                     handler();
                 },
             },