use std; use std::cell::RefCell; use std::rc::Rc; use rustv::isa; use rustv::memory::SharedMemory; use rustv::register_file::RegisterFile; use rustv::syscall; use rustv::trap::Trap; use shareable_cache::ShareableCache; pub struct SyscallHandler<'a> { memory: SharedMemory<'a>, caches: Vec>>>, } impl<'a> SyscallHandler<'a> { pub fn new(memory: SharedMemory<'a>, caches: Vec>>>) -> SyscallHandler<'a> { SyscallHandler { memory: memory, caches: caches, } } } impl<'a> SyscallHandler<'a> { fn print(&mut self, core_id: usize, registers: &mut RegisterFile) -> Option { let mut base = registers.read_word(isa::Register::X11); let mut string = vec![]; loop { let c = self.memory.borrow_mut().read_byte(base); if let Ok(0x00) = c { break; } else if let Ok(c) = c { string.push(c); } base += 1; } let result = std::str::from_utf8(&string); if let Ok(string) = result { println!("{}", string); } else { println!("Error printing string: not valid UTF-8: {:?}", result); } None } fn enable_secondary(&mut self, core_id: usize, registers: &mut RegisterFile) -> Option { self.caches[core_id].borrow_mut().enable_secondary(); None } fn disable_secondary(&mut self, core_id: usize, registers: &mut RegisterFile) -> Option { self.caches[core_id].borrow_mut().disable_secondary(); None } } impl<'a> syscall::SyscallHandler for SyscallHandler<'a> { // TODO: is trap really appropriate here? fn syscall(&mut self, core_id: usize, registers: &mut RegisterFile) -> Option { let syscall_number = registers.read_word(isa::Register::X10); match syscall_number { 22 => self.print(core_id, registers), 23 => self.enable_secondary(core_id, registers), 24 => self.disable_secondary(core_id, registers), _ => { // TODO: some sort of error reporting None } } } }