From c238b2ea1dff60a5be6a796f44e533e89a346199 Mon Sep 17 00:00:00 2001 From: Christian Cunningham Date: Mon, 22 Aug 2022 21:28:18 -0700 Subject: Add serial suite --- src/kernel.rs | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 3 deletions(-) (limited to 'src/kernel.rs') diff --git a/src/kernel.rs b/src/kernel.rs index 2382345..cf594cd 100644 --- a/src/kernel.rs +++ b/src/kernel.rs @@ -5,13 +5,44 @@ #![no_std] // don't link the Rust standard library #![no_main] // disable all Rust-level entry points #![feature(const_mut_refs)] +#![feature(custom_test_frameworks)] +#![test_runner(crate::test_runner)] +#![reexport_test_harness_main = "test_main"] mod sync; mod vga; +mod serial; use vga::*; +use serial::*; use core::panic::PanicInfo; +pub trait Testable { + fn run(&self) -> (); +} + +impl Testable for T +where + T: Fn(), +{ + fn run(&self) { + serial_print!("{}...\t", core::any::type_name::()); + self(); + serial_println!("[ok]"); + } +} + +/// This function is called on panic. +#[cfg(test)] +#[panic_handler] +fn panic(info: &PanicInfo) -> ! { + serial_println!("[failed]\n"); + serial_println!("Error: {}\n", info); + exit_qemu(QemuExitCode::Failed); + loop {} +} + /// This function is called on panic. +#[cfg(not(test))] #[panic_handler] fn panic(info: &PanicInfo) -> ! { println!("{}", info); @@ -20,15 +51,52 @@ fn panic(info: &PanicInfo) -> ! { fn kernel_init() { WRITER.init(); + SERIAL1.init(); } #[no_mangle] pub extern "C" fn _start() -> ! { kernel_init(); - WRITER.write_string("Hello World!"); - WRITER.write_string("\n\nHi\n"); - println!("{}", 5); + #[cfg(not(test))] + { + WRITER.write_string("Hello World!"); + WRITER.write_string("\n\nHi\n"); + println!("{}", 5); + } + + #[cfg(test)] + test_main(); loop {} } + +#[cfg(test)] +fn test_runner(tests: &[&dyn Testable]) { + serial_println!("Running {} tests", tests.len()); + for test in tests { + test.run(); + } + exit_qemu(QemuExitCode::Success); +} + +#[test_case] +fn trivial_assertion() { + assert_eq!(1, 1); +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u32)] +pub enum QemuExitCode { + Success = 0x10, + Failed = 0x11, +} + +pub fn exit_qemu(exit_code: QemuExitCode) { + use x86_64::instructions::port::Port; + + unsafe { + let mut port = Port::new(0xf4); + port.write(exit_code as u32); + } +} -- cgit v1.2.1