Merge remote-tracking branch 'origin/thread_scheduler' into thread_scheduler
This commit is contained in:
commit
aa6d52fae7
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
|||||||
/.idea
|
/.idea
|
||||||
*.iml
|
*.iml
|
||||||
/*.txt
|
/*.txt
|
||||||
|
/.vscode
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
default:
|
default:
|
||||||
image: rust:1.68
|
image: rust:1.68
|
||||||
|
before_script:
|
||||||
|
- 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
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- test
|
- test
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
use crate::simulator::machine::{ExceptionType, Machine};
|
use libc::printf;
|
||||||
|
|
||||||
|
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_EXIT: u8 = 1;
|
||||||
pub const SC_EXEC: u8 = 2;
|
pub const SC_EXEC: u8 = 2;
|
||||||
pub const SC_JOIN: u8 = 3;
|
pub const SC_JOIN: u8 = 3;
|
||||||
@ -17,28 +19,30 @@ pub const SC_PERROR: u8 = 12;
|
|||||||
pub const SC_P: u8 = 13;
|
pub const SC_P: u8 = 13;
|
||||||
pub const SC_V: u8 = 14;
|
pub const SC_V: u8 = 14;
|
||||||
pub const SC_SEM_CREATE: u8 = 15 ;
|
pub const SC_SEM_CREATE: u8 = 15 ;
|
||||||
pub const SC_SEM_DESTROY: u8 = 16;
|
pub const SC_SEM_DESTROY: u8 = 16;
|
||||||
pub const SC_LOCK_CREATE: u8 = 17 ;
|
pub const SC_LOCK_CREATE: u8 = 17 ;
|
||||||
pub const SC_LOCK_DESTROY: u8 = 18 ;
|
pub const SC_LOCK_DESTROY: u8 = 18 ;
|
||||||
pub const SC_LOCK_ACQUIRE: u8 = 19 ;
|
pub const SC_LOCK_ACQUIRE: u8 = 19 ;
|
||||||
pub const SC_LOCK_RELEASE: u8 = 20 ;
|
pub const SC_LOCK_RELEASE: u8 = 20 ;
|
||||||
pub const SC_COND_CREATE: u8 = 21 ;
|
pub const SC_COND_CREATE: u8 = 21 ;
|
||||||
pub const SC_COND_DESTROY: u8 = 22 ;
|
pub const SC_COND_DESTROY: u8 = 22 ;
|
||||||
pub const SC_COND_WAIT: u8 = 23 ;
|
pub const SC_COND_WAIT: u8 = 23 ;
|
||||||
pub const SC_COND_SIGNAL: u8 = 24;
|
pub const SC_COND_SIGNAL: u8 = 24;
|
||||||
pub const SC_COND_BROADCAST: u8 = 25;
|
pub const SC_COND_BROADCAST: u8 = 25;
|
||||||
pub const SC_TTY_SEND: u8 = 26;
|
pub const SC_TTY_SEND: u8 = 26;
|
||||||
pub const SC_TTY_RECEIVE: u8 = 27;
|
pub const SC_TTY_RECEIVE: u8 = 27;
|
||||||
pub const SC_MKDIR: u8 = 28;
|
pub const SC_MKDIR: u8 = 28;
|
||||||
pub const SC_RMDIR: u8 = 29;
|
pub const SC_RMDIR: u8 = 29;
|
||||||
pub const SC_REMOVE: u8 = 30;
|
pub const SC_REMOVE: u8 = 30;
|
||||||
pub const SC_FSLIST: u8 = 31;
|
pub const SC_FSLIST: u8 = 31;
|
||||||
pub const SC_SYS_TIME: u8 = 32 ;
|
pub const SC_SYS_TIME: u8 = 32 ;
|
||||||
pub const SC_MMAP: u8 = 33;
|
pub const SC_MMAP: u8 = 33;
|
||||||
pub const SC_DEBUG: u8 = 34;
|
pub const SC_DEBUG: u8 = 34;
|
||||||
|
|
||||||
|
pub const CONSOLE_OUTPUT: u8 = 1;
|
||||||
|
|
||||||
pub fn call(exception: ExceptionType, machine: &Machine) {
|
// todo : returns new types, not just machine errors and machine ok
|
||||||
|
pub fn call(exception: ExceptionType, machine: &Machine) -> Result<MachineOk, MachineError> {
|
||||||
|
|
||||||
match exception {
|
match exception {
|
||||||
ExceptionType::NoException => todo!(),
|
ExceptionType::NoException => todo!(),
|
||||||
@ -53,8 +57,116 @@ pub fn call(exception: ExceptionType, machine: &Machine) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn syscall(machine: &Machine) {
|
fn syscall(machine: &Machine) -> Result<MachineOk, MachineError> {
|
||||||
let call_type = machine.read_int_register(17);
|
let call_type = machine.read_int_register(17) as u8;
|
||||||
|
|
||||||
|
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 => {
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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!(),
|
||||||
|
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};
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
@ -230,7 +230,13 @@ impl Machine {
|
|||||||
|
|
||||||
self.set_status(MachineStatus::SystemMode);
|
self.set_status(MachineStatus::SystemMode);
|
||||||
// Handle the interruption
|
// 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);
|
self.set_status(MachineStatus::UserMode);
|
||||||
Ok(MachineOk::Ok)
|
Ok(MachineOk::Ok)
|
||||||
}
|
}
|
||||||
@ -243,7 +249,8 @@ impl Machine {
|
|||||||
pub fn run(&mut self) {
|
pub fn run(&mut self) {
|
||||||
loop {
|
loop {
|
||||||
match self.one_instruction() {
|
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) }
|
Err(e) => { if e.to_string().contains("System") { break; } panic!("FATAL at pc {} -> {}", self.pc, e) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -291,7 +298,7 @@ impl Machine {
|
|||||||
RISCV_JAL => {
|
RISCV_JAL => {
|
||||||
self.int_reg.set_reg(inst.rd, self.pc as i64);
|
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;
|
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)
|
// Treatment for: JUMP AND LINK REGISTER INSTRUCTIONS (indirect jump)
|
||||||
@ -299,7 +306,7 @@ impl Machine {
|
|||||||
let tmp = self.pc;
|
let tmp = self.pc;
|
||||||
self.pc = (self.int_reg.get_reg(inst.rs1) + inst.imm12_I_signed as i64) as u64 & 0xfffffffe;
|
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);
|
self.int_reg.set_reg(inst.rd, tmp as i64);
|
||||||
Ok((MachineOk::Ok))
|
Ok(MachineOk::Ok)
|
||||||
},
|
},
|
||||||
|
|
||||||
// Treatment for: BRANCH INSTRUCTIONS
|
// Treatment for: BRANCH INSTRUCTIONS
|
||||||
|
Loading…
Reference in New Issue
Block a user