Преглед изворни кода

Test-kernel: update SBI base module test

luojia65 пре 4 година
родитељ
комит
78071a15e0
2 измењених фајлова са 95 додато и 5 уклоњено
  1. 19 0
      test-kernel/src/main.rs
  2. 76 5
      test-kernel/src/sbi.rs

+ 19 - 0
test-kernel/src/main.rs

@@ -11,6 +11,7 @@ use riscv::register::{sepc, stvec::{self, TrapMode}};
 
 pub extern "C" fn rust_main(hartid: usize, dtb_pa: usize) -> ! {
     println!("<< Test-kernel: Hart id = {}, DTB physical address = {:#x}", hartid, dtb_pa);
+    test_base_extension();
     unsafe { stvec::write(start_trap as usize, TrapMode::Direct) };
     println!(">> Test-kernel: Trigger illegal exception");
     unsafe { asm!("csrw mcycle, x0") }; // mcycle cannot be written, this is always a 4-byte illegal instruction
@@ -18,6 +19,24 @@ pub extern "C" fn rust_main(hartid: usize, dtb_pa: usize) -> ! {
     sbi::shutdown()
 }
 
+fn test_base_extension() {
+    println!("<< Test-kernel: Testing base extension");
+    let base_version = sbi::probe_extension(sbi::EXTENSION_BASE);
+    if base_version == 0 {
+        println!("!! Test-kernel: no base extension probed; SBI call returned value '0'");
+        println!("!! Test-kernel: This SBI implementation may only have legacy extension implemented");
+        println!("!! Test-kernel: SBI test FAILED due to no base extension found");
+        sbi::shutdown()
+    }
+    println!("<< Test-kernel: Base extension version: {:x}", base_version);
+    println!("<< Test-kernel: SBI specification version: {:x}", sbi::get_spec_version());
+    println!("<< Test-kernel: SBI implementation Id: {:x}", sbi::get_sbi_impl_id());
+    println!("<< Test-kernel: SBI implementation version: {:x}", sbi::get_sbi_impl_version());
+    println!("<< Test-kernel: Device mvendorid: {:x}", sbi::get_mvendorid());
+    println!("<< Test-kernel: Device marchid: {:x}", sbi::get_marchid());
+    println!("<< Test-kernel: Device mimpid: {:x}", sbi::get_mimpid());
+}
+
 pub extern "C" fn rust_trap_exception() {
     println!("<< Test-kernel: Illegal exception delegate success");
     sepc::write(sepc::read().wrapping_add(4));

+ 76 - 5
test-kernel/src/sbi.rs

@@ -1,7 +1,78 @@
 #![allow(unused)]
 
+pub const EXTENSION_BASE: usize = 0x10;
+pub const EXTENSION_TIMER: usize = 0x54494D45;
+pub const EXTENSION_IPI: usize = 0x735049;
+pub const EXTENSION_RFENCE: usize = 0x52464E43;
+pub const EXTENSION_HSM: usize = 0x48534D;
+pub const EXTENSION_SRST: usize = 0x53525354;
+
+const FUNCTION_BASE_GET_SPEC_VERSION: usize = 0x0;
+const FUNCTION_BASE_GET_SBI_IMPL_ID: usize = 0x1;
+const FUNCTION_BASE_GET_SBI_IMPL_VERSION: usize = 0x2;
+const FUNCTION_BASE_PROBE_EXTENSION: usize = 0x3;
+const FUNCTION_BASE_GET_MVENDORID: usize = 0x4;
+const FUNCTION_BASE_GET_MARCHID: usize = 0x5;
+const FUNCTION_BASE_GET_MIMPID: usize = 0x6;
+
+#[repr(C)]
+pub struct SbiRet {
+    /// Error number
+    pub error: usize,
+    /// Result value
+    pub value: usize,
+}
+
+#[inline(always)]
+fn sbi_call(extension: usize, function: usize, arg0: usize, arg1: usize, arg2: usize) -> SbiRet {
+    let (error, value);
+    unsafe {
+        llvm_asm!("ecall"
+            : "={x10}" (error), "={x11}" (value)
+            : "{x10}" (arg0), "{x11}" (arg1), "{x12}" (arg2), "{x16}" (function), "{x17}" (extension)
+            : "memory"
+            : "volatile"); 
+    }
+    SbiRet { error, value }
+}
+
+#[inline]
+pub fn get_spec_version() -> usize {
+    sbi_call(EXTENSION_BASE, FUNCTION_BASE_GET_SPEC_VERSION, 0, 0, 0).value
+}
+
+#[inline]
+pub fn get_sbi_impl_id() -> usize {
+    sbi_call(EXTENSION_BASE, FUNCTION_BASE_GET_SBI_IMPL_ID, 0, 0, 0).value
+}
+
+#[inline]
+pub fn get_sbi_impl_version() -> usize {
+    sbi_call(EXTENSION_BASE, FUNCTION_BASE_GET_SBI_IMPL_VERSION, 0, 0, 0).value
+}
+
+#[inline]
+pub fn probe_extension(extension_id: usize) -> usize {
+    sbi_call(EXTENSION_BASE, FUNCTION_BASE_PROBE_EXTENSION, extension_id, 0, 0).value
+}
+
+#[inline]
+pub fn get_mvendorid() -> usize {
+    sbi_call(EXTENSION_BASE, FUNCTION_BASE_GET_MVENDORID, 0, 0, 0).value
+}
+
+#[inline]
+pub fn get_marchid() -> usize {
+    sbi_call(EXTENSION_BASE, FUNCTION_BASE_GET_MARCHID, 0, 0, 0).value
+}
+
+#[inline]
+pub fn get_mimpid() -> usize {
+    sbi_call(EXTENSION_BASE, FUNCTION_BASE_GET_MIMPID, 0, 0, 0).value
+}
+
 #[inline(always)]
-fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize {
+fn sbi_call_legacy(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize {
     let ret;
     unsafe {
         llvm_asm!("ecall"
@@ -24,18 +95,18 @@ const SBI_REMOTE_SFENCE_VMA_ASID: usize = 7;
 const SBI_SHUTDOWN: usize = 8;
 
 pub fn console_putchar(c: usize) {
-    sbi_call(SBI_CONSOLE_PUTCHAR, c, 0, 0);
+    sbi_call_legacy(SBI_CONSOLE_PUTCHAR, c, 0, 0);
 }
 
 pub fn console_getchar() -> usize {
-    sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0)
+    sbi_call_legacy(SBI_CONSOLE_GETCHAR, 0, 0, 0)
 }
 
 pub fn shutdown() -> ! {
-    sbi_call(SBI_SHUTDOWN, 0, 0, 0);
+    sbi_call_legacy(SBI_SHUTDOWN, 0, 0, 0);
     unreachable!()
 }
 
 pub fn set_timer(time: usize) {
-    sbi_call(SBI_SET_TIMER, time, 0, 0);
+    sbi_call_legacy(SBI_SET_TIMER, time, 0, 0);
 }