burritos/src/kernel/exception.rs

182 lines
6.1 KiB
Rust
Raw Normal View History

2023-04-05 12:01:31 +02:00
use std::rc::Rc;
2023-03-29 17:21:34 +02:00
use crate::simulator::{machine::{ExceptionType, Machine}, error::{MachineOk, MachineError}};
2023-03-29 16:13:57 +02:00
2023-04-05 12:01:31 +02:00
use super::system::System;
2023-03-29 16:13:57 +02:00
2023-03-29 17:21:34 +02:00
pub const SC_SHUTDOWN: u8 = 0;
2023-03-29 16:13:57 +02:00
pub const SC_EXIT: u8 = 1;
pub const SC_EXEC: u8 = 2;
pub const SC_JOIN: u8 = 3;
pub const SC_CREATE: u8 = 4;
pub const SC_OPEN: u8 = 5;
pub const SC_READ: u8 = 6;
pub const SC_WRITE: u8 = 7;
pub const SC_SEEK: u8 = 8;
pub const SC_CLOSE: u8 = 9;
pub const SC_NEW_THREAD: u8 = 10;
pub const SC_YIELD: u8 = 11;
pub const SC_PERROR: u8 = 12;
pub const SC_P: u8 = 13;
pub const SC_V: u8 = 14;
pub const SC_SEM_CREATE: u8 = 15 ;
2023-03-29 17:21:34 +02:00
pub const SC_SEM_DESTROY: u8 = 16;
pub const SC_LOCK_CREATE: u8 = 17 ;
pub const SC_LOCK_DESTROY: u8 = 18 ;
pub const SC_LOCK_ACQUIRE: u8 = 19 ;
pub const SC_LOCK_RELEASE: u8 = 20 ;
pub const SC_COND_CREATE: u8 = 21 ;
pub const SC_COND_DESTROY: u8 = 22 ;
pub const SC_COND_WAIT: u8 = 23 ;
pub const SC_COND_SIGNAL: u8 = 24;
2023-03-29 16:13:57 +02:00
pub const SC_COND_BROADCAST: u8 = 25;
2023-03-29 17:21:34 +02:00
pub const SC_TTY_SEND: u8 = 26;
pub const SC_TTY_RECEIVE: u8 = 27;
pub const SC_MKDIR: u8 = 28;
pub const SC_RMDIR: u8 = 29;
pub const SC_REMOVE: u8 = 30;
pub const SC_FSLIST: u8 = 31;
pub const SC_SYS_TIME: u8 = 32 ;
pub const SC_MMAP: u8 = 33;
pub const SC_DEBUG: u8 = 34;
2023-03-29 16:13:57 +02:00
2023-03-29 17:52:25 +02:00
pub const CONSOLE_OUTPUT: u8 = 1;
2023-03-29 16:13:57 +02:00
2023-03-29 17:52:25 +02:00
// todo : returns new types, not just machine errors and machine ok
2023-04-05 12:01:31 +02:00
pub fn call(exception: ExceptionType, machine: &mut Machine, system: &mut System) -> Result<MachineOk, MachineError> {
2023-03-29 16:13:57 +02:00
match exception {
ExceptionType::NoException => todo!(),
2023-04-05 12:01:31 +02:00
ExceptionType::SyscallException => syscall(machine, system),
2023-03-29 16:13:57 +02:00
ExceptionType::PagefaultException => todo!(),
ExceptionType::ReadOnlyException => todo!(),
ExceptionType::BusErrorException => todo!(),
ExceptionType::AddressErrorException => todo!(),
ExceptionType::OverflowException => todo!(),
ExceptionType::IllegalInstrException => todo!(),
ExceptionType::NumExceptionTypes => todo!(),
}
}
2023-04-05 12:01:31 +02:00
fn syscall(machine: &mut Machine, system: &mut System) -> Result<MachineOk, MachineError> {
2023-03-29 17:21:34 +02:00
let call_type = machine.read_int_register(17) as u8;
2023-03-29 16:13:57 +02:00
2023-03-29 17:21:34 +02:00
match call_type {
SC_SHUTDOWN => Ok(MachineOk::Shutdown),
2023-04-05 12:01:31 +02:00
SC_EXIT => {
2023-04-05 13:34:06 +02:00
let th = match &system.get_thread_manager().g_current_thread {
Some(th) => th,
None => Err("Current thread is None".into())
}?;
system.get_thread_manager().thread_finish(machine, th);
Ok(MachineOk::Ok)
2023-04-05 12:01:31 +02:00
},
2023-03-29 17:21:34 +02:00
SC_EXEC => todo!(),
SC_JOIN => todo!(),
SC_CREATE => todo!(),
SC_OPEN => todo!(),
SC_READ => todo!(),
2023-03-29 17:52:25 +02:00
SC_WRITE => {
let address = machine.read_int_register(10);
let size = machine.read_int_register(11);
// openfileid or 1 (console)
let f = machine.read_int_register(12);
// load buffer
let mut buffer = "".to_string();
for i in 0..size {
buffer.push((machine.read_memory(1, (address + i) as usize)) as u8 as char);
2023-03-29 17:52:25 +02:00
}
if f as u8 == CONSOLE_OUTPUT {
println!("{}", buffer); // todo replace with console driver in the future
} else {
todo!("SC_WRITE to file is not yet implemented")
}
Ok(MachineOk::Ok)
},
2023-03-29 17:21:34 +02:00
SC_SEEK => todo!(),
SC_CLOSE => todo!(),
SC_NEW_THREAD => todo!(),
SC_YIELD => todo!(),
SC_PERROR => todo!(),
SC_P => todo!(),
SC_V => todo!(),
SC_SEM_CREATE => todo!(),
SC_SEM_DESTROY => todo!(),
SC_LOCK_CREATE => todo!(),
SC_LOCK_DESTROY => todo!(),
SC_LOCK_ACQUIRE => todo!(),
SC_LOCK_RELEASE => todo!(),
SC_COND_CREATE => todo!(),
SC_COND_DESTROY => todo!(),
SC_COND_WAIT => todo!(),
SC_COND_SIGNAL => todo!(),
SC_COND_BROADCAST => todo!(),
SC_TTY_SEND => todo!(),
SC_TTY_RECEIVE => todo!(),
SC_MKDIR => todo!(),
SC_RMDIR => todo!(),
SC_REMOVE => todo!(),
SC_FSLIST => todo!(),
SC_SYS_TIME => todo!(),
SC_MMAP => todo!(),
SC_DEBUG => todo!(),
_ => todo!()
}
}
#[cfg(test)]
mod test {
use crate::kernel::exception::{SC_SHUTDOWN, SC_WRITE};
2023-04-05 12:01:31 +02:00
use crate::kernel::system::System;
use crate::simulator::instruction::Instruction;
use crate::simulator::machine::Machine;
#[test]
fn test_sc_shutdown() {
let mut machine = Machine::init_machine();
machine.write_int_register(17, SC_SHUTDOWN as i64); // Set type to shutdown
let ecall = Instruction::new(0b000000000000_00000_000_00000_1110011);
machine.write_memory(4, 0, 0b000000000000_00000_000_00000_1110011); // ecall
machine.write_memory(4, 4, 0b000000001010_00000_000_00001_0010011); // r1 <- 10
2023-04-05 12:01:31 +02:00
let mut system = System::default();
machine.run(&mut system);
// If the machine was stopped with no error, the shutdown worked
assert_ne!(machine.read_int_register(1), 10); // Check if the next instruction was executed
}
// This test print HELLO in the console
#[test]
#[ignore]
fn test_sc_print() {
let mut machine = Machine::init_machine();
let address = machine.read_int_register(10);
// Write string 'HELLO' in memory
machine.write_memory(1, 4000, 72);
machine.write_memory(1, 4001, 69);
machine.write_memory(1, 4002, 76);
machine.write_memory(1, 4003, 76);
machine.write_memory(1, 4004, 79);
machine.write_int_register(10, 4000); // String address
machine.write_int_register(11, 5); // String size
machine.write_int_register(12, 1); // Console output
machine.write_memory(4, 0, 0b000000000000_00000_000_00000_1110011); // ecall
machine.write_int_register(17, SC_WRITE as i64); // Set type to write
machine.write_memory(4, 4, 0b000000000000_00000_000_10001_0010011); // r17 <- SC_SHUTDOWN
machine.write_memory(4, 8, 0b000000000000_00000_000_00000_1110011); // ecall
2023-04-05 12:01:31 +02:00
let mut system = System::default();
machine.run(&mut system);
}
2023-03-29 16:13:57 +02:00
}