Compare commits
33 Commits
clippy_fix
...
fix_debug_
Author | SHA1 | Date | |
---|---|---|---|
8fe1e03309 | |||
569929098d | |||
8929326505 | |||
a16d92ab7e | |||
df0930850a | |||
0ba9a136cc | |||
ec2eea05ad | |||
7f40538bc4 | |||
20af365080 | |||
01b1e90dba | |||
3f51413038 | |||
e3654de298 | |||
98fe63f487 | |||
15a04fb9da | |||
86113da9d3 | |||
c51bb694a5 | |||
8c61fd1aa6 | |||
7be0c0accc | |||
7d29b92eba | |||
2884d5d479 | |||
c862c42e43 | |||
5000c28b97 | |||
5f8965b94d | |||
e0eb027aea | |||
6eeaa57647 | |||
bec0143a40 | |||
28cd0a9f6e | |||
43f023e0b0 | |||
02cdb5239b | |||
a211e93905 | |||
1055e6a0ac | |||
c278236d81 | |||
597ffa753a |
26
Makefile
26
Makefile
@ -1,6 +1,13 @@
|
|||||||
TOPDIR=.
|
TOPDIR=.
|
||||||
include $(TOPDIR)/Makefile.config
|
include $(TOPDIR)/Makefile.config
|
||||||
|
|
||||||
|
#
|
||||||
|
# Demo vars
|
||||||
|
#
|
||||||
|
FLAGS=--offline -r --
|
||||||
|
CARGO=RUSTFLAGS=-Awarnings cargo run ${FLAGS}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
all: dumps user_lib instruction_tests syscall
|
all: dumps user_lib instruction_tests syscall
|
||||||
#
|
#
|
||||||
@ -22,10 +29,27 @@ syscall: user_lib
|
|||||||
$(MAKE) build -C test/syscall_tests/
|
$(MAKE) build -C test/syscall_tests/
|
||||||
$(RM) test/syscall_tests/*.o
|
$(RM) test/syscall_tests/*.o
|
||||||
mkdir -p ${TOPDIR}/target/guac/
|
mkdir -p ${TOPDIR}/target/guac/
|
||||||
find . -name '*.guac' -exec mv {} ${TOPDIR}/target/guac/ \;
|
find . -name '*.guac' -exec mv {} ${TOPDIR}/target/guac/ 2> /dev/null \;
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) clean -C userlib/
|
$(MAKE) clean -C userlib/
|
||||||
$(MAKE) clean -C test/
|
$(MAKE) clean -C test/
|
||||||
$(RM) -rf $(TOPDIR)/target
|
$(RM) -rf $(TOPDIR)/target
|
||||||
|
|
||||||
|
#
|
||||||
|
# Demo targets
|
||||||
|
#
|
||||||
|
halt: syscall
|
||||||
|
${CARGO} -x ./target/guac/halt.guac -d3
|
||||||
|
|
||||||
|
pc: syscall
|
||||||
|
${CARGO} -x ./target/guac/producteur_consommateur.guac -d2
|
||||||
|
|
||||||
|
matmult: syscall
|
||||||
|
${CARGO} -x ./target/guac/matmult.guac -d2
|
||||||
|
|
||||||
|
lr: syscall
|
||||||
|
${CARGO} -x ./target/guac/lecteur_redacteur.guac -d2
|
||||||
|
|
||||||
|
prints: syscall
|
||||||
|
${CARGO} -x ./target/guac/prints.guac -d2
|
||||||
|
12
build.rs
12
build.rs
@ -1,12 +0,0 @@
|
|||||||
//! Build script for BurritOS.
|
|
||||||
//!
|
|
||||||
//! Moves files from the assets folder to the target directory
|
|
||||||
//! and runs `make all`.
|
|
||||||
|
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let mut make_all = Command::new("make");
|
|
||||||
make_all.arg("all");
|
|
||||||
println!("{:?}", make_all.output().unwrap());
|
|
||||||
}
|
|
@ -2,7 +2,7 @@
|
|||||||
# BurritOS configuration file
|
# BurritOS configuration file
|
||||||
##################################################
|
##################################################
|
||||||
|
|
||||||
NumPhysPages = 400
|
NumPhysPages = 40000000
|
||||||
UserStackSize = 4096
|
UserStackSize = 4096
|
||||||
MaxFileNameSize = 256
|
MaxFileNameSize = 256
|
||||||
NumDirEntries = 30
|
NumDirEntries = 30
|
||||||
|
@ -3,7 +3,7 @@ use std::{cell::RefCell, rc::Rc};
|
|||||||
use crate::{simulator::{machine::{ExceptionType, Machine}, error::{MachineOk, MachineError}}};
|
use crate::{simulator::{machine::{ExceptionType, Machine}, error::{MachineOk, MachineError}}};
|
||||||
use crate::kernel::synch::{Lock, Semaphore};
|
use crate::kernel::synch::{Lock, Semaphore};
|
||||||
|
|
||||||
use super::{system::{System}, thread::Thread};
|
use super::{system::System, thread::Thread};
|
||||||
|
|
||||||
/// The halt system call. Stops Burritos.
|
/// The halt system call. Stops Burritos.
|
||||||
pub const SC_SHUTDOWN: u8 = 0;
|
pub const SC_SHUTDOWN: u8 = 0;
|
||||||
@ -138,7 +138,8 @@ fn syscall(machine: &mut Machine, system: &mut System) -> Result<MachineOk, Mach
|
|||||||
Some(th) => th.clone(),
|
Some(th) => th.clone(),
|
||||||
None => Err("Current thread is None")?
|
None => Err("Current thread is None")?
|
||||||
};
|
};
|
||||||
system.get_thread_manager().thread_finish(machine, th);
|
let code = machine.read_int_register(10);
|
||||||
|
system.get_thread_manager().thread_finish(machine, th, code);
|
||||||
Ok(MachineOk::Ok)
|
Ok(MachineOk::Ok)
|
||||||
},
|
},
|
||||||
SC_EXEC => todo!(),
|
SC_EXEC => todo!(),
|
||||||
@ -154,13 +155,17 @@ fn syscall(machine: &mut Machine, system: &mut System) -> Result<MachineOk, Mach
|
|||||||
let f = machine.read_int_register(12);
|
let f = machine.read_int_register(12);
|
||||||
|
|
||||||
// load buffer
|
// load buffer
|
||||||
let mut buffer = "".to_string();
|
let mut buffer = String::new();
|
||||||
|
let mut val: [u8; 4] = [0; 4];
|
||||||
|
for (j, elem) in val.iter_mut().enumerate() {
|
||||||
|
*elem = machine.read_memory(1, address as usize + j) as u8;
|
||||||
|
}
|
||||||
for i in 0..size {
|
for i in 0..size {
|
||||||
buffer.push((machine.read_memory(1, (address + i) as usize)) as u8 as char);
|
buffer.push((machine.read_memory(1, (address + i) as usize)) as u8 as char);
|
||||||
}
|
}
|
||||||
|
|
||||||
if f as u8 == CONSOLE_OUTPUT {
|
if f as u8 == CONSOLE_OUTPUT {
|
||||||
println!("{}", buffer); // todo replace with console driver in the future
|
print!("{}", buffer); // todo replace with console driver in the future
|
||||||
Ok(MachineOk::Ok)
|
Ok(MachineOk::Ok)
|
||||||
} else {
|
} else {
|
||||||
Err("SC_WRITE to file is not yet implemented")?
|
Err("SC_WRITE to file is not yet implemented")?
|
||||||
@ -239,7 +244,7 @@ fn sc_sem_create(machine: &mut Machine, system: &mut System) -> Result<MachineOk
|
|||||||
let size = get_length_param(addr_name, machine);
|
let size = get_length_param(addr_name, machine);
|
||||||
let _name = get_string_param(addr_name, size, machine);
|
let _name = get_string_param(addr_name, size, machine);
|
||||||
match initial_count < 0 {
|
match initial_count < 0 {
|
||||||
true => Err("Initial_count < 0".to_string())?,
|
true => Err(format!("Initial_count < 0"))?,
|
||||||
false => {
|
false => {
|
||||||
let id = system.get_thread_manager().get_obj_addrs().add_semaphore(Semaphore::new(initial_count));
|
let id = system.get_thread_manager().get_obj_addrs().add_semaphore(Semaphore::new(initial_count));
|
||||||
machine.write_int_register(10, id as i64);
|
machine.write_int_register(10, id as i64);
|
||||||
@ -278,12 +283,14 @@ fn sc_new_thread(machine: &mut Machine, system: &mut System) -> Result<MachineOk
|
|||||||
};
|
};
|
||||||
let current_thread = current_thread.borrow_mut();
|
let current_thread = current_thread.borrow_mut();
|
||||||
if let Some(process) = current_thread.get_process_owner() {
|
if let Some(process) = current_thread.get_process_owner() {
|
||||||
system.get_thread_manager().start_thread(n_thread, Rc::clone(process), func as u64, current_thread.thread_context.int_registers[2] as u64 + machine.page_size, args);
|
let sp_max = system.get_thread_manager().get_sp_max() + machine.user_stack_size;
|
||||||
|
system.get_thread_manager().set_sp_max(sp_max);
|
||||||
|
system.get_thread_manager().start_thread(n_thread, Rc::clone(&process), func as u64, sp_max, args);
|
||||||
// TODO changé la valeur de sp quand on supportera les addresses virtuels
|
// TODO changé la valeur de sp quand on supportera les addresses virtuels
|
||||||
machine.write_int_register(10, tid as i64);
|
machine.write_int_register(10, tid as i64);
|
||||||
Ok(MachineOk::Ok)
|
Ok(MachineOk::Ok)
|
||||||
} else {
|
} else {
|
||||||
Err("Process owner of current thread is none")?
|
return Err("Process owner of current thread is none")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,9 +356,18 @@ mod test {
|
|||||||
let mut machine = Machine::new(true, get_debug_configuration());
|
let mut machine = Machine::new(true, get_debug_configuration());
|
||||||
machine.write_int_register(17, SC_SHUTDOWN as i64); // Set type to shutdown
|
machine.write_int_register(17, SC_SHUTDOWN as i64); // Set type to shutdown
|
||||||
// let ecall = Instruction::new(0b000000000000_00000_000_00000_1110011);
|
// let ecall = Instruction::new(0b000000000000_00000_000_00000_1110011);
|
||||||
|
let insts: [u8; 4] = 0b000000000000_00000_000_00000_1110011_u32.to_le_bytes();
|
||||||
machine.write_memory(4, 0, 0b0000_0000_0000_0000_0000_0000_0111_0011); // ecall
|
machine.write_memory(1, 0, insts[0] as u64);
|
||||||
machine.write_memory(4, 4, 0b0000_0000_1010_0000_0000_0000_1001_0011); // r1 <- 10
|
machine.write_memory(1, 1, insts[1] as u64);
|
||||||
|
machine.write_memory(1, 2, insts[2] as u64);
|
||||||
|
machine.write_memory(1, 3, insts[3] as u64); // ecall
|
||||||
|
// machine.write_memory(4, 0, 0b000000000000_00000_000_00000_1110011_u64.to_be()); // ecall
|
||||||
|
let insts: [u8; 4] = 0b000000001010_00000_000_00001_0010011_u32.to_le_bytes();
|
||||||
|
machine.write_memory(1, 4, insts[0] as u64);
|
||||||
|
machine.write_memory(1, 5, insts[1] as u64);
|
||||||
|
machine.write_memory(1, 6, insts[2] as u64);
|
||||||
|
machine.write_memory(1, 7, insts[3] as u64); // r1 <- 10
|
||||||
|
// machine.write_memory(4, 4, 0b000000001010_00000_000_00001_0010011_u64.to_be()); // r1 <- 10
|
||||||
let mut system = System::new(true);
|
let mut system = System::new(true);
|
||||||
machine.run(&mut system);
|
machine.run(&mut system);
|
||||||
// If the machine was stopped with no error, the shutdown worked
|
// If the machine was stopped with no error, the shutdown worked
|
||||||
@ -377,11 +393,11 @@ mod test {
|
|||||||
machine.write_int_register(11, 5); // String size
|
machine.write_int_register(11, 5); // String size
|
||||||
machine.write_int_register(12, 1); // Console output
|
machine.write_int_register(12, 1); // Console output
|
||||||
|
|
||||||
machine.write_memory(4, 0, 0b0000_0000_0000_0000_0000_0000_0111_0011); // ecall
|
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_int_register(17, SC_WRITE as i64); // Set type to write
|
||||||
|
|
||||||
machine.write_memory(4, 4, 0b0000_0000_0000_0000_0000_1000_1001_0011); // r17 <- SC_SHUTDOWN
|
machine.write_memory(4, 4, 0b000000000000_00000_000_10001_0010011); // r17 <- SC_SHUTDOWN
|
||||||
machine.write_memory(4, 8, 0b0000_0000_0000_0000_0000_0000_0111_0011); // ecall
|
machine.write_memory(4, 8, 0b000000000000_00000_000_00000_1110011); // ecall
|
||||||
|
|
||||||
let mut system = System::new(true);
|
let mut system = System::new(true);
|
||||||
machine.run(&mut system);
|
machine.run(&mut system);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub struct Process {
|
pub struct Process {
|
||||||
pub num_thread: usize,
|
pub num_thread: usize,
|
||||||
}
|
}
|
@ -74,14 +74,14 @@ impl Lock {
|
|||||||
self.free = false;
|
self.free = false;
|
||||||
self.owner = Option::Some(match thread_manager.get_g_current_thread() {
|
self.owner = Option::Some(match thread_manager.get_g_current_thread() {
|
||||||
Some(th) => {
|
Some(th) => {
|
||||||
Rc::clone(th)
|
Rc::clone(&th)
|
||||||
},
|
},
|
||||||
None => unreachable!()
|
None => unreachable!()
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
match thread_manager.get_g_current_thread() {
|
match thread_manager.get_g_current_thread() {
|
||||||
Some(x) => {
|
Some(x) => {
|
||||||
let x = Rc::clone(x);
|
let x = Rc::clone(&x);
|
||||||
self.waiting_queue.push(Rc::clone(&x));
|
self.waiting_queue.push(Rc::clone(&x));
|
||||||
thread_manager.thread_sleep(machine, Rc::clone(&x));
|
thread_manager.thread_sleep(machine, Rc::clone(&x));
|
||||||
},
|
},
|
||||||
@ -111,7 +111,7 @@ impl Lock {
|
|||||||
Some(thread) => {
|
Some(thread) => {
|
||||||
self.owner = Some(thread);
|
self.owner = Some(thread);
|
||||||
match &self.owner {
|
match &self.owner {
|
||||||
Some(x) => thread_manager.ready_to_run(Rc::clone(x)),
|
Some(x) => thread_manager.ready_to_run(Rc::clone(&x)),
|
||||||
None => ()
|
None => ()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -118,7 +118,8 @@ pub struct ThreadManager {
|
|||||||
/// List of objects created by the thread manager (such as Locks and Semaphores)
|
/// List of objects created by the thread manager (such as Locks and Semaphores)
|
||||||
obj_addrs: ObjAddr,
|
obj_addrs: ObjAddr,
|
||||||
/// If true, enables debug mode
|
/// If true, enables debug mode
|
||||||
debug: bool
|
debug: bool,
|
||||||
|
sp_max: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ThreadManager {
|
impl ThreadManager {
|
||||||
@ -130,7 +131,8 @@ impl ThreadManager {
|
|||||||
g_alive: List::default(),
|
g_alive: List::default(),
|
||||||
ready_list: List::default(),
|
ready_list: List::default(),
|
||||||
obj_addrs: ObjAddr::init(),
|
obj_addrs: ObjAddr::init(),
|
||||||
debug
|
debug,
|
||||||
|
sp_max: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,20 +241,24 @@ impl ThreadManager {
|
|||||||
while next_thread.is_none() {
|
while next_thread.is_none() {
|
||||||
eprintln!("Nobody to run => idle");
|
eprintln!("Nobody to run => idle");
|
||||||
machine.interrupt.idle();
|
machine.interrupt.idle();
|
||||||
next_thread = self.find_next_to_run();
|
if let Some(t) = self.find_next_to_run() {
|
||||||
|
next_thread = Some(t);
|
||||||
|
} else {
|
||||||
|
panic!("Couldn't find next thread to run.\nShutting down...");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.switch_to(machine, Rc::clone(&next_thread.unwrap()));
|
self.switch_to(machine, Rc::clone(&next_thread.unwrap()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finish the execution of the thread and prepare its deallocation
|
/// Finish the execution of the thread and prepare its deallocation
|
||||||
pub fn thread_finish(&mut self, machine: &mut Machine, thread: ThreadRef) {
|
pub fn thread_finish(&mut self, machine: &mut Machine, thread: ThreadRef, exit_code: i64) {
|
||||||
let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff);
|
let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff);
|
||||||
assert!(self.g_alive.remove(Rc::clone(&thread)));
|
assert!(self.g_alive.remove(Rc::clone(&thread)));
|
||||||
self.debug(format!("Finishing thread {}", thread.borrow().get_name()));
|
self.debug(format!("Finishing thread {} with code {}", thread.borrow().get_name(), exit_code));
|
||||||
// g_objets_addrs->removeObject(self.thread) // a ajouté plus tard
|
// g_objets_addrs->removeObject(self.thread) // a ajouté plus tard
|
||||||
for (_, el) in thread.borrow().join_thread.iter().enumerate() {
|
for (_, el) in thread.borrow().join_thread.iter().enumerate() {
|
||||||
self.ready_to_run(Rc::clone(el));
|
self.ready_to_run(Rc::clone(&el));
|
||||||
}
|
}
|
||||||
self.thread_sleep(machine, Rc::clone(&thread));
|
self.thread_sleep(machine, Rc::clone(&thread));
|
||||||
machine.interrupt.set_status(old_status);
|
machine.interrupt.set_status(old_status);
|
||||||
@ -423,6 +429,14 @@ impl ThreadManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_sp_max(&self) -> u64 {
|
||||||
|
self.sp_max
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_sp_max(&mut self, sp_max: u64) {
|
||||||
|
self.sp_max = sp_max;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -512,7 +526,7 @@ mod test {
|
|||||||
thread_manager.lock_acquire(lock_id, &mut machine).expect("lock acquire return an error at second iteration: ");
|
thread_manager.lock_acquire(lock_id, &mut machine).expect("lock acquire return an error at second iteration: ");
|
||||||
{
|
{
|
||||||
let lock = thread_manager.get_obj_addrs().search_lock(lock_id).unwrap();
|
let lock = thread_manager.get_obj_addrs().search_lock(lock_id).unwrap();
|
||||||
assert_eq!(lock.owner,Some(thread_1));
|
assert_eq!(lock.owner,Some(thread_1.clone()));
|
||||||
assert!(!lock.free);
|
assert!(!lock.free);
|
||||||
assert_eq!(lock.waiting_queue.iter().count(),1);
|
assert_eq!(lock.waiting_queue.iter().count(),1);
|
||||||
}
|
}
|
||||||
@ -525,7 +539,7 @@ mod test {
|
|||||||
assert!(lock.waiting_queue.is_empty());
|
assert!(lock.waiting_queue.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_manager.set_g_current_thread(Some(thread_2));
|
thread_manager.set_g_current_thread(Some(thread_2.clone()));
|
||||||
thread_manager.lock_release(lock_id, &mut machine).expect("lock release return an error at second iteration: ");
|
thread_manager.lock_release(lock_id, &mut machine).expect("lock release return an error at second iteration: ");
|
||||||
{
|
{
|
||||||
let lock = thread_manager.get_obj_addrs().search_lock(lock_id).unwrap();
|
let lock = thread_manager.get_obj_addrs().search_lock(lock_id).unwrap();
|
||||||
|
12
src/main.rs
12
src/main.rs
@ -1,7 +1,4 @@
|
|||||||
#![doc(
|
|
||||||
html_logo_url = "https://gitlab.istic.univ-rennes1.fr/simpleos/burritos/-/raw/main/assets/logo/logo.svg",
|
|
||||||
html_favicon_url = "https://gitlab.istic.univ-rennes1.fr/simpleos/burritos/-/raw/main/assets/logo/logo.svg")
|
|
||||||
]
|
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
#![warn(clippy::missing_docs_in_private_items)]
|
#![warn(clippy::missing_docs_in_private_items)]
|
||||||
|
|
||||||
@ -10,8 +7,10 @@
|
|||||||
//! Burritos is an educational operating system written in Rust
|
//! Burritos is an educational operating system written in Rust
|
||||||
//! running on RISC-V emulator.
|
//! running on RISC-V emulator.
|
||||||
|
|
||||||
|
/// Contain hardware simulated part of the machine
|
||||||
mod simulator;
|
mod simulator;
|
||||||
mod kernel;
|
mod kernel;
|
||||||
|
/// module containing useful tools which can be use in most part of the OS to ease the development of the OS
|
||||||
pub mod utility;
|
pub mod utility;
|
||||||
|
|
||||||
use std::{rc::Rc, cell::RefCell};
|
use std::{rc::Rc, cell::RefCell};
|
||||||
@ -56,7 +55,10 @@ fn main() {
|
|||||||
|
|
||||||
let owner1 = Process { num_thread: 0 };
|
let owner1 = Process { num_thread: 0 };
|
||||||
let owner1 = Rc::new(RefCell::new(owner1));
|
let owner1 = Rc::new(RefCell::new(owner1));
|
||||||
system.get_thread_manager().start_thread(Rc::clone(&thread_exec), owner1, loader.elf_header.entrypoint, ptr + machine.page_size, -1);
|
let sp_max = ptr + machine.user_stack_size;
|
||||||
|
system.get_thread_manager().set_sp_max(sp_max);
|
||||||
|
system.get_thread_manager().start_thread(Rc::clone(&thread_exec), owner1, loader.elf_header.entrypoint, sp_max, -1);
|
||||||
|
|
||||||
|
|
||||||
let to_run = system.get_thread_manager().find_next_to_run().unwrap();
|
let to_run = system.get_thread_manager().find_next_to_run().unwrap();
|
||||||
system.get_thread_manager().switch_to(&mut machine, Rc::clone(&to_run));
|
system.get_thread_manager().switch_to(&mut machine, Rc::clone(&to_run));
|
||||||
|
@ -349,11 +349,11 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_op() {
|
fn test_op() {
|
||||||
let sub = Instruction::new(0b0100000_10000_10001_000_11100_0110011);
|
let sub = Instruction::new(0b0100000_10000_10001_000_11100_0110011_u64.to_le());
|
||||||
let add = Instruction::new(0b0000000_10000_10001_000_11100_0110011);
|
let add = Instruction::new(0b0000000_10000_10001_000_11100_0110011_u64.to_le());
|
||||||
let xor = Instruction::new(0b0000000_10000_10001_100_11100_0110011);
|
let xor = Instruction::new(0b0000000_10000_10001_100_11100_0110011_u64.to_le());
|
||||||
let slr = Instruction::new(0b0000000_10000_10001_101_11100_0110011);
|
let slr = Instruction::new(0b0000000_10000_10001_101_11100_0110011_u64.to_le());
|
||||||
let sra = Instruction::new(0b0100000_10000_10001_101_11100_0110011);
|
let sra = Instruction::new(0b0100000_10000_10001_101_11100_0110011_u64.to_le());
|
||||||
|
|
||||||
assert_eq!("sub\tt3,a7,a6", instruction_debug(&sub, 0));
|
assert_eq!("sub\tt3,a7,a6", instruction_debug(&sub, 0));
|
||||||
assert_eq!("xor\tt3,a7,a6", instruction_debug(&xor, 0));
|
assert_eq!("xor\tt3,a7,a6", instruction_debug(&xor, 0));
|
||||||
@ -365,13 +365,13 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_opi() {
|
fn test_opi() {
|
||||||
let addi = Instruction::new(0b0000000000_10001_000_11100_0010011);
|
let addi = Instruction::new(0b0000000000_10001_000_11100_0010011_u64.to_le());
|
||||||
let slli = Instruction::new(0b0000000000_10001_001_11100_0010011);
|
let slli = Instruction::new(0b0000000000_10001_001_11100_0010011_u64.to_le());
|
||||||
let slti = Instruction::new(0b0000000000_10001_010_11100_0010011);
|
let slti = Instruction::new(0b0000000000_10001_010_11100_0010011_u64.to_le());
|
||||||
let sltiu = Instruction::new(0b0000000000_10001_011_11100_0010011);
|
let sltiu = Instruction::new(0b0000000000_10001_011_11100_0010011_u64.to_le());
|
||||||
let xori = Instruction::new(0b_0000000000010001_100_11100_0010011);
|
let xori = Instruction::new(0b_0000000000010001_100_11100_0010011_u64.to_le());
|
||||||
let ori = Instruction::new(0b00000000000_10001_110_11100_0010011);
|
let ori = Instruction::new(0b00000000000_10001_110_11100_0010011_u64.to_le());
|
||||||
let andi = Instruction::new(0b000000000000_10001_111_11100_0010011);
|
let andi = Instruction::new(0b000000000000_10001_111_11100_0010011_u64.to_le());
|
||||||
assert_eq!("andi\tt3,a7,0", instruction_debug(&andi, 0));
|
assert_eq!("andi\tt3,a7,0", instruction_debug(&andi, 0));
|
||||||
assert_eq!("addi\tt3,a7,0", instruction_debug(&addi, 0));
|
assert_eq!("addi\tt3,a7,0", instruction_debug(&addi, 0));
|
||||||
assert_eq!("slli\tt3,a7,0", instruction_debug(&slli, 0));
|
assert_eq!("slli\tt3,a7,0", instruction_debug(&slli, 0));
|
||||||
@ -383,8 +383,8 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_lui() {
|
fn test_lui() {
|
||||||
let lui = Instruction::new(0b01110001000011111000_11100_0110111);
|
let lui = Instruction::new(0b01110001000011111000_11100_0110111_u64.to_le());
|
||||||
let lui_negatif = Instruction::new(0b11110001000011111000_11100_0110111);
|
let lui_negatif = Instruction::new(0b11110001000011111000_11100_0110111_u64.to_le());
|
||||||
assert_eq!("lui\tt3,710f8000", instruction_debug(&lui, 0));
|
assert_eq!("lui\tt3,710f8000", instruction_debug(&lui, 0));
|
||||||
assert_eq!("lui\tt3,f10f8000", instruction_debug(&lui_negatif, 0));
|
assert_eq!("lui\tt3,f10f8000", instruction_debug(&lui_negatif, 0));
|
||||||
}
|
}
|
||||||
@ -392,13 +392,13 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_ld() {
|
fn test_ld() {
|
||||||
// imm rs1 f3 rd opcode
|
// imm rs1 f3 rd opcode
|
||||||
let lb = Instruction::new(0b010111110000_10001_000_11100_0000011);
|
let lb = Instruction::new(0b010111110000_10001_000_11100_0000011_u64.to_le());
|
||||||
let lh = Instruction::new(0b010111110000_10001_001_11100_0000011);
|
let lh = Instruction::new(0b010111110000_10001_001_11100_0000011_u64.to_le());
|
||||||
let lw = Instruction::new(0b010111110000_10001_010_11100_0000011);
|
let lw = Instruction::new(0b010111110000_10001_010_11100_0000011_u64.to_le());
|
||||||
let lbu = Instruction::new(0b010111110000_10001_100_11100_0000011);
|
let lbu = Instruction::new(0b010111110000_10001_100_11100_0000011_u64.to_le());
|
||||||
let lhu = Instruction::new(0b010111110000_10001_101_11100_0000011);
|
let lhu = Instruction::new(0b010111110000_10001_101_11100_0000011_u64.to_le());
|
||||||
let ld = Instruction::new(0b010111110000_10001_011_11100_0000011);
|
let ld = Instruction::new(0b010111110000_10001_011_11100_0000011_u64.to_le());
|
||||||
let lwu = Instruction::new(0b010111110000_10001_110_11100_0000011);
|
let lwu = Instruction::new(0b010111110000_10001_110_11100_0000011_u64.to_le());
|
||||||
|
|
||||||
assert_eq!("lb\tt3,1520(a7)", instruction_debug(&lb, 0));
|
assert_eq!("lb\tt3,1520(a7)", instruction_debug(&lb, 0));
|
||||||
assert_eq!("lh\tt3,1520(a7)", instruction_debug(&lh, 0));
|
assert_eq!("lh\tt3,1520(a7)", instruction_debug(&lh, 0));
|
||||||
@ -411,10 +411,10 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_opw() {
|
fn test_opw() {
|
||||||
let addw: Instruction = Instruction::new(0b0000000_10000_10001_000_11100_0111011);
|
let addw: Instruction = Instruction::new(0b0000000_10000_10001_000_11100_0111011_u64.to_le());
|
||||||
let sllw: Instruction = Instruction::new(0b0000000_10000_10001_001_11100_0111011);
|
let sllw: Instruction = Instruction::new(0b0000000_10000_10001_001_11100_0111011_u64.to_le());
|
||||||
let srlw: Instruction = Instruction::new(0b0000000_10000_10001_101_11100_0111011);
|
let srlw: Instruction = Instruction::new(0b0000000_10000_10001_101_11100_0111011_u64.to_le());
|
||||||
let sraw: Instruction = Instruction::new(0b0100000_10000_10001_101_11100_0111011);
|
let sraw: Instruction = Instruction::new(0b0100000_10000_10001_101_11100_0111011_u64.to_le());
|
||||||
|
|
||||||
assert_eq!("addw\tt3,a7,a6", instruction_debug(&addw, 0));
|
assert_eq!("addw\tt3,a7,a6", instruction_debug(&addw, 0));
|
||||||
assert_eq!("sllw\tt3,a7,a6", instruction_debug(&sllw, 0));
|
assert_eq!("sllw\tt3,a7,a6", instruction_debug(&sllw, 0));
|
||||||
@ -424,9 +424,9 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_opwi() {
|
fn test_opwi() {
|
||||||
let addiw: Instruction =Instruction::new(0b000000000000_10001_000_11100_0011011);
|
let addiw: Instruction =Instruction::new(0b000000000000_10001_000_11100_0011011_u64.to_le());
|
||||||
let slliw: Instruction = Instruction::new(0b0000000_10000_10001_001_11100_0011011);
|
let slliw: Instruction = Instruction::new(0b0000000_10000_10001_001_11100_0011011_u64.to_le());
|
||||||
let srai: Instruction = Instruction::new(0b010000010001_10001_101_11100_0010011);
|
let srai: Instruction = Instruction::new(0b010000010001_10001_101_11100_0010011_u64.to_le());
|
||||||
assert_eq!("addiw\tt3,a7,0x0", instruction_debug(&addiw, 0));
|
assert_eq!("addiw\tt3,a7,0x0", instruction_debug(&addiw, 0));
|
||||||
assert_eq!("slliw\tt3,a7,0x10", instruction_debug(&slliw, 0));
|
assert_eq!("slliw\tt3,a7,0x10", instruction_debug(&slliw, 0));
|
||||||
assert_eq!("srai\tt3,a7,17", instruction_debug(&srai, 0));
|
assert_eq!("srai\tt3,a7,17", instruction_debug(&srai, 0));
|
||||||
@ -435,13 +435,13 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_br() {
|
fn test_br() {
|
||||||
let beq: Instruction = Instruction::new(0b0000000_10000_10001_000_00000_1100011);
|
let beq: Instruction = Instruction::new(0b0000000_10000_10001_000_00000_1100011_u64.to_le());
|
||||||
let bne: Instruction = Instruction::new(0b0000000_10000_10001_001_00000_1100011);
|
let bne: Instruction = Instruction::new(0b0000000_10000_10001_001_00000_1100011_u64.to_le());
|
||||||
let blt: Instruction = Instruction::new(0b0000000_10000_10001_100_00000_1100011);
|
let blt: Instruction = Instruction::new(0b0000000_10000_10001_100_00000_1100011_u64.to_le());
|
||||||
let bge: Instruction = Instruction::new(0b0000000_10000_10001_101_00000_1100011);
|
let bge: Instruction = Instruction::new(0b0000000_10000_10001_101_00000_1100011_u64.to_le());
|
||||||
let bge2: Instruction = Instruction::new(0x00f75863);
|
let bge2: Instruction = Instruction::new(0x00f75863_u64.to_le());
|
||||||
let bltu: Instruction = Instruction::new(0b0000000_10000_10001_110_00000_1100011);
|
let bltu: Instruction = Instruction::new(0b0000000_10000_10001_110_00000_1100011_u64.to_le());
|
||||||
let bgeu: Instruction = Instruction::new(0b0000000_10000_10001_111_00000_1100011);
|
let bgeu: Instruction = Instruction::new(0b0000000_10000_10001_111_00000_1100011_u64.to_le());
|
||||||
assert_eq!("blt\ta7,a6,0", instruction_debug(&blt, 0));
|
assert_eq!("blt\ta7,a6,0", instruction_debug(&blt, 0));
|
||||||
assert_eq!("bge\ta7,a6,0", instruction_debug(&bge, 0));
|
assert_eq!("bge\ta7,a6,0", instruction_debug(&bge, 0));
|
||||||
assert_eq!("bge\ta4,a5,104d4", instruction_debug(&bge2, 0x104c4));
|
assert_eq!("bge\ta4,a5,104d4", instruction_debug(&bge2, 0x104c4));
|
||||||
@ -461,72 +461,72 @@ mod test {
|
|||||||
a = a + b;
|
a = a + b;
|
||||||
b = a - b;
|
b = a - b;
|
||||||
*/
|
*/
|
||||||
assert_eq!("addi sp,sp,-32", instruction_debug(&Instruction::new(0xfe010113), 0));
|
assert_eq!("addi sp,sp,-32", instruction_debug(&Instruction::new(0xfe010113_u64.to_le()), 0));
|
||||||
assert_eq!("sd s0,24(sp)", instruction_debug(&Instruction::new(0x00813c23), 0));
|
assert_eq!("sd s0,24(sp)", instruction_debug(&Instruction::new(0x00813c23_u64.to_le()), 0));
|
||||||
assert_eq!("addi s0,sp,32", instruction_debug(&Instruction::new(0x02010413), 0));
|
assert_eq!("addi s0,sp,32", instruction_debug(&Instruction::new(0x02010413_u64.to_le()), 0));
|
||||||
assert_eq!("sw zero,-20(s0)", instruction_debug(&Instruction::new(0xfe042623), 0));
|
assert_eq!("sw zero,-20(s0)", instruction_debug(&Instruction::new(0xfe042623_u64.to_le()), 0));
|
||||||
assert_eq!("addi a5,zero,5", instruction_debug(&Instruction::new(0x00500793), 0));
|
assert_eq!("addi a5,zero,5", instruction_debug(&Instruction::new(0x00500793_u64.to_le()), 0));
|
||||||
assert_eq!("sw a5,-24(s0)", instruction_debug(&Instruction::new(0xfef42423), 0));
|
assert_eq!("sw a5,-24(s0)", instruction_debug(&Instruction::new(0xfef42423_u64.to_le()), 0));
|
||||||
assert_eq!("lw a5,-24(s0)", instruction_debug(&Instruction::new(0xfe842783), 0));
|
assert_eq!("lw a5,-24(s0)", instruction_debug(&Instruction::new(0xfe842783_u64.to_le()), 0));
|
||||||
assert_eq!("sw a5,-20(s0)", instruction_debug(&Instruction::new(0xfef42623), 0));
|
assert_eq!("sw a5,-20(s0)", instruction_debug(&Instruction::new(0xfef42623_u64.to_le()), 0));
|
||||||
assert_eq!("lw a5,-20(s0)", instruction_debug(&Instruction::new(0xfec42783), 0));
|
assert_eq!("lw a5,-20(s0)", instruction_debug(&Instruction::new(0xfec42783_u64.to_le()), 0));
|
||||||
assert_eq!("addi a4,a5,0", instruction_debug(&Instruction::new(0x00078713), 0));
|
assert_eq!("addi a4,a5,0", instruction_debug(&Instruction::new(0x00078713_u64.to_le()), 0));
|
||||||
assert_eq!("lw a5,-24(s0)", instruction_debug(&Instruction::new(0xfe842783), 0));
|
assert_eq!("lw a5,-24(s0)", instruction_debug(&Instruction::new(0xfe842783_u64.to_le()), 0));
|
||||||
assert_eq!("mulw a5,a4,a5", instruction_debug(&Instruction::new(0x02f707bb), 0));
|
assert_eq!("mulw a5,a4,a5", instruction_debug(&Instruction::new(0x02f707bb_u64.to_le()), 0));
|
||||||
assert_eq!("sw a5,-20(s0)", instruction_debug(&Instruction::new(0xfef42623), 0));
|
assert_eq!("sw a5,-20(s0)", instruction_debug(&Instruction::new(0xfef42623_u64.to_le()), 0));
|
||||||
assert_eq!("lw a5,-20(s0)", instruction_debug(&Instruction::new(0xfec42783), 0));
|
assert_eq!("lw a5,-20(s0)", instruction_debug(&Instruction::new(0xfec42783_u64.to_le()), 0));
|
||||||
assert_eq!("addi a4,a5,0", instruction_debug(&Instruction::new(0x00078713), 0));
|
assert_eq!("addi a4,a5,0", instruction_debug(&Instruction::new(0x00078713_u64.to_le()), 0));
|
||||||
assert_eq!("lw a5,-24(s0)", instruction_debug(&Instruction::new(0xfe842783), 0));
|
assert_eq!("lw a5,-24(s0)", instruction_debug(&Instruction::new(0xfe842783_u64.to_le()), 0));
|
||||||
assert_eq!("addw a5,a4,a5", instruction_debug(&Instruction::new(0x00f707bb), 0));
|
assert_eq!("addw a5,a4,a5", instruction_debug(&Instruction::new(0x00f707bb_u64.to_le()), 0));
|
||||||
assert_eq!("sw a5,-20(s0)", instruction_debug(&Instruction::new(0xfef42623), 0));
|
assert_eq!("sw a5,-20(s0)", instruction_debug(&Instruction::new(0xfef42623_u64.to_le()), 0));
|
||||||
assert_eq!("lw a5,-20(s0)", instruction_debug(&Instruction::new(0xfec42783), 0));
|
assert_eq!("lw a5,-20(s0)", instruction_debug(&Instruction::new(0xfec42783_u64.to_le()), 0));
|
||||||
assert_eq!("addi a4,a5,0", instruction_debug(&Instruction::new(0x00078713), 0));
|
assert_eq!("addi a4,a5,0", instruction_debug(&Instruction::new(0x00078713_u64.to_le()), 0));
|
||||||
assert_eq!("lw a5,-24(s0)", instruction_debug(&Instruction::new(0xfe842783), 0));
|
assert_eq!("lw a5,-24(s0)", instruction_debug(&Instruction::new(0xfe842783_u64.to_le()), 0));
|
||||||
assert_eq!("subw a5,a4,a5", instruction_debug(&Instruction::new(0x40f707bb), 0));
|
assert_eq!("subw a5,a4,a5", instruction_debug(&Instruction::new(0x40f707bb_u64.to_le()), 0));
|
||||||
assert_eq!("sw a5,-24(s0)", instruction_debug(&Instruction::new(0xfef42423), 0));
|
assert_eq!("sw a5,-24(s0)", instruction_debug(&Instruction::new(0xfef42423_u64.to_le()), 0));
|
||||||
assert_eq!("addi a5,zero,0", instruction_debug(&Instruction::new(0x00000793), 0));
|
assert_eq!("addi a5,zero,0", instruction_debug(&Instruction::new(0x00000793_u64.to_le()), 0));
|
||||||
assert_eq!("addi a0,a5,0", instruction_debug(&Instruction::new(0x00078513), 0));
|
assert_eq!("addi a0,a5,0", instruction_debug(&Instruction::new(0x00078513_u64.to_le()), 0));
|
||||||
assert_eq!("ld s0,24(sp)", instruction_debug(&Instruction::new(0x01813403), 0));
|
assert_eq!("ld s0,24(sp)", instruction_debug(&Instruction::new(0x01813403_u64.to_le()), 0));
|
||||||
assert_eq!("addi sp,sp,32", instruction_debug(&Instruction::new(0x02010113), 0));
|
assert_eq!("addi sp,sp,32", instruction_debug(&Instruction::new(0x02010113_u64.to_le()), 0));
|
||||||
assert_eq!("jalr zero,0(ra)", instruction_debug(&Instruction::new(0x00008067), 0));
|
assert_eq!("jalr zero,0(ra)", instruction_debug(&Instruction::new(0x00008067_u64.to_le()), 0));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fibo() {
|
fn test_fibo() {
|
||||||
assert_eq!("jal zero,10504", instruction_debug(&Instruction::new(0x0500006f), 0x104b4));
|
assert_eq!("jal zero,10504", instruction_debug(&Instruction::new(0x0500006f_u64.to_le()), 0x104b4));
|
||||||
assert_eq!("blt a4,a5,104b8", instruction_debug(&Instruction::new(0xfaf740e3), 0x10518));
|
assert_eq!("blt a4,a5,104b8", instruction_debug(&Instruction::new(0xfaf740e3_u64.to_le()), 0x10518));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_mul_prog() {
|
fn test_mul_prog() {
|
||||||
assert_eq!("addi sp,sp,-32", instruction_debug(&Instruction::new(0xfe010113), 0));
|
assert_eq!("addi sp,sp,-32", instruction_debug(&Instruction::new(0xfe010113_u64.to_le()), 0));
|
||||||
assert_eq!("sd s0,24(sp)", instruction_debug(&Instruction::new(0x00813c23), 0));
|
assert_eq!("sd s0,24(sp)", instruction_debug(&Instruction::new(0x00813c23_u64.to_le()), 0));
|
||||||
assert_eq!("addi s0,sp,32", instruction_debug(&Instruction::new(0x02010413), 0));
|
assert_eq!("addi s0,sp,32", instruction_debug(&Instruction::new(0x02010413_u64.to_le()), 0));
|
||||||
assert_eq!("addi a5,zero,5", instruction_debug(&Instruction::new(0x00500793), 0));
|
assert_eq!("addi a5,zero,5", instruction_debug(&Instruction::new(0x00500793_u64.to_le()), 0));
|
||||||
assert_eq!("sw a5,-20(s0)", instruction_debug(&Instruction::new(0xfef42623), 0));
|
assert_eq!("sw a5,-20(s0)", instruction_debug(&Instruction::new(0xfef42623_u64.to_le()), 0));
|
||||||
assert_eq!("lw a5,-20(s0)", instruction_debug(&Instruction::new(0xfec42783), 0));
|
assert_eq!("lw a5,-20(s0)", instruction_debug(&Instruction::new(0xfec42783_u64.to_le()), 0));
|
||||||
assert_eq!("addi a4,a5,0", instruction_debug(&Instruction::new(0x00078713), 0));
|
assert_eq!("addi a4,a5,0", instruction_debug(&Instruction::new(0x00078713_u64.to_le()), 0));
|
||||||
assert_eq!("addi a5,a4,0", instruction_debug(&Instruction::new(0x00070793), 0));
|
assert_eq!("addi a5,a4,0", instruction_debug(&Instruction::new(0x00070793_u64.to_le()), 0));
|
||||||
assert_eq!("slliw a5,a5,0x2", instruction_debug(&Instruction::new(0x0027979b), 0));
|
assert_eq!("slliw a5,a5,0x2", instruction_debug(&Instruction::new(0x0027979b_u64.to_le()), 0));
|
||||||
assert_eq!("addw a5,a5,a4", instruction_debug(&Instruction::new(0x00e787bb), 0));
|
assert_eq!("addw a5,a5,a4", instruction_debug(&Instruction::new(0x00e787bb_u64.to_le()), 0));
|
||||||
assert_eq!("sw a5,-24(s0)", instruction_debug(&Instruction::new(0xfef42423), 0));
|
assert_eq!("sw a5,-24(s0)", instruction_debug(&Instruction::new(0xfef42423_u64.to_le()), 0));
|
||||||
assert_eq!("lw a5,-20(s0)", instruction_debug(&Instruction::new(0xfec42783), 0));
|
assert_eq!("lw a5,-20(s0)", instruction_debug(&Instruction::new(0xfec42783_u64.to_le()), 0));
|
||||||
assert_eq!("addi a4,a5,0", instruction_debug(&Instruction::new(0x00078713), 0));
|
assert_eq!("addi a4,a5,0", instruction_debug(&Instruction::new(0x00078713_u64.to_le()), 0));
|
||||||
assert_eq!("lw a5,-24(s0)", instruction_debug(&Instruction::new(0xfe842783), 0));
|
assert_eq!("lw a5,-24(s0)", instruction_debug(&Instruction::new(0xfe842783_u64.to_le()), 0));
|
||||||
assert_eq!("mulw a5,a4,a5", instruction_debug(&Instruction::new(0x02f707bb), 0));
|
assert_eq!("mulw a5,a4,a5", instruction_debug(&Instruction::new(0x02f707bb_u64.to_le()), 0));
|
||||||
assert_eq!("sw a5,-28(s0)", instruction_debug(&Instruction::new(0xfef42223), 0));
|
assert_eq!("sw a5,-28(s0)", instruction_debug(&Instruction::new(0xfef42223_u64.to_le()), 0));
|
||||||
assert_eq!("lw a5,-28(s0)", instruction_debug(&Instruction::new(0xfe442783), 0));
|
assert_eq!("lw a5,-28(s0)", instruction_debug(&Instruction::new(0xfe442783_u64.to_le()), 0));
|
||||||
assert_eq!("addi a4,a5,0", instruction_debug(&Instruction::new(0x00078713), 0));
|
assert_eq!("addi a4,a5,0", instruction_debug(&Instruction::new(0x00078713_u64.to_le()), 0));
|
||||||
assert_eq!("lw a5,-24(s0)", instruction_debug(&Instruction::new(0xfe842783), 0));
|
assert_eq!("lw a5,-24(s0)", instruction_debug(&Instruction::new(0xfe842783_u64.to_le()), 0));
|
||||||
assert_eq!("divw a5,a4,a5", instruction_debug(&Instruction::new(0x02f747bb), 0));
|
assert_eq!("divw a5,a4,a5", instruction_debug(&Instruction::new(0x02f747bb_u64.to_le()), 0));
|
||||||
assert_eq!("sw a5,-20(s0)", instruction_debug(&Instruction::new(0xfef42623), 0));
|
assert_eq!("sw a5,-20(s0)", instruction_debug(&Instruction::new(0xfef42623_u64.to_le()), 0));
|
||||||
assert_eq!("addi a5,zero,0", instruction_debug(&Instruction::new(0x00000793), 0));
|
assert_eq!("addi a5,zero,0", instruction_debug(&Instruction::new(0x00000793_u64.to_le()), 0));
|
||||||
assert_eq!("addi a0,a5,0", instruction_debug(&Instruction::new(0x00078513), 0));
|
assert_eq!("addi a0,a5,0", instruction_debug(&Instruction::new(0x00078513_u64.to_le()), 0));
|
||||||
assert_eq!("ld s0,24(sp)", instruction_debug(&Instruction::new(0x01813403), 0));
|
assert_eq!("ld s0,24(sp)", instruction_debug(&Instruction::new(0x01813403_u64.to_le()), 0));
|
||||||
assert_eq!("addi sp,sp,32", instruction_debug(&Instruction::new(0x02010113), 0));
|
assert_eq!("addi sp,sp,32", instruction_debug(&Instruction::new(0x02010113_u64.to_le()), 0));
|
||||||
assert_eq!("jalr zero,0(ra)", instruction_debug(&Instruction::new(0x00008067), 0));
|
assert_eq!("jalr zero,0(ra)", instruction_debug(&Instruction::new(0x00008067_u64.to_le()), 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq)]
|
||||||
pub struct Interrupt {
|
pub struct Interrupt {
|
||||||
level: InterruptStatus
|
level: InterruptStatus
|
||||||
}
|
}
|
||||||
@ -21,7 +21,7 @@ impl Interrupt {
|
|||||||
old
|
old
|
||||||
}
|
}
|
||||||
|
|
||||||
fn one_tick(&self, _nb_cycle: i32) {
|
fn one_tick(&self, nb_cycle: i32) {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ impl Interrupt {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
#[derive(PartialEq, Clone, Copy, Debug)]
|
||||||
pub enum InterruptStatus {
|
pub enum InterruptStatus {
|
||||||
InterruptOff,
|
InterruptOff,
|
||||||
InterruptOn
|
InterruptOn
|
||||||
|
@ -463,7 +463,12 @@ impl Loader {
|
|||||||
buf[k] = self.bytes.get(section.image_offset as usize + j + k).copied().ok_or(LoaderError::ParsingError(format!("index 0x{:x} is out of bound because list have a size of 0x{:x} (image offset 0x{:x}, j 0x{:x}, k 0x{:x})", section.image_offset as usize + j + k, self.bytes.len(), section.image_offset, j, k)))?;
|
buf[k] = self.bytes.get(section.image_offset as usize + j + k).copied().ok_or(LoaderError::ParsingError(format!("index 0x{:x} is out of bound because list have a size of 0x{:x} (image offset 0x{:x}, j 0x{:x}, k 0x{:x})", section.image_offset as usize + j + k, self.bytes.len(), section.image_offset, j, k)))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
machine.write_memory(4, start_index + section.virt_addr as usize + j, u32::from_le_bytes(buf) as u64);
|
|
||||||
|
machine.write_memory(1, start_index + section.virt_addr as usize + j, buf[0] as u64);
|
||||||
|
machine.write_memory(1, start_index + section.virt_addr as usize + j + 1, buf[1] as u64);
|
||||||
|
machine.write_memory(1, start_index + section.virt_addr as usize + j + 2, buf[2] as u64);
|
||||||
|
machine.write_memory(1, start_index + section.virt_addr as usize + j + 3, buf[3] as u64);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -619,7 +624,7 @@ mod test {
|
|||||||
assert_eq!(loader.sections[1].virt_addr, 0x4000);
|
assert_eq!(loader.sections[1].virt_addr, 0x4000);
|
||||||
assert_eq!(loader.sections[1].image_offset, 0x1000);
|
assert_eq!(loader.sections[1].image_offset, 0x1000);
|
||||||
assert!(loader.sections[1].does_flag_contains_key(crate::simulator::loader::FlagValue::ShfAlloc));
|
assert!(loader.sections[1].does_flag_contains_key(crate::simulator::loader::FlagValue::ShfAlloc));
|
||||||
assert_eq!(loader.sections[2].virt_addr, 0x0040_0000);
|
assert_eq!(loader.sections[2].virt_addr, 0x400_000);
|
||||||
assert_eq!(loader.sections[2].image_offset, 0x2000);
|
assert_eq!(loader.sections[2].image_offset, 0x2000);
|
||||||
assert!(loader.sections[2].does_flag_contains_key(crate::simulator::loader::FlagValue::ShfAlloc));
|
assert!(loader.sections[2].does_flag_contains_key(crate::simulator::loader::FlagValue::ShfAlloc));
|
||||||
}
|
}
|
||||||
|
@ -96,6 +96,7 @@ pub struct Machine {
|
|||||||
//creer une struct cfg(configuration) qui s'initialise avec valeur dans un fichier cfg
|
//creer une struct cfg(configuration) qui s'initialise avec valeur dans un fichier cfg
|
||||||
num_phy_page: u64,
|
num_phy_page: u64,
|
||||||
pub page_size: u64,
|
pub page_size: u64,
|
||||||
|
pub user_stack_size: u64,
|
||||||
/// Current machine status
|
/// Current machine status
|
||||||
pub status: MachineStatus
|
pub status: MachineStatus
|
||||||
}
|
}
|
||||||
@ -115,7 +116,8 @@ impl Machine {
|
|||||||
|
|
||||||
let num_phy_page = *settings.get(&MachineSettingKey::NumPhysPages).unwrap();
|
let num_phy_page = *settings.get(&MachineSettingKey::NumPhysPages).unwrap();
|
||||||
let page_size = *settings.get(&MachineSettingKey::PageSize).unwrap();
|
let page_size = *settings.get(&MachineSettingKey::PageSize).unwrap();
|
||||||
let mem_size = (page_size*num_phy_page*100_000) as usize;
|
let user_stack_size = *settings.get(&MachineSettingKey::UserStackSize).unwrap();
|
||||||
|
let mem_size = (page_size*num_phy_page) as usize;
|
||||||
|
|
||||||
Machine {
|
Machine {
|
||||||
debug,
|
debug,
|
||||||
@ -129,7 +131,8 @@ impl Machine {
|
|||||||
registers_trace : String::from(""),
|
registers_trace : String::from(""),
|
||||||
status: MachineStatus::SystemMode,
|
status: MachineStatus::SystemMode,
|
||||||
num_phy_page,
|
num_phy_page,
|
||||||
page_size
|
page_size,
|
||||||
|
user_stack_size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +231,7 @@ impl Machine {
|
|||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn raise_exception(&mut self, exception: ExceptionType, _address : u64, system: &mut System) -> Result<MachineOk, MachineError>{
|
pub fn raise_exception(&mut self, exception: ExceptionType, address : u64, system: &mut System) -> Result<MachineOk, MachineError>{
|
||||||
self.set_status(MachineStatus::SystemMode);
|
self.set_status(MachineStatus::SystemMode);
|
||||||
// Handle the interruption
|
// Handle the interruption
|
||||||
match exception::call(&exception, self, system) {
|
match exception::call(&exception, self, system) {
|
||||||
@ -284,7 +287,7 @@ impl Machine {
|
|||||||
*elem = self.main_memory[self.pc as usize + i];
|
*elem = self.main_memory[self.pc as usize + i];
|
||||||
}
|
}
|
||||||
|
|
||||||
let val = u32::from_be_bytes(val) as u64;
|
let val = u32::from_le_bytes(val) as u64;
|
||||||
let inst : Instruction = Instruction::new(val);
|
let inst : Instruction = Instruction::new(val);
|
||||||
if self.debug {
|
if self.debug {
|
||||||
self.print_status();
|
self.print_status();
|
||||||
@ -425,10 +428,10 @@ impl Machine {
|
|||||||
RISCV_OPI_XORI => compute(&core::ops::BitXor::bitxor, rs1, imm12),
|
RISCV_OPI_XORI => compute(&core::ops::BitXor::bitxor, rs1, imm12),
|
||||||
RISCV_OPI_ORI => compute(&core::ops::BitOr::bitor, rs1, imm12),
|
RISCV_OPI_ORI => compute(&core::ops::BitOr::bitor, rs1, imm12),
|
||||||
RISCV_OPI_ANDI => compute(&core::ops::BitAnd::bitand, rs1, imm12),
|
RISCV_OPI_ANDI => compute(&core::ops::BitAnd::bitand, rs1, imm12),
|
||||||
RISCV_OPI_SLLI => compute(&core::ops::Shl::shl, rs1, imm12),
|
RISCV_OPI_SLLI => compute(&core::ops::Shl::shl, rs1, shamt),
|
||||||
RISCV_OPI_SRI => if inst.funct7_smaller == RISCV_OPI_SRI_SRLI {
|
RISCV_OPI_SRI => if inst.funct7_smaller == RISCV_OPI_SRI_SRLI {
|
||||||
compute(&|a, b| { (a >> b) & self.shiftmask[inst.shamt as usize] as i64 }, rs1, shamt)
|
compute(&|a, b| { (a >> b) & self.shiftmask[inst.shamt as usize] as i64 }, rs1, shamt)
|
||||||
} else {
|
} else { // SRAI
|
||||||
compute(&core::ops::Shr::shr, rs1, shamt)
|
compute(&core::ops::Shr::shr, rs1, shamt)
|
||||||
}
|
}
|
||||||
_ => Err(format!("Unreachable in opi_instruction match! Instruction was {:?}", inst))?
|
_ => Err(format!("Unreachable in opi_instruction match! Instruction was {:?}", inst))?
|
||||||
@ -501,8 +504,8 @@ impl Machine {
|
|||||||
let local_data = self.int_reg.get_reg(inst.rs1);
|
let local_data = self.int_reg.get_reg(inst.rs1);
|
||||||
let result = match inst.funct3 {
|
let result = match inst.funct3 {
|
||||||
RISCV_OPIW_ADDIW => local_data + inst.imm12_I_signed as i64,
|
RISCV_OPIW_ADDIW => local_data + inst.imm12_I_signed as i64,
|
||||||
RISCV_OPIW_SLLIW => local_data << inst.shamt,
|
RISCV_OPIW_SLLIW => local_data << inst.rs2,
|
||||||
RISCV_OPIW_SRW => (local_data >> inst.shamt) & if inst.funct7 == RISCV_OPIW_SRW_SRLIW { self.shiftmask[32 + inst.shamt as usize] as i64 } else { 1 },
|
RISCV_OPIW_SRW => (local_data >> inst.rs2) & if inst.funct7 == RISCV_OPIW_SRW_SRLIW { self.shiftmask[32 + inst.rs2 as usize] as i64 } else { 1 },
|
||||||
_ => Err(format!("Unreachable in op_instruction match! Instruction was {:?}", inst))?
|
_ => Err(format!("Unreachable in op_instruction match! Instruction was {:?}", inst))?
|
||||||
};
|
};
|
||||||
self.int_reg.set_reg(inst.rd, result);
|
self.int_reg.set_reg(inst.rd, result);
|
||||||
@ -519,7 +522,7 @@ impl Machine {
|
|||||||
|
|
||||||
// Match case for multiplication operations (in standard extension RV32M)
|
// Match case for multiplication operations (in standard extension RV32M)
|
||||||
match inst.funct3 {
|
match inst.funct3 {
|
||||||
RISCV_OPW_M_MULW => self.int_reg.set_reg(inst.rd, local_data_a * local_data_b),
|
RISCV_OPW_M_MULW => self.int_reg.set_reg(inst.rd, (local_data_a * local_data_b) & 0xffffffff),
|
||||||
RISCV_OPW_M_DIVW => self.int_reg.set_reg(inst.rd, local_data_a / local_data_b),
|
RISCV_OPW_M_DIVW => self.int_reg.set_reg(inst.rd, local_data_a / local_data_b),
|
||||||
RISCV_OPW_M_DIVUW => self.int_reg.set_reg(inst.rd, local_data_a_unsigned / local_data_b_unsigned),
|
RISCV_OPW_M_DIVUW => self.int_reg.set_reg(inst.rd, local_data_a_unsigned / local_data_b_unsigned),
|
||||||
RISCV_OPW_M_REMW => self.int_reg.set_reg(inst.rd, local_data_a % local_data_b),
|
RISCV_OPW_M_REMW => self.int_reg.set_reg(inst.rd, local_data_a % local_data_b),
|
||||||
@ -538,9 +541,9 @@ impl Machine {
|
|||||||
},
|
},
|
||||||
RISCV_OPW_SLLW => self.int_reg.set_reg(inst.rd, local_dataa << (local_datab & 0x1f)),
|
RISCV_OPW_SLLW => self.int_reg.set_reg(inst.rd, local_dataa << (local_datab & 0x1f)),
|
||||||
RISCV_OPW_SRW => if inst.funct7 == RISCV_OPW_SRW_SRLW {
|
RISCV_OPW_SRW => if inst.funct7 == RISCV_OPW_SRW_SRLW {
|
||||||
self.int_reg.set_reg(inst.rd, local_dataa >> (local_datab & 0x1f) & self.shiftmask[32 + local_datab as usize] as i64)
|
self.int_reg.set_reg(inst.rd, local_dataa >> (local_datab /* & 0x1f */) & self.shiftmask[32 + local_datab as usize] as i64)
|
||||||
} else { // SRAW
|
} else { // SRAW
|
||||||
self.int_reg.set_reg(inst.rd, local_dataa >> (local_datab & 0x1f))
|
self.int_reg.set_reg(inst.rd, local_dataa >> (local_datab /* & 0x1f */))
|
||||||
},
|
},
|
||||||
_ => Err(format!("Unreachable in opw_instruction match! Instruction was {:?}", inst))?
|
_ => Err(format!("Unreachable in opw_instruction match! Instruction was {:?}", inst))?
|
||||||
}
|
}
|
||||||
|
@ -36,14 +36,22 @@ pub struct Section{
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Section {
|
impl Section {
|
||||||
|
|
||||||
/// Creates a memory section from a SectionFormat
|
/// Creates a memory section from a SectionFormat
|
||||||
fn from(section: &SectionFormat) -> Section {
|
fn from(section: &mut SectionFormat) -> Section {
|
||||||
let addr = usize::from_str_radix(§ion.addr, 16).unwrap_or_default();
|
let addr = usize::from_str_radix(§ion.addr, 16).unwrap_or_default();
|
||||||
let len = usize::from_str_radix(§ion.len, 16).unwrap_or_default();
|
let len = usize::from_str_radix(§ion.len, 16).unwrap_or_default();
|
||||||
let content: Vec<u8> = section.content.as_bytes().chunks(2).map(|x| {
|
let content: Vec<u8>;
|
||||||
u8::from_str_radix(std::str::from_utf8(x).unwrap_or_default(), 16).unwrap_or_default()
|
unsafe {
|
||||||
}).collect();
|
content = section.content.as_bytes_mut()
|
||||||
|
.chunks_mut(4).map(
|
||||||
|
|x| {
|
||||||
|
x.reverse();
|
||||||
|
u8::from_str_radix(
|
||||||
|
std::str::from_utf8(x).unwrap_or_default(), 16
|
||||||
|
).unwrap_or_default()
|
||||||
|
}
|
||||||
|
).collect();
|
||||||
|
}
|
||||||
Section { addr, len, content }
|
Section { addr, len, content }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,12 +134,12 @@ impl MemChecker{
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//lecture ligne CONTENT
|
//lecture ligne CONTENT
|
||||||
let section_f = SectionFormat{
|
let mut section_f = SectionFormat {
|
||||||
addr: tmp_addr_str.clone(),
|
addr: tmp_addr_str.clone(),
|
||||||
len: tmp_len_str.clone(),
|
len: tmp_len_str.clone(),
|
||||||
content: current_line.clone().replace(' ', ""),
|
content: current_line.clone().replace(' ', ""),
|
||||||
};
|
};
|
||||||
sections.push(Section::from(§ion_f));
|
sections.push(Section::from(&mut section_f));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -235,12 +243,12 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_create_section_content(){
|
fn test_create_section_content(){
|
||||||
let section_format = SectionFormat{
|
let mut section_format = SectionFormat{
|
||||||
addr: "0".to_string(),
|
addr: "0".to_string(),
|
||||||
len: "0".to_string(),
|
len: "0".to_string(),
|
||||||
content: "00FF0AA0A5".to_string(),
|
content: "00FF0AA0A5".to_string(),
|
||||||
};
|
};
|
||||||
let section = Section::from(§ion_format);
|
let section = Section::from(&mut section_format);
|
||||||
let expected_vec: Vec<u8> = vec![0u8, 255u8, 10u8, 160u8, 165u8];
|
let expected_vec: Vec<u8> = vec![0u8, 255u8, 10u8, 160u8, 165u8];
|
||||||
assert_eq!(section.content, expected_vec);
|
assert_eq!(section.content, expected_vec);
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ pub mod global {
|
|||||||
///
|
///
|
||||||
/// Shift left logical immediate
|
/// Shift left logical immediate
|
||||||
///
|
///
|
||||||
/// `SLLI rd, rs1, shamt` => `rd <- rs1 >> shamt`
|
/// `SLLI rd, rs1, shamt` => `rd <- rs1 << shamt`
|
||||||
pub const RISCV_OPI_SLLI: u8 = 0x1;
|
pub const RISCV_OPI_SLLI: u8 = 0x1;
|
||||||
/// Shift right immediate, may be SRAI or SRLI
|
/// Shift right immediate, may be SRAI or SRLI
|
||||||
pub const RISCV_OPI_SRI: u8 = 0x5;
|
pub const RISCV_OPI_SRI: u8 = 0x5;
|
||||||
|
@ -21,7 +21,7 @@ impl RegisterNum for i64 {}
|
|||||||
impl RegisterNum for f32 {}
|
impl RegisterNum for f32 {}
|
||||||
|
|
||||||
/// Machine register array
|
/// Machine register array
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq)]
|
||||||
pub struct Register<U: RegisterNum> {
|
pub struct Register<U: RegisterNum> {
|
||||||
/// 32 available registers of type U
|
/// 32 available registers of type U
|
||||||
register: [U; 32]
|
register: [U; 32]
|
||||||
|
@ -22,7 +22,7 @@ impl TranslationTable {
|
|||||||
|
|
||||||
let mut tmp_vec : Vec<PageTableEntry> = Vec::new();
|
let mut tmp_vec : Vec<PageTableEntry> = Vec::new();
|
||||||
|
|
||||||
for _i in 0..MaxVirtPages {
|
for i in 0..MaxVirtPages {
|
||||||
tmp_vec.push(PageTableEntry::create());
|
tmp_vec.push(PageTableEntry::create());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ impl TranslationTable {
|
|||||||
//Assert a mettre dans chacune des fonctions suivantes
|
//Assert a mettre dans chacune des fonctions suivantes
|
||||||
|
|
||||||
pub fn get_max_num_pages(&self) -> u64{
|
pub fn get_max_num_pages(&self) -> u64{
|
||||||
self.maxNumPages
|
return self.maxNumPages;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_physical_page(&mut self, vpn : u64, physical_page : i32){
|
pub fn set_physical_page(&mut self, vpn : u64, physical_page : i32){
|
||||||
|
@ -93,17 +93,17 @@ pub fn read_settings() -> Result<Settings, Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a mock configuration for Machine unit testing
|
/// Returns a mock configuration for Machine unit testing
|
||||||
|
///
|
||||||
|
/// FIXME: Does not cover the whole configuration yet
|
||||||
pub fn get_debug_configuration() -> Settings {
|
pub fn get_debug_configuration() -> Settings {
|
||||||
let mut settings_map = Settings::new();
|
let mut settings_map = Settings::new();
|
||||||
settings_map.insert(MachineSettingKey::PageSize, 128);
|
settings_map.insert(MachineSettingKey::PageSize, 128);
|
||||||
settings_map.insert(MachineSettingKey::NumPhysPages, 400);
|
settings_map.insert(MachineSettingKey::NumPhysPages, 40000000);
|
||||||
|
settings_map.insert(MachineSettingKey::UserStackSize, 4096);
|
||||||
settings_map
|
settings_map
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Filters out empty lines and comments from the reader `BufReader`.
|
/// Removes comments and empty lines
|
||||||
///
|
|
||||||
/// Returns a [`Vec<String>`], each entry containing a valid
|
|
||||||
/// line from the input file.
|
|
||||||
fn filter_garbage<R: std::io::Read>(reader: BufReader<R>) -> Vec<String> {
|
fn filter_garbage<R: std::io::Read>(reader: BufReader<R>) -> Vec<String> {
|
||||||
reader.lines()
|
reader.lines()
|
||||||
.map(|l| l.unwrap())
|
.map(|l| l.unwrap())
|
||||||
@ -111,12 +111,11 @@ fn filter_garbage<R: std::io::Read>(reader: BufReader<R>) -> Vec<String> {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a <K, V> pair to a [`Settings`] map.
|
|
||||||
///
|
/// Inserts user settings into setting map
|
||||||
/// Returns the updated [`Settings`].
|
|
||||||
fn update_settings_map(mut settings_map: Settings, key: &str, setting: &str) -> Settings {
|
fn update_settings_map(mut settings_map: Settings, key: &str, setting: &str) -> Settings {
|
||||||
let key = MachineSettingKey::from(key);
|
let key = MachineSettingKey::from(key);
|
||||||
let setting = str::parse::<u64>(setting).unwrap_or(0);
|
let setting = setting.parse::<u64>().unwrap_or(0);
|
||||||
settings_map.insert(key, setting);
|
settings_map.insert(key, setting);
|
||||||
settings_map
|
settings_map
|
||||||
}
|
}
|
@ -9,7 +9,7 @@ use std::ptr;
|
|||||||
/// These methods wrap unsafe instructions because it doesn't respect borrow rules per example
|
/// These methods wrap unsafe instructions because it doesn't respect borrow rules per example
|
||||||
/// but everything has been tested with miri to assure there's no Undefined Behaviour (use-after-free, double free, etc.)
|
/// but everything has been tested with miri to assure there's no Undefined Behaviour (use-after-free, double free, etc.)
|
||||||
/// or memory leak
|
/// or memory leak
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
#[derive(PartialEq, Clone, Debug)]
|
||||||
pub struct List<T: PartialEq> {
|
pub struct List<T: PartialEq> {
|
||||||
head: Link<T>,
|
head: Link<T>,
|
||||||
tail: Link<T>,
|
tail: Link<T>,
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
//! This module contains data type definitions used in other parts the BurritOS
|
|
||||||
//! They are separated from the rest of the operating system so as to promote
|
|
||||||
//! reusability and to separate data constructs proper from state and actions.
|
|
||||||
pub mod list;
|
pub mod list;
|
||||||
pub mod objaddr;
|
pub mod objaddr;
|
||||||
pub mod cfg;
|
pub mod cfg;
|
@ -17,13 +17,9 @@ use crate::kernel::{synch::{ Semaphore, Lock }, thread::Thread};
|
|||||||
/// calls.
|
/// calls.
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub struct ObjAddr {
|
pub struct ObjAddr {
|
||||||
/// Id of the last added object
|
|
||||||
last_id: i32,
|
last_id: i32,
|
||||||
/// List of [Semaphore] added in this struct. Each is keyed with a unique i32 id.
|
|
||||||
semaphores: HashMap<i32, Semaphore>,
|
semaphores: HashMap<i32, Semaphore>,
|
||||||
/// List of [Lock] added in this struct. Each is keyed with a unique i32 id.
|
|
||||||
locks: HashMap<i32, Lock>,
|
locks: HashMap<i32, Lock>,
|
||||||
/// List of threads known by this instance of ObjAddr (useful for managing lock ownership)
|
|
||||||
threads: HashMap<i32, Rc<RefCell<Thread>>>,
|
threads: HashMap<i32, Rc<RefCell<Thread>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
int main() {
|
int main() {
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = 1;
|
int y = 1;
|
||||||
while (x <= y) {
|
|
||||||
if (x > y) {
|
if (x > y) {
|
||||||
x += 1;
|
x += 1;
|
||||||
} else if (x == y) {
|
}
|
||||||
|
if (x == y) {
|
||||||
x += y;
|
x += y;
|
||||||
} else if (x < y) {
|
}
|
||||||
|
if (x < y) {
|
||||||
y += 1;
|
y += 1;
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
PROGRAMS = halt.guac prints.guac producteur_consommateur.guac join.guac
|
PROGRAMS = halt.guac prints.guac producteur_consommateur.guac lecteur_redacteur.guac join.guac matmult.guac
|
||||||
TOPDIR = ../..
|
TOPDIR = ../..
|
||||||
include $(TOPDIR)/Makefile.rules
|
include $(TOPDIR)/Makefile.rules
|
||||||
|
|
||||||
|
60
test/syscall_tests/lecteur_redacteur.c
Normal file
60
test/syscall_tests/lecteur_redacteur.c
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#include "userlib/syscall.h"
|
||||||
|
#include "userlib/libnachos.h"
|
||||||
|
|
||||||
|
SemId red;
|
||||||
|
SemId mutex;
|
||||||
|
SemId util;
|
||||||
|
int nblect = 0;
|
||||||
|
int nbWrite = 0;
|
||||||
|
|
||||||
|
void lecteur() {
|
||||||
|
while(1) {
|
||||||
|
P(red);
|
||||||
|
P(mutex);
|
||||||
|
if (nblect == 0) {
|
||||||
|
V(util);
|
||||||
|
}
|
||||||
|
nblect++;
|
||||||
|
V(mutex);
|
||||||
|
V(red);
|
||||||
|
n_printf("Lecture de l'information \n");
|
||||||
|
if(nbWrite == 10)
|
||||||
|
return;
|
||||||
|
P(mutex);
|
||||||
|
nblect--;
|
||||||
|
if(nblect == 0) {
|
||||||
|
V(util);
|
||||||
|
}
|
||||||
|
V(mutex);
|
||||||
|
}
|
||||||
|
Exit(nblect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void redacteur() {
|
||||||
|
while(1) {
|
||||||
|
P(red);
|
||||||
|
P(util);
|
||||||
|
V(red);
|
||||||
|
n_printf((char*)"Ecriture de l'information\n");
|
||||||
|
nbWrite++;
|
||||||
|
if(nbWrite == 10)
|
||||||
|
return;
|
||||||
|
V(util);
|
||||||
|
}
|
||||||
|
Exit(nbWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
red = SemCreate((char*)"redacteur", 1);
|
||||||
|
mutex = SemCreate((char*)"mutex lecteur redacteur", 1);
|
||||||
|
util = SemCreate((char*)"Mutex util lecteur redacteur", 1);
|
||||||
|
ThreadId lecteurTh = threadCreate((char*)"Lecteur", (VoidNoArgFunctionPtr) lecteur);
|
||||||
|
ThreadId lecteur1 = threadCreate((char*)"Lecteur", (VoidNoArgFunctionPtr) lecteur);
|
||||||
|
ThreadId lecteur2 = threadCreate((char*)"Lecteur", (VoidNoArgFunctionPtr) lecteur);
|
||||||
|
ThreadId redacteurTh = threadCreate((char*)"redacteur", (VoidNoArgFunctionPtr) redacteur);
|
||||||
|
Join(lecteurTh);
|
||||||
|
Join(lecteur1);
|
||||||
|
Join(lecteur2);
|
||||||
|
Join(redacteurTh);
|
||||||
|
return 0;
|
||||||
|
}
|
60
test/syscall_tests/matmult.c
Normal file
60
test/syscall_tests/matmult.c
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/* matmult.c
|
||||||
|
* Test program to do matrix multiplication on large arrays.
|
||||||
|
*
|
||||||
|
* Intended to stress virtual memory system.
|
||||||
|
*
|
||||||
|
* Ideally, we could read the matrices off of the file system,
|
||||||
|
* and store the result back to the file system!
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------
|
||||||
|
* This file is part of the Nachos-RiscV distribution
|
||||||
|
* Copyright (c) 2022 University of Rennes 1.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details
|
||||||
|
* (see see <http://www.gnu.org/licenses/>).
|
||||||
|
* -----------------------------------------------------
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "userlib/syscall.h"
|
||||||
|
|
||||||
|
#define Dim 10 /* sum total of the arrays doesn't fit in
|
||||||
|
* physical memory
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The matrices to be filled-in and multiplied */
|
||||||
|
int A[Dim][Dim];
|
||||||
|
int B[Dim][Dim];
|
||||||
|
int C[Dim][Dim];
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
int i, j, k;
|
||||||
|
|
||||||
|
Write("Start matmult\n",14,CONSOLE_OUTPUT);
|
||||||
|
|
||||||
|
for (i = 0; i < Dim; i++) /* first initialize the matrices */
|
||||||
|
for (j = 0; j < Dim; j++) {
|
||||||
|
A[i][j] = i;
|
||||||
|
B[i][j] = j;
|
||||||
|
C[i][j] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < Dim; i++) /* then multiply them together */
|
||||||
|
for (j = 0; j < Dim; j++)
|
||||||
|
for (k = 0; k < Dim; k++)
|
||||||
|
C[i][j] += A[i][k] * B[k][j];
|
||||||
|
|
||||||
|
|
||||||
|
Exit(C[Dim-1][Dim-1]); /* and then we're done */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -2,9 +2,53 @@
|
|||||||
#include "userlib/libnachos.h"
|
#include "userlib/libnachos.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
n_printf("Hello World 1");
|
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
|
||||||
n_printf("Hello World 2");
|
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&##BBGGGPPGGGBB##&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
|
||||||
n_printf("Hello World 3");
|
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&#G5J?!~^::............::^~!?J5G#&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
|
||||||
n_printf("Hello World 4");
|
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@&B5?!^:....:^^~!!7777??7777!!~~^::...:^!JPB&@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@B57^....^~!?JJYYY5555555555555555Y5PGP57~::..:^75B@@@@@@@@@@@@@@@@@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@@@@@@@@@@@@@&G?~. .:~7?JY55555YYYYYYYYYYYYYYYYY5PB##BPY???7!~^:..:~JG&@@@@@@@@@@@@@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@@@@@@@@@@@BJ~. .^!?Y5555YYYYYYYYYYYYYYYYYYYY5PB##B5J?77???????7!~^:.:~JB@@@@@@@@@@@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@@@@@@@@&P!. .^!JY55YYYYYYYYYYYYYYYYYYYYYY5PB##B5J?77??????????????7~^:.:!P&@@@@@@@@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@@@@@@&Y^..:~?Y55YYYYYYYYYYYYYYYYYYYYYY5PB##B5J?77????????????????????7~:.:~5&@@@@@@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@@@@&5^..:!J55YYYYYYYYYYYYYYYYYYYYYY5PB##B5J?77?????????????????????????7~^::~5@@@@@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@@@G~..:!Y55YYYYYYYYYYYYYYYYYYYYY5PB##B5J?77??????????????????????????????7~:::!B@@@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@&J...~J55YYYYYYYYYYYYYYYYYYYY5PB##B5J?77??????????????????????????????777?Y57:::J&@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@#!..:7Y5YYYYYYYYYYYYYYYYYYY5PB##B5J?77??????????????????????????????777?YPB##G?^::7#@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@G^..^J5YYYYYYYYYYYYYYYYYY5PB##B5J?77??????????????????????????????777?YPB##GP5Y5J~::~B@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@G^..^Y5YYYYYYYYYYYYYYYY5PB##B5J?77??????????????????????????????777?YPB##GP55Y5555Y~::^B@@@@@@\n");
|
||||||
|
n_printf("@@@@@B^..^Y5YYYYYYYYYYYYYY5PB##B5J?77??????????????????????????????777?YPB##GP5YYYY555555Y~::~B@@@@@\n");
|
||||||
|
n_printf("@@@@&!..^J5YYYYYYYYYYYY5PB##B5J?77??????????????????????????????777?YPB#BGPYYYYYY555555555Y~::7&@@@@\n");
|
||||||
|
n_printf("@@@@J..:?5YYYYYYYYYY5PB##B5J?77??????????????????????????????777?YPB#BG5YYYYYYY55YY55555555J^::Y@@@@\n");
|
||||||
|
n_printf("@@@B:..~5YYYYYYYY5PB##G5J?77??????????????????????????????777?YPB#BG5YYYYYYYY5YYY55555555555!::^#@@@\n");
|
||||||
|
n_printf("@@@?..:JYYYYYY5PB##G5J?77??????????????????????????????777?YPB#BG5YYYYYYYYYYYYY55YY555555555Y^::J@@@\n");
|
||||||
|
n_printf("@@&^..~YYYY5PB##G5J?77??????????????????????????????777?YPB#BG5YYYYYYYYYYYYYYYYYY5555Y5555555!::~&@@\n");
|
||||||
|
n_printf("@@G:..7Y5PB##G5J?77??????????????????????????????777?YPB#BG5YJYYYYYYYYYYYYYYYYY55YYY555555555?::^B@@\n");
|
||||||
|
n_printf("@@5:..YB##G5J?77??????????????????????????????777?YPB#BG5JJJYYYJYYYYYYYYYYYYYY5YY5555Y5555555J:^^P@@\n");
|
||||||
|
n_printf("@@5:..PB5J?77??????????????????????????????777?YGB#BG5JJJYYJYYYYYYYYYYYYYYYYYYY55Y55555555555J:^^5@@\n");
|
||||||
|
n_printf("@@5:..7?77??????????????????????????????777?YPB#BG5JJJJJJJJYYYYYYYYYYYYYYYYYYY5YY5Y5555555555J:^^P@@\n");
|
||||||
|
n_printf("@@G:..~??????????????????????????????777?YGB#BPYJJJJJJJJJJJYYYYYYYYYYYYYYYYYYYY5YY55555555555?:^^B@@\n");
|
||||||
|
n_printf("@@&^..^???????????????????????????777?YGB#BPYJ?JJJJJJJJJJJYYJYYYYYYYYYYYYYYYYY5YY5Y5555555555!^:~@@@\n");
|
||||||
|
n_printf("@@@?.::7???????????????????????777?YGB#BPYJ???JJJJJJJJJJJJJYYYYYYYYYYYYYYYYYYYYYYY5555555555Y^^:J@@@\n");
|
||||||
|
n_printf("@@@#:..^????????????????????777?YG##BPYJ????JJJJJJJJJJJJJJYJJYYYYYYYYYYYYYYYYY5YYYY555555555!^^^#@@@\n");
|
||||||
|
n_printf("@@@@J.::!????????????????777?YG##BPY???????JJJJJJJJJJJJJJJJYYYYYYYYYYYYYYYYYY5YYY5555555555J^^:Y@@@@\n");
|
||||||
|
n_printf("@@@@&!..:7????????????777?YGB#BPJ????????????JJJJJJJJJJJJYYJJYYYYYYYYYYYYYYYYYY55YY5555555Y~::7&@@@@\n");
|
||||||
|
n_printf("@@@@@B^.:^7????????777?YGB#BPJ?7???????????JJJ?JJJJJJJJJJJJYYYYJYYYYYYYYYYYYYYYYY5555Y555Y~^:~B@@@@@\n");
|
||||||
|
n_printf("@@@@@@G^.:^7????777?YGB#BPJ?7????????????????JJJJJJJJJJJJYYJJYYYYYYYYYYYYYYYYYY55YYY5555Y~::~B@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@B^.:^7?77?YGB#BPJ?77??7?????????????JJJ?JJJJJJJJJJJJYYYYJYYYYYYYYYYYYYYYYY5555Y5J~::~B@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@#!..:!YG##BPJ?77?????????????????????JJJJJJJJJJJJYYJYYYYYYYYYYYYYYYYYYY55YYY55?^::7#@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@&J:.:7PPY?77???7????7??????????????JJ?JJJJJJJJJJJJYYYYJYYYYYYYYYYYYYY5YY555J!^:^Y&@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@@@G!..:~7?????????????????????????JJJJJJJJJJJJJJYYJYYYYYYYYYYYYYYYYYYY555Y7^::7G@@@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@@@@@5~..:~7????????????????????????JJJJJJJJJJJJJJJYJYYYYYYYYYYYYYYYYY5YY7^::~5@@@@@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@@@@@@&Y~..:~7?????????????????????JJJJJJJJJJJJJJJJYYYYYYYYYYYYYYYYY5YJ!^::!5&@@@@@@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@@@@@@@@&P!:.:^~7???????????????????JJJJJJJJJJJJJJJJJYYYYYYYYYYYYYYJ7~::^7P&@@@@@@@@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@@@@@@@@@@@BJ~:.:^~77??????????????JJ?JJJJJJJJJJJJJYYYYYYYYYYYYYJ7~^::!YB@@@@@@@@@@@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@@@@@@@@@@@@@&GJ~:.::~!!7????????????JJJJJJJJJJJJJYJJYYYYYYJ?7!^::^!JG&@@@@@@@@@@@@@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@B5?~::::^~~!7????JJJJJJJJJJJJYYJJJJJJ?77!~^::^~?5B@@@@@@@@@@@@@@@@@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@&BPJ7~^:::::^~~~!!77777777!!!~~^^::::^~7JPB&@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&#G5Y?7!~^^::::::::::::^~~!7JYPG#&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&##BGGGGGGGBB##&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
|
||||||
|
n_printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
|
||||||
|
Shutdown();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -9,9 +9,32 @@ int tab[3];
|
|||||||
SemId svide;
|
SemId svide;
|
||||||
SemId splein;
|
SemId splein;
|
||||||
|
|
||||||
void producteur();
|
void producteur() {
|
||||||
|
for(int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
n_printf("batir une information\n");
|
||||||
|
P(svide);
|
||||||
|
iplein = (iplein + 1) % N;
|
||||||
|
// n_printf("communique une information : %d\n", i);
|
||||||
|
tab[iplein] = i;
|
||||||
|
V(splein);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void consommateur();
|
void consommateur() {
|
||||||
|
int sum = 0;
|
||||||
|
for(int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
P(splein);
|
||||||
|
ivide = (ivide +1) % N;
|
||||||
|
n_printf("recevoir une information\n");
|
||||||
|
int info = tab[ivide];
|
||||||
|
V(svide);
|
||||||
|
sum += info;
|
||||||
|
// n_printf("exploiter l'information : %d\n", info);
|
||||||
|
}
|
||||||
|
Exit(sum);
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
svide = SemCreate("producteur", N);
|
svide = SemCreate("producteur", N);
|
||||||
@ -20,29 +43,6 @@ int main() {
|
|||||||
ThreadId consommateurTh = threadCreate("consommateur", consommateur);
|
ThreadId consommateurTh = threadCreate("consommateur", consommateur);
|
||||||
Join(producteurTh);
|
Join(producteurTh);
|
||||||
Join(consommateurTh);
|
Join(consommateurTh);
|
||||||
|
Shutdown();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void producteur() {
|
|
||||||
for(int i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
n_printf("batir une information\n");
|
|
||||||
P(svide);
|
|
||||||
iplein = (iplein + 1) % N;
|
|
||||||
n_printf("communique une information : %d\n", i);
|
|
||||||
tab[iplein] = i;
|
|
||||||
V(splein);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void consommateur() {
|
|
||||||
for(int i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
P(splein);
|
|
||||||
ivide = (ivide +1) % N;
|
|
||||||
n_printf("recevoir une information\n");
|
|
||||||
int info = tab[ivide];
|
|
||||||
V(svide);
|
|
||||||
n_printf("exploiter l'information : %d\n", info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user