diff --git a/.cargo/config.toml b/.cargo/config.toml index 13e8aca..da57549 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,6 +1,7 @@ [unstable] build-std-features = ["compiler-builtins-mem"] build-std = ["core", "compiler_builtins"] +profile-rustflags = true [build] target = "arch/riscv32imc-unknown-none-elf.json" @@ -18,27 +19,38 @@ rustflags = [ # Print memory usage "-C", "link-arg=--print-memory-usage", + # Generate a memory map at compilation time # "-C", - # "link-arg=-Map=memory.map", + # "link-arg=-Map=logs/memory.map", ] [profile.dev] opt-level = 0 debug = 2 -debug-assertions = true +debug-assertions = true lto = false strip = false codegen-units = 1 -panic = "unwind" +panic = "abort" +rustflags = [ + # Improve backtrace + "-C", + "force-frame-pointers=yes", +] [profile.test] opt-level = 0 debug = 2 -debug-assertions = true +debug-assertions = true lto = false strip = false codegen-units = 1 -panic = "unwind" +panic = "abort" +rustflags = [ + # Improve backtrace + "-C", + "force-frame-pointers=yes", +] [profile.release] opt-level = 2 @@ -47,13 +59,13 @@ strip = true codegen-units = 1 panic = "abort" debug = false -debug-assertions = false +debug-assertions = false [alias] -b = "build --profile=dev -Zjson-target-spec --target arch/riscv32imc-unknown-none-elf.json" -rb = "build --profile=release -Zjson-target-spec --target arch/riscv32imc-unknown-none-elf.json" -tb = "build --profile=test --features=test -Zjson-target-spec --target arch/riscv32imc-unknown-none-elf.json" +b = "build --profile=dev -Zjson-target-spec" +rb = "build --profile=release -Zjson-target-spec" +tb = "build --profile=test --features=test -Zjson-target-spec" c = "clean" ft = "fmt --all -- --check" -w = "clippy -Zjson-target-spec --target arch/riscv32imc-unknown-none-elf.json -- -D warnings" -clip = "clippy -Zjson-target-spec --target arch/riscv32imc-unknown-none-elf.json" +w = "clippy -Zjson-target-spec -- -D warnings" +clip = "clippy -Zjson-target-spec" diff --git a/Cargo.lock b/Cargo.lock index 7d18cc5..fff8951 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "lrnrtos" -version = "0.4.1" +version = "0.4.2" dependencies = [ "arrayvec", ] diff --git a/Cargo.toml b/Cargo.toml index 67e7519..f3833d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lrnrtos" -version = "0.4.1" +version = "0.4.2" edition = "2024" [[bin]] diff --git a/Documentation/kernel/test_framework.md b/Documentation/kernel/test_framework.md index 20c5fad..a3b4cda 100644 --- a/Documentation/kernel/test_framework.md +++ b/Documentation/kernel/test_framework.md @@ -68,8 +68,6 @@ pub fn foo_test_suite() { )], // Name of the test suite name: "Foo", - // Number of tests inside the suite - tests_nb: 1, // Behavior of the test suite // Default: run the suite normally // Skipped: don't run the suite at all diff --git a/src/arch/riscv32/mem.rs b/src/arch/riscv32/mem.rs new file mode 100644 index 0000000..84040bf --- /dev/null +++ b/src/arch/riscv32/mem.rs @@ -0,0 +1,6 @@ +use super::asm; + +pub fn update_kernel_sp(sp: usize) { + unsafe { core::arch::asm!("mv a0, {}", in(reg) sp) }; + unsafe { asm::set_kernel_sp() }; +} diff --git a/src/arch/riscv32/mod.rs b/src/arch/riscv32/mod.rs index ed4df01..65da303 100644 --- a/src/arch/riscv32/mod.rs +++ b/src/arch/riscv32/mod.rs @@ -1,4 +1,5 @@ pub mod asm; +pub mod mem; pub mod scheduler; pub mod start; pub mod task; diff --git a/src/arch/riscv32/scheduler/mod.rs b/src/arch/riscv32/scheduler/mod.rs index 497dcc8..65a1c55 100644 --- a/src/arch/riscv32/scheduler/mod.rs +++ b/src/arch/riscv32/scheduler/mod.rs @@ -1,4 +1,4 @@ -use crate::primitives::stack::AlignedStack; +use crate::primitives::stack::AlignedStack16; #[repr(C)] pub struct SchedulerCtx { @@ -10,7 +10,7 @@ pub struct SchedulerCtx { sp: *mut u8, // Offset 132 } -pub static mut SCHEDULER_STACK: AlignedStack<4098> = AlignedStack::new(); +pub static mut SCHEDULER_STACK: AlignedStack16<4098> = AlignedStack16::new(); pub static mut SCHEDULER_CTX: SchedulerCtx = unsafe { core::mem::zeroed() }; impl SchedulerCtx { diff --git a/src/arch/riscv32/traps/trap_frame.rs b/src/arch/riscv32/traps/trap_frame.rs index 2ac05c4..7502695 100644 --- a/src/arch/riscv32/traps/trap_frame.rs +++ b/src/arch/riscv32/traps/trap_frame.rs @@ -18,6 +18,8 @@ Tests files: use core::{mem, ptr::null_mut}; +use crate::primitives::stack::AlignedStack16; + #[repr(C)] // Trap frame structure, used to store all global registers, give a stack for the trap handling // to avoid using the kernel stack. @@ -45,7 +47,7 @@ impl TrapFrame { } // Static buffer used as a stack for trap handling -pub static mut TRAP_STACK_BUFF: [u8; 1024] = [0u8; 1024]; +pub static mut TRAP_STACK_BUFF: AlignedStack16<1024> = AlignedStack16::new(); // Init TrapFrame with 0 in mem pub static mut KERNEL_TRAP_FRAME: TrapFrame = unsafe { mem::zeroed() }; @@ -55,6 +57,6 @@ pub fn init_trap_frame() { // Static mut safe because it's only used in kernel boot #[allow(static_mut_refs)] unsafe { - KERNEL_TRAP_FRAME.trap_stack = TRAP_STACK_BUFF.as_mut_ptr() + KERNEL_TRAP_FRAME.trap_stack = TRAP_STACK_BUFF.buf.as_mut_ptr().wrapping_add(1024); } } diff --git a/src/boot.rs b/src/boot.rs index 05805eb..9c17b40 100644 --- a/src/boot.rs +++ b/src/boot.rs @@ -7,7 +7,7 @@ use crate::{ ktime::set_ktime_seconds, log, logs::LogLevel, - mem::{memory_init, update_kernel_sp}, + mem::{mem_update_kernel_sp, memory_init}, platform::platform_init, }; @@ -34,7 +34,7 @@ pub fn kernel_early_boot(core: usize, dtb_addr: usize) -> ! { ); memory_init(); log!(LogLevel::Debug, "Switch to new kernel stack..."); - update_kernel_sp(); + mem_update_kernel_sp(); // Allow empty loop because it will never enter, just to make the fn never return without // warning #[allow(clippy::empty_loop)] diff --git a/src/info.rs b/src/info.rs index c6a28dc..d3760f2 100644 --- a/src/info.rs +++ b/src/info.rs @@ -1,4 +1,4 @@ // The kernel exposes build-time version information at runtime. // This information is immutable and reflects the exact binary currently running. // It is intended for debugging, logging, and diagnostic purposes. -pub static KERNEL_VERSION: &str = "0.4.1"; +pub static KERNEL_VERSION: &str = "0.4.2"; diff --git a/src/mem/mod.rs b/src/mem/mod.rs index e9d1875..a0df021 100644 --- a/src/mem/mod.rs +++ b/src/mem/mod.rs @@ -19,12 +19,13 @@ Tests files: mod kernel; -use core::{arch::asm, mem}; +use core::mem; use kernel::{__kernel_end, __kernel_start, KernelStack}; use crate::{ - arch, config::KERNEL_STACK_SIZE, log, logs::LogLevel, platform::mem::platform_init_mem, + arch::mem::update_kernel_sp, config::KERNEL_STACK_SIZE, log, logs::LogLevel, + platform::mem::platform_init_mem, }; pub struct Memory { @@ -137,12 +138,6 @@ pub fn memory_init() { } } -#[unsafe(no_mangle)] -pub fn update_kernel_sp() { - unsafe { asm!("mv a0, {}", in(reg) MEMORY.kernel_stack.top) }; - unsafe { arch::asm::set_kernel_sp() }; -} - pub fn mem_kernel_stack_info<'a>() -> &'a KernelStack { #[allow(static_mut_refs)] unsafe { @@ -150,6 +145,11 @@ pub fn mem_kernel_stack_info<'a>() -> &'a KernelStack { } } +pub fn mem_update_kernel_sp() { + let sp: usize = unsafe { MEMORY.kernel_stack.top }; + update_kernel_sp(sp); +} + /// Return the hi and lo address of the RAM /// first index is hi, second is lo pub fn mem_reg_info() -> [usize; 2] { diff --git a/src/primitives/stack.rs b/src/primitives/stack.rs index 78e73f7..a853a19 100644 --- a/src/primitives/stack.rs +++ b/src/primitives/stack.rs @@ -14,14 +14,15 @@ Tests files: References: */ -pub struct AlignedStack { +#[repr(align(16))] +pub struct AlignedStack16 { pub buf: [u8; N], } -impl AlignedStack { +impl AlignedStack16 { // Don't bother with this warning #[allow(clippy::new_without_default)] pub const fn new() -> Self { - AlignedStack { buf: [0u8; N] } + AlignedStack16 { buf: [0u8; N] } } } diff --git a/src/tests/arch/riscv32/task/task_context.rs b/src/tests/arch/riscv32/task/task_context.rs index 11e8940..6e63da1 100644 --- a/src/tests/arch/riscv32/task/task_context.rs +++ b/src/tests/arch/riscv32/task/task_context.rs @@ -157,11 +157,10 @@ pub fn task_context_test_suite() { TestCase::init( "Task context switch no invariants violated", test_task_context_switch, - TestBehavior::Default, + TestBehavior::Skipped, ), ], name: "RISC-V32 bit task context layout", - tests_nb: 3, behavior: TestSuiteBehavior::Default, }; #[allow(static_mut_refs)] diff --git a/src/tests/arch/riscv32/traps/handler.rs b/src/tests/arch/riscv32/traps/handler.rs index f855bc9..754853f 100644 --- a/src/tests/arch/riscv32/traps/handler.rs +++ b/src/tests/arch/riscv32/traps/handler.rs @@ -29,7 +29,6 @@ pub fn trap_handler_test_suite() { TestBehavior::Default, )], name: "Trap handler", - tests_nb: 1, behavior: TestSuiteBehavior::Default, }; #[allow(static_mut_refs)] diff --git a/src/tests/arch/riscv32/traps/interrupt.rs b/src/tests/arch/riscv32/traps/interrupt.rs index b6b265e..c7dc1ef 100644 --- a/src/tests/arch/riscv32/traps/interrupt.rs +++ b/src/tests/arch/riscv32/traps/interrupt.rs @@ -133,7 +133,6 @@ pub fn interrupt_enabling_test_suite() { // }, ], name: "Interruptions enabling", - tests_nb: 6, behavior: TestSuiteBehavior::Default, }; #[allow(static_mut_refs)] diff --git a/src/tests/arch/riscv32/traps/trap_frame.rs b/src/tests/arch/riscv32/traps/trap_frame.rs index ad1e17f..5f2ec1c 100644 --- a/src/tests/arch/riscv32/traps/trap_frame.rs +++ b/src/tests/arch/riscv32/traps/trap_frame.rs @@ -38,7 +38,9 @@ pub fn test_trap_frame_init() -> u8 { init_trap_frame(); // Ok because test env, no concurrency #[allow(static_mut_refs)] - if unsafe { KERNEL_TRAP_FRAME.trap_stack } != unsafe { TRAP_STACK_BUFF.as_mut_ptr() } { + if unsafe { KERNEL_TRAP_FRAME.trap_stack } + != unsafe { TRAP_STACK_BUFF.buf.as_mut_ptr().wrapping_add(1024) } + { panic!("Trap frame trap_stack field should be initialized with ptr to TRAP_STACK_BUFF"); } 0 @@ -59,7 +61,6 @@ pub fn trap_frame_test_suite() { ), ], name: "Trap frame", - tests_nb: 2, behavior: TestSuiteBehavior::Default, }; #[allow(static_mut_refs)] diff --git a/src/tests/drivers/cpu_intc/subsystem.rs b/src/tests/drivers/cpu_intc/subsystem.rs index e055b64..32eabee 100644 --- a/src/tests/drivers/cpu_intc/subsystem.rs +++ b/src/tests/drivers/cpu_intc/subsystem.rs @@ -124,7 +124,6 @@ pub fn cpu_intc_subsystem_test_suite() { ), ], name: "CPU interrupt-controller", - tests_nb: 3, behavior: TestSuiteBehavior::Default, }; #[allow(static_mut_refs)] diff --git a/src/tests/drivers/serials/ns16550a.rs b/src/tests/drivers/serials/ns16550a.rs index d6581d4..3c962da 100644 --- a/src/tests/drivers/serials/ns16550a.rs +++ b/src/tests/drivers/serials/ns16550a.rs @@ -33,7 +33,6 @@ pub fn ns16550_test_suite() { TestBehavior::Default, )], name: "Ns16550", - tests_nb: 1, behavior: TestSuiteBehavior::Skipped, }; #[allow(static_mut_refs)] diff --git a/src/tests/drivers/serials/subsystem.rs b/src/tests/drivers/serials/subsystem.rs index 6a67269..90e8ed2 100644 --- a/src/tests/drivers/serials/subsystem.rs +++ b/src/tests/drivers/serials/subsystem.rs @@ -229,7 +229,6 @@ pub fn serial_subsystem_test_suite() { ), ], name: "Serial sub-system", - tests_nb: 3, behavior: TestSuiteBehavior::Default, }; #[allow(static_mut_refs)] diff --git a/src/tests/drivers/timer/subsystem.rs b/src/tests/drivers/timer/subsystem.rs index 00cfdff..94e8991 100644 --- a/src/tests/drivers/timer/subsystem.rs +++ b/src/tests/drivers/timer/subsystem.rs @@ -224,7 +224,6 @@ pub fn timer_subsystem_test_suite() { ), ], name: "Timer sub-system", - tests_nb: 4, behavior: TestSuiteBehavior::Default, }; diff --git a/src/tests/ktime/mod.rs b/src/tests/ktime/mod.rs index 412fbbc..a444a18 100644 --- a/src/tests/ktime/mod.rs +++ b/src/tests/ktime/mod.rs @@ -58,7 +58,6 @@ pub fn ktime_test_suite() { ), ], name: "Ktime", - tests_nb: 3, behavior: TestSuiteBehavior::Default, }; #[allow(static_mut_refs)] diff --git a/src/tests/mem/mod.rs b/src/tests/mem/mod.rs index 314a1a7..5479769 100644 --- a/src/tests/mem/mod.rs +++ b/src/tests/mem/mod.rs @@ -59,7 +59,6 @@ pub fn memory_test_suite() { ), ], name: "Kernel memory", - tests_nb: 2, behavior: TestSuiteBehavior::Default, }; #[allow(static_mut_refs)] diff --git a/src/tests/mod.rs b/src/tests/mod.rs index f4cf38e..a7f3dc9 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -94,7 +94,6 @@ impl<'a> TestManager<'a> { pub struct TestSuite<'a> { pub tests: &'a [TestCase<'a>], pub name: &'a str, - pub tests_nb: u32, pub behavior: TestSuiteBehavior, } @@ -103,21 +102,14 @@ impl<'a> TestSuite<'a> { TestSuite { tests: &[], name: "", - tests_nb: 0, behavior: TestSuiteBehavior::Skipped, } } - pub fn init( - tests: &'a [TestCase], - name: &'a str, - tests_nb: u32, - behavior: TestSuiteBehavior, - ) -> Self { + pub fn init(tests: &'a [TestCase], name: &'a str, behavior: TestSuiteBehavior) -> Self { TestSuite { tests, name, - tests_nb, behavior, } } @@ -155,7 +147,6 @@ impl<'a> TestCase<'a> { pub static mut TEST_MANAGER: TestManager = TestManager::init(); -#[unsafe(no_mangle)] pub fn test_runner(core: usize, dtb_addr: usize) -> ! { // Basic test before running all test suites kprint!("Starting kernel in test mode.\n"); @@ -182,7 +173,8 @@ pub fn test_runner(core: usize, dtb_addr: usize) -> ! { let mut test_suites_skipped: usize = 0; // Iterate over all test suite and run all test inside for test_suite in unsafe { TEST_MANAGER.test_pool } { - if test_suite.tests_nb == 0 { + let test_nb = test_suite.tests.len(); + if test_nb == 0 { continue; } if test_suite.behavior == TestSuiteBehavior::Skipped { @@ -191,10 +183,10 @@ pub fn test_runner(core: usize, dtb_addr: usize) -> ! { } kprint_fmt!( "\nRunning {} tests from test suite: {}\n", - test_suite.tests_nb, + test_nb, test_suite.name ); - let test_to_pass = test_suite.tests_nb; + let test_to_pass = test_nb; let mut test_passed: usize = 0; let mut test_failed: usize = 0; let mut test_skipped: usize = 0; diff --git a/src/tests/platform/mod.rs b/src/tests/platform/mod.rs index b1a6034..3e508ed 100644 --- a/src/tests/platform/mod.rs +++ b/src/tests/platform/mod.rs @@ -132,7 +132,6 @@ pub fn platform_test_suite() { ), ], name: "Platform", - tests_nb: 2, behavior: TestSuiteBehavior::Default, }; #[allow(static_mut_refs)] diff --git a/src/tests/primitives/ring_buff.rs b/src/tests/primitives/ring_buff.rs index c0ac3a2..06dcb35 100644 --- a/src/tests/primitives/ring_buff.rs +++ b/src/tests/primitives/ring_buff.rs @@ -154,7 +154,6 @@ pub fn ring_buff_primitive_test_suite() { TestCase::init("RingBuffer pop", test_ringbuffer_pop, TestBehavior::Default), ], name: "RingBuffer primitive type", - tests_nb: 3, behavior: TestSuiteBehavior::Default, }; #[allow(static_mut_refs)] diff --git a/src/tests/task/list.rs b/src/tests/task/list.rs index 3e04a38..ebf7b09 100644 --- a/src/tests/task/list.rs +++ b/src/tests/task/list.rs @@ -4,7 +4,6 @@ pub fn task_list_test_suite() { const TASK_LIST_TEST_SUITE: TestSuite = TestSuite { tests: &[], name: "Task list", - tests_nb: 0, behavior: TestSuiteBehavior::Skipped, }; #[allow(static_mut_refs)] diff --git a/src/tests/task/mod.rs b/src/tests/task/mod.rs index 54c8238..a11cbe5 100644 --- a/src/tests/task/mod.rs +++ b/src/tests/task/mod.rs @@ -35,7 +35,6 @@ pub fn task_test_suite() { TestBehavior::Default, )], name: "Task", - tests_nb: 1, behavior: TestSuiteBehavior::Default, }; #[allow(static_mut_refs)]