Esempio n. 1
0
File: mmu.c Progetto: dtbinh/m1s1
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;
}
Esempio n. 2
0
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;
}