mmu.c 1.8 KB
Newer Older
P
Parallels 已提交
1 2
#include "nemu.h"
#include "memory/memory.h"
Z
Zihao Yu 已提交
3
#include "csr.h"
P
Parallels 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

/* the 32bit Page Table Entry(second level page table) data structure */
typedef union PageTableEntry {
  struct {
    uint32_t valid  : 1;
    uint32_t read   : 1;
    uint32_t write  : 1;
    uint32_t exec   : 1;
    uint32_t user   : 1;
    uint32_t global : 1;
    uint32_t access : 1;
    uint32_t dirty  : 1;
    uint32_t rsw    : 2;
    uint32_t ppn    :22;
  };
  uint32_t val;
} PTE;

typedef union {
  struct {
    uint32_t pf_off		:12;
    uint32_t pt_idx		:10;
    uint32_t pdir_idx	:10;
  };
  uint32_t addr;
} PageAddr;

static paddr_t page_walk(vaddr_t vaddr, bool is_write) {
  PageAddr *addr = (void *)&vaddr;
Z
Zihao Yu 已提交
33
  paddr_t pdir_base = satp->ppn << 12;
P
Parallels 已提交
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

  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);
  }

  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);
  }

  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 pte.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);
}

Z
Zihao Yu 已提交
62
word_t isa_vaddr_read(vaddr_t addr, int len) {
Z
Zihao Yu 已提交
63
  paddr_t paddr = (satp->mode ? page_translate(addr, false) : addr);
P
Parallels 已提交
64 65 66
  return paddr_read(paddr, len);
}

Z
Zihao Yu 已提交
67
void isa_vaddr_write(vaddr_t addr, word_t data, int len) {
Z
Zihao Yu 已提交
68
  paddr_t paddr = (satp->mode ? page_translate(addr, true) : addr);
P
Parallels 已提交
69 70
  paddr_write(paddr, data, len);
}