From 29819254014ef765e4b139a1dcfc45bbe0f067f8 Mon Sep 17 00:00:00 2001 From: Samy Solhi Date: Wed, 29 Mar 2023 17:21:34 +0200 Subject: [PATCH 1/7] Added shutdown system call --- src/kernel/exception.rs | 85 ++++++++++++++++++++++++++++------------ src/simulator/machine.rs | 11 +++++- 2 files changed, 70 insertions(+), 26 deletions(-) diff --git a/src/kernel/exception.rs b/src/kernel/exception.rs index a62042d..cf320d0 100644 --- a/src/kernel/exception.rs +++ b/src/kernel/exception.rs @@ -1,7 +1,7 @@ -use crate::simulator::machine::{ExceptionType, Machine}; +use crate::simulator::{machine::{ExceptionType, Machine}, error::{MachineOk, MachineError}}; -pub const SC_HALT: u8 = 0; +pub const SC_SHUTDOWN: u8 = 0; pub const SC_EXIT: u8 = 1; pub const SC_EXEC: u8 = 2; pub const SC_JOIN: u8 = 3; @@ -17,28 +17,28 @@ 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_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 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) { +pub fn call(exception: ExceptionType, machine: &Machine) -> Result { match exception { ExceptionType::NoException => todo!(), @@ -53,8 +53,45 @@ pub fn call(exception: ExceptionType, machine: &Machine) { } } -fn syscall(machine: &Machine) { - let call_type = machine.read_int_register(17); +fn syscall(machine: &Machine) -> Result { + let call_type = machine.read_int_register(17) as u8; - todo!() + match call_type { + SC_SHUTDOWN => Ok(MachineOk::Shutdown), + SC_EXIT => todo!(), + SC_EXEC => todo!(), + SC_JOIN => todo!(), + SC_CREATE => todo!(), + SC_OPEN => todo!(), + SC_READ => todo!(), + SC_WRITE => todo!(), + 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!() + } } \ No newline at end of file diff --git a/src/simulator/machine.rs b/src/simulator/machine.rs index a4bcdaa..9e4b4af 100644 --- a/src/simulator/machine.rs +++ b/src/simulator/machine.rs @@ -230,7 +230,13 @@ impl Machine { self.set_status(MachineStatus::SystemMode); // Handle the interruption - exception::call(exception, self); // todo: return error if the syscall code is invalid + match exception::call(exception, self) { + Ok(MachineOk::Shutdown) => { + self.set_status(MachineStatus::UserMode); + return Ok(MachineOk::Shutdown); + } + _ => () + } // todo: return error if the syscall code is invalid self.set_status(MachineStatus::UserMode); Ok(MachineOk::Ok) } @@ -243,7 +249,8 @@ impl Machine { pub fn run(&mut self) { loop { match self.one_instruction() { - Ok(_) => println!("hello"), + Ok(MachineOk::Ok) => println!("hello"), + Ok(MachineOk::Shutdown) => break, Err(e) => { if e.to_string().contains("System") { break; } panic!("FATAL at pc {} -> {}", self.pc, e) } } } From 5c7979b746da258d9787825ae34ed77bd881faf2 Mon Sep 17 00:00:00 2001 From: Samy Solhi Date: Wed, 29 Mar 2023 17:52:25 +0200 Subject: [PATCH 2/7] Added Write system call --- src/kernel/exception.rs | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/kernel/exception.rs b/src/kernel/exception.rs index cf320d0..61b1544 100644 --- a/src/kernel/exception.rs +++ b/src/kernel/exception.rs @@ -1,3 +1,5 @@ +use libc::printf; + use crate::simulator::{machine::{ExceptionType, Machine}, error::{MachineOk, MachineError}}; @@ -37,7 +39,9 @@ pub const SC_SYS_TIME: u8 = 32 ; pub const SC_MMAP: u8 = 33; pub const SC_DEBUG: u8 = 34; +pub const CONSOLE_OUTPUT: u8 = 1; +// todo : returns new types, not just machine errors and machine ok pub fn call(exception: ExceptionType, machine: &Machine) -> Result { match exception { @@ -64,7 +68,30 @@ fn syscall(machine: &Machine) -> Result { SC_CREATE => todo!(), SC_OPEN => todo!(), SC_READ => todo!(), - SC_WRITE => todo!(), + 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 { + match char::from_digit(machine.read_memory(1, (address + i) as usize) as u32, 2) { + Some(c) => buffer.push(c), + None => todo!() // Throw a proper error + } + } + + 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) + }, SC_SEEK => todo!(), SC_CLOSE => todo!(), SC_NEW_THREAD => todo!(), From 655bf9eab77e7c8692af5418da5fbb022e12074e Mon Sep 17 00:00:00 2001 From: Samy Solhi Date: Mon, 3 Apr 2023 23:08:13 +0200 Subject: [PATCH 3/7] added tests for SC_SHUTDOWN and SC_WRITE (print) --- src/kernel/exception.rs | 56 +++++++++++++++++++++++++++++++++++++--- src/simulator/machine.rs | 4 +-- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/kernel/exception.rs b/src/kernel/exception.rs index 61b1544..24555fe 100644 --- a/src/kernel/exception.rs +++ b/src/kernel/exception.rs @@ -78,10 +78,7 @@ fn syscall(machine: &Machine) -> Result { // load buffer let mut buffer = "".to_string(); for i in 0..size { - match char::from_digit(machine.read_memory(1, (address + i) as usize) as u32, 2) { - Some(c) => buffer.push(c), - None => todo!() // Throw a proper error - } + buffer.push((machine.read_memory(1, (address + i) as usize)) as u8 as char); } if f as u8 == CONSOLE_OUTPUT { @@ -121,4 +118,55 @@ fn syscall(machine: &Machine) -> Result { SC_DEBUG => todo!(), _ => todo!() } +} + +#[cfg(test)] +mod test { + use crate::kernel::exception::{SC_SHUTDOWN, SC_WRITE}; + 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 + + machine.run(); + // 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 + + + machine.run(); + } + } \ No newline at end of file diff --git a/src/simulator/machine.rs b/src/simulator/machine.rs index 9e4b4af..7862785 100644 --- a/src/simulator/machine.rs +++ b/src/simulator/machine.rs @@ -298,7 +298,7 @@ impl Machine { RISCV_JAL => { self.int_reg.set_reg(inst.rd, self.pc as i64); self.pc = (self.pc as i64 + inst.imm21_1_signed as i64 - 4) as u64; - Ok((MachineOk::Ok)) + Ok(MachineOk::Ok) }, // Treatment for: JUMP AND LINK REGISTER INSTRUCTIONS (indirect jump) @@ -306,7 +306,7 @@ impl Machine { let tmp = self.pc; self.pc = (self.int_reg.get_reg(inst.rs1) + inst.imm12_I_signed as i64) as u64 & 0xfffffffe; self.int_reg.set_reg(inst.rd, tmp as i64); - Ok((MachineOk::Ok)) + Ok(MachineOk::Ok) }, // Treatment for: BRANCH INSTRUCTIONS From 57e3ef397bb852917f41c90ed28d85c3fabee1f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Autin?= Date: Tue, 4 Apr 2023 14:16:00 +0200 Subject: [PATCH 4/7] Updated .gitignore to exclude .vscode folder --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b81b510..58e09e4 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /.idea *.iml /*.txt +/.vscode From f19515f6e85b02e10f5d391ea5c040a22d199e7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Autin?= Date: Tue, 4 Apr 2023 14:35:33 +0200 Subject: [PATCH 5/7] Update .gitlab-ci.yml --- .gitlab-ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0746ff7..66a7f8c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,9 @@ default: image: rust:1.68 + before_script: + - wget https://cloud.cuwott.fr/s/9fyrejDxMdNRQNn/download/riscv64-cross-compiler-multilib.tar.gz + - tar xzf https://cloud.cuwott.fr/s/9fyrejDxMdNRQNn/download/riscv64-cross-compiler-multilib.tar.gz + - mv riscv64-unknown-elf /opt/riscv stages: - test From ba8e7fe2054127a098ccc6957f45c51c1f4ca756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Autin?= Date: Tue, 4 Apr 2023 14:36:40 +0200 Subject: [PATCH 6/7] i am stupid i reckon --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 66a7f8c..a089067 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,7 @@ default: image: rust:1.68 before_script: - wget https://cloud.cuwott.fr/s/9fyrejDxMdNRQNn/download/riscv64-cross-compiler-multilib.tar.gz - - tar xzf https://cloud.cuwott.fr/s/9fyrejDxMdNRQNn/download/riscv64-cross-compiler-multilib.tar.gz + - tar xzf riscv64-cross-compiler-multilib.tar.gz - mv riscv64-unknown-elf /opt/riscv stages: From 4be02a2a03a6daf8a017b473ab90bc69190899cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Autin?= Date: Tue, 4 Apr 2023 14:41:14 +0200 Subject: [PATCH 7/7] Calmly asked wget to shut the fuck up --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a089067..d427948 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ default: image: rust:1.68 before_script: - - wget https://cloud.cuwott.fr/s/9fyrejDxMdNRQNn/download/riscv64-cross-compiler-multilib.tar.gz + - wget -q https://cloud.cuwott.fr/s/9fyrejDxMdNRQNn/download/riscv64-cross-compiler-multilib.tar.gz - tar xzf riscv64-cross-compiler-multilib.tar.gz - mv riscv64-unknown-elf /opt/riscv