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

riscv64,csr: correctly implement sstatus and sie

* They are really the subset of mstatus and mie. We should refactor the
  access of CSR to support this.
上级 c79ac84f
......@@ -120,7 +120,8 @@ CSR_STRUCT_END(sscratch)
#define CSRS_DECL(name, addr) extern concat(name, _t)* const name;
MAP(CSRS, CSRS_DECL)
word_t* csr_decode(uint32_t addr);
void csr_read(rtlreg_t *dest, uint32_t addr);
void csr_write(uint32_t addr, rtlreg_t *src);
enum { MODE_U = 0, MODE_S, MODE_H, MODE_M };
void change_mode(uint8_t m);
......
#include "cpu/exec.h"
#include "../csr.h"
static inline word_t* csr_decode_wrapper(uint32_t addr) {
difftest_skip_dut(1, 3);
return csr_decode(addr);
}
make_EHelper(csrrw) {
rtlreg_t *csr = csr_decode_wrapper(id_src2->val);
rtl_sr(id_dest->reg, csr, 8);
rtl_mv(csr, &id_src->val);
uint32_t addr = id_src2->val;
csr_read(&s0, addr);
rtl_sr(id_dest->reg, &s0, 8);
csr_write(addr, &id_src->val);
print_asm_template3("csrrw");
}
make_EHelper(csrrs) {
rtlreg_t *csr = csr_decode_wrapper(id_src2->val);
rtl_sr(id_dest->reg, csr, 8);
rtl_or(csr, csr, &id_src->val);
uint32_t addr = id_src2->val;
csr_read(&s0, addr);
rtl_sr(id_dest->reg, &s0, 8);
if (id_src->reg != 0) {
rtl_or(&s0, &s0, &id_src->val);
csr_write(addr, &s0);
}
print_asm_template3("csrrs");
}
make_EHelper(csrrc) {
rtlreg_t *csr = csr_decode_wrapper(id_src2->val);
rtl_sr(id_dest->reg, csr, 8);
rtl_not(&s0, &id_src->val);
rtl_and(csr, csr, &s0);
uint32_t addr = id_src2->val;
csr_read(&s0, addr);
rtl_sr(id_dest->reg, &s0, 8);
if (id_src->reg != 0) {
rtl_not(&s1, &id_src->val);
rtl_and(&s0, &s0, &s1);
csr_write(addr, &s0);
}
print_asm_template3("csrrc");
}
......
#include "nemu.h"
#include "monitor/diff-test.h"
#include "csr.h"
const char *regsl[] = {
......@@ -47,12 +48,40 @@ static bool csr_exist[4096] = {
MAP(CSRS, CSRS_EXIST)
};
word_t* csr_decode(uint32_t addr) {
static inline 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];
}
#define SSTATUS_WMASK ((1 << 19) | (1 << 18) | (1 << 8) | (1 << 5) | (1 << 1))
#define SSTATUS_RMASK (SSTATUS_WMASK | (0xf << 13) | (1ull << 63) | (3ull << 32))
#define SIE_MASK (((3 << 8) | (3 << 4) | 3) & mideleg->val)
void csr_read(rtlreg_t *dest, uint32_t addr) {
word_t *src = csr_decode(addr);
difftest_skip_dut(1, 3);
if (src == (void *)sstatus) {
*dest = mstatus->val & SSTATUS_RMASK;
} else if (src == (void *)sie) {
*dest = mie->val & SIE_MASK;
} else {
*dest = *src;
}
}
void csr_write(uint32_t addr, rtlreg_t *src) {
word_t *dest = csr_decode(addr);
if (dest == (void *)sstatus) {
mstatus->val = (mstatus->val & ~SSTATUS_WMASK) | (*src & SSTATUS_WMASK);
} else if (dest == (void *)sie) {
mie->val = (mie->val & ~SIE_MASK) | (*src & SIE_MASK);
} else {
*dest = *src;
}
}
void change_mode(uint8_t m) {
assert(m < 4 && m != MODE_H);
cpu.mode = m;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册