int ppage_of_vaddr(unsigned int vaddr) { unsigned int vpage; /* Test si l'adresse est bien virtuelle */ if(vaddr < (unsigned)virtual_memory || vaddr > ((unsigned)virtual_memory + VM_SIZE - 1)){ return -1; } vpage = vpage_of_vaddr(vaddr); if(vpage < 0 || vpage > N) return -1; return vpage+1; }
static void mmuhandler() { int fault = _in(MMU_FAULT_ADDR); struct tlb_entry_s tlb_entry; assert(fault >= (int)virtual_memory && fault <= (int)virtual_memory + VM_SIZE - 1); tlb_entry.tlbe_cfu = 0; tlb_entry.tlbe_x_access = 1; tlb_entry.tlbe_w_access = 1; tlb_entry.tlbe_r_access = 1; tlb_entry.tlbe_used = 1; if(vm_mapping[vpage_of_vaddr(fault)].mapped) { tlb_entry.tlbe_physical_page = vm_mapping[vpage_of_vaddr(fault)].ppage; tlb_entry.tlbe_virtual_page = vpage_of_vaddr(fault); _out(TLB_ADD_ENTRY, *((int*)&tlb_entry)); return; } if(pm_mapping[victime_rr].mapped) { store_to_swap(pm_mapping[victime_rr].vpage, victime_rr); pm_mapping[victime_rr].mapped = 0; vm_mapping[pm_mapping[victime_rr].vpage].mapped = 0; tlb_entry.tlbe_physical_page = victime_rr; _out(TLB_DEL_ENTRY, *((int*)&tlb_entry)); } fetch_from_swap(vpage_of_vaddr(fault), victime_rr); pm_mapping[victime_rr].mapped = 1; pm_mapping[victime_rr].vpage = vpage_of_vaddr(fault); vm_mapping[vpage_of_vaddr(fault)].mapped = 1; vm_mapping[vpage_of_vaddr(fault)].ppage = victime_rr; tlb_entry.tlbe_physical_page = victime_rr; tlb_entry.tlbe_virtual_page = vpage_of_vaddr(fault); _out(TLB_ADD_ENTRY, *((int*)&tlb_entry)); victime_rr = (victime_rr % 255) + 1; return; }
void mmu_handler() { union tlb_entry_u union_entry; unsigned int vaddr = _in(MMU_FAULT_ADDR); int ppage = ppage_of_vaddr(current_process, vaddr); if(ppage < 0) exit(-1); union_entry.entry.ppage = ppage; union_entry.entry.vpage = vpage_of_vaddr(vaddr); union_entry.entry.access_x = 1; union_entry.entry.access_r = 1; union_entry.entry.access_w = 1; union_entry.entry.used = 1; _out(TLB_ADD_ENTRY, union_entry.asInt); }
/* Retourne le numéro de la page physique associée à l'@ virtuelle vaddr du process * process (0 pour le premier processus, 1 pour le second). La fonction retourne -1 * si l'@ virtuelle est en dehors de l'espace alloué au processus */ static int ppage_of_vaddr(int process, unsigned vaddr){ int vpage = vpage_of_vaddr(vaddr); if(vpage < 0) return -1; return (vpage < N/2) ? process*N/2 + vpage +1 : -1; }