From 4f670845ff9ab6c48bcb5f7bf4d4ef6dc3c3064b Mon Sep 17 00:00:00 2001 From: manuel Date: Tue, 27 Mar 2012 11:51:08 +0200 Subject: reorganize file structure to match the upstream requirements --- pintos-progos/userprog/pagedir.c | 263 --------------------------------------- 1 file changed, 263 deletions(-) delete mode 100644 pintos-progos/userprog/pagedir.c (limited to 'pintos-progos/userprog/pagedir.c') diff --git a/pintos-progos/userprog/pagedir.c b/pintos-progos/userprog/pagedir.c deleted file mode 100644 index a6a87b8..0000000 --- a/pintos-progos/userprog/pagedir.c +++ /dev/null @@ -1,263 +0,0 @@ -#include "userprog/pagedir.h" -#include -#include -#include -#include "threads/init.h" -#include "threads/pte.h" -#include "threads/palloc.h" - -static uint32_t *active_pd (void); -static void invalidate_pagedir (uint32_t *); - -/* Creates a new page directory that has mappings for kernel - virtual addresses, but none for user virtual addresses. - Returns the new page directory, or a null pointer if memory - allocation fails. */ -uint32_t * -pagedir_create (void) -{ - uint32_t *pd = palloc_get_page (0); - if (pd != NULL) - memcpy (pd, init_page_dir, PGSIZE); - return pd; -} - -/* Destroys page directory PD, freeing all the pages it - references. */ -void -pagedir_destroy (uint32_t *pd) -{ - uint32_t *pde; - - if (pd == NULL) - return; - - ASSERT (pd != init_page_dir); - for (pde = pd; pde < pd + pd_no (PHYS_BASE); pde++) - if (*pde & PTE_P) - { - uint32_t *pt = pde_get_pt (*pde); - uint32_t *pte; - - for (pte = pt; pte < pt + PGSIZE / sizeof *pte; pte++) - if (*pte & PTE_P) - palloc_free_page (pte_get_page (*pte)); - palloc_free_page (pt); - } - palloc_free_page (pd); -} - -/* Returns the address of the page table entry for virtual - address VADDR in page directory PD. - If PD does not have a page table for VADDR, behavior depends - on CREATE. If CREATE is true, then a new page table is - created and a pointer into it is returned. Otherwise, a null - pointer is returned. */ -static uint32_t * -lookup_page (uint32_t *pd, const void *vaddr, bool create) -{ - uint32_t *pt, *pde; - - ASSERT (pd != NULL); - - /* Shouldn't create new kernel virtual mappings. */ - ASSERT (!create || is_user_vaddr (vaddr)); - - /* Check for a page table for VADDR. - If one is missing, create one if requested. */ - pde = pd + pd_no (vaddr); - if (*pde == 0) - { - if (create) - { - pt = palloc_get_page (PAL_ZERO); - if (pt == NULL) - return NULL; - - *pde = pde_create (pt); - } - else - return NULL; - } - - /* Return the page table entry. */ - pt = pde_get_pt (*pde); - return &pt[pt_no (vaddr)]; -} - -/* Adds a mapping in page directory PD from user virtual page - UPAGE to the physical frame identified by kernel virtual - address KPAGE. - UPAGE must not already be mapped. - KPAGE should probably be a page obtained from the user pool - with palloc_get_page(). - If WRITABLE is true, the new page is read/write; - otherwise it is read-only. - Returns true if successful, false if memory allocation - failed. */ -bool -pagedir_set_page (uint32_t *pd, void *upage, void *kpage, bool writable) -{ - uint32_t *pte; - - ASSERT (pg_ofs (upage) == 0); - ASSERT (pg_ofs (kpage) == 0); - ASSERT (is_user_vaddr (upage)); - ASSERT (vtop (kpage) >> PTSHIFT < init_ram_pages); - ASSERT (pd != init_page_dir); - - pte = lookup_page (pd, upage, true); - - if (pte != NULL) - { - ASSERT ((*pte & PTE_P) == 0); - *pte = pte_create_user (kpage, writable); - return true; - } - else - return false; -} - -/* Looks up the physical address that corresponds to user virtual - address UADDR in PD. Returns the kernel virtual address - corresponding to that physical address, or a null pointer if - UADDR is unmapped. */ -void * -pagedir_get_page (uint32_t *pd, const void *uaddr) -{ - uint32_t *pte; - - ASSERT (is_user_vaddr (uaddr)); - - pte = lookup_page (pd, uaddr, false); - if (pte != NULL && (*pte & PTE_P) != 0) - return pte_get_page (*pte) + pg_ofs (uaddr); - else - return NULL; -} - -/* Marks user virtual page UPAGE "not present" in page - directory PD. Later accesses to the page will fault. Other - bits in the page table entry are preserved. - UPAGE need not be mapped. */ -void -pagedir_clear_page (uint32_t *pd, void *upage) -{ - uint32_t *pte; - - ASSERT (pg_ofs (upage) == 0); - ASSERT (is_user_vaddr (upage)); - - pte = lookup_page (pd, upage, false); - if (pte != NULL && (*pte & PTE_P) != 0) - { - *pte &= ~PTE_P; - invalidate_pagedir (pd); - } -} - -/* Returns true if the PTE for virtual page VPAGE in PD is dirty, - that is, if the page has been modified since the PTE was - installed. - Returns false if PD contains no PTE for VPAGE. */ -bool -pagedir_is_dirty (uint32_t *pd, const void *vpage) -{ - uint32_t *pte = lookup_page (pd, vpage, false); - return pte != NULL && (*pte & PTE_D) != 0; -} - -/* Set the dirty bit to DIRTY in the PTE for virtual page VPAGE - in PD. */ -void -pagedir_set_dirty (uint32_t *pd, const void *vpage, bool dirty) -{ - uint32_t *pte = lookup_page (pd, vpage, false); - if (pte != NULL) - { - if (dirty) - *pte |= PTE_D; - else - { - *pte &= ~(uint32_t) PTE_D; - invalidate_pagedir (pd); - } - } -} - -/* Returns true if the PTE for virtual page VPAGE in PD has been - accessed recently, that is, between the time the PTE was - installed and the last time it was cleared. Returns false if - PD contains no PTE for VPAGE. */ -bool -pagedir_is_accessed (uint32_t *pd, const void *vpage) -{ - uint32_t *pte = lookup_page (pd, vpage, false); - return pte != NULL && (*pte & PTE_A) != 0; -} - -/* Sets the accessed bit to ACCESSED in the PTE for virtual page - VPAGE in PD. */ -void -pagedir_set_accessed (uint32_t *pd, const void *vpage, bool accessed) -{ - uint32_t *pte = lookup_page (pd, vpage, false); - if (pte != NULL) - { - if (accessed) - *pte |= PTE_A; - else - { - *pte &= ~(uint32_t) PTE_A; - invalidate_pagedir (pd); - } - } -} - -/* Loads page directory PD into the CPU's page directory base - register. */ -void -pagedir_activate (uint32_t *pd) -{ - if (pd == NULL) - pd = init_page_dir; - - /* Store the physical address of the page directory into CR3 - aka PDBR (page directory base register). This activates our - new page tables immediately. See [IA32-v2a] "MOV--Move - to/from Control Registers" and [IA32-v3a] 3.7.5 "Base - Address of the Page Directory". */ - asm volatile ("movl %0, %%cr3" : : "r" (vtop (pd)) : "memory"); -} - -/* Returns the currently active page directory. */ -static uint32_t * -active_pd (void) -{ - /* Copy CR3, the page directory base register (PDBR), into - `pd'. - See [IA32-v2a] "MOV--Move to/from Control Registers" and - [IA32-v3a] 3.7.5 "Base Address of the Page Directory". */ - uintptr_t pd; - asm volatile ("movl %%cr3, %0" : "=r" (pd)); - return ptov (pd); -} - -/* Seom page table changes can cause the CPU's translation - lookaside buffer (TLB) to become out-of-sync with the page - table. When this happens, we have to "invalidate" the TLB by - re-activating it. - - This function invalidates the TLB if PD is the active page - directory. (If PD is not active then its entries are not in - the TLB, so there is no need to invalidate anything.) */ -static void -invalidate_pagedir (uint32_t *pd) -{ - if (active_pd () == pd) - { - /* Re-activating PD clears the TLB. See [IA32-v3a] 3.12 - "Translation Lookaside Buffers (TLBs)". */ - pagedir_activate (pd); - } -} -- cgit v1.2.3