checkpoint before refactor

This commit is contained in:
2021-03-06 07:17:42 +00:00
parent f7cec99fa6
commit dae8acb8a3
6 changed files with 55 additions and 29 deletions

View File

@ -50,6 +50,7 @@
#include <sstream>
#include <type_traits>
#include <unordered_map>
#include <functional>
#include <util/bit_field.h>
#include <util/ities.h>
#include <util/sparse_array.h>
@ -344,7 +345,15 @@ public:
};
iss::instrumentation_if *get_instrumentation_if() override { return &instr_if; }
void setMemReadCb(std::function<iss::status(phys_addr_t, unsigned, uint8_t* const)> const& memReadCb) {
mem_read_cb = memReadCb;
}
void setMemWriteCb(std::function<iss::status(phys_addr_t, unsigned, const uint8_t* const)> const& memWriteCb) {
mem_write_cb = memWriteCb;
}
protected:
struct riscv_instrumentation_if : public iss::instrumentation_if {
@ -407,6 +416,8 @@ private:
iss::status read_hartid(unsigned addr, reg_t &val);
reg_t mhartid_reg{0xF};
std::function<iss::status(phys_addr_t, unsigned, uint8_t *const)>mem_read_cb;
std::function<iss::status(phys_addr_t, unsigned, const uint8_t *const)> mem_write_cb;
protected:
void check_interrupt();
@ -653,7 +664,7 @@ iss::status riscv_hart_m_p<BASE>::write(const address_type type, const access_ty
template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_csr(unsigned addr, reg_t &val) {
if (addr >= csr.size()) return iss::Err;
auto req_priv_lvl = (addr >> 8) & 0x3;
if (this->reg.machine_state < req_priv_lvl) throw illegal_instruction_fault(this->fault_data);
if (this->reg.PRIV < req_priv_lvl) throw illegal_instruction_fault(this->fault_data);
auto it = csr_rd_cb.find(addr);
if (it == csr_rd_cb.end()) {
val = csr[addr & csr.page_addr_mask];
@ -667,7 +678,7 @@ template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_csr(unsigned add
template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_csr(unsigned addr, reg_t val) {
if (addr >= csr.size()) return iss::Err;
auto req_priv_lvl = (addr >> 8) & 0x3;
if (this->reg.machine_state < req_priv_lvl)
if (this->reg.PRIV < req_priv_lvl)
throw illegal_instruction_fault(this->fault_data);
if((addr&0xc00)==0xc00)
throw illegal_instruction_fault(this->fault_data);
@ -749,6 +760,7 @@ template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_ip(unsigned add
template <typename BASE>
iss::status riscv_hart_m_p<BASE>::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) {
if ((paddr.val + length) > mem.size()) return iss::Err;
if(mem_read_cb) return mem_read_cb(paddr, length, data);
switch (paddr.val) {
case 0x0200BFF8: { // CLINT base, mtime reg
if (sizeof(reg_t) < length) return iss::Err;
@ -774,6 +786,7 @@ iss::status riscv_hart_m_p<BASE>::read_mem(phys_addr_t paddr, unsigned length, u
template <typename BASE>
iss::status riscv_hart_m_p<BASE>::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) {
if ((paddr.val + length) > mem.size()) return iss::Err;
if(mem_write_cb) return mem_write_cb(paddr, length, data);
switch (paddr.val) {
case 0x10013000: // UART0 base, TXFIFO reg
case 0x10023000: // UART1 base, TXFIFO reg
@ -861,7 +874,7 @@ template <typename BASE> void riscv_hart_m_p<BASE>::check_interrupt() {
auto ena_irq = csr[mip] & csr[mie];
bool mie = state.mstatus.MIE;
auto m_enabled = this->reg.machine_state < PRIV_M || (this->reg.machine_state == PRIV_M && mie);
auto m_enabled = this->reg.PRIV < PRIV_M || (this->reg.PRIV == PRIV_M && mie);
auto enabled_interrupts = m_enabled ? ena_irq & ~ideleg : 0;
if (enabled_interrupts != 0) {
@ -906,7 +919,7 @@ template <typename BASE> uint64_t riscv_hart_m_p<BASE>::enter_trap(uint64_t flag
this->reg.NEXT_PC = ivec & ~0x1UL;
if ((ivec & 0x1) == 1 && trap_id != 0) this->reg.NEXT_PC += 4 * cause;
// reset trap state
this->reg.machine_state = PRIV_M;
this->reg.PRIV = PRIV_M;
this->reg.trap_state = 0;
std::array<char, 32> buffer;
sprintf(buffer.data(), "0x%016lx", addr);
@ -918,14 +931,14 @@ template <typename BASE> uint64_t riscv_hart_m_p<BASE>::enter_trap(uint64_t flag
}
template <typename BASE> uint64_t riscv_hart_m_p<BASE>::leave_trap(uint64_t flags) {
auto cur_priv = this->reg.machine_state;
auto cur_priv = this->reg.PRIV;
auto inst_priv = flags & 0x3;
auto status = state.mstatus;
// pop the relevant lower-privilege interrupt enable and privilege mode stack
// clear respective yIE
if (inst_priv == PRIV_M) {
this->reg.machine_state = state.mstatus.MPP;
this->reg.PRIV = state.mstatus.MPP;
state.mstatus.MPP = 0; // clear mpp to U mode
state.mstatus.MIE = state.mstatus.MPIE;
} else {

View File

@ -78,7 +78,8 @@ template <> struct traits<tgf_c> {
{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,8,32,32,64}};
static constexpr std::array<const uint32_t, 38> reg_byte_offsets{
{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,137,141,145}};
{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,
128,132,136,137,141,145}};
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
@ -222,6 +223,7 @@ struct tgf_c: public arch_if {
inline uint32_t get_last_branch() { return reg.last_branch; }
protected:
#pragma pack(push, 1)
struct TGF_C_regs {
uint32_t X0 = 0;
uint32_t X1 = 0;
@ -258,10 +260,11 @@ protected:
uint32_t PC = 0;
uint32_t NEXT_PC = 0;
uint8_t PRIV = 0;
uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0;
uint32_t trap_state = 0, pending_trap = 0;
uint64_t icount = 0;
uint32_t last_branch;
} reg;
#pragma pack(pop)
std::array<address_type, 4> addr_mode;
uint64_t interrupt_sim=0;