Merge branch 'machine_refactor' into 'thread_scheduler'
♻️ Machine.rs refactoring See merge request simpleos/burritos!11
This commit is contained in:
commit
2e41758a52
@ -17,6 +17,7 @@ use kernel::system::System;
|
|||||||
use simulator::machine::Machine;
|
use simulator::machine::Machine;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let machine = Machine::init_machine();
|
let mut machine = Machine::init_machine();
|
||||||
let system = System::default();
|
let system = System::default();
|
||||||
|
machine.run()
|
||||||
}
|
}
|
||||||
|
55
src/simulator/error.rs
Normal file
55
src/simulator/error.rs
Normal 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
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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
53
src/simulator/register.rs
Normal 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]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user