From f18e73a522578e5672e7e5bcfa96d85fd4f6ce28 Mon Sep 17 00:00:00 2001 From: yangminz Date: Sun, 11 Jul 2021 12:13:36 +0800 Subject: [PATCH] reversed mapping for physical page --- src/hardware/cpu/mmu.c | 46 ++++++++++++++++++++++++++++++++++++++++++ src/headers/memory.h | 19 +++++++++++++++-- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/hardware/cpu/mmu.c b/src/hardware/cpu/mmu.c index d701903..550ee96 100644 --- a/src/hardware/cpu/mmu.c +++ b/src/hardware/cpu/mmu.c @@ -18,6 +18,7 @@ #include "headers/address.h" static uint64_t page_walk(uint64_t vaddr_value); +static void page_fault_handler(pte4_t *pte, address_t vaddr); // consider this function va2pa as functional uint64_t va2pa(uint64_t vaddr) @@ -73,6 +74,12 @@ static uint64_t page_walk(uint64_t vaddr_value) #ifdef DBUEG_PAGE_WALK printf("page walk level 4: pt[%lx].present == 0\n\tmalloc new page table for it\n", vaddr.vpn1); #endif + // search paddr from main memory and disk + // TODO: raise exception 14 (page fault) here + // switch privilege from user mode (ring 3) to kernel mode (ring 0) + page_fault_handler(&pt[vaddr.vpn4], vaddr); + + /* pte4_t *pt = malloc(page_table_size); memset(pt, 0, page_table_size); @@ -83,6 +90,7 @@ static uint64_t page_walk(uint64_t vaddr_value) // TODO: page fault here // map the physical page and the virtual page exit(0); + */ } } else @@ -138,4 +146,42 @@ static uint64_t page_walk(uint64_t vaddr_value) // map the physical page and the virtual page exit(0); } +} + +static void page_fault_handler(pte4_t *pte, address_t vaddr) +{ + // select one victim physical page to swap to disk + + // this is the selected ppn for vaddr + int ppn = -1; + + // 1. try to request one free physical page from DRAM + // kernel's responsibility + for (int i = 0; i < MAX_NUM_PHYSICAL_PAGE; ++ i) + { + if (page_map[i].pte4->present == 0) + { + printf("PageFault: use free ppn %d\n", i); + + // found i as free ppn + ppn = i; + + page_map[ppn].allocated = 1; // allocate for vaddr + page_map[ppn].dirty = 0; // allocated as clean + page_map[ppn].time = 0; // most recently used physical page + page_map[ppn].pte4 = pte; + + pte->present = 1; + pte->ppn = ppn; + pte->dirty = 0; + + return; + } + } + + // 2. no free physical page: select one clean page (LRU) and overwrite + // in this case, there is no DRAM - DISK transaction + + // 3. no free nor clean physical page: select one LRU victim + // write back (swap out) the DIRTY victim to disk } \ No newline at end of file diff --git a/src/headers/memory.h b/src/headers/memory.h index 45ff6f0..c55031c 100644 --- a/src/headers/memory.h +++ b/src/headers/memory.h @@ -25,6 +25,7 @@ // total 16 physical memory #define PHYSICAL_MEMORY_SPACE (65536) #define MAX_INDEX_PHYSICAL_PAGE (15) +#define MAX_NUM_PHYSICAL_PAGE (16) // 1 + MAX_INDEX_PHYSICAL_PAGE #define PAGE_TABLE_ENTRY_NUM (512) @@ -77,7 +78,7 @@ typedef union struct { - uint64_t present : 1; + uint64_t present : 1; // present = 1 uint64_t readonly : 1; uint64_t usermode : 1; uint64_t writethough : 1; @@ -94,11 +95,25 @@ typedef union struct { - uint64_t _present : 1; + uint64_t _present : 1; // present = 0 uint64_t swap_id : 63; // disk address }; } pte4_t; // PT +// physical page descriptor +typedef struct +{ + int allocated; + int dirty; + int time; // LRU cache + + pte4_t *pte4; // the reversed mapping: from PPN to page table entry +} pd_t; + +// for each pagable (swappable) physical page +// create one reversed mapping +pd_t page_map[MAX_NUM_PHYSICAL_PAGE]; + /*======================================*/ /* memory R/W */ /*======================================*/