From d95a73203b261c95afc141615de2ba42fdab7ea4 Mon Sep 17 00:00:00 2001 From: Bryan McShea Date: Thu, 22 Feb 2024 23:24:06 -0500 Subject: [PATCH] VERY SAFE TESTING and also runner is not needed for now --- kernel/.cargo/config.toml | 1 + kernel/Cargo.lock | 110 -------------------------- kernel/Cargo.toml | 29 +++---- kernel/src/arch/riscv64/init.rs | 4 +- kernel/src/arch/riscv64/interrupts.rs | 2 +- kernel/src/arch/riscv64/qemu.rs | 34 ++++---- kernel/src/main.rs | 37 ++++++--- kernel/src/test.rs | 69 ++++++++++++++++ runner/src/main.rs | 29 +++++-- 9 files changed, 152 insertions(+), 163 deletions(-) create mode 100644 kernel/src/test.rs diff --git a/kernel/.cargo/config.toml b/kernel/.cargo/config.toml index 3b3ddd3..24f54fa 100644 --- a/kernel/.cargo/config.toml +++ b/kernel/.cargo/config.toml @@ -8,6 +8,7 @@ rustflags = [ "-C", "link-arg=-Tsrc/arch/riscv64/link.ld", "-C", "link-arg=--omagic", ] +runner = "qemu-system-riscv64 -nographic -semihosting -cpu rv64 -machine virt -bios none -smp 4 -m 1G -kernel" [unstable] build-std = ["core", "compiler_builtins", "alloc"] diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 401621a..0dd1539 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -2,116 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "bit_field" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" - -[[package]] -name = "bootloader_api" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daaa1fb791aea49e19db7b7b3662665d511eb4e30a0627fa525fd92652f39358" - [[package]] name = "kernel" version = "0.1.0" -dependencies = [ - "bootloader_api", - "lazy_static", - "pic8259", - "uart_16550", - "x86_64", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -dependencies = [ - "spin", -] - -[[package]] -name = "pic8259" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb844b5b01db1e0b17938685738f113bfc903846f18932b378bc0eabfa40e194" -dependencies = [ - "x86_64", -] - -[[package]] -name = "raw-cpuid" -version = "10.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "rustversion" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "uart_16550" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dc00444796f6c71f47c85397a35e9c4dbf9901902ac02386940d178e2b78687" -dependencies = [ - "bitflags 1.3.2", - "rustversion", - "x86", -] - -[[package]] -name = "volatile" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "442887c63f2c839b346c192d047a7c87e73d0689c9157b00b53dcc27dd5ea793" - -[[package]] -name = "x86" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2781db97787217ad2a2845c396a5efe286f87467a5810836db6d74926e94a385" -dependencies = [ - "bit_field", - "bitflags 1.3.2", - "raw-cpuid", -] - -[[package]] -name = "x86_64" -version = "0.14.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b835097a84e4457323331ec5d6eb23d096066cbfb215d54096dcb4b2e85f500" -dependencies = [ - "bit_field", - "bitflags 2.4.2", - "rustversion", - "volatile", -] diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 9d4219f..377ff78 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -3,26 +3,15 @@ name = "kernel" version = "0.1.0" edition = "2021" -[[bin]] -name = "kernel" -test = false -bench = false - [dependencies] -[target.'cfg(target_arch = "x86_64")'.dependencies] -pic8259 = "0.10.1" -bootloader_api = "0.11.5" -x86_64 = "0.14.11" -uart_16550 = "0.3.0" - -[dependencies.lazy_static] -version = "1.4.0" -features = ["spin_no_std"] - -[profile.dev] -panic = "abort" - -[profile.release] -panic = "abort" +# [target.'cfg(target_arch = "x86_64")'.dependencies] +# pic8259 = "0.10.1" +# bootloader_api = "0.11.5" +# x86_64 = "0.14.11" +# uart_16550 = "0.3.0" +# +# [dependencies.lazy_static] +# version = "1.4.0" +# features = ["spin_no_std"] diff --git a/kernel/src/arch/riscv64/init.rs b/kernel/src/arch/riscv64/init.rs index 4c02e57..2b130ed 100644 --- a/kernel/src/arch/riscv64/init.rs +++ b/kernel/src/arch/riscv64/init.rs @@ -3,7 +3,7 @@ use core::{arch::asm, ops::Range}; use crate::{ arch::{asm, csr, interrupts, paging, wait}, fdt::FDT, - main, + start, }; #[no_mangle] @@ -70,5 +70,5 @@ pub unsafe fn init() -> ! { end: raw_mem_range.end(), }; to_supervisor(); - main(heap_mem, fdt); + start(heap_mem, fdt) } diff --git a/kernel/src/arch/riscv64/interrupts.rs b/kernel/src/arch/riscv64/interrupts.rs index 9daf548..d6d99d8 100644 --- a/kernel/src/arch/riscv64/interrupts.rs +++ b/kernel/src/arch/riscv64/interrupts.rs @@ -8,5 +8,5 @@ pub fn init() { pub fn stuff() -> ! { let mcause = csr::mcause::read(); crate::println!("interrupt triggered: {mcause:?}"); - super::qemu::exit(); + super::qemu::exit(1); } diff --git a/kernel/src/arch/riscv64/qemu.rs b/kernel/src/arch/riscv64/qemu.rs index 1a39c08..c9b5d53 100644 --- a/kernel/src/arch/riscv64/qemu.rs +++ b/kernel/src/arch/riscv64/qemu.rs @@ -1,6 +1,7 @@ use core::fmt::{self, Write}; use crate::util::mutex::Mutex; +use core::arch::asm; // --machine sifive_u // const UART_BASE: u32 = 0x10010000; @@ -28,22 +29,27 @@ impl fmt::Write for Uart { } } -pub fn exit() -> ! { +pub fn exit(code: usize) -> ! { + let data = [0x20026, code]; unsafe { - core::arch::asm!( - "li t0, 0x20026", - "sw t0, 0(sp)", - "move a1, sp", - "li a0, 0x18", - ".balign 16", - ".option push", - ".option norvc", - "slli zero, zero, 0x1f", - "ebreak", - "srai zero, zero, 0x7", - options(noreturn) - ); + semihost(0x18, data.as_ptr() as *const u8); } + super::wait() +} + +unsafe fn semihost(call: usize, data: *const u8) { + asm!( + "mv a0, {call}", + "mv a1, {data}", + ".balign 16", + ".option push", + ".option norvc", + "slli zero, zero, 0x1f", + "ebreak", + "srai zero, zero, 0x7", + call = in(reg) call, + data = in(reg) data + ) } pub fn _print(args: core::fmt::Arguments<'_>) { diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 120971c..5e2fe3f 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -3,12 +3,13 @@ #![feature(abi_x86_interrupt)] #![feature(naked_functions)] #![feature(fn_align)] - -use core::ops::Range; - -use fdt::FDT; +#![feature(custom_test_frameworks)] +#![test_runner(crate::test::test_runner)] +#![reexport_test_harness_main = "test_main"] use crate::allocator::ALLOCATOR; +use core::ops::Range; +use fdt::FDT; extern crate alloc; @@ -19,9 +20,19 @@ pub mod fdt; pub mod heap; pub mod log; pub mod qemu; +#[cfg(test)] +mod test; pub mod util; -pub fn main(heap_mem: Range<*mut u8>, fdt: FDT) -> ! { +pub fn start(heap_mem: Range<*mut u8>, fdt: FDT) -> ! { + #[cfg(test)] + test_main(); + #[cfg(not(test))] + main(heap_mem, fdt); + qemu::exit(0) +} + +pub fn main(heap_mem: Range<*mut u8>, fdt: FDT) { println!("we out here vibin"); println!("memory range: {:?}", fdt.mem_range()); for node in &fdt {} @@ -42,8 +53,8 @@ pub fn main(heap_mem: Range<*mut u8>, fdt: FDT) -> ! { println!("----------- vec vec test:"); let mut test = alloc::vec::Vec::new(); for i in 0..4 { - let n = i*4; - test.push(alloc::vec![n, n+1, n+2, n+3]); + let n = i * 4; + test.push(alloc::vec![n, n + 1, n + 2, n + 3]); } ALLOCATOR.print(); println!("{:?}", test); @@ -57,11 +68,17 @@ pub fn main(heap_mem: Range<*mut u8>, fdt: FDT) -> ! { // for _ in 0..40000000 {} // let x = unsafe { *(0x10000000000 as *mut u8) }; // println!("we got {x}"); - qemu::exit(); } #[panic_handler] pub fn panic(info: &core::panic::PanicInfo) -> ! { - println!("{}", info); - qemu::exit() + #[cfg(test)] + crate::test::test_panic(info); + #[cfg(not(test))] + main_panic(info); +} + +pub fn main_panic(info: &core::panic::PanicInfo) -> ! { + println!("{}", info); + qemu::exit(1); } diff --git a/kernel/src/test.rs b/kernel/src/test.rs new file mode 100644 index 0000000..4d55cb2 --- /dev/null +++ b/kernel/src/test.rs @@ -0,0 +1,69 @@ +use crate::{print, println, qemu}; + +// SURELY I will not have threading tests that cause problems +// SURELY I don't need to pin the input to test_runner +static mut TESTS: &[&dyn Testable] = &[]; +static mut TEST: usize = 0; +static mut FAILED: usize = 0; + +pub trait Testable { + fn run(&self) -> (); +} + +impl Testable for T { + fn run(&self) { + print!("test {}... ", core::any::type_name::()); + self(); + println!("\x1b[92mok\x1b[0m"); + } +} + +pub fn test_runner(tests: &[&dyn Testable]) { + unsafe { TESTS = core::mem::transmute(tests) }; + println!("Running {} tests", tests.len()); + run_tests(); +} + +pub fn run_tests() -> ! { + unsafe { + for i in TEST..TESTS.len() { + let test = TESTS[i]; + TEST += 1; + test.run(); + } + print!( + "results: {}. {} passed; {} failed", + if FAILED > 0 { + "\x1b[91mFAILED\x1b[0m" + } else { + "\x1b[92mok\x1b[0m" + }, + TEST - FAILED, + FAILED + ); + } + println!(); + qemu::exit(0) +} + +pub fn test_panic(info: &core::panic::PanicInfo) -> ! { + println!("\x1b[91mFAILED\x1b[0m"); + println!("\x1b[93m{}\x1b[0m", info); + unsafe { FAILED += 1 }; + run_tests(); +} + +#[test_case] +fn test1() { + assert_eq!(1, 1); +} + +#[test_case] +fn test2() { + assert_eq!(1, 0); +} + +#[test_case] +fn test3() { + assert_eq!(5, 4); +} diff --git a/runner/src/main.rs b/runner/src/main.rs index 2d38e87..f9490fd 100644 --- a/runner/src/main.rs +++ b/runner/src/main.rs @@ -2,8 +2,8 @@ use clap::Parser; use std::process::{self, Command, Stdio}; use target::Target; -mod boot; -mod target; +pub mod boot; +pub mod target; #[derive(Parser)] #[command(author, version, about, long_about = None)] @@ -20,7 +20,7 @@ fn main() { let args = Args::parse(); let target = args.target.unwrap_or(Target::default()); std::env::set_current_dir("../kernel").expect("uh oh"); - build(&target); + build(&target, false); run_qemu(&target, args.gdb); } @@ -51,10 +51,14 @@ fn run_qemu(target: &Target, gdb: Option>) { } } -fn build(target: &Target) { +fn build(target: &Target, test: bool) { let mut cargo = Command::new("cargo"); - cargo.arg("build"); - cargo.args(["--package", "kernel"]); + if test { + cargo.arg("test"); + cargo.arg("--no-run"); + } else { + cargo.arg("build"); + } cargo.args(["--target", target.rust_target()]); let status = cargo.status().expect("uh oh"); if !status.success() { @@ -64,3 +68,16 @@ fn build(target: &Target) { boot::build_bootloader_img(bootloader); } } + +#[cfg(test)] +mod tests { + use crate::{build, run_qemu, target::Target}; + + #[test] + fn default() { + std::env::set_current_dir("../kernel").expect("uh oh"); + let target = Target::default(); + build(&target, true); + run_qemu(&target, None); + } +}