diff --git a/src/kernel/exception.rs b/src/kernel/exception.rs new file mode 100644 index 0000000..a62042d --- /dev/null +++ b/src/kernel/exception.rs @@ -0,0 +1,60 @@ +use crate::simulator::machine::{ExceptionType, Machine}; + + +pub const SC_HALT: u8 = 0; +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 ; +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; +pub const SC_COND_BROADCAST: u8 = 25; +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; + + +pub fn call(exception: ExceptionType, machine: &Machine) { + + match exception { + ExceptionType::NoException => todo!(), + ExceptionType::SyscallException => syscall(machine), + ExceptionType::PagefaultException => todo!(), + ExceptionType::ReadOnlyException => todo!(), + ExceptionType::BusErrorException => todo!(), + ExceptionType::AddressErrorException => todo!(), + ExceptionType::OverflowException => todo!(), + ExceptionType::IllegalInstrException => todo!(), + ExceptionType::NumExceptionTypes => todo!(), + } +} + +fn syscall(machine: &Machine) { + let call_type = machine.read_int_register(17); + + todo!() +} \ No newline at end of file diff --git a/src/kernel/mod.rs b/src/kernel/mod.rs index 67a43cb..7081829 100644 --- a/src/kernel/mod.rs +++ b/src/kernel/mod.rs @@ -4,4 +4,5 @@ pub mod mgerror; pub mod system; mod ucontext; mod synch; -mod thread_manager; \ No newline at end of file +mod thread_manager; +pub mod exception; \ No newline at end of file diff --git a/src/simulator/machine.rs b/src/simulator/machine.rs index d54ce8f..0b470ec 100644 --- a/src/simulator/machine.rs +++ b/src/simulator/machine.rs @@ -23,6 +23,10 @@ use crate::simulator::{ register::* }; +use crate::kernel::{ + exception +}; + /// # Exceptions /// /// Textual names of the exceptions that can be generated by user program @@ -48,6 +52,16 @@ pub enum ExceptionType { NumExceptionTypes } +/// # Machine Status +/// +/// The machine can be running kernel code (SystemMode), user code (UserMode), +/// or there can be no running thread if the ready list is empty (IdleMode). +pub enum MachineStatus { + IdleMode, + SystemMode, + UserMode +} + /// ID of the stack register pub const STACK_REG: usize = 2; /// Number of available Integer registers @@ -78,9 +92,12 @@ pub struct Machine { /// Debug data pub registers_trace : String, // for tests /// todo: document Interrupts - pub interrupt: Interrupt + pub interrupt: Interrupt, // futur taille à calculer int memSize = g_cfg->NumPhysPages * g_cfg->PageSize; //creer une struct cfg(configuration) qui s'initialise avec valeur dans un fichier cfg + + /// Current machine status + pub status: MachineStatus } @@ -105,7 +122,8 @@ impl Machine { main_memory : vec![0_u8; MEM_SIZE], shiftmask, interrupt: Interrupt::new(), - registers_trace : String::from("") + registers_trace : String::from(""), + status: MachineStatus::SystemMode } } @@ -206,6 +224,15 @@ impl Machine { s } + pub fn raise_exception(&mut self, exception: ExceptionType, address : u64) -> Result<(), MachineError>{ + + self.set_status(MachineStatus::SystemMode); + // Handle the interruption + exception::call(exception, self); // todo: return error if the syscall code is invalid + self.set_status(MachineStatus::UserMode); + Ok(()) + } + /// Execute the instructions table of a machine putted in param /// /// ### Parameters @@ -298,7 +325,7 @@ impl Machine { RISCV_FP => self.fp_instruction(inst), // Treatment for: SYSTEM CALLS - RISCV_SYSTEM => Err(format!("{:x}: System opcode\npc: {:x}", inst.opcode, self.pc))?, + RISCV_SYSTEM => self.raise_exception(ExceptionType::SyscallException, self.pc), // Default case _ => Err(format!("{:x}: Unknown opcode\npc: {:x}", inst.opcode, self.pc))? @@ -640,6 +667,14 @@ impl Machine { pub fn write_fp_register(&mut self, index: usize, value: f32) { self.fp_reg.set_reg(index as u8, value); } + + pub fn get_status(&self) -> MachineStatus { + todo!() + } + + pub fn set_status(&mut self, new_status: MachineStatus) { + self.status = new_status; + } } #[cfg(test)]