X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=inline;f=src%2Fthreads%2Fpaging.c;h=587813cb3c3707071316d9926979873a98d8f91e;hb=994aa9cbadb9bb822df3adfffad8de40997fc562;hp=190d4fc27394feec77570944dcfa588779690dc8;hpb=8ca3547f6c4d6d01a76d3ce642a0c1bf884c4c2a;p=pintos-anon diff --git a/src/threads/paging.c b/src/threads/paging.c index 190d4fc..587813c 100644 --- a/src/threads/paging.c +++ b/src/threads/paging.c @@ -8,33 +8,26 @@ static uint32_t *base_page_dir; -static uint32_t -make_pde (uint32_t *pagetab) -{ - ASSERT (PGOFS ((uintptr_t) pagetab) == 0); - - return vtop (pagetab) | PG_U | PG_P | PG_W; +static uint32_t make_pde (uint32_t *pt) { + ASSERT (pg_ofs (pt) == 0); + return vtop (pt) | PG_U | PG_P | PG_W; } -static uint32_t -make_pte (uint32_t *page, bool writable) -{ - uint32_t entry; +static uint32_t make_kernel_pte (uint32_t *page, bool writable) { + ASSERT (pg_ofs (page) == 0); + return vtop (page) | PG_P | (writable ? PG_W : 0); +} - ASSERT (PGOFS ((uintptr_t) page) == 0); - - entry = vtop (page) | PG_U | PG_P; - if (writable) - entry |= PG_W; - return entry; +static uint32_t make_user_pte (uint32_t *page, bool writable) { + return make_kernel_pte (page, writable) | PG_U; } static uint32_t * -pde_get_pagetab (uint32_t pde) +pde_get_pt (uint32_t pde) { ASSERT (pde & PG_P); - return ptov (PGROUNDDOWN (pde)); + return ptov (pde & ~PGMASK); } static void * @@ -42,7 +35,7 @@ pte_get_page (uint32_t pte) { ASSERT (pte & PG_P); - return ptov (PGROUNDDOWN (pte)); + return ptov (pte & ~PGMASK); } /* Populates the base page directory and page table with the @@ -50,9 +43,9 @@ pte_get_page (uint32_t pte) new page directory. At the time this function is called, the active page table - only maps the first 4 MB of RAM, so it should not try to use - extravagant amounts of memory. Fortunately, there is no need - to do so. */ + (set up by loader.S) only maps the first 4 MB of RAM, so we + should not try to use extravagant amounts of memory. + Fortunately, there is no need to do so. */ void paging_init (void) { @@ -63,10 +56,10 @@ paging_init (void) pt = NULL; for (page = 0; page < ram_pages; page++) { - uintptr_t paddr = page * NBPG; + uintptr_t paddr = page * PGSIZE; void *vaddr = ptov (paddr); - size_t pde_idx = PDENO ((uintptr_t) vaddr); - size_t pte_idx = PTENO ((uintptr_t) vaddr); + size_t pde_idx = pd_no (vaddr); + size_t pte_idx = pt_no (vaddr); if (pd[pde_idx] == 0) { @@ -74,18 +67,17 @@ paging_init (void) pd[pde_idx] = make_pde (pt); } - pt[pte_idx] = make_pte (vaddr, true); + pt[pte_idx] = make_kernel_pte (vaddr, true); } - /* Set the page table. */ - asm volatile ("movl %0,%%cr3" :: "r" (vtop (pd))); + pagedir_activate (pd); } uint32_t * pagedir_create (void) { uint32_t *pd = palloc_get (0); - memcpy (pd, base_page_dir, NBPG); + memcpy (pd, base_page_dir, PGSIZE); return pd; } @@ -101,49 +93,49 @@ pagedir_destroy (uint32_t *pd) } static uint32_t * -lookup_page (uint32_t *pagedir, void *upage, bool create) +lookup_page (uint32_t *pd, void *upage, bool create) { - uint32_t *pagetab; + uint32_t *pt; uint32_t *pde; - ASSERT (pagedir != NULL); - ASSERT (PGOFS ((uintptr_t) upage) == 0); - ASSERT ((uintptr_t) upage < PHYS_BASE); + ASSERT (pd != NULL); + ASSERT (pg_ofs (upage) == 0); + ASSERT (upage < PHYS_BASE); /* Check for a page table for UPAGE. If one is missing, create one if requested. */ - pde = pagedir + PDENO ((uint32_t) upage); + pde = pd + pd_no (upage); if (*pde == 0) { if (create) { - pagetab = palloc_get (PAL_ZERO); - if (pagetab == NULL) + pt = palloc_get (PAL_ZERO); + if (pt == NULL) return NULL; - *pde = make_pde (pagetab); + *pde = make_pde (pt); } else return NULL; } /* Return the page table entry. */ - pagetab = pde_get_pagetab (*pde); - return &pagetab[PTENO ((uintptr_t) upage)]; + pt = pde_get_pt (*pde); + return &pt[pt_no (upage)]; } bool -pagedir_set_page (uint32_t *pagedir, void *upage, void *kpage, +pagedir_set_page (uint32_t *pd, void *upage, void *kpage, bool writable) { uint32_t *pte; - ASSERT (PGOFS ((uintptr_t) kpage) == 0); + ASSERT (pg_ofs (kpage) == 0); - pte = lookup_page (pagedir, upage, true); + pte = lookup_page (pd, upage, true); if (pte != NULL) { - *pte = make_pte (kpage, writable); + *pte = make_user_pte (kpage, writable); return true; } else @@ -151,16 +143,16 @@ pagedir_set_page (uint32_t *pagedir, void *upage, void *kpage, } void * -pagedir_get_page (uint32_t *pagedir, void *upage) +pagedir_get_page (uint32_t *pd, void *upage) { - uint32_t *pte = lookup_page (pagedir, upage, false); + uint32_t *pte = lookup_page (pd, upage, false); return pte != NULL && *pte != 0 ? pte_get_page (*pte) : NULL; } void -pagedir_clear_page (uint32_t *pagedir, void *upage) +pagedir_clear_page (uint32_t *pd, void *upage) { - uint32_t *pte = lookup_page (pagedir, upage, false); + uint32_t *pte = lookup_page (pd, upage, false); if (pte != NULL) *pte = 0; } @@ -168,7 +160,7 @@ pagedir_clear_page (uint32_t *pagedir, void *upage) static uint32_t * scan_pt (uint32_t *pt, unsigned pde_idx, unsigned pte_idx, void **upage) { - for (; pte_idx < NBPG / sizeof *pt; pte_idx++) + for (; pte_idx < PGSIZE / sizeof *pt; pte_idx++) { uint32_t pte = pt[pte_idx]; @@ -177,8 +169,7 @@ scan_pt (uint32_t *pt, unsigned pde_idx, unsigned pte_idx, void **upage) void *kpage = pte_get_page (pte); if (kpage != NULL) { - *upage = (void *) ((pde_idx << PDSHIFT) - | (pte_idx << PGSHIFT)); + *upage = (void *) ((pde_idx << PDSHIFT) | (pte_idx << PTSHIFT)); return kpage; } } @@ -190,13 +181,13 @@ scan_pt (uint32_t *pt, unsigned pde_idx, unsigned pte_idx, void **upage) static void * scan_pd (uint32_t *pd, unsigned pde_idx, void **upage) { - for (; pde_idx < PDENO (PHYS_BASE); pde_idx++) + for (; pde_idx < pd_no (PHYS_BASE); pde_idx++) { uint32_t pde = pd[pde_idx]; if (pde != 0) { - void *kpage = scan_pt (pde_get_pagetab (pde), pde_idx, 0, upage); + void *kpage = scan_pt (pde_get_pt (pde), pde_idx, 0, upage); if (kpage != NULL) return kpage; } @@ -206,9 +197,9 @@ scan_pd (uint32_t *pd, unsigned pde_idx, void **upage) } void * -pagedir_first (uint32_t *pagedir, void **upage) +pagedir_first (uint32_t *pd, void **upage) { - return scan_pd (pagedir, 0, upage); + return scan_pd (pd, 0, upage); } void * @@ -217,13 +208,17 @@ pagedir_next (uint32_t *pd, void **upage) unsigned pde_idx, pte_idx; void *kpage; - pde_idx = PDENO (*upage); - pte_idx = PTENO (*upage); - kpage = scan_pt (pde_get_pagetab (pd[pde_idx]), + pde_idx = pd_no (*upage); + pte_idx = pt_no (*upage); + kpage = scan_pt (pde_get_pt (pd[pde_idx]), pde_idx, pte_idx + 1, upage); if (kpage == NULL) kpage = scan_pd (pd, pde_idx + 1, upage); return kpage; } -void pagedir_activate (uint32_t *pagedir); +void +pagedir_activate (uint32_t *pd) +{ + asm volatile ("movl %0,%%cr3" :: "r" (vtop (pd))); +}