projects
/
pintos-anon
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Redo makefiles.
[pintos-anon]
/
src
/
threads
/
paging.c
diff --git
a/src/threads/paging.c
b/src/threads/paging.c
index 9fd568caf894107e02b09edda8dff05d9d060d9e..ca5f4b49ac0e56ea4c1bad738230f26f9c83e69e 100644
(file)
--- a/
src/threads/paging.c
+++ b/
src/threads/paging.c
@@
-2,35
+2,28
@@
#include <stdbool.h>
#include <stddef.h>
#include "init.h"
#include <stdbool.h>
#include <stddef.h>
#include "init.h"
-#include "lib.h"
#include "mmu.h"
#include "palloc.h"
#include "mmu.h"
#include "palloc.h"
+#include "lib/lib.h"
static uint32_t *base_page_dir;
static uint32_t *base_page_dir;
-static uint32_t
-make_pde (uint32_t *pagetab)
-{
- ASSERT (pg_ofs (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);
ASSERT (pg_ofs (page) == 0);
-
- entry = vtop (page) | PG_U | PG_P;
- if (writable)
- entry |= PG_W;
- return
entry
;
+ return vtop (page) | PG_P | (writable ? PG_W : 0);
+}
+
+static uint32_t make_user_pte (uint32_t *page, bool writable) {
+ return
make_kernel_pte (page, writable) | PG_U
;
}
static uint32_t *
}
static uint32_t *
-pde_get_p
agetab
(uint32_t pde)
+pde_get_p
t
(uint32_t pde)
{
ASSERT (pde & PG_P);
{
ASSERT (pde & PG_P);
@@
-50,9
+43,9
@@
pte_get_page (uint32_t pte)
new page directory.
At the time this function is called, the active page table
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 us
e
- 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 w
e
+ should not try to use extravagant amounts of memory.
+
Fortunately, there is no need
to do so. */
void
paging_init (void)
{
void
paging_init (void)
{
@@
-74,11
+67,10
@@
paging_init (void)
pd[pde_idx] = make_pde (pt);
}
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 *
}
uint32_t *
@@
-93,57
+85,73
@@
void
pagedir_destroy (uint32_t *pd)
{
void *kpage, *upage;
pagedir_destroy (uint32_t *pd)
{
void *kpage, *upage;
+ unsigned pde_idx;
+ /* Destroy user pages. */
for (kpage = pagedir_first (pd, &upage); kpage != NULL;
kpage = pagedir_next (pd, &upage))
palloc_free (kpage);
for (kpage = pagedir_first (pd, &upage); kpage != NULL;
kpage = pagedir_next (pd, &upage))
palloc_free (kpage);
+
+ /* Destroy page table pages. */
+ for (pde_idx = 0; pde_idx < pd_no (PHYS_BASE); pde_idx++)
+ {
+ uint32_t pde = pd[pde_idx];
+
+ if (pde != 0)
+ {
+ uint32_t *pt = pde_get_pt (pde);
+ palloc_free (pt);
+ }
+ }
+
+ /* Destroy page directory. */
palloc_free (pd);
}
static uint32_t *
palloc_free (pd);
}
static uint32_t *
-lookup_page (uint32_t *p
agedir
, void *upage, bool create)
+lookup_page (uint32_t *p
d
, void *upage, bool create)
{
{
- uint32_t *p
agetab
;
+ uint32_t *p
t
;
uint32_t *pde;
uint32_t *pde;
- ASSERT (p
agedir
!= NULL);
+ ASSERT (p
d
!= 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. */
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 = p
agedir
+ pd_no (upage);
+ pde = p
d
+ pd_no (upage);
if (*pde == 0)
{
if (create)
{
if (*pde == 0)
{
if (create)
{
- p
agetab
= palloc_get (PAL_ZERO);
- if (p
agetab
== NULL)
+ p
t
= palloc_get (PAL_ZERO);
+ if (p
t
== NULL)
return NULL;
return NULL;
- *pde = make_pde (p
agetab
);
+ *pde = make_pde (p
t
);
}
else
return NULL;
}
/* Return the page table entry. */
}
else
return NULL;
}
/* Return the page table entry. */
- p
agetab = pde_get_pagetab
(*pde);
- return &p
agetab
[pt_no (upage)];
+ p
t = pde_get_pt
(*pde);
+ return &p
t
[pt_no (upage)];
}
bool
}
bool
-pagedir_set_page (uint32_t *p
agedir
, void *upage, void *kpage,
+pagedir_set_page (uint32_t *p
d
, void *upage, void *kpage,
bool writable)
{
uint32_t *pte;
ASSERT (pg_ofs (kpage) == 0);
bool writable)
{
uint32_t *pte;
ASSERT (pg_ofs (kpage) == 0);
- pte = lookup_page (p
agedir
, upage, true);
+ pte = lookup_page (p
d
, upage, true);
if (pte != NULL)
{
if (pte != NULL)
{
- *pte = make_pte (kpage, writable);
+ *pte = make_
user_
pte (kpage, writable);
return true;
}
else
return true;
}
else
@@
-151,16
+159,16
@@
pagedir_set_page (uint32_t *pagedir, void *upage, void *kpage,
}
void *
}
void *
-pagedir_get_page (uint32_t *p
agedir
, void *upage)
+pagedir_get_page (uint32_t *p
d
, void *upage)
{
{
- uint32_t *pte = lookup_page (p
agedir
, upage, false);
+ uint32_t *pte = lookup_page (p
d
, upage, false);
return pte != NULL && *pte != 0 ? pte_get_page (*pte) : NULL;
}
void
return pte != NULL && *pte != 0 ? pte_get_page (*pte) : NULL;
}
void
-pagedir_clear_page (uint32_t *p
agedir
, void *upage)
+pagedir_clear_page (uint32_t *p
d
, void *upage)
{
{
- uint32_t *pte = lookup_page (p
agedir
, upage, false);
+ uint32_t *pte = lookup_page (p
d
, upage, false);
if (pte != NULL)
*pte = 0;
}
if (pte != NULL)
*pte = 0;
}
@@
-195,7
+203,7
@@
scan_pd (uint32_t *pd, unsigned pde_idx, void **upage)
if (pde != 0)
{
if (pde != 0)
{
- void *kpage = scan_pt (pde_get_p
agetab
(pde), pde_idx, 0, upage);
+ void *kpage = scan_pt (pde_get_p
t
(pde), pde_idx, 0, upage);
if (kpage != NULL)
return kpage;
}
if (kpage != NULL)
return kpage;
}
@@
-205,9
+213,9
@@
scan_pd (uint32_t *pd, unsigned pde_idx, void **upage)
}
void *
}
void *
-pagedir_first (uint32_t *p
agedir
, void **upage)
+pagedir_first (uint32_t *p
d
, void **upage)
{
{
- return scan_pd (p
agedir
, 0, upage);
+ return scan_pd (p
d
, 0, upage);
}
void *
}
void *
@@
-218,11
+226,17
@@
pagedir_next (uint32_t *pd, void **upage)
pde_idx = pd_no (*upage);
pte_idx = pt_no (*upage);
pde_idx = pd_no (*upage);
pte_idx = pt_no (*upage);
- kpage = scan_pt (pde_get_p
agetab
(pd[pde_idx]),
+ kpage = scan_pt (pde_get_p
t
(pd[pde_idx]),
pde_idx, pte_idx + 1, upage);
if (kpage == NULL)
kpage = scan_pd (pd, pde_idx + 1, upage);
return kpage;
}
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)
+{
+ if (pd == NULL)
+ pd = base_page_dir;
+ asm volatile ("movl %0,%%cr3" :: "r" (vtop (pd)));
+}