Prechádzať zdrojové kódy

feat(prototyper): add heap

guttatus 2 mesiacov pred
rodič
commit
cf87a9bde8

+ 19 - 0
.vscode/launch.json

@@ -0,0 +1,19 @@
+{
+    // Use IntelliSense to learn about possible attributes.
+    // Hover to view descriptions of existing attributes.
+    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "type": "gdb",
+            "request": "attach",
+            "name": "Attach to gdbserver",
+            "executable": "${workspaceRoot}/target/riscv64imac-unknown-none-elf/release/rustsbi-prototyper",
+            "target": "127.0.0.1:1234",
+            "remote": true,
+            "cwd": "${workspaceRoot}/prototyper/src",
+            "valuesFormatting": "parseText",
+            "gdbpath": "/usr/bin/riscv64-linux-gnu-gdb"
+        }
+    ]
+}

+ 10 - 0
Cargo.lock

@@ -75,6 +75,15 @@ version = "2.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
 
+[[package]]
+name = "buddy_system_allocator"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1a0108968a3a2dab95b089c0fc3f1afa7759aa5ebe6f1d86d206d6f7ba726eb"
+dependencies = [
+ "spin",
+]
+
 [[package]]
 name = "cfg-if"
 version = "1.0.0"
@@ -332,6 +341,7 @@ name = "rustsbi-prototyper"
 version = "0.0.0"
 dependencies = [
  "aclint",
+ "buddy_system_allocator",
  "cfg-if",
  "fast-trap",
  "log",

+ 3 - 2
prototyper/Cargo.toml

@@ -16,15 +16,16 @@ riscv = "0.11.1"
 rustsbi = { version = "0.4.0", features = ["machine"] }
 sbi-spec = { version = "0.0.8", features = ["legacy"] }
 serde = { version = "1.0.202", default-features = false, features = ["derive"] }
-serde-device-tree = { git = "https://github.com/rustsbi/serde-device-tree", default-features = false }
 sifive-test-device = "0.0.0"
 spin = "0.9.8"
 uart16550 = "0.0.1"
 riscv-decode = "0.2.1"
+cfg-if = "1.0.0"
+buddy_system_allocator = "0.11.0"
 fast-trap = { version = "0.0.1", features = ["riscv-m"] }
+serde-device-tree = { git = "https://github.com/rustsbi/serde-device-tree", default-features = false }
 uart_xilinx = { git = "https://github.com/duskmoon314/uart-rs/" }
 xuantie-riscv = { git= "https://github.com/rustsbi/xuantie" }
-cfg-if = "1.0.0"
 
 [[bin]]
 name = "rustsbi-prototyper"

+ 4 - 1
prototyper/build.rs

@@ -60,7 +60,10 @@ SECTIONS {
     sidata = LOADADDR(.data);
 
     .bss (NOLOAD) : ALIGN(0x1000) {  
-        *(.bss.uninit)
+        *(.bss.stack)
+        sbi_heap_start = .;
+        *(.bss.heap)
+        sbi_heap_end = .;
         sbi_bss_start = .;
         *(.bss .bss.*)
         *(.sbss .sbss.*)

+ 2 - 0
prototyper/src/cfg.rs

@@ -2,6 +2,8 @@
 pub const NUM_HART_MAX: usize = 8;
 /// Stack size per hart (hardware thread) in bytes.
 pub const LEN_STACK_PER_HART: usize = 16 * 1024;
+/// Heap Size of SBI firmware
+pub const HEAP_SIZE: usize = 32 * 1024;
 /// Page size
 pub const PAGE_SIZE: usize = 4096;
 /// TLB_FLUSH_LIMIT defines the TLB refresh range limit. 

+ 13 - 0
prototyper/src/fail.rs

@@ -1,10 +1,23 @@
 use serde_device_tree::Dtb;
+use crate::riscv::current_hartid;
 
 use crate::devicetree;
 
 #[cfg(all(feature = "payload", feature = "jump"))]
 compile_error!("feature \"payload\" and feature \"jump\" cannot be enabled at the same time");
 
+#[panic_handler]
+fn panic(info: &core::panic::PanicInfo) -> ! {
+    use ::riscv::register::*;
+    error!("Hart {} {info}", current_hartid());
+    error!("-----------------------------");
+    error!("mcause:  {:?}", mcause::read().cause());
+    error!("mepc:    {:#018x}", mepc::read());
+    error!("mtval:   {:#018x}", mtval::read());
+    error!("-----------------------------");
+    error!("System shutdown scheduled due to RustSBI panic");
+    loop {}
+}
 
 /// Handles device tree format parsing errors by logging and resetting.
 #[cold]

+ 9 - 12
prototyper/src/main.rs

@@ -1,9 +1,11 @@
+#![feature(alloc_error_handler)]
 #![feature(naked_functions)]
 #![feature(fn_align)]
 #![no_std]
 #![no_main]
 #![allow(static_mut_refs)]
 
+extern crate alloc;
 #[macro_use]
 extern crate log;
 #[macro_use]
@@ -19,6 +21,8 @@ mod sbi;
 
 use core::arch::asm;
 
+use sbi::heap::heap_test;
+
 use crate::platform::PLATFORM;
 use crate::riscv::csr::menvcfg;
 use crate::riscv::current_hartid;
@@ -31,6 +35,7 @@ use crate::sbi::hsm::local_remote_hsm;
 use crate::sbi::ipi;
 use crate::sbi::trap::{self, trap_vec};
 use crate::sbi::trap_stack;
+use crate::sbi::heap::sbi_heap_init;
 
 pub const START_ADDRESS: usize = 0x80000000;
 pub const R_RISCV_RELATIVE: usize = 3;
@@ -42,6 +47,9 @@ extern "C" fn rust_main(_hart_id: usize, opaque: usize, nonstandard_a2: usize) {
     let boot_hart_info = firmware::get_boot_hart(opaque, nonstandard_a2);
     // boot hart task entry.
     if boot_hart_info.is_boot_hart {
+        // Initialize the sbi heap
+        sbi_heap_init();
+        
         // parse the device tree
         let fdt_address = boot_hart_info.fdt_address;
 
@@ -52,6 +60,7 @@ extern "C" fn rust_main(_hart_id: usize, opaque: usize, nonstandard_a2: usize) {
 
         firmware::set_pmp(unsafe { PLATFORM.info.memory_range.as_ref().unwrap() });
         firmware::log_pmp_cfg(unsafe { PLATFORM.info.memory_range.as_ref().unwrap() });
+        heap_test();
 
         // Get boot information and prepare for kernel entry.
         let boot_info = firmware::get_boot_info(nonstandard_a2);
@@ -199,15 +208,3 @@ unsafe extern "C" fn relocation_update() {
     )
 }
 
-#[panic_handler]
-fn panic(info: &core::panic::PanicInfo) -> ! {
-    use ::riscv::register::*;
-    error!("Hart {} {info}", current_hartid());
-    error!("-----------------------------");
-    error!("mcause:  {:?}", mcause::read().cause());
-    error!("mepc:    {:#018x}", mepc::read());
-    error!("mtval:   {:#018x}", mtval::read());
-    error!("-----------------------------");
-    error!("System shutdown scheduled due to RustSBI panic");
-    loop {}
-}

+ 21 - 0
prototyper/src/sbi/heap.rs

@@ -0,0 +1,21 @@
+use buddy_system_allocator::LockedHeap;
+use crate::cfg::HEAP_SIZE;
+
+#[link_section = ".bss.heap"]
+static mut HEAP: [u8; HEAP_SIZE] = [0; HEAP_SIZE];
+
+#[global_allocator]
+static HEAP_ALLOCATOR: LockedHeap::<15> = LockedHeap::<15>::empty();
+
+pub fn sbi_heap_init() {
+    unsafe {
+        HEAP_ALLOCATOR
+            .lock()
+            .init(HEAP.as_ptr() as usize, HEAP_SIZE);
+    }
+}
+
+#[alloc_error_handler]
+pub fn handle_alloc_error(layout: core::alloc::Layout) -> ! {
+    panic!("Heap allocation error, layout = {:?}", layout);
+}

+ 1 - 0
prototyper/src/sbi/mod.rs

@@ -13,6 +13,7 @@ pub mod hart_context;
 pub mod logger;
 pub mod trap;
 pub mod trap_stack;
+pub mod heap;
 
 use console::{ConsoleDevice, SbiConsole};
 use hsm::SbiHsm;

+ 2 - 2
prototyper/src/sbi/trap_stack.rs

@@ -5,8 +5,8 @@ use core::mem::forget;
 use fast_trap::FreeTrapStack;
 use crate::cfg::{NUM_HART_MAX, LEN_STACK_PER_HART};
 
-/// Root stack array for all harts, placed in uninitialized BSS section.
-#[link_section = ".bss.uninit"]
+/// Root stack array for all harts, placed in BSS Stack section.
+#[link_section = ".bss.stack"]
 pub(crate) static mut ROOT_STACK: [Stack; NUM_HART_MAX] = [Stack::ZERO; NUM_HART_MAX];
 
 /// Locates and initializes stack for each hart.

+ 1 - 1
xtask/src/prototyper.rs

@@ -45,7 +45,7 @@ pub fn run(arg: &PrototyperArg) -> Option<ExitStatus> {
     cargo::Cargo::new("build")
         .package("rustsbi-prototyper")
         .target(arch)
-        .unstable("build-std", ["core"])
+        .unstable("build-std", ["core","alloc"])
         .env("RUSTFLAGS", "-C relocation-model=pie -C link-arg=-pie")
         .features(&arg.features)
         .optional(arg.fdt.is_some(), |cargo| {