diff --git a/src/hardware/cpu/mmu.c b/src/hardware/cpu/mmu.c index e93424b..9e7f4a9 100644 --- a/src/hardware/cpu/mmu.c +++ b/src/hardware/cpu/mmu.c @@ -21,4 +21,18 @@ uint64_t va2pa(uint64_t vaddr) { // use page table as va2pa +} + +// input - virtual address +// output - physical address +static uint64_t page_walk(uint64_t vaddr_value) +{ + address_t vaddr = { + .vaddr_value = vaddr_value + }; + + // CR3 register's value is malloced on the heap of the simulator + pte123_t *pgd = (pte123_t *)cpu_controls.cr3; + + pte123_t *pmd = (pte123_t *)(pgd[vaddr.vpn1].paddr); } \ No newline at end of file diff --git a/src/hardware/cpu/sram.c b/src/hardware/cpu/sram.c index 525c800..a986d58 100644 --- a/src/hardware/cpu/sram.c +++ b/src/hardware/cpu/sram.c @@ -73,7 +73,7 @@ uint8_t sram_cache_read(uint64_t paddr_value) .paddr_value = paddr_value, }; - sram_cacheset_t *set = &cache.sets[paddr.CI]; + sram_cacheset_t *set = &cache.sets[paddr.ci]; // update LRU time sram_cacheline_t *victim = NULL; @@ -106,7 +106,7 @@ uint8_t sram_cache_read(uint64_t paddr_value) { sram_cacheline_t *line = &(set->lines[i]); - if (line->state != CACHE_LINE_INVALID && line->tag == paddr.CT) + if (line->state != CACHE_LINE_INVALID && line->tag == paddr.ct) { #ifdef CACHE_SIMULATION_VERIFICATION sprintf(trace_buf, "hit"); @@ -118,7 +118,7 @@ uint8_t sram_cache_read(uint64_t paddr_value) line->time = 0; // find the byte - return line->block[paddr.CO]; + return line->block[paddr.co]; } } @@ -142,9 +142,9 @@ uint8_t sram_cache_read(uint64_t paddr_value) invalid->time = 0; // update tag - invalid->tag = paddr.CT; + invalid->tag = paddr.ct; - return invalid->block[paddr.CO]; + return invalid->block[paddr.co]; } // no free cache line, use LRU policy @@ -182,9 +182,9 @@ uint8_t sram_cache_read(uint64_t paddr_value) victim->time = 0; // update tag - victim->tag = paddr.CT; + victim->tag = paddr.ct; - return victim->block[paddr.CO]; + return victim->block[paddr.co]; } void sram_cache_write(uint64_t paddr_value, uint8_t data) @@ -193,7 +193,7 @@ void sram_cache_write(uint64_t paddr_value, uint8_t data) .paddr_value = paddr_value, }; - sram_cacheset_t *set = &(cache.sets[paddr.CI]); + sram_cacheset_t *set = &(cache.sets[paddr.ci]); // update LRU time sram_cacheline_t *victim = NULL; @@ -225,7 +225,7 @@ void sram_cache_write(uint64_t paddr_value, uint8_t data) { sram_cacheline_t *line = &(set->lines[i]); - if (line->state != CACHE_LINE_INVALID && line->tag == paddr.CT) + if (line->state != CACHE_LINE_INVALID && line->tag == paddr.ct) { #ifdef CACHE_SIMULATION_VERIFICATION // cache hit @@ -242,7 +242,7 @@ void sram_cache_write(uint64_t paddr_value, uint8_t data) line->time = 0; // find the byte - line->block[paddr.CO] = data; + line->block[paddr.co] = data; // update state line->state = CACHE_LINE_DIRTY; @@ -276,10 +276,10 @@ void sram_cache_write(uint64_t paddr_value, uint8_t data) invalid->time = 0; // update tag - invalid->tag = paddr.CT; + invalid->tag = paddr.ct; // write data - invalid->block[paddr.CO] = data; + invalid->block[paddr.co] = data; return; } @@ -322,9 +322,9 @@ void sram_cache_write(uint64_t paddr_value, uint8_t data) victim->time = 0; // update tag - victim->tag = paddr.CT; + victim->tag = paddr.ct; - victim->block[paddr.CO] = data; + victim->block[paddr.co] = data; } #ifdef CACHE_SIMULATION_VERIFICATION diff --git a/src/headers/address.h b/src/headers/address.h index 4c68e1c..4fdd6b7 100644 --- a/src/headers/address.h +++ b/src/headers/address.h @@ -56,8 +56,8 @@ typedef union uint64_t paddr_value : PHYSICAL_ADDRESS_LENGTH; struct { - uint64_t PPO : PHYSICAL_PAGE_OFFSET_LENGTH; - uint64_t PPN : PHYSICAL_PAGE_NUMBER_LENGTH; + uint64_t ppo : PHYSICAL_PAGE_OFFSET_LENGTH; + uint64_t ppn : PHYSICAL_PAGE_NUMBER_LENGTH; }; }; }; @@ -70,11 +70,11 @@ typedef union uint64_t vaddr_value : VIRTUAL_ADDRESS_LENGTH; struct { - uint64_t VPO : VIRTUAL_PAGE_OFFSET_LENGTH; - uint64_t VPN3 : VIRTUAL_PAGE_NUMBER_LENGTH; - uint64_t VPN2 : VIRTUAL_PAGE_NUMBER_LENGTH; - uint64_t VPN1 : VIRTUAL_PAGE_NUMBER_LENGTH; - uint64_t VPN0 : VIRTUAL_PAGE_NUMBER_LENGTH; + uint64_t vpo : VIRTUAL_PAGE_OFFSET_LENGTH; + uint64_t vpn4 : VIRTUAL_PAGE_NUMBER_LENGTH; + uint64_t vpn3 : VIRTUAL_PAGE_NUMBER_LENGTH; + uint64_t vpn2 : VIRTUAL_PAGE_NUMBER_LENGTH; + uint64_t vpn1 : VIRTUAL_PAGE_NUMBER_LENGTH; }; }; }; @@ -82,9 +82,9 @@ typedef union // sram cache: 52 struct { - uint64_t CO : SRAM_CACHE_OFFSET_LENGTH; - uint64_t CI : SRAM_CACHE_INDEX_LENGTH; - uint64_t CT : SRAM_CACHE_TAG_LENGTH; + uint64_t co : SRAM_CACHE_OFFSET_LENGTH; + uint64_t ci : SRAM_CACHE_INDEX_LENGTH; + uint64_t ct : SRAM_CACHE_TAG_LENGTH; }; } address_t; diff --git a/src/headers/cpu.h b/src/headers/cpu.h index eded3da..9df0e48 100644 --- a/src/headers/cpu.h +++ b/src/headers/cpu.h @@ -252,6 +252,18 @@ typedef union } cpu_pc_t; cpu_pc_t cpu_pc; +// control registers +typedef struct +{ + uint64_t cr0; + uint64_t cr1; + uint64_t cr2; + uint64_t cr3; // should be a 40-bit PPN for PGD in DRAM + // but we are using 48-bit virutal address on simulator's heap + // (by malloc()) +} cpu_cr_t; +cpu_cr_t cpu_controls; + // move to common.h to be shared by linker // #define MAX_INSTRUCTION_CHAR 64 #define NUM_INSTRTYPE 14 diff --git a/src/headers/memory.h b/src/headers/memory.h index e5bdbb2..276a0de 100644 --- a/src/headers/memory.h +++ b/src/headers/memory.h @@ -28,8 +28,75 @@ // physical memory // 16 physical memory pages +// used only for user process uint8_t pm[PHYSICAL_MEMORY_SPACE]; +// page table entry struct + +// 8 bytes = 64 bits +typedef union +{ + uint64_t pte_value; + + struct + { + uint64_t present : 1; + uint64_t readonly : 1; + uint64_t usermode : 1; + uint64_t writethough : 1; + uint64_t cachedisabled : 1; + uint64_t reference : 1; + uint64_t unused6 : 1; + uint64_t smallpage : 1; + uint64_t global : 1; + uint64_t unused9_11 : 3; + /* + uint64_t paddr : 40; + uint64_t unused52_62 : 10; + + for malloc, a virtual address on heap is 48 bits + for real world, a physical page number is 40 bits + */ + uint64_t paddr : 50; // virtual address (48 bits) on simulator's heap + uint64_t xdisabled : 1; + }; + + struct + { + uint64_t _present : 1; + uint64_t swap_id : 63; // disk address + }; +} pte123_t; // PGD, PUD, PMD + +// 8 bytes = 64 bits +typedef union +{ + uint64_t pte_value; + + struct + { + uint64_t present : 1; + uint64_t readonly : 1; + uint64_t usermode : 1; + uint64_t writethough : 1; + uint64_t cachedisabled : 1; + uint64_t reference : 1; + uint64_t dirty : 1; // dirty bit - 1: dirty; 0: clean + uint64_t zero7 : 1; + uint64_t global : 1; + uint64_t unused9_11 : 3; + uint64_t ppn : 40; + uint64_t unused52_62 : 10; + uint64_t xdisabled : 1; + }; + + struct + { + uint64_t _present : 1; + uint64_t swap_id : 63; // disk address + }; +} pte4_t; // PT + /*======================================*/ /* memory R/W */ /*======================================*/