impl translation table + debut impl mmu
This commit is contained in:
parent
7de7f2e007
commit
3391d3cb65
@ -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 {}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -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 {
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user