提交 5beb8194 编写于 作者: Z Zihao Yu

Merge branch 'riscv64-sv39' into 'rv64'

Riscv64 sv39

See merge request projectn/nemu!17
......@@ -2,7 +2,7 @@
#include "device/alarm.h"
#include "device/map.h"
#define CLINT_MMIO 0x2000000
#define CLINT_MMIO 0xa2000000
#define CLINT_MTIMECMP (0x4000 / sizeof(clint_base[0]))
#define CLINT_MTIME (0xBFF8 / sizeof(clint_base[0]))
......
......@@ -2,7 +2,6 @@
#include "memory/memory.h"
#include "csr.h"
/* the 32bit Page Table Entry(second level page table) data structure */
typedef union PageTableEntry {
struct {
uint32_t valid : 1;
......@@ -14,57 +13,71 @@ typedef union PageTableEntry {
uint32_t access : 1;
uint32_t dirty : 1;
uint32_t rsw : 2;
uint32_t ppn :22;
uint64_t ppn :44;
uint32_t pad :10;
};
uint32_t val;
uint64_t val;
} PTE;
typedef union {
struct {
uint32_t pf_off :12;
uint32_t pt_idx :10;
uint32_t pdir_idx :10;
uint64_t pf_off :12;
uint64_t vpn0 : 9;
uint64_t vpn1 : 9;
uint64_t vpn2 : 9;
};
uint32_t addr;
uint64_t addr;
} PageAddr;
static paddr_t page_walk(vaddr_t vaddr, bool is_write) {
// Sv39 page walk
static word_t page_walk(vaddr_t vaddr, bool is_write) {
PageAddr *addr = (void *)&vaddr;
paddr_t pdir_base = satp->ppn << 12;
word_t pdir_base = satp->ppn << 12;
PTE pde;
pde.val = paddr_read(pdir_base + addr->pdir_idx * 4, 4);
if (!pde.valid) {
panic("pc = %lx, vaddr = %lx, pdir_base = %x, pde = %x", cpu.pc, vaddr, pdir_base, pde.val);
PTE pte2;
pte2.val = paddr_read(pdir_base + addr->vpn2 * 8, 8);
if (!pte2.valid) {
panic("pc = " FMT_WORD ", vaddr = " FMT_WORD ", pdir_base = " FMT_WORD ", pte2 = " FMT_WORD,
cpu.pc, vaddr, pdir_base, pte2.val);
}
paddr_t pt_base = pde.ppn << 12;
PTE pte;
pte.val = paddr_read(pt_base + addr->pt_idx * 4, 4);
if (!pte.valid) {
panic("pc = %lx, vaddr = %lx, pt_base = %x, pte = %x", cpu.pc, vaddr, pt_base, pte.val);
word_t pt_base1 = pte2.ppn << 12;
PTE pte1;
pte1.val = paddr_read(pt_base1 + addr->vpn1 * 8, 8);
if (!pte1.valid) {
panic("pc = " FMT_WORD ", vaddr = " FMT_WORD ", pt_base1 = " FMT_WORD ", pte1 = " FMT_WORD,
cpu.pc, vaddr, pt_base1, pte1.val);
}
if (!pte.access || (pte.dirty == 0 && is_write)) {
pte.access = 1;
pte.dirty |= is_write;
paddr_write(pt_base + addr->pt_idx * 4, pte.val, 4);
word_t pt_base0 = pte1.ppn << 12;
PTE pte0;
pte0.val = paddr_read(pt_base0 + addr->vpn0 * 8, 8);
if (!pte0.valid) {
panic("pc = " FMT_WORD ", vaddr = " FMT_WORD ", pt_base0 = " FMT_WORD ", pte0 = " FMT_WORD,
cpu.pc, vaddr, pt_base0, pte0.val);
}
return pte.ppn << 12;
//if (!pte.access || (pte.dirty == 0 && is_write)) {
// pte.access = 1;
// pte.dirty |= is_write;
// paddr_write(pt_base + addr->pt_idx * 4, pte.val, 4);
//}
return pte0.ppn << 12;
}
static inline paddr_t page_translate(vaddr_t addr, bool is_write) {
printf("There's page translate\n");
return page_walk(addr, is_write) | (addr & PAGE_MASK);
}
word_t isa_vaddr_read(vaddr_t addr, int len) {
paddr_t paddr = (satp->mode ? page_translate(addr, false) : addr);
assert(satp->mode == 0 || satp->mode == 4);
paddr_t paddr = (satp->mode == 4 ? page_translate(addr, false) : addr);
return paddr_read(paddr, len);
}
void isa_vaddr_write(vaddr_t addr, word_t data, int len) {
paddr_t paddr = (satp->mode ? page_translate(addr, true) : addr);
assert(satp->mode == 0 || satp->mode == 4);
paddr_t paddr = (satp->mode == 4 ? page_translate(addr, true) : addr);
paddr_write(paddr, data, len);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册