diff --git a/src/userprog/pagedir.c b/src/userprog/pagedir.c index ef5bbff..f222c18 100644 --- a/src/userprog/pagedir.c +++ b/src/userprog/pagedir.c @@ -53,7 +53,7 @@ pagedir_destroy (uint32_t *pd) 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 * +uint32_t * lookup_page (uint32_t *pd, const void *vaddr, bool create) { uint32_t *pt, *pde; diff --git a/src/userprog/pagedir.h b/src/userprog/pagedir.h index 06e45d2..b9ec549 100644 --- a/src/userprog/pagedir.h +++ b/src/userprog/pagedir.h @@ -6,6 +6,7 @@ uint32_t *pagedir_create (void); void pagedir_destroy (uint32_t *pd); +uint32_t *lookup_page (uint32_t *pd, const void *vaddr, bool create); bool pagedir_set_page (uint32_t *pd, void *upage, void *kpage, bool rw); void *pagedir_get_page (uint32_t *pd, const void *upage); void pagedir_clear_page (uint32_t *pd, void *upage); diff --git a/src/vm/page.c b/src/vm/page.c index 8ebc71c..01eeda7 100644 --- a/src/vm/page.c +++ b/src/vm/page.c @@ -1,4 +1,9 @@ #include "page.h" +#include "userprog/pagedir.h" +#include "threads/pte.h" + +#define SWAP_FLAG_BIT 9 +#define ADDR_START_BIT 12 /* Updates the 'owner' thread's page table entry for virtual address 'upage' to have a present bit of 0 and stores the specified swap slot value in the @@ -6,6 +11,17 @@ void page_set_swap (struct thread *owner, void *upage, size_t swap_slot) { + uint32_t *pte = lookup_page (owner->pagedir, upage, false); + *pte &= ~PTE_P; //clears the first bit (present bit) to be 0 + + //ASSERT (swap_slot < (1 << 20)); //not sure if this is needed + + //shifts the swap slot addr to take up bits 31 to 12 + //uses bitwise & to make sure it does not affect flags + //then applies it to pte + *pte |= (1 << SWAP_FLAG_BIT); // sets the 9th bit + uint32_t swap_slot_bits = (swap_slot << ADDR_START_BIT) & PTE_ADDR; + *pte = (*pte & PTE_FLAGS) | swap_slot_bits; } @@ -15,6 +31,13 @@ page_set_swap (struct thread *owner, void *upage, size_t swap_slot) size_t page_get_swap (struct thread *owner, void *upage) { + uint32_t *pte = lookup_page (owner->pagedir, upage, false); + //these should always be checked and true before using this func + ASSERT ((*pte & PTE_P) == 0); + ASSERT ((*pte & (1 << 9)) == 1); + + //masks address bits and returns truncated value + return ((*pte & PTE_ADDR) >> 12); }