提交 3746f5fd 编写于 作者: Z Zihao Yu

Merge branch 'intr' into 'rv64'

Intr

See merge request projectn/nemu!10
#ifndef __CSR_H__
#define __CSR_H__
#include "common.h"
#define CSRS(f) \
f(mstatus , 0x300) f(mtvec , 0x305) f(mepc , 0x341) f(mcause , 0x342) \
f(satp , 0x180)
#define CSR_STRUCT_START(name) \
typedef union { \
struct {
#define CSR_STRUCT_END(name) \
}; \
word_t val; \
} concat(name, _t);
CSR_STRUCT_START(mstatus)
uint64_t uie : 1;
uint64_t sie : 1;
uint64_t pad0: 1;
uint64_t mie : 1;
uint64_t upie: 1;
uint64_t spie: 1;
uint64_t pad1: 1;
uint64_t mpie: 1;
uint64_t spp : 1;
uint64_t pad2: 2;
uint64_t mpp : 2;
CSR_STRUCT_END(mstatus)
CSR_STRUCT_START(satp)
uint64_t ppn :44;
uint64_t asid:16;
uint64_t mode: 4;
CSR_STRUCT_END(satp)
CSR_STRUCT_START(mtvec)
CSR_STRUCT_END(mtvec)
CSR_STRUCT_START(mcause)
CSR_STRUCT_END(mcause)
CSR_STRUCT_START(mepc)
CSR_STRUCT_END(mepc)
#define CSRS_DECL(name, val) extern concat(name, _t)* const name;
MAP(CSRS, CSRS_DECL)
word_t* csr_decode(uint32_t addr);
#endif
#include "cpu/exec.h"
#include "../csr.h"
static inline rtlreg_t* csr_decode(uint32_t csr) {
static inline word_t* csr_decode_wrapper(uint32_t addr) {
difftest_skip_dut(1, 3);
switch (csr) {
case 0x180: return &cpu.satp.val;
case 0x300: return &cpu.mstatus.val;
case 0x305: return &cpu.mtvec;
case 0x341: return &cpu.mepc;
case 0x342: return &cpu.mcause;
default: panic("unimplemented CSR 0x%x", csr);
}
return NULL;
return csr_decode(addr);
}
make_EHelper(csrrw) {
rtlreg_t *csr = csr_decode(id_src2->val);
rtlreg_t *csr = csr_decode_wrapper(id_src2->val);
rtl_sr(id_dest->reg, csr, 8);
rtl_mv(csr, &id_src->val);
......@@ -24,7 +16,7 @@ make_EHelper(csrrw) {
}
make_EHelper(csrrs) {
rtlreg_t *csr = csr_decode(id_src2->val);
rtlreg_t *csr = csr_decode_wrapper(id_src2->val);
rtl_sr(id_dest->reg, csr, 8);
rtl_or(csr, csr, &id_src->val);
......@@ -42,9 +34,9 @@ make_EHelper(priv) {
print_asm("ecall");
break;
case 0x302:
cpu.mstatus.mie = cpu.mstatus.mpie;
cpu.mstatus.mpie = 1;
rtl_li(&s0, cpu.mepc);
mstatus->mie = mstatus->mpie;
mstatus->mpie = 1;
rtl_li(&s0, mepc->val);
rtl_jr(&s0);
print_asm("mret");
break;
......
......@@ -15,33 +15,6 @@ typedef struct {
} gpr[32];
vaddr_t pc;
vaddr_t mtvec;
vaddr_t mcause;
vaddr_t mepc;
union {
struct {
uint64_t uie : 1;
uint64_t sie : 1;
uint64_t pad0: 1;
uint64_t mie : 1;
uint64_t upie: 1;
uint64_t spie: 1;
uint64_t pad1: 1;
uint64_t mpie: 1;
uint64_t spp : 1;
uint64_t pad2: 2;
uint64_t mpp : 2;
};
uint64_t val;
} mstatus;
union {
struct {
uint64_t ppn :44;
uint64_t asid:16;
uint64_t mode: 4;
};
uint64_t val;
} satp;
bool INTR;
} CPU_state;
......
#include "nemu.h"
#include "csr.h"
// this is not consistent with uint8_t
// but it is ok since we do not access the array directly
......@@ -13,7 +14,7 @@ const long isa_default_img_size = sizeof(isa_default_img);
void init_isa(void) {
cpu.gpr[0]._64 = 0;
cpu.pc = PC_START;
cpu.mstatus.val = 0x000c0100;
mstatus->val = 0x000c0100;
register_pmem(0x80000000u);
}
#include "rtl/rtl.h"
#include "csr.h"
void raise_intr(uint32_t NO, vaddr_t epc) {
/* TODO: Trigger an interrupt/exception with ``NO''.
* That is, use ``NO'' to index the IDT.
*/
cpu.mcause = NO;
cpu.mepc = epc;
cpu.mstatus.mpie = cpu.mstatus.mie;
cpu.mstatus.mie = 0;
rtl_li(&s0, cpu.mtvec);
mcause->val = NO;
mepc->val = epc;
mstatus->mpie = mstatus->mie;
mstatus->mie = 0;
rtl_li(&s0, mtvec->val);
rtl_jr(&s0);
}
bool isa_query_intr(void) {
if (cpu.INTR && cpu.mstatus.mie) {
if (cpu.INTR && mstatus->mie) {
cpu.INTR = false;
raise_intr(0x80000005, cpu.pc);
// machine external interrupt
raise_intr(0x8000000b, cpu.pc);
return true;
}
return false;
......
#include "nemu.h"
#include "memory/memory.h"
#include "csr.h"
/* the 32bit Page Table Entry(second level page table) data structure */
typedef union PageTableEntry {
......@@ -29,7 +30,7 @@ typedef union {
static paddr_t page_walk(vaddr_t vaddr, bool is_write) {
PageAddr *addr = (void *)&vaddr;
paddr_t pdir_base = cpu.satp.ppn << 12;
paddr_t pdir_base = satp->ppn << 12;
PTE pde;
pde.val = paddr_read(pdir_base + addr->pdir_idx * 4, 4);
......@@ -59,11 +60,11 @@ static inline paddr_t page_translate(vaddr_t addr, bool is_write) {
}
word_t isa_vaddr_read(vaddr_t addr, int len) {
paddr_t paddr = (cpu.satp.mode ? page_translate(addr, false) : addr);
paddr_t paddr = (satp->mode ? 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 = (cpu.satp.mode ? page_translate(addr, true) : addr);
paddr_t paddr = (satp->mode ? page_translate(addr, true) : addr);
paddr_write(paddr, data, len);
}
#include "nemu.h"
#include "csr.h"
const char *regsl[] = {
"$0", "ra", "sp", "gp", "tp", "t0", "t1", "t2",
......@@ -34,3 +35,20 @@ rtlreg_t isa_reg_str2val(const char *s, bool *success) {
*success = false;
return 0;
}
static word_t csr_array[4096] = {};
#define CSRS_DEF(name, val) \
concat(name, _t)* const name = (void *)&csr_array[val];
MAP(CSRS, CSRS_DEF)
#define CSRS_EXIST(name, val) [val] = 1,
static bool csr_exist[4096] = {
MAP(CSRS, CSRS_EXIST)
};
word_t* csr_decode(uint32_t addr) {
assert(addr < 4096);
Assert(csr_exist[addr], "unimplemented CSR 0x%x at pc = " FMT_WORD, addr, cpu.pc);
return &csr_array[addr];
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册