Compare commits
1 Commits
documentat
...
clippy_fix
Author | SHA1 | Date | |
---|---|---|---|
9b87a0cd83 |
@ -1,14 +1,9 @@
|
|||||||
//! # Exceprions
|
|
||||||
//!
|
|
||||||
//! This module Enum the constant values of the exceptions.
|
|
||||||
//! They are used to stop the system to execute some opperation
|
|
||||||
|
|
||||||
use std::{cell::RefCell, rc::Rc};
|
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, self}, 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;
|
||||||
@ -244,7 +239,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(format!("Initial_count < 0"))?,
|
true => Err("Initial_count < 0".to_string())?,
|
||||||
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);
|
||||||
@ -283,12 +278,12 @@ 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);
|
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);
|
||||||
// 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 {
|
||||||
return Err("Process owner of current thread is none")?;
|
Err("Process owner of current thread is none")?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,8 +350,8 @@ mod test {
|
|||||||
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);
|
||||||
|
|
||||||
machine.write_memory(4, 0, 0b000000000000_00000_000_00000_1110011); // ecall
|
machine.write_memory(4, 0, 0b0000_0000_0000_0000_0000_0000_0111_0011); // ecall
|
||||||
machine.write_memory(4, 4, 0b000000001010_00000_000_00001_0010011); // r1 <- 10
|
machine.write_memory(4, 4, 0b0000_0000_1010_0000_0000_0000_1001_0011); // 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
|
||||||
@ -382,11 +377,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, 0b000000000000_00000_000_00000_1110011); // ecall
|
machine.write_memory(4, 0, 0b0000_0000_0000_0000_0000_0000_0111_0011); // 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, 0b000000000000_00000_000_10001_0010011); // r17 <- SC_SHUTDOWN
|
machine.write_memory(4, 4, 0b0000_0000_0000_0000_0000_1000_1001_0011); // r17 <- SC_SHUTDOWN
|
||||||
machine.write_memory(4, 8, 0b000000000000_00000_000_00000_1110011); // ecall
|
machine.write_memory(4, 8, 0b0000_0000_0000_0000_0000_0000_0111_0011); // ecall
|
||||||
|
|
||||||
let mut system = System::new(true);
|
let mut system = System::new(true);
|
||||||
machine.run(&mut system);
|
machine.run(&mut system);
|
||||||
|
@ -1,11 +1,3 @@
|
|||||||
//! # Error Code
|
|
||||||
//!
|
|
||||||
//! This module enumerate the possibles error code who could get in a function
|
|
||||||
//!
|
|
||||||
//! **Basic Usage:*
|
|
||||||
//!
|
|
||||||
//! Result<YourSuccessStruct, **ErrorCode**
|
|
||||||
|
|
||||||
#![allow(unused, clippy::missing_docs_in_private_items)]
|
#![allow(unused, clippy::missing_docs_in_private_items)]
|
||||||
/// Error enum, use it with Result<YourSucessStruct, **ErrorCode**>
|
/// Error enum, use it with Result<YourSucessStruct, **ErrorCode**>
|
||||||
pub enum ErrorCode {
|
pub enum ErrorCode {
|
||||||
|
@ -1,9 +1,3 @@
|
|||||||
//! # Kernel
|
|
||||||
//!
|
|
||||||
//! This module contains all the tool required for the kernel to work.
|
|
||||||
//!
|
|
||||||
//! Currently it contains the scheduling and synchroisation tools, but it will contains the tools
|
|
||||||
//! required Memory gestion, Files gestion and peripheral pilots.
|
|
||||||
pub mod process;
|
pub mod process;
|
||||||
pub mod thread;
|
pub mod thread;
|
||||||
pub mod mgerror;
|
pub mod mgerror;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
pub struct Process {
|
pub struct Process {
|
||||||
pub num_thread: usize,
|
pub num_thread: usize,
|
||||||
}
|
}
|
@ -1,11 +1,3 @@
|
|||||||
//! # Synchronisation
|
|
||||||
//!
|
|
||||||
//! This module contains some scheduling and synchronisation utilities:
|
|
||||||
//! - **Semaphore**
|
|
||||||
//! - **Lock**
|
|
||||||
//!
|
|
||||||
//! Conditions aren't implemented currently
|
|
||||||
|
|
||||||
use crate::utility::list::List;
|
use crate::utility::list::List;
|
||||||
use crate::kernel::thread::Thread;
|
use crate::kernel::thread::Thread;
|
||||||
use crate::simulator::interrupt::InterruptStatus::InterruptOff;
|
use crate::simulator::interrupt::InterruptStatus::InterruptOff;
|
||||||
@ -14,21 +6,20 @@ use std::cell::RefCell;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use super::thread_manager::ThreadManager;
|
use super::thread_manager::ThreadManager;
|
||||||
|
|
||||||
/// Structure of a Semaphore used for synchronisation.
|
/// Structure of a Semaphore used for synchronisation
|
||||||
/// It use a counter to determine the number of thread that can be executed simultaneously.
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub struct Semaphore {
|
pub struct Semaphore {
|
||||||
|
|
||||||
/// Counter of simultaneous Semaphore
|
/// Counter of simultanous Semaphore
|
||||||
pub counter:i32,
|
pub counter:i32,
|
||||||
/// QUeue of Semaphore waiting to be executed
|
/// QUeue of Semaphore waiting to be exucated
|
||||||
pub waiting_queue:List<Rc<RefCell<Thread>>>,
|
pub waiting_queue:List<Rc<RefCell<Thread>>>,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Semaphore {
|
impl Semaphore {
|
||||||
|
|
||||||
/// Initializes a semaphore, so that it can be used for synchronization.
|
/// Initializes a semaphore, so that it can be used for synchronization.
|
||||||
///
|
///
|
||||||
/// ### Parameters
|
/// ### Parameters
|
||||||
/// - *counter* initial value of counter
|
/// - *counter* initial value of counter
|
||||||
@ -58,7 +49,7 @@ pub struct Lock {
|
|||||||
impl Lock {
|
impl Lock {
|
||||||
|
|
||||||
/// Initialize a Lock, so that it can be used for synchronization.
|
/// Initialize a Lock, so that it can be used for synchronization.
|
||||||
/// The lock is initially free
|
/// The lock is initialy free
|
||||||
///
|
///
|
||||||
/// ### Parameters
|
/// ### Parameters
|
||||||
/// - **thread_manager** Thread manager which managing threads
|
/// - **thread_manager** Thread manager which managing threads
|
||||||
@ -81,16 +72,16 @@ impl Lock {
|
|||||||
let old_status = machine.interrupt.set_status(InterruptOff);
|
let old_status = machine.interrupt.set_status(InterruptOff);
|
||||||
if self.free {
|
if self.free {
|
||||||
self.free = false;
|
self.free = false;
|
||||||
self.owner = 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));
|
||||||
},
|
},
|
||||||
@ -120,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 => ()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -137,14 +128,8 @@ impl Lock {
|
|||||||
machine.interrupt.set_status(old_status);
|
machine.interrupt.set_status(old_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Say if the lock is held by the current thread
|
/// True if the current thread holds this lock.
|
||||||
/// Useful for checking in Release, and in Condition operations below.
|
/// Useful for checking in Release, and in Condition operations below.
|
||||||
/// ### Parameters
|
|
||||||
/// - **self** The current lock
|
|
||||||
/// - **thread-manager** The thread manager present in the system
|
|
||||||
/// ### Return
|
|
||||||
/// True if the current thread holds this lock.
|
|
||||||
|
|
||||||
pub fn held_by_current_thread(&mut self, thread_manager: &mut ThreadManager) -> bool {
|
pub fn held_by_current_thread(&mut self, thread_manager: &mut ThreadManager) -> bool {
|
||||||
match &self.owner {
|
match &self.owner {
|
||||||
Some(x) =>
|
Some(x) =>
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
//! # Thread
|
|
||||||
//!
|
|
||||||
//!
|
|
||||||
use std::{rc::Rc, cell::RefCell};
|
use std::{rc::Rc, cell::RefCell};
|
||||||
|
|
||||||
use super::{process::Process, thread_manager::ThreadRef};
|
use super::{process::Process, thread_manager::ThreadRef};
|
||||||
|
@ -252,7 +252,7 @@ impl ThreadManager {
|
|||||||
self.debug(format!("Finishing thread {}", thread.borrow().get_name()));
|
self.debug(format!("Finishing thread {}", thread.borrow().get_name()));
|
||||||
// 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);
|
||||||
@ -512,7 +512,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.clone()));
|
assert_eq!(lock.owner,Some(thread_1));
|
||||||
assert!(!lock.free);
|
assert!(!lock.free);
|
||||||
assert_eq!(lock.waiting_queue.iter().count(),1);
|
assert_eq!(lock.waiting_queue.iter().count(),1);
|
||||||
}
|
}
|
||||||
@ -525,7 +525,7 @@ mod test {
|
|||||||
assert!(lock.waiting_queue.is_empty());
|
assert!(lock.waiting_queue.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_manager.set_g_current_thread(Some(thread_2.clone()));
|
thread_manager.set_g_current_thread(Some(thread_2));
|
||||||
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();
|
||||||
|
@ -1,38 +1,17 @@
|
|||||||
//! # Interrupt
|
|
||||||
//!
|
|
||||||
//! This module contains an interrupt Handler.
|
|
||||||
//! The methodes one_trick and idle aren't implemented for now
|
|
||||||
|
|
||||||
/// # Interrupt
|
#[derive(PartialEq, Eq)]
|
||||||
///
|
|
||||||
/// Interrupt Handler
|
|
||||||
#[derive(PartialEq)]
|
|
||||||
pub struct Interrupt {
|
pub struct Interrupt {
|
||||||
/// Current Status
|
|
||||||
level: InterruptStatus
|
level: InterruptStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interrupt {
|
impl Interrupt {
|
||||||
|
|
||||||
/// Interrupt constructor
|
|
||||||
///
|
|
||||||
/// ### Return
|
|
||||||
/// Interrupt with status Off
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
level: InterruptStatus::InterruptOff
|
level: InterruptStatus::InterruptOff
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Interrupt setter
|
|
||||||
/// Change the value of the Interrupt
|
|
||||||
///
|
|
||||||
/// ### Parameters
|
|
||||||
/// - **self** the interupt handler
|
|
||||||
/// - **new_status** the new status value
|
|
||||||
///
|
|
||||||
/// ### return
|
|
||||||
/// The previus status
|
|
||||||
pub fn set_status(&mut self, new_status: InterruptStatus) -> InterruptStatus {
|
pub fn set_status(&mut self, new_status: InterruptStatus) -> InterruptStatus {
|
||||||
let old = self.level;
|
let old = self.level;
|
||||||
self.level = new_status;
|
self.level = new_status;
|
||||||
@ -42,11 +21,10 @@ impl Interrupt {
|
|||||||
old
|
old
|
||||||
}
|
}
|
||||||
|
|
||||||
fn one_tick(&self, nb_cycle: i32) {
|
fn one_tick(&self, _nb_cycle: i32) {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Interupt getter
|
|
||||||
pub fn get_status(&self) -> InterruptStatus {
|
pub fn get_status(&self) -> InterruptStatus {
|
||||||
self.level
|
self.level
|
||||||
}
|
}
|
||||||
@ -57,7 +35,7 @@ impl Interrupt {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Copy, Debug)]
|
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||||
pub enum InterruptStatus {
|
pub enum InterruptStatus {
|
||||||
InterruptOff,
|
InterruptOff,
|
||||||
InterruptOn
|
InterruptOn
|
||||||
|
@ -1,25 +1,9 @@
|
|||||||
//! # Loader
|
|
||||||
//!
|
|
||||||
//! This module contains a loader for file section.
|
|
||||||
//! Following the common standard file format for executable files
|
|
||||||
//! [ELF (Executable and Linkable Format)](https://en.wikipedia.org/wiki/Executable_and_Linkable_Forma)
|
|
||||||
//!
|
|
||||||
//! It's used to charge a programme into the machine from a binary file (.guac files)
|
|
||||||
//!
|
|
||||||
//! Basic usage:
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! let args = Args::parse();
|
|
||||||
//! let mut machine = Machine::new(args.debug & 1 != 0, read_settings().unwrap());
|
|
||||||
//! let (loader, ptr) = loader::Loader::new(args.executable.as_str(), &mut machine, 0).expect("An error occured while parsing the program");
|
|
||||||
//! ```
|
|
||||||
|
|
||||||
use crate::Machine;
|
use crate::Machine;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|
||||||
/// The elf header defines principes aspects of the binary files, it's place at the start of the file
|
/// The elf header defines principes aspects of the binary files, it's place at the start of the file
|
||||||
/// see [ELF file Header](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header) for more informations
|
/// see <https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header> for more informations
|
||||||
pub struct ElfHeader {
|
pub struct ElfHeader {
|
||||||
/// Defines whether the file is big or little endian
|
/// Defines whether the file is big or little endian
|
||||||
/// true correspond to big endian, false otherwise
|
/// true correspond to big endian, false otherwise
|
||||||
@ -635,7 +619,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, 0x400_000);
|
assert_eq!(loader.sections[2].virt_addr, 0x0040_0000);
|
||||||
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));
|
||||||
}
|
}
|
||||||
|
@ -228,7 +228,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) {
|
||||||
|
@ -1,31 +1,14 @@
|
|||||||
//! # Memory Comparator
|
///! FILE.TXT FORMAT Representing machine memory memory
|
||||||
//!
|
/// - PC
|
||||||
//! This module contains a MemChecker.
|
/// - SP
|
||||||
//!
|
/// - Section_1
|
||||||
//! It's used to compare state memory obtained after a dump memory from NachOS and BurritOS.
|
/// - Section_2
|
||||||
//!
|
/// - ...
|
||||||
//! This module is used exclusively for testing the instruction simulator.
|
/// - Section_n
|
||||||
//!
|
///
|
||||||
//! Basic usage:
|
/// Each section is divided in 3 parts, on two lines of text
|
||||||
//!
|
/// addr SPACE len
|
||||||
//! ```
|
/// content
|
||||||
//! let mut m = Machine::new(true, get_debug_configuration());
|
|
||||||
//! let mut MemChecker = mem_cmp::MemChecker::from(get_full_path!("memory", expr));
|
|
||||||
//! mem_cmp::MemChecker::fill_memory_from_mem_checker(&MemChecker, &mut m);
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//!
|
|
||||||
//! ! FILE.TXT FORMAT Representing machine memory memory
|
|
||||||
//! - PC
|
|
||||||
//! - SP
|
|
||||||
//! - Section_1
|
|
||||||
//! - Section_2
|
|
||||||
//! - ...
|
|
||||||
//! - Section_n
|
|
||||||
//!
|
|
||||||
//! Each section is divided in 3 parts, on two lines of text
|
|
||||||
//! addr SPACE len
|
|
||||||
//! content
|
|
||||||
|
|
||||||
use std::{fs, io::{BufRead, BufReader, Lines, Error}};
|
use std::{fs, io::{BufRead, BufReader, Lines, Error}};
|
||||||
use crate::Machine;
|
use crate::Machine;
|
||||||
@ -111,7 +94,7 @@ impl MemChecker{
|
|||||||
/// Extract the values of pc, sp and sections
|
/// Extract the values of pc, sp and sections
|
||||||
///
|
///
|
||||||
/// ### Parameter
|
/// ### Parameter
|
||||||
/// - **path** addr to the file
|
/// -**path** addr to the file
|
||||||
///
|
///
|
||||||
/// ### Return
|
/// ### Return
|
||||||
/// Mem-checker filled
|
/// Mem-checker filled
|
||||||
|
@ -1,38 +1,18 @@
|
|||||||
//! # MMU
|
|
||||||
//!
|
|
||||||
//! This module contains a MMU implementation
|
|
||||||
//!
|
|
||||||
//! This part isn't tested nor integrated to BurritOS because of the lack of pagination implementation
|
|
||||||
//!
|
|
||||||
//!
|
|
||||||
|
|
||||||
use crate::simulator::translationtable::*;
|
use crate::simulator::translationtable::*;
|
||||||
use crate::simulator::machine::*;
|
use crate::simulator::machine::*;
|
||||||
|
|
||||||
/// # Memory Management Unit
|
|
||||||
/// An MMU possesses a single reference to a translation table
|
|
||||||
/// This table is associated to the current process
|
|
||||||
pub struct MMU <'a>{
|
pub struct MMU <'a>{
|
||||||
/// Reference to a page table
|
/* Un MMU possède une seule référence vers une table des pages à un instant donné
|
||||||
|
* Cette table est associée au processus courant
|
||||||
|
* Cette référence peut etre mise a jour par exemple lors d'un switchTo
|
||||||
|
*/
|
||||||
translationTable : Option<&'a mut TranslationTable>,
|
translationTable : Option<&'a mut TranslationTable>,
|
||||||
/// The number of physique pages
|
|
||||||
numPhyPages : u64,
|
numPhyPages : u64,
|
||||||
/// Size of each page
|
|
||||||
pageSize : u64
|
pageSize : u64
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a>MMU <'_>{
|
impl <'a>MMU <'_>{
|
||||||
|
|
||||||
/// Create a MMU with a None reference for the translation table
|
|
||||||
///
|
|
||||||
/// ### Parameters
|
|
||||||
///
|
|
||||||
/// - **numPhyPages** the number of physique pages
|
|
||||||
/// - **pageSize** the size of a page
|
|
||||||
///
|
|
||||||
/// ### Return
|
|
||||||
///
|
|
||||||
/// MMU with None reference and the value for the number of physical pages and pae size associated
|
|
||||||
fn create(numPhyPages: u64, pageSize: u64) -> MMU <'a>{
|
fn create(numPhyPages: u64, pageSize: u64) -> MMU <'a>{
|
||||||
MMU {
|
MMU {
|
||||||
translationTable : None,
|
translationTable : None,
|
||||||
|
@ -1,12 +1,3 @@
|
|||||||
//! This module implement an Instruction simulator
|
|
||||||
//! with all the simulated hardware requested to run the Machine :
|
|
||||||
//! - **MMU**
|
|
||||||
//! - **Processor**
|
|
||||||
//! - **RAM**
|
|
||||||
//! - **Interruption Controler**
|
|
||||||
//!
|
|
||||||
//! The disk, the console and the serial coupler aren't implmented for now
|
|
||||||
//!
|
|
||||||
pub mod machine;
|
pub mod machine;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod instruction;
|
pub mod instruction;
|
||||||
|
@ -21,7 +21,7 @@ impl RegisterNum for i64 {}
|
|||||||
impl RegisterNum for f32 {}
|
impl RegisterNum for f32 {}
|
||||||
|
|
||||||
/// Machine register array
|
/// Machine register array
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq, Eq)]
|
||||||
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]
|
||||||
|
@ -1,40 +1,28 @@
|
|||||||
//! # Translation Table
|
//Nombre maximum de correspondances dans une table des pages
|
||||||
//!
|
//Cette donnée devra a terme etre recupérée depuis un fichier de configuration
|
||||||
//! This module implement a trnslation table used for fot the MMU Emulator
|
|
||||||
//!
|
|
||||||
//! This part isn't tested nor integrated to BurritOS,
|
|
||||||
//! but will be useful in the futur when the pagination will be implemented.
|
|
||||||
//!
|
|
||||||
//! It contains:
|
|
||||||
//! - all the setters and getters for translation table
|
|
||||||
//! - modificaters of table values
|
|
||||||
|
|
||||||
|
|
||||||
/// Maximum number in a Page Table
|
|
||||||
/// For a futur evolution of program, this value should be load from a configuration file
|
|
||||||
const MaxVirtPages : u64 = 200000;
|
const MaxVirtPages : u64 = 200000;
|
||||||
|
|
||||||
/// Translation Table corresponding to a process
|
|
||||||
/// An iteration of type TranslationTable should be possesses by an oject of type Process
|
/* Une table de correspondance propre à un processus
|
||||||
|
* Une variable de type TranslationTable devra etre possédée par un objet de type Process
|
||||||
|
*/
|
||||||
pub struct TranslationTable{
|
pub struct TranslationTable{
|
||||||
/// Table size <=> nb of possible translation
|
//capacité de cette table <=> nombre de correspondances possibles
|
||||||
|
//A voir si cette donnée doit etre immuable
|
||||||
pub maxNumPages : u64,
|
pub maxNumPages : u64,
|
||||||
|
|
||||||
///The table *Vec impemente Index Trait*
|
//la table en question
|
||||||
|
//Vec implemente le trait Index, donc un bon choix
|
||||||
pub pageTable : Vec<PageTableEntry>
|
pub pageTable : Vec<PageTableEntry>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TranslationTable {
|
impl TranslationTable {
|
||||||
|
|
||||||
/// TranslationTable constructor
|
|
||||||
///
|
|
||||||
/// ### Return
|
|
||||||
/// TranslationTable with an empty Vector
|
|
||||||
pub fn create() -> TranslationTable {
|
pub fn create() -> 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());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,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{
|
||||||
return self.maxNumPages;
|
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){
|
||||||
|
@ -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, Clone, Debug)]
|
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||||
pub struct List<T: PartialEq> {
|
pub struct List<T: PartialEq> {
|
||||||
head: Link<T>,
|
head: Link<T>,
|
||||||
tail: Link<T>,
|
tail: Link<T>,
|
||||||
|
Reference in New Issue
Block a user