Merge branch 'thread_scheduler' into bin-loader

This commit is contained in:
Quentin Legot 2023-03-28 21:08:00 +02:00
commit 7dff3bcdd9
6 changed files with 580 additions and 640 deletions

View File

@ -18,5 +18,6 @@ use simulator::machine::Machine;
fn main() { fn main() {
let mut machine = Machine::init_machine(); let mut machine = Machine::init_machine();
let system = &mut System::default(); let system = System::default();
machine.run()
} }

55
src/simulator/error.rs Normal file
View File

@ -0,0 +1,55 @@
//! # Error
//!
//! This module contains the definition of the MachineError struct,
//! for error management in the Machine module.
//!
//! Basic usage:
//!
//! ```
//! fn example(x: bool) -> Result<(), MachineError> {
//! match x {
//! true => Ok(()),
//! _ => Err(MachineError::new("Machine failed because of ..."));
//! }
//! }
//! ```
use std::fmt;
/// Machine Error
/// This error serves as a specific exception handler for the Machine struct
#[derive(Debug, Clone)]
pub struct MachineError {
/// The error message
message: String
}
/// This impl allows this MachineError to be formatted into an empty format.
///
/// ```
/// // Result of printing a MachineError
/// let m = MachineError::new("Lorem Ipsum");
/// println!("Example: {}", m);
/// ```
///
/// Console output:Error}
/// ```
/// example Lorem Ipsum
/// ```
impl fmt::Display for MachineError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Machine error: {}", &self.message)
}
}
impl From<&str> for MachineError {
fn from(value: &str) -> Self {
MachineError { message: value.to_string() }
}
}
impl From<String> for MachineError {
fn from(value: String) -> Self {
MachineError { message: value }
}
}

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@ impl <'a>MMU <'_>{
MMU::translate(mmu, virt_addr, &mut phy_addr_double_check, false); MMU::translate(mmu, virt_addr, &mut phy_addr_double_check, false);
match exc { match exc {
ExceptionType::NO_EXCEPTION => { ExceptionType::NoException => {
if phy_addr != phy_addr_double_check { if phy_addr != phy_addr_double_check {
//Besoin ici d'une impl pour gestion d'exeption //Besoin ici d'une impl pour gestion d'exeption
//dans nachos : g-machine->RaiseException(exc, virt_addr); //dans nachos : g-machine->RaiseException(exc, virt_addr);
@ -44,7 +44,7 @@ impl <'a>MMU <'_>{
_ => { _ => {
//Besoin ici d'une impl pour gestion d'exeption //Besoin ici d'une impl pour gestion d'exeption
//dans nachos : g-machine->RaiseException(exc, virt_addr); //dans nachos : g-machine->RaiseException(exc, virt_addr);
println!("Error from mmu_read_mem :: Exception different from NO_EXCEPTION"); println!("Error from mmu_read_mem :: Exception different from NoException");
return false; return false;
} }
} }
@ -63,7 +63,7 @@ impl <'a>MMU <'_>{
MMU::translate(mmu, virt_addr, &mut phy_addr_double_check, true); MMU::translate(mmu, virt_addr, &mut phy_addr_double_check, true);
match exc { match exc {
ExceptionType::NO_EXCEPTION => { ExceptionType::NoException => {
if phy_addr != phy_addr_double_check { if phy_addr != phy_addr_double_check {
//Besoin ici d'une impl pour gestion d'exeption //Besoin ici d'une impl pour gestion d'exeption
//dans nachos : g-machine->RaiseException(exc, virt_addr); //dans nachos : g-machine->RaiseException(exc, virt_addr);
@ -78,7 +78,7 @@ impl <'a>MMU <'_>{
_ => { _ => {
//Besoin ici d'une impl pour gestion d'exeption //Besoin ici d'une impl pour gestion d'exeption
//dans nachos : g-machine->RaiseException(exc, virt_addr); //dans nachos : g-machine->RaiseException(exc, virt_addr);
println!("Error from mmu_write_mem :: Exception different from NO_EXCEPTION"); println!("Error from mmu_write_mem :: Exception different from NoException");
return false; return false;
} }
} }
@ -96,7 +96,7 @@ impl <'a>MMU <'_>{
match &mut mmu.translationTable { match &mut mmu.translationTable {
None => { None => {
println!("Error from translate : MMU refers to None (No page Table)"); println!("Error from translate : MMU refers to None (No page Table)");
return ExceptionType::ADDRESSERROR_EXCEPTION; return ExceptionType::AddressErrorException;
} }
Some(table_ref) => { Some(table_ref) => {
@ -104,7 +104,7 @@ impl <'a>MMU <'_>{
//On verifie que notre index est valide //On verifie que notre index est valide
if vpn >= table_ref.get_max_num_pages(){ if vpn >= table_ref.get_max_num_pages(){
println!("Error from translate :: index is out of bound"); println!("Error from translate :: index is out of bound");
return ExceptionType::ADDRESSERROR_EXCEPTION; return ExceptionType::AddressErrorException;
} }
/*Doc nachos dit que ce test sert a savoir si la page est mappée /*Doc nachos dit que ce test sert a savoir si la page est mappée
@ -113,13 +113,13 @@ impl <'a>MMU <'_>{
*/ */
if !table_ref.get_bit_read(vpn) && !table_ref.get_bit_write(vpn) { if !table_ref.get_bit_read(vpn) && !table_ref.get_bit_write(vpn) {
println!("Error from translate :: virtual page # {} not mapped",vpn); println!("Error from translate :: virtual page # {} not mapped",vpn);
return ExceptionType::ADDRESSERROR_EXCEPTION; return ExceptionType::AddressErrorException;
} }
//si on souhaite effectuer un acces lecture, on verifie que l'on dispose du droit d'acces sur cette page //si on souhaite effectuer un acces lecture, on verifie que l'on dispose du droit d'acces sur cette page
if writing && !table_ref.get_bit_write(vpn) { if writing && !table_ref.get_bit_write(vpn) {
println!("Error from translate :: write access on a read only virtual page # {}",vpn); println!("Error from translate :: write access on a read only virtual page # {}",vpn);
return ExceptionType::READONLY_EXCEPTION; return ExceptionType::AddressErrorException;
} }
//if the page is not yet in main memory, run the page fault manager //if the page is not yet in main memory, run the page fault manager
@ -129,13 +129,13 @@ impl <'a>MMU <'_>{
println!("We need to update the page table by raising an exception -> not implemented"); println!("We need to update the page table by raising an exception -> not implemented");
//Ici il faudra reverifier le bit valid apres intervention du page fault manager //Ici il faudra reverifier le bit valid apres intervention du page fault manager
return ExceptionType::ADDRESSERROR_EXCEPTION; return ExceptionType::AddressErrorException;
} }
//Make sure that the physical adress is correct //Make sure that the physical adress is correct
if table_ref.get_physical_page(vpn) < 0 || table_ref.get_physical_page(vpn) >= (NUM_PHY_PAGE as i32) { if table_ref.get_physical_page(vpn) < 0 || table_ref.get_physical_page(vpn) >= (NUM_PHY_PAGE as i32) {
println!("Error from translate :: no valid correspondance"); println!("Error from translate :: no valid correspondance");
return ExceptionType::BUSERROR_EXCEPTION; return ExceptionType::BusErrorException;
} }
//Set U/M bits to 1 //Set U/M bits to 1
@ -151,6 +151,6 @@ impl <'a>MMU <'_>{
} }
} }
ExceptionType::NO_EXCEPTION ExceptionType::NoException
} }
} }

View File

@ -1,4 +1,5 @@
pub mod machine; pub mod machine;
pub mod error;
pub mod decode; pub mod decode;
pub mod print; pub mod print;
pub mod mem_cmp; pub mod mem_cmp;
@ -6,7 +7,9 @@ pub mod loader;
pub mod interrupt; pub mod interrupt;
pub mod translationtable; pub mod translationtable;
pub mod mmu; pub mod mmu;
pub mod register;
/// Definition of global constants
pub mod global { pub mod global {
#![allow(dead_code)] #![allow(dead_code)]
@ -52,15 +55,15 @@ pub mod global {
/// ///
/// See func3 to know the type of instruction (LD, LW, LH, LB, LWU, LHU, LBU) /// See func3 to know the type of instruction (LD, LW, LH, LB, LWU, LHU, LBU)
pub const RISCV_LD: u8 = 0x3; pub const RISCV_LD: u8 = 0x3;
// Store instructions /// Store instructions
pub const RISCV_ST: u8 = 0x23; pub const RISCV_ST: u8 = 0x23;
// immediate Arithmetic operations /// immediate Arithmetic operations
pub const RISCV_OPI: u8 = 0x13; pub const RISCV_OPI: u8 = 0x13;
// Arithmetic operations /// Arithmetic operations
pub const RISCV_OP: u8 = 0x33; pub const RISCV_OP: u8 = 0x33;
/// Immediate arithmetic operations for rv64i /// Immediate arithmetic operations for rv64i
pub const RISCV_OPIW: u8 = 0x1b; pub const RISCV_OPIW: u8 = 0x1b;
// Arithmetic operations for rv64i /// Arithmetic operations for rv64i
pub const RISCV_OPW: u8 = 0x3b; pub const RISCV_OPW: u8 = 0x3b;
/// Type: B /// Type: B

53
src/simulator/register.rs Normal file
View File

@ -0,0 +1,53 @@
//! # Register
//!
//! This mod contains the definition of the Register structs
//! for use within the Machine module.
use crate::simulator::machine::{NUM_FP_REGS, NUM_INT_REGS};
use std::ops::{Add, Sub};
pub trait RegisterNum: Add<Output=Self> + Sub<Output=Self> + PartialEq + Copy {}
impl RegisterNum for i64 {}
impl RegisterNum for f32 {}
/// Machine register array
#[derive(PartialEq)]
pub struct Register<U: RegisterNum> {
/// 32 available registers of type U
register: [U; 32]
}
impl<U: RegisterNum> Register<U> {
/// Returns the current value held in register *position*
pub fn get_reg(&self, position: u8) -> U {
self.register[position as usize]
}
/// Set value of register *position* to *value*
///
/// Checking against trying to set a new value to the 0th register
/// as its value is NOT supposed to change
pub fn set_reg(&mut self, position: u8, value: U) {
if position != 0 { self.register[position as usize] = value; }
}
}
impl Register<i64> {
/// i64 register constructor
pub fn init() -> Register<i64> {
Register {
register: [0i64; NUM_INT_REGS]
}
}
}
impl Register<f32> {
/// f32 register constructor
pub fn init() -> Register<f32> {
Register {
register: [0f32; NUM_FP_REGS]
}
}
}