VERY SAFE TESTING and also runner is not needed for now

This commit is contained in:
Bryan McShea
2024-02-22 23:24:06 -05:00
parent df670e9998
commit d95a73203b
9 changed files with 152 additions and 163 deletions

View File

@@ -8,6 +8,7 @@ rustflags = [
"-C", "link-arg=-Tsrc/arch/riscv64/link.ld", "-C", "link-arg=-Tsrc/arch/riscv64/link.ld",
"-C", "link-arg=--omagic", "-C", "link-arg=--omagic",
] ]
runner = "qemu-system-riscv64 -nographic -semihosting -cpu rv64 -machine virt -bios none -smp 4 -m 1G -kernel"
[unstable] [unstable]
build-std = ["core", "compiler_builtins", "alloc"] build-std = ["core", "compiler_builtins", "alloc"]

110
kernel/Cargo.lock generated
View File

@@ -2,116 +2,6 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 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]] [[package]]
name = "kernel" name = "kernel"
version = "0.1.0" 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",
]

View File

@@ -3,26 +3,15 @@ name = "kernel"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
[[bin]]
name = "kernel"
test = false
bench = false
[dependencies] [dependencies]
[target.'cfg(target_arch = "x86_64")'.dependencies] # [target.'cfg(target_arch = "x86_64")'.dependencies]
pic8259 = "0.10.1" # pic8259 = "0.10.1"
bootloader_api = "0.11.5" # bootloader_api = "0.11.5"
x86_64 = "0.14.11" # x86_64 = "0.14.11"
uart_16550 = "0.3.0" # uart_16550 = "0.3.0"
#
[dependencies.lazy_static] # [dependencies.lazy_static]
version = "1.4.0" # version = "1.4.0"
features = ["spin_no_std"] # features = ["spin_no_std"]
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"

View File

@@ -3,7 +3,7 @@ use core::{arch::asm, ops::Range};
use crate::{ use crate::{
arch::{asm, csr, interrupts, paging, wait}, arch::{asm, csr, interrupts, paging, wait},
fdt::FDT, fdt::FDT,
main, start,
}; };
#[no_mangle] #[no_mangle]
@@ -70,5 +70,5 @@ pub unsafe fn init() -> ! {
end: raw_mem_range.end(), end: raw_mem_range.end(),
}; };
to_supervisor(); to_supervisor();
main(heap_mem, fdt); start(heap_mem, fdt)
} }

View File

@@ -8,5 +8,5 @@ pub fn init() {
pub fn stuff() -> ! { pub fn stuff() -> ! {
let mcause = csr::mcause::read(); let mcause = csr::mcause::read();
crate::println!("interrupt triggered: {mcause:?}"); crate::println!("interrupt triggered: {mcause:?}");
super::qemu::exit(); super::qemu::exit(1);
} }

View File

@@ -1,6 +1,7 @@
use core::fmt::{self, Write}; use core::fmt::{self, Write};
use crate::util::mutex::Mutex; use crate::util::mutex::Mutex;
use core::arch::asm;
// --machine sifive_u // --machine sifive_u
// const UART_BASE: u32 = 0x10010000; // 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 { unsafe {
core::arch::asm!( semihost(0x18, data.as_ptr() as *const u8);
"li t0, 0x20026", }
"sw t0, 0(sp)", super::wait()
"move a1, sp", }
"li a0, 0x18",
unsafe fn semihost(call: usize, data: *const u8) {
asm!(
"mv a0, {call}",
"mv a1, {data}",
".balign 16", ".balign 16",
".option push", ".option push",
".option norvc", ".option norvc",
"slli zero, zero, 0x1f", "slli zero, zero, 0x1f",
"ebreak", "ebreak",
"srai zero, zero, 0x7", "srai zero, zero, 0x7",
options(noreturn) call = in(reg) call,
); data = in(reg) data
} )
} }
pub fn _print(args: core::fmt::Arguments<'_>) { pub fn _print(args: core::fmt::Arguments<'_>) {

View File

@@ -3,12 +3,13 @@
#![feature(abi_x86_interrupt)] #![feature(abi_x86_interrupt)]
#![feature(naked_functions)] #![feature(naked_functions)]
#![feature(fn_align)] #![feature(fn_align)]
#![feature(custom_test_frameworks)]
use core::ops::Range; #![test_runner(crate::test::test_runner)]
#![reexport_test_harness_main = "test_main"]
use fdt::FDT;
use crate::allocator::ALLOCATOR; use crate::allocator::ALLOCATOR;
use core::ops::Range;
use fdt::FDT;
extern crate alloc; extern crate alloc;
@@ -19,9 +20,19 @@ pub mod fdt;
pub mod heap; pub mod heap;
pub mod log; pub mod log;
pub mod qemu; pub mod qemu;
#[cfg(test)]
mod test;
pub mod util; 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!("we out here vibin");
println!("memory range: {:?}", fdt.mem_range()); println!("memory range: {:?}", fdt.mem_range());
for node in &fdt {} for node in &fdt {}
@@ -42,8 +53,8 @@ pub fn main(heap_mem: Range<*mut u8>, fdt: FDT) -> ! {
println!("----------- vec vec test:"); println!("----------- vec vec test:");
let mut test = alloc::vec::Vec::new(); let mut test = alloc::vec::Vec::new();
for i in 0..4 { for i in 0..4 {
let n = i*4; let n = i * 4;
test.push(alloc::vec![n, n+1, n+2, n+3]); test.push(alloc::vec![n, n + 1, n + 2, n + 3]);
} }
ALLOCATOR.print(); ALLOCATOR.print();
println!("{:?}", test); println!("{:?}", test);
@@ -57,11 +68,17 @@ pub fn main(heap_mem: Range<*mut u8>, fdt: FDT) -> ! {
// for _ in 0..40000000 {} // for _ in 0..40000000 {}
// let x = unsafe { *(0x10000000000 as *mut u8) }; // let x = unsafe { *(0x10000000000 as *mut u8) };
// println!("we got {x}"); // println!("we got {x}");
qemu::exit();
} }
#[panic_handler] #[panic_handler]
pub fn panic(info: &core::panic::PanicInfo) -> ! { pub fn panic(info: &core::panic::PanicInfo) -> ! {
println!("{}", info); #[cfg(test)]
qemu::exit() crate::test::test_panic(info);
#[cfg(not(test))]
main_panic(info);
}
pub fn main_panic(info: &core::panic::PanicInfo) -> ! {
println!("{}", info);
qemu::exit(1);
} }

69
kernel/src/test.rs Normal file
View File

@@ -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<T: Fn()> Testable for T {
fn run(&self) {
print!("test {}... ", core::any::type_name::<T>());
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);
}

View File

@@ -2,8 +2,8 @@ use clap::Parser;
use std::process::{self, Command, Stdio}; use std::process::{self, Command, Stdio};
use target::Target; use target::Target;
mod boot; pub mod boot;
mod target; pub mod target;
#[derive(Parser)] #[derive(Parser)]
#[command(author, version, about, long_about = None)] #[command(author, version, about, long_about = None)]
@@ -20,7 +20,7 @@ fn main() {
let args = Args::parse(); let args = Args::parse();
let target = args.target.unwrap_or(Target::default()); let target = args.target.unwrap_or(Target::default());
std::env::set_current_dir("../kernel").expect("uh oh"); std::env::set_current_dir("../kernel").expect("uh oh");
build(&target); build(&target, false);
run_qemu(&target, args.gdb); run_qemu(&target, args.gdb);
} }
@@ -51,10 +51,14 @@ fn run_qemu(target: &Target, gdb: Option<Option<u16>>) {
} }
} }
fn build(target: &Target) { fn build(target: &Target, test: bool) {
let mut cargo = Command::new("cargo"); let mut cargo = Command::new("cargo");
if test {
cargo.arg("test");
cargo.arg("--no-run");
} else {
cargo.arg("build"); cargo.arg("build");
cargo.args(["--package", "kernel"]); }
cargo.args(["--target", target.rust_target()]); cargo.args(["--target", target.rust_target()]);
let status = cargo.status().expect("uh oh"); let status = cargo.status().expect("uh oh");
if !status.success() { if !status.success() {
@@ -64,3 +68,16 @@ fn build(target: &Target) {
boot::build_bootloader_img(bootloader); 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);
}
}