Skip to content

Commit

Permalink
page table entry and page walk
Browse files Browse the repository at this point in the history
  • Loading branch information
yangminz committed Jun 20, 2021
1 parent 516a86d commit 6c640bc
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 24 deletions.
14 changes: 14 additions & 0 deletions src/hardware/cpu/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
28 changes: 14 additions & 14 deletions src/hardware/cpu/sram.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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");
Expand All @@ -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];
}
}

Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
Expand Down
20 changes: 10 additions & 10 deletions src/headers/address.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
};
};
Expand All @@ -70,21 +70,21 @@ 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;
};
};
};

// 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;

Expand Down
12 changes: 12 additions & 0 deletions src/headers/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
67 changes: 67 additions & 0 deletions src/headers/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
/*======================================*/
Expand Down

0 comments on commit 6c640bc

Please sign in to comment.