mod plic; pub mod tasks; pub mod trap; use crate::ktask; use crate::syscalls::{create_task}; use crate::uart::{Serial, UART}; use core::arch::{asm, global_asm}; #[cfg(feature = "debug_messages")] use core::fmt::Write; use liblbos::TaskSetup; global_asm!(include_str!("asm/boot.s")); global_asm!(include_str!("asm/trap.s")); #[unsafe(no_mangle)] extern "C" fn eh_personality() {} #[panic_handler] //#[cfg(feature = "debug_messages")] fn panic(info: &core::panic::PanicInfo) -> ! { use core::fmt::Write; let mut uart = UART::new(0x1000_0000); let _ = writeln!(uart, "abort"); let _ = writeln!(uart, "message: {}", info.message()); if let Some(p) = info.location() { let _ = writeln!( uart, "line {}, column {}, file {}", p.line(), p.column(), p.file() ); } loop { unsafe { asm!("wfi"); } } } /* #[panic_handler] #[cfg(not(feature = "debug_messages"))] fn panic(_info: &core::panic::PanicInfo) -> ! { let uart = UART::new(0x1000_0000); for c in b"PANIC".iter() { uart.put(*c); } loop { unsafe { asm!("wfi"); } } } */ pub fn virt_rough_panic(errcode: [char; 3]) -> ! { let uart = UART::new(0x1000_0000); for c in b"PANIC".iter() { uart.put(*c); } for c in errcode.iter() { uart.put(*c as _); } loop { unsafe { asm!("wfi"); } } } #[unsafe(no_mangle)] extern "C" fn _virt_init() -> ! { UART::new_and_init(0x1000_0000); plic::set_threshold(0); for i in 1..=10 { plic::enable(i); plic::set_priority(i, 1); } trap::enable_traps(); create_task(TaskSetup { epc: ktask as usize, ddi_first_addr: 0, ddi_size: 0, environment: 0, wait_for_task_exit: false, }); loop { stall() } } pub fn stall() { unsafe { asm!("wfi"); } } pub const fn serial_port() -> Option<&'static dyn Serial> { static UART_STATIC: UART = UART::new(0x1000_0000); Some(&UART_STATIC) } unsafe extern "C" { fn _syscall(syscall_num: u32, a1: u32, a2: u32, a3: u32, a4: u32, a5: u32, a6: u32) -> u32; } pub fn virt_syscall(num: u32, a1: u32, a2: u32, a3: u32, a4: u32, a5: u32, a6: u32) -> u32 { unsafe { _syscall(num, a1, a2, a3, a4, a5, a6) } }