示例#1
0
int
page_insert(Pde *pgdir, struct Page *pp, u_long va, u_int perm)
{
	// Fill this function in
	u_int PERM;
	Pte *pgtable_entry;
	PERM = perm | PTE_V;

	pgdir_walk(pgdir, va, 0, &pgtable_entry);

	if (pgtable_entry != 0 && (*pgtable_entry & PTE_V) != 0) {
		if (pa2page(*pgtable_entry) != pp) {
			page_remove(pgdir, va);
		} else	{
			tlb_invalidate(pgdir, va);
			*pgtable_entry = (page2pa(pp) | PERM);

			return 0;
		}
	}

	tlb_invalidate(pgdir, va);

	if (pgdir_walk(pgdir, va, 1, &pgtable_entry) != 0) {
		return -E_NO_MEM;    // panic("page insert wrong.\n");
	}

	*pgtable_entry = (page2pa(pp) | PERM);
	//printf("page_insert:PTE:\tcon:%x\t@:%x\n",(int)*pgtable_entry,(int)pgtable_entry);
	pp->pp_ref++;
	return 0;
}
示例#2
0
文件: swap.c 项目: spinlock/ucore
// swap_out_vma - try unmap pte & move pages into swap active list.
static int
swap_out_vma(struct mm_struct *mm, struct vma_struct *vma, uintptr_t addr, size_t require) {
    if (require == 0 || !(addr >= vma->vm_start && addr < vma->vm_end)) {
        return 0;
    }
    uintptr_t end;
    size_t free_count = 0;
    addr = ROUNDDOWN(addr, PGSIZE), end = ROUNDUP(vma->vm_end, PGSIZE);
    while (addr < end && require != 0) {
        pte_t *ptep = get_pte(mm->pgdir, addr, 0);
        if (ptep == NULL) {
            if (get_pud(mm->pgdir, addr, 0) == NULL) {
                addr = ROUNDDOWN(addr + PUSIZE, PUSIZE);
            }
            else if (get_pmd(mm->pgdir, addr, 0) == NULL) {
                addr = ROUNDDOWN(addr + PMSIZE, PMSIZE);
            }
            else {
                addr = ROUNDDOWN(addr + PTSIZE, PTSIZE);
            }
            continue ;
        }
        if (*ptep & PTE_P) {
            struct Page *page = pte2page(*ptep);
            assert(!PageReserved(page));
            if (*ptep & PTE_A) {
                *ptep &= ~PTE_A;
                tlb_invalidate(mm->pgdir, addr);
                goto try_next_entry;
            }
            if (!PageSwap(page)) {
                if (!swap_page_add(page, 0)) {
                    goto try_next_entry;
                }
                swap_active_list_add(page);
            }
            else if (*ptep & PTE_D) {
                SetPageDirty(page);
            }
            swap_entry_t entry = page->index;
            swap_duplicate(entry);
            page_ref_dec(page);
            *ptep = entry;
            tlb_invalidate(mm->pgdir, addr);
            mm->swap_address = addr + PGSIZE;
            free_count ++, require --;
            if ((vma->vm_flags & VM_SHARE) && page_ref(page) == 1) {
                uintptr_t shmem_addr = addr - vma->vm_start + vma->shmem_off;
                pte_t *sh_ptep = shmem_get_entry(vma->shmem, shmem_addr, 0);
                assert(sh_ptep != NULL && *sh_ptep != 0);
                if (*sh_ptep & PTE_P) {
                    shmem_insert_entry(vma->shmem, shmem_addr, entry);
                }
            }
        }
    try_next_entry:
        addr += PGSIZE;
    }
    return free_count;
}
示例#3
0
//
// Map the physical page 'pp' at virtual address 'va'.
// The permissions (the low 12 bits) of the page table entry
// should be set to 'perm|PTE_P'.
//
// Requirements
//   - If there is already a page mapped at 'va', it should be page_remove()d.
//   - If necessary, on demand, a page table should be allocated and inserted
//     into 'pgdir'.
//   - pp->pp_ref should be incremented if the insertion succeeds.
//   - The TLB must be invalidated if a page was formerly present at 'va'.
//
// Corner-case hint: Make sure to consider what happens when the same
// pp is re-inserted at the same virtual address in the same pgdir.
// However, try not to distinguish this case in your code, as this
// frequently leads to subtle bugs; there's an elegant way to handle
// everything in one code path.
//
// RETURNS:
//   0 on success
//   -E_NO_MEM, if page table couldn't be allocated
//
// Hint: The TA solution is implemented using pgdir_walk, page_remove,
// and page2pa.
//
int
page_insert(pde_t *pgdir, struct PageInfo *pp, void *va, int perm)
{
	// Fill this function in
	
	pte_t* ptep = pgdir_walk(pgdir, va, true);
	
	if(!ptep) {
		return -E_NO_MEM;
	}

	
	if( pa2page(*ptep) != pp ){
		page_remove(pgdir, va);
		assert( *ptep == 0 );
		assert(pp->pp_ref >= 0);
		pp->pp_ref++;
	}
	else {
		tlb_invalidate(pgdir, va);
	}

	
	*ptep = page2pa(pp) | perm | PTE_P;
	/* we should also change pde's perm*/
	pde_t *pde = pgdir + PDX(va); 
	*pde = *pde | perm;
	
	
	return 0;
}
void  call_linux(long a0, long a1, long a2)
{
 	local_irq_disable();
	cache_clean_invalidate();
	tlb_invalidate();

__asm__(
	"mov	r0, %0\n"
	"mov	r1, %1\n"
	"mov	r2, %2\n"
	"mov	ip, #0\n"
	"mcr	p15, 0, ip, c13, c0, 0\n"	/* zero PID */
	"mcr	p15, 0, ip, c7, c7, 0\n"	/* invalidate I,D caches */
	"mcr	p15, 0, ip, c7, c10, 4\n"	/* drain write buffer */
	"mcr	p15, 0, ip, c8, c7, 0\n"	/* invalidate I,D TLBs */
	"mrc	p15, 0, ip, c1, c0, 0\n"	/* get control register */
	"bic	ip, ip, #0x0001\n"		/* disable MMU */
	"mcr	p15, 0, ip, c1, c0, 0\n"	/* write control register */
	"mov	pc, r2\n"
	"nop\n"
	"nop\n"
	: /* no outpus */
	: "r" (a0), "r" (a1), "r" (a2)
	: "r0","r1","r2","ip"
	);
}
示例#5
0
//
// Map the physical page 'pp' at virtual address 'va'.
// The permissions (the low 12 bits) of the page table entry
// should be set to 'perm|PTE_P'.
//
// Requirements
//   - If there is already a page mapped at 'va', it should be page_remove()d.
//   - If necessary, on demand, a page table should be allocated and inserted
//     into 'pgdir'.
//   - pp->pp_ref should be incremented if the insertion succeeds.
//   - The TLB must be invalidated if a page was formerly present at 'va'.
//
// Corner-case hint: Make sure to consider what happens when the same
// pp is re-inserted at the same virtual address in the same pgdir.
//
// RETURNS:
//   0 on success
//   -E_NO_MEM, if page table couldn't be allocated
//
// Hint: Check out pgdir_walk, page_remove, page2pa, and similar functions.
//
int
page_insert(pde_t *pgdir, struct Page *pp, uintptr_t va, pte_t perm)
{
	// Make sure the page table exists. If it doesn't, try and create one.
	// If that fails, exit with status -E_NO_MEM.
	pte_t *pte = pgdir_walk(pgdir, va, true);
	if (pte == NULL) return -E_NO_MEM;

	physaddr_t pa = page2pa(pp);
	Page *virtpage = page_lookup(pgdir, va, &pte);

	// See if there was an existing entry for va
	if (virtpage && (*pte & PTE_P)) {
		// Is it the same as the one we're entering?
		if (PTE_ADDR(*pte) == pa) {
			// Then just change the permissions and return
			*pte = PTE_ADDR(*pte) | perm | PTE_P;
			// Don't forget to invalidate the tlb!
			tlb_invalidate(pgdir, va);
//			cprintf("Found existing entry... changing permissions.\n");
		      	return 0;
		}
	        // Remove the old entry
//		cprintf("Found an existing entry... removing\n");
	        page_remove(pgdir, va);
	}
	// Either there was no entry for va, or there was an old entry and we removed it
//	cprintf("Adding entry...\n");
	*pte = pa | perm | PTE_P;
	pp->pp_ref++;
	assert(page_lookup(pgdir, va, &pte));
	assert(PTE_ADDR(*pte) == pa);
	return 0;
}
示例#6
0
void
page_remove(Pde *pgdir, u_long va)
{
	// Fill this function in
	Pte *pagetable_entry;
	struct Page *ppage;
	//	pgdir_walk(pgdir, va, 0, &pagetable_entry);

	//	if(pagetable_entry==0) return;
	//	if((*pagetable_entry & PTE_P)==0) return;	//the page is not in memory.

	//	ppage = pa2page(*pagetable_entry);
	ppage = page_lookup(pgdir, va, &pagetable_entry);

	if (ppage == 0) {
		return;
	}

	ppage->pp_ref--;

	if (ppage->pp_ref == 0) {
		page_free(ppage);
	}

	*pagetable_entry = 0;
	//printf("	in page_remove pagetalbe_entry=%x\n",pagetable_entry);
	tlb_invalidate(pgdir, va);
	return;
}
示例#7
0
文件: pmap.c 项目: prasadv90/AdvOS
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{	
	// Fill this function in
	struct PageInfo *pg;
	pte_t *pte;
	pte_t **pte_store=&pte;

	pg=page_lookup(pgdir,va,pte_store);
// If there is no physical page at that address, silently does nothing.
	if (!pg)
	{cprintf("page not found \n");
		return;}

//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
	
	page_decref(pg);
	//cprintf("page ref after decrement : %d \n",pg->pp_ref);
//- The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
	if(pte_store){
		**pte_store=0;
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
	tlb_invalidate(pgdir,va);	
	}
}
示例#8
0
//
// Map the physical page 'pp' at virtual address 'va'.
// The permissions (the low 12 bits) of the page table entry
// should be set to 'perm|PTE_P'.
//
// Requirements
//   - If there is already a page mapped at 'va', it should be page_remove()d.
//   - If necessary, on demand, a page table should be allocated and inserted
//     into 'pgdir'.
//   - pp->pp_ref should be incremented if the insertion succeeds.
//   - The TLB must be invalidated if a page was formerly present at 'va'.
//
// Corner-case hint: Make sure to consider what happens when the same
// pp is re-inserted at the same virtual address in the same pgdir.
// However, try not to distinguish this case in your code, as this
// frequently leads to subtle bugs; there's an elegant way to handle
// everything in one code path.
//
// RETURNS:
//   0 on success
//   -E_NO_MEM, if page table couldn't be allocated
//
// Hint: The TA solution is implemented using pgdir_walk, page_remove,
// and page2pa.
//
int
page_insert(pde_t *pgdir, struct PageInfo *pp, void *va, int perm)
{
	// Fill this function in
	if(!pgdir)
		return -E_NO_MEM;
	if(!pp)
		return -E_NO_MEM;
	pte_t *pt = pgdir_walk(pgdir, va, 1);
	if(!pt)
		return -E_NO_MEM;
	if(pt[0] & PTE_P){
		//Already exsists
		if(PTE_ADDR(pt[0]) != page2pa(pp)) {
			page_remove(pgdir, va);
		} else {
			pt[0] = PTE_ADDR(pt[0]) | perm | PTE_P;
			return 0;
		}
	}
	pp->pp_ref++;
	tlb_invalidate(pgdir, va);
	pt[0] = page2pa(pp) | perm | PTE_P;
	return 0;
}
示例#9
0
//
// Map the physical page 'pp' at virtual address 'va'.
// The permissions (the low 12 bits) of the page table entry
// should be set to 'perm|PTE_P'.
//
// Requirements
//   - If there is already a page mapped at 'va', it should be page_remove()d.
//   - If necessary, on demand, a page table should be allocated and inserted
//     into 'pgdir'.
//   - pp->pp_ref should be incremented if the insertion succeeds.
//   - The TLB must be invalidated if a page was formerly present at 'va'.
//
// Corner-case hint: Make sure to consider what happens when the same
// pp is re-inserted at the same virtual address in the same pgdir.
// Don't be tempted to write special-case code to handle this
// situation, though; there's an elegant way to address it.
//
// RETURNS:
//   0 on success
//   -E_NO_MEM, if page table couldn't be allocated
//
// Hint: The TA solution is implemented using pgdir_walk, page_remove,
// and page2pa.
//
int
page_insert(pde_t *pgdir, struct Page *pp, void *va, int perm)
{
//	cprintf("page_insert: pp:0x%x va:0x%x perm:0x%x\n",pp,va,perm);
	bool exist = 0;
	pte_t *pte = pgdir_walk(pgdir,va,1);
//	cprintf("page_insert: pte:0x%x *pte:0x%x\n",pte,*pte);
	if (pte == NULL) 
		return -E_NO_MEM;
	if (*pte & PTE_P)
	{
		struct Page *nowpp = page_lookup(pgdir,va,0);
		if (nowpp!=pp)
			page_remove(pgdir,va);
		else{
			tlb_invalidate(pgdir, va);
			exist = 1;
		}
	}
//	cprintf("page_insert: do not exist\n");
	*pte = page2pa(pp) | perm | PTE_P;
	if (exist == 0)
	{
		pp->pp_ref++;
	}
	return 0;
}
示例#10
0
文件: vm_tlb.c 项目: jessZhAnG/OS
void
tlb_flush(void)
{
    vmstats_inc(3);
    int i;
    for (i = 0 ; i < NUM_TLB; ++i){
       tlb_invalidate(i);
    }
}
示例#11
0
文件: pmap.c 项目: prasadv90/AdvOS
//
// Map the physical page 'pp' at virtual address 'va'.
// The permissions (the low 12 bits) of the page table entry
// should be set to 'perm|PTE_P'.
//
// Requirements
//   - If there is already a page mapped at 'va', it should be page_remove()d.
//   - If necessary, on demand, a page table should be allocated and inserted
//     into 'pgdir'.
//   - pp->pp_ref should be incremented if the insertion succeeds.
//   - The TLB must be invalidated if a page was formerly present at 'va'.
//
// Corner-case hint: Make sure to consider what happens when the same
// pp is re-inserted at the same virtual address in the same pgdir.
// However, try not to distinguish this case in your code, as this
// frequently leads to subtle bugs; there's an elegant way to handle
// everything in one code path.
//
// RETURNS:
//   0 on success
//   -E_NO_MEM, if page table couldn't be allocated
//
// Hint: The TA solution is implemented using pgdir_walk, page_remove,
// and page2pa.
//
int
page_insert(pde_t *pgdir, struct PageInfo *pp, void *va, int perm)
{/*	// Fill this function in
	pte_t *pte;
	physaddr_t pa=page2pa(pp);
	
	pte=pgdir_walk(pgdir,va,1);
	
	if (pte==NULL){
		cprintf("return error\n");
		return -E_NO_MEM;}	
//Check If there is already a page mapped at 'va',		
	if(*pte & PTE_P){
	
// check if same page is reinserted at the same virtual addr in same pgdir
		if(PTE_ADDR(*pte)==pa){
			*pte=pa|perm|PTE_P;
			return 0;
		}
//page should be page_remove()d and tlb invalidated.			
	page_remove(pgdir,va);
	tlb_invalidate(pgdir,va);	
	}
//set permission of page_table_entry and increment pp->ref count
	*pte=pa |perm| PTE_P ;
	 pp->pp_ref++;
	return 0;
*/
    pte_t *pte = pgdir_walk(pgdir, va, 0);
    physaddr_t ppa = page2pa(pp);

    if (pte != NULL) {
        // for page alreay mapped
        if (*pte & PTE_P){
		if(PTE_ADDR(*pte)==ppa){
			*pte=ppa|perm|PTE_P;
			return 0;
		}
            page_remove(pgdir, va); // also invalidates tlb
	}
        if (page_free_list == pp) 
            page_free_list = page_free_list->pp_link; 
		
	} else {
	    pte = pgdir_walk(pgdir, va, 1);
	    if (!pte)
		    return -E_NO_MEM;
    	    
	}
	*pte = page2pa(pp) | perm | PTE_P;
	pp->pp_ref++;
	//cprintf("ref variable count: %d \n",pp->pp_ref);
    	tlb_invalidate(pgdir, va);
	return 0;
}
示例#12
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, uintptr_t va)
{
	pte_t *pte;
	Page *pp = page_lookup(pgdir, va, &pte);
	if (pp != NULL) {
		page_decref(pp);
		*pte = *pte & ~0x1;
		tlb_invalidate(pgdir, va);
	}
}
示例#13
0
static inline void
page_remove_pte(pgd_t *pgdir, uintptr_t la, pte_t *ptep) {
    if (*ptep & PTE_P) {
        struct Page *page = pte2page(*ptep);
        if (page_ref_dec(page) == 0) {
            free_page(page);
        }
        *ptep = 0;
        tlb_invalidate(pgdir, la);
    }
}
示例#14
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
//  tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
   // Fill this function in
   pte_t *pte;
   struct PageInfo *pp = page_lookup(pgdir, va, &pte);
   if (!pp || !(*pte & PTE_P)) return;
   page_decref(pp);
   *pte = 0;
   tlb_invalidate(pgdir, va);
}
示例#15
0
文件: pmm.c 项目: haozhun/ucore_plus
/**
 * Check whether page directory for boot lives well.
 *     NOTE: we don't have mm_struct at present.
 *           as write to a clean page also raises SIGSEGV, we're not able to deal with it now.
 *           so just mark all page inserted to be accessed and dirty.
 */
void
check_boot_pgdir(void) {
    pte_t *ptep;
    int i;
    for (i = 0; i < npage; i += PGSIZE) {
        assert((ptep = get_pte(boot_pgdir, (uintptr_t)KADDR(i), 0)) != NULL);
        assert(PTE_ADDR(*ptep) == i);
    }

    //assert(PDE_ADDR(boot_pgdir[PDX(VPT)]) == PADDR(boot_pgdir));

    assert(boot_pgdir[PDX(TEST_PAGE)] == 0);

    struct Page *p;
    p = alloc_page();
    assert(page_insert(boot_pgdir, p, TEST_PAGE, PTE_W | PTE_D | PTE_A) == 0);
    assert(page_ref(p) == 1);
    assert(page_insert(boot_pgdir, p, TEST_PAGE + PGSIZE, PTE_W | PTE_D | PTE_A) == 0);
    assert(page_ref(p) == 2);

    const char *str = "ucore: Hello world!!";
    strcpy((void *)TEST_PAGE, str);
    assert(strcmp((void *)TEST_PAGE, (void *)(TEST_PAGE + PGSIZE)) == 0);

    *(char *)(page2kva(p)) = '\0';
    assert(strlen((const char *)TEST_PAGE) == 0);

    /*
     * in um architecture clear page table doesn't mean
     *     the linear address is invalid
     * so remove them by hand
     */
    tlb_invalidate (boot_pgdir, TEST_PAGE);
    tlb_invalidate (boot_pgdir, TEST_PAGE + PGSIZE);

    free_page(p);
    free_page(pa2page(PDE_ADDR(boot_pgdir[PDX(TEST_PAGE)])));
    boot_pgdir[PDX(TEST_PAGE)] = 0;

    kprintf("check_boot_pgdir() succeeded.\n");
}
示例#16
0
文件: pmap.c 项目: eshyong/MIT-JOS
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
//     tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
    pte_t *table_entry;
    struct PageInfo *page = page_lookup(pgdir, va, &table_entry);
    if (page) {
        // Decrement/free page, reset table entry, and invalidate TLB entry.
        page_decref(page);
        *table_entry = 0x0;
        tlb_invalidate(pgdir, va);
    }
}
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	// Fill this function in
        pte_t *tmppte;
        struct PageInfo *tmp = page_lookup(pgdir, va, &tmppte);
        if( tmp != NULL && (*tmppte & PTE_P)) {
                page_decref(tmp);
                *tmppte = 0;
        }
        tlb_invalidate(pgdir, va);
}
示例#18
0
文件: pmap.c 项目: bosswissam/djos
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	pte_t *pte;
	struct Page* pp = page_lookup(pgdir, va, &pte);
	
	if (pp) {
		page_decref(pp);
		*pte = 0;
		tlb_invalidate(pgdir, va);
	}
}
示例#19
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
	void
page_remove(pde_t *pgdir, void *va)
{
	// Fill this function in
	pte_t* pte_store = NULL;
	struct PageInfo* pg = page_lookup(pgdir, va, &pte_store); 
	if (!pg) 
		return;
	page_decref(pg);	
	tlb_invalidate(pgdir, va);
	*pte_store = 0;
}
示例#20
0
文件: pmap.c 项目: ajsbu/cse506
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
	void
page_remove(pml4e_t *pml4e, void *va)
{
	// Fill this function in
	pte_t* pte = NULL;
	struct Page *page = page_lookup(pml4e, va, &pte);
	if(page != 0){
		page_decref(page);
		*pte = 0;
		tlb_invalidate(pml4e, va);
	}
}
示例#21
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	// Fill this function in
    pte_t * pte_page;
    struct Page * page = page_lookup(pgdir, va, &pte_page);
    if(page) {
      page_decref(page);
      (* pte_page) = 0;
      tlb_invalidate(pgdir, va);
    }
}
示例#22
0
文件: coremap.c 项目: YueGan/CSCC69A2
/*
 * tlb_clear: flushes the TLB by loading it with invalid entries.
 *
 * Synchronization: assumes we hold coremap_spinlock. Does not block.
 */
static
void
tlb_clear(void)
{
	int i;	

	KASSERT(spinlock_do_i_hold(&coremap_spinlock));
	for (i=0; i<NUM_TLB; i++) {
		tlb_invalidate(i);
	}
	curcpu->c_vm.cvm_nexttlb = 0;
}
示例#23
0
void *
nw_mmio_map_region(physaddr_t pa, size_t size)
{
	static uintptr_t base = NW_MMIOBASE;
	uintptr_t ret_base = base;

	boot_map_region(kern_pgdir, base, ROUNDUP(size, PGSIZE) , pa , PTE_P | PTE_W | PTE_PCD | PTE_PWT);
	base = (uintptr_t)((char *)base + ROUNDUP(size, PGSIZE));
	// Fo now, there is only one address space, so always invalidate.
	tlb_invalidate(kern_pgdir, (void *)base);
	return (void *)ret_base;
}
示例#24
0
文件: pmap.c 项目: yuki252111/os
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	pte_t* pte;
	struct Page* res;
	res=page_lookup(pgdir,va,&pte);
	if(res!=NULL)
	{
		page_decref(res);
		*pte=0;
		tlb_invalidate(pgdir,va);
	}
}
示例#25
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	// Fill this function in
	//bluesea
	struct PageInfo *page = NULL;
	pte_t *ptep = NULL;
	if ((page = page_lookup(pgdir, va, &ptep)) != NULL){
		page_decref(page);
		*ptep = *ptep & (0xfff & ~PTE_P);
		tlb_invalidate(pgdir, va);
	}
}
示例#26
0
void tlb_init(reconos_tlb_t * tlb)
{
        fprintf(stderr, "tlb_init called\n");

	if(dcrraw_fd = -1) open_dcrraw();
	tlb->page_faults = 0;
	tlb->invalidate_dcrn = 11;
	tlb->id_dcrn = 10;
	tlb->status1_dcrn = 5;
	tlb->status2_dcrn = 4;
	
	tlb_invalidate(tlb);
}
示例#27
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	// Fill this function in
	pte_t* pte;
	struct Page* pp = page_lookup(pgdir, va, &pte);
	
	if (pp != NULL) {
		*pte = 0;
		page_decref(pp);
		tlb_invalidate(pgdir, va);
	}
}
示例#28
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	// Fill this function in
	/*stone's solution for lab2*/
	pte_t* pte;
	struct Page* pp = page_lookup(pgdir, va, &pte);
	if (pp != NULL){
		*pte = 0;
		page_decref(pp);
		tlb_invalidate(pgdir, va);		
	}
	return;
}
示例#29
0
//
// Unmaps the physical page at virtual address 'va'.
// If there is no physical page at that address, silently does nothing.
//
// Details:
//   - The ref count on the physical page should decrement.
//   - The physical page should be freed if the refcount reaches 0.
//   - The pg table entry corresponding to 'va' should be set to 0.
//     (if such a PTE exists)
//   - The TLB must be invalidated if you remove an entry from
//     the page table.
//
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
	// Fill this function in
	pte_t *pte_store;
	struct PageInfo *pp = page_lookup(pgdir, va, &pte_store);
	
	if(!pte_store || !(pte_store[0] & PTE_P)){
		return ;
	}
	page_decref(pp);
	*pte_store = 0;
	tlb_invalidate(pgdir, va);
}
示例#30
0
void mmu_early_disable(void)
{
	unsigned int cr;

	cr = get_cr();
	cr &= ~(CR_M | CR_C);

	set_cr(cr);
	v8_flush_dcache_all();
	tlb_invalidate();

	dsb();
	isb();
}