impl translation table + debut impl mmu

This commit is contained in:
Moysan Gabriel 2023-03-13 22:52:27 +01:00
parent 7de7f2e007
commit 3391d3cb65
4 changed files with 184 additions and 15 deletions

View File

@ -36,6 +36,8 @@ pub const NUM_FP_REGS: usize = 32;
/// doit disparaitre /// doit disparaitre
const MEM_SIZE : usize = 0x500000; const MEM_SIZE : usize = 0x500000;
//doit etre une puissance de deux
pub const PAGE_SIZE : u64 = 128;
pub trait RegisterNum: Add<Output=Self> + Sub<Output=Self> + PartialEq + Copy {} pub trait RegisterNum: Add<Output=Self> + Sub<Output=Self> + PartialEq + Copy {}

View File

@ -0,0 +1,50 @@
use crate::simulator::translationtable::*;
use crate::simulator::machine::*;
use super::machine::ExceptionType;
pub struct MMU <'a>{
/* 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>
}
impl <'a>MMU <'_>{
fn create() -> MMU <'a>{
MMU{
translationTable : None
}
}
fn translate(mmu : &mut MMU, virtAddr : u64, physAddr : &mut u64, size : usize, writing : bool) -> ExceptionType {
let virtual_page_index : u64 = virtAddr/PAGE_SIZE;
let offset : u64 = virtAddr%PAGE_SIZE;
match &mmu.translationTable {
None => {
println!("Error from translate : MMU refers to None (No page Table)");
return ExceptionType::ADDRESSERROR_EXCEPTION;
}
Some(table_ref) => {
//On verifie que notre index est valide
if virtual_page_index >= table_ref.get_max_num_pages(){
}
//is the page correctyl mapped ?
//if table_ref.pageTable.get
}
}
ExceptionType::NO_EXCEPTION
}
}

View File

@ -4,6 +4,8 @@ pub mod print;
pub mod mem_cmp; pub mod mem_cmp;
pub mod loader; pub mod loader;
pub mod interrupt; pub mod interrupt;
pub mod translationtable;
pub mod mmu;
pub mod global { pub mod global {

View File

@ -4,26 +4,141 @@ const MaxVirtPages : u64 = 200000;
/* Une table de correspondance propre à un processus /* Une table de correspondance propre à un processus
* Une variable de type TranslationTable devra etre possédée par un objet de type Process
*/ */
struct TranslationTable{ pub struct TranslationTable{
//capacité de cette table <=> nombre de correspondances possibles //capacité de cette table <=> nombre de correspondances possibles
maxNumPages : u64, //A voir si cette donnée doit etre immuable
pub maxNumPages : u64,
//la table en question //la table en question
//Vec implemente le trait Index, donc un bon choix //Vec implemente le trait Index, donc un bon choix
pageTable : Vec<PageTableEntry> pub pageTable : Vec<PageTableEntry>
} }
impl TranslationTable { impl TranslationTable {
fn create() -> TranslationTable { pub fn create() -> TranslationTable {
let mut tmp_vec : Vec<PageTableEntry> = Vec::new();
for i in 0..MaxVirtPages {
tmp_vec.push(PageTableEntry::create());
}
TranslationTable{ TranslationTable{
maxNumPages : MaxVirtPages, maxNumPages : MaxVirtPages,
page pageTable : tmp_vec
} }
} }
//vpn = virtual page number, c'est un index dans la table des page
//Assert a mettre dans chacune des fonctions suivantes
pub fn get_max_num_pages(&self) -> u64{
return self.maxNumPages;
}
pub fn set_physical_page(&mut self, vpn : u64, physical_page : i32){
self.pageTable[vpn as usize].physical_page = physical_page;
}
pub fn get_physical_page(&self, vpn : u64) -> i32{
self.pageTable[vpn as usize].physical_page
}
pub fn set_addr_disk(&mut self, vpn : u64, addr_disk : i32){
self.pageTable[vpn as usize].addr_disk = addr_disk;
}
pub fn get_addr_disk(&self, vpn : u64) -> i32 {
self.pageTable[vpn as usize].addr_disk
}
pub fn set_bit_valid(&mut self, vpn : u64){
self.pageTable[vpn as usize].valid = true;
}
pub fn clear_bit_valid(&mut self, vpn : u64){
self.pageTable[vpn as usize].valid = false;
}
pub fn get_bit_valid(&self, vpn : u64) -> bool{
self.pageTable[vpn as usize].valid
}
pub fn set_bit_io(&mut self, vpn : u64){
self.pageTable[vpn as usize].io = true;
}
pub fn clear_bit_io(&mut self, vpn : u64){
self.pageTable[vpn as usize].io = false;
}
pub fn get_bit_io(&self, vpn : u64) -> bool{
self.pageTable[vpn as usize].io
}
pub fn set_bit_swap(&mut self, vpn : u64){
self.pageTable[vpn as usize].swap = true;
}
pub fn clear_bit_swap(&mut self, vpn : u64){
self.pageTable[vpn as usize].swap = false;
}
pub fn get_bit_swap(&self, vpn : u64) -> bool{
self.pageTable[vpn as usize].swap
}
pub fn set_bit_write(&mut self, vpn : u64){
self.pageTable[vpn as usize].write_allowed = true;
}
pub fn clear_bit_write(&mut self, vpn : u64){
self.pageTable[vpn as usize].write_allowed = false;
}
pub fn get_bit_write(&self, vpn : u64) -> bool{
self.pageTable[vpn as usize].write_allowed
}
pub fn set_bit_read(&mut self, vpn : u64){
self.pageTable[vpn as usize].read_allowed = true;
}
pub fn clear_bit_read(&mut self, vpn : u64){
self.pageTable[vpn as usize].read_allowed = false;
}
pub fn get_bit_read(&self, vpn : u64) -> bool{
self.pageTable[vpn as usize].read_allowed
}
pub fn set_bit_U(&mut self, vpn : u64){
self.pageTable[vpn as usize].U = true;
}
pub fn clear_bit_U(&mut self, vpn : u64){
self.pageTable[vpn as usize].U = false;
}
pub fn get_bit_U(&self, vpn : u64) -> bool{
self.pageTable[vpn as usize].U
}
pub fn set_bit_M(&mut self, vpn : u64){
self.pageTable[vpn as usize].M = true;
}
pub fn clear_bit_M(&mut self, vpn : u64){
self.pageTable[vpn as usize].M = false;
}
pub fn get_bit_M(&self, vpn : u64) -> bool{
self.pageTable[vpn as usize].M
}
} }
@ -31,7 +146,7 @@ impl TranslationTable {
/* Une correspondance + données sur cette correspondance /* Une correspondance + données sur cette correspondance
*/ */
struct PageTableEntry{ pub struct PageTableEntry{
//true <=> la correspondance est valide et la page est présente dans la ram //true <=> la correspondance est valide et la page est présente dans la ram
valid : bool, valid : bool,
@ -42,17 +157,17 @@ struct PageTableEntry{
M : bool, M : bool,
//droits d'accès sur cette page //droits d'accès sur cette page
readAllowed : bool, read_allowed : bool,
writeAllowed : bool, write_allowed : bool,
//numero de page physique <=> c'est notre correspondance //numero de page physique <=> c'est notre correspondance
physicalPage : i32, physical_page : i32,
//true <=> cette page doit etre chargée depuis la swap zone du disque //true <=> cette page doit etre chargée depuis la swap zone du disque
swap : bool, swap : bool,
//a définir plus tard, en relation avec swap //a définir plus tard, en relation avec swap
addrDisk : i32, addr_disk : i32,
//mis à 1 par le système quand cette page est impliquée dans une opération d'IO //mis à 1 par le système quand cette page est impliquée dans une opération d'IO
io : bool io : bool
@ -61,16 +176,16 @@ struct PageTableEntry{
impl PageTableEntry{ impl PageTableEntry{
//Default PageTableEntry Constructor //Default PageTableEntry Constructor
fn create() -> PageTableEntry { pub fn create() -> PageTableEntry {
PageTableEntry { PageTableEntry {
valid : false, valid : false,
U : false, U : false,
M : false, M : false,
readAllowed : false, read_allowed : false,
writeAllowed : false, write_allowed : false,
physicalPage : -1i32, physical_page : -1i32,
swap : false, swap : false,
addrDisk : -1i32, addr_disk : -1i32,
io : false io : false
} }
} }