checkpoint before refactor
This commit is contained in:
@ -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 {
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user