Skip to content

Commit

Permalink
feat(dbltrp): support full dbltrp extension in spike
Browse files Browse the repository at this point in the history
  • Loading branch information
lewislzh committed Nov 13, 2024
1 parent 37bfda6 commit 366757c
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 8 deletions.
3 changes: 2 additions & 1 deletion difftest/difftest-def.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@
"_zfa_zfh_zvfh" \
"_svinval_sscofpmf" \
"_svpbmt" \
"_zicbom_zicboz"
"_zicbom_zicboz" \
"_smrnmi_smdbltrp_ssdbltrp" \

#define CONFIG_MEMORY_SIZE (16 * 1024 * 1024 * 1024UL)
#define CONFIG_FLASH_BASE 0x10000000UL
Expand Down
8 changes: 8 additions & 0 deletions difftest/difftest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,10 @@ void DifftestRef::raise_intr(uint64_t no) {
}
}

bool DifftestRef::raise_critical_error() {
return state->critical_error;
}

void DifftestRef::update_mip(void *non_reg_interrupt_pending) {
auto n = (DifftestNonRegInterruptPending *) non_reg_interrupt_pending;
state->mip->backdoor_write_with_mask(MIP_MTIP, n->platform_irp_mtip ? MIP_MTIP : 0);
Expand Down Expand Up @@ -568,6 +572,10 @@ void difftest_raise_intr(uint64_t NO) {
ref->raise_intr(NO);
}

bool difftest_raise_critical_error() {
return ref->raise_critical_error();
}

void isa_reg_display() {
ref->display();
}
Expand Down
1 change: 1 addition & 0 deletions difftest/difftest.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ class DifftestRef {
void debug_memcpy_from_dut(reg_t dest, void* src, size_t n);
int store_commit(uint64_t *addr, uint64_t *data, uint8_t *mask);
void raise_intr(uint64_t no);
bool raise_critical_error();
void display();
void update_mip(void *non_reg_interrupt_pending);
void update_dynamic_config(void* config) {
Expand Down
2 changes: 1 addition & 1 deletion riscv/csr_init.cc
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa)
if (proc->extension_enabled_const(EXT_SMRNMI)) {
add_csr(CSR_MNSCRATCH, std::make_shared<basic_csr_t>(proc, CSR_MNSCRATCH, 0));
add_csr(CSR_MNEPC, mnepc = std::make_shared<epc_csr_t>(proc, CSR_MNEPC));
add_csr(CSR_MNCAUSE, std::make_shared<const_csr_t>(proc, CSR_MNCAUSE, (reg_t)1 << (xlen - 1)));
add_csr(CSR_MNCAUSE, mncause = std::make_shared<cause_csr_t>(proc, CSR_MNCAUSE));
add_csr(CSR_MNSTATUS, mnstatus = std::make_shared<mnstatus_csr_t>(proc, CSR_MNSTATUS));
}

Expand Down
19 changes: 18 additions & 1 deletion riscv/csrs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -598,18 +598,31 @@ reg_t mstatus_csr_t::compute_mstatus_initial_value() const noexcept {
| (proc->extension_enabled_const('U') && (proc->get_const_xlen() != 32) ? set_field((reg_t)0, MSTATUS_UXL, xlen_to_uxl(proc->get_const_xlen())) : 0)
| (proc->extension_enabled_const('S') && (proc->get_const_xlen() != 32) ? set_field((reg_t)0, MSTATUS_SXL, xlen_to_uxl(proc->get_const_xlen())) : 0)
| (proc->get_mmu()->is_target_big_endian() ? big_endian_bits : 0)
#if defined(DIFFTEST) && defined(CPU_XIANGSHAN)
| 0
#else
| (proc->extension_enabled(EXT_SMDBLTRP) ? MSTATUS_MDT : 0)
#endif
| 0; // initial value for mstatus
}

// implement class mnstatus_csr_t
mnstatus_csr_t::mnstatus_csr_t(processor_t* const proc, const reg_t addr):
basic_csr_t(proc, addr, 0) {
#if defined(DIFFTEST) && defined(CPU_XIANGSHAN)
basic_csr_t(proc, addr, MNSTATUS_NMIE)
#else
basic_csr_t(proc, addr, 0)
#endif
{
}

bool mnstatus_csr_t::unlogged_write(const reg_t val) noexcept {
// NMIE can be set but not cleared
#if defined(DIFFTEST) && defined(CPU_XIANGSHAN)
const reg_t mask = MNSTATUS_NMIE
#else
const reg_t mask = (~read() & MNSTATUS_NMIE)
#endif
| (proc->extension_enabled('H') ? MNSTATUS_MNPV : 0)
| MNSTATUS_MNPP;

Expand All @@ -620,6 +633,10 @@ bool mnstatus_csr_t::unlogged_write(const reg_t val) noexcept {
return basic_csr_t::unlogged_write(new_mnstatus);
}

bool mnstatus_csr_t::bare_write(const reg_t val) noexcept {
return basic_csr_t::unlogged_write(val);
}

// implement class rv32_low_csr_t
rv32_low_csr_t::rv32_low_csr_t(processor_t* const proc, const reg_t addr, csr_t_p orig):
csr_t(proc, addr),
Expand Down
3 changes: 3 additions & 0 deletions riscv/csrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ typedef std::shared_ptr<mstatus_csr_t> mstatus_csr_t_p;
class mnstatus_csr_t final: public basic_csr_t {
public:
mnstatus_csr_t(processor_t* const proc, const reg_t addr);
bool bare_write(const reg_t val) noexcept;
protected:
virtual bool unlogged_write(const reg_t val) noexcept override;
};
Expand Down Expand Up @@ -551,6 +552,8 @@ class wide_counter_csr_t: public csr_t {

typedef std::shared_ptr<wide_counter_csr_t> wide_counter_csr_t_p;

typedef std::shared_ptr<mnstatus_csr_t> mnstatus_csr_t_p;

class time_counter_csr_t: public csr_t {
public:
time_counter_csr_t(processor_t* const proc, const reg_t addr);
Expand Down
29 changes: 25 additions & 4 deletions riscv/processor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
// An unexpected trap - a trap when SDT is 1 - traps to M-mode
if ((state.prv <= PRV_S && bit < max_xlen) &&
(((vsdeleg >> bit) & 1) || ((hsdeleg >> bit) & 1))) {
reg_t s = curr_virt ? state.nonvirtual_sstatus->read() : state.sstatus->read();
reg_t s = state.sstatus->read();
supv_double_trap = get_field(s, MSTATUS_SDT);
if (supv_double_trap)
vsdeleg = hsdeleg = 0;
Expand Down Expand Up @@ -534,17 +534,38 @@ void processor_t::take_trap(trap_t& t, reg_t epc)

reg_t s = state.mstatus->read();
if ( extension_enabled(EXT_SMDBLTRP)) {
if (get_field(s, MSTATUS_MDT) || !nmie) {
bool m_double_trap = get_field(s, MSTATUS_MDT);
if (!nmie) {
// Critical error - Double trap in M-mode or trap when nmie is 0
// RNMI is not modeled else double trap in M-mode would trap to
// RNMI handler instead of leading to a critical error
state.critical_error = 1;
return;
}
s = set_field(s, MSTATUS_MDT, 1);
if (m_double_trap) {
state.pc = trap_handler_address;
reg_t mnstatus_val = state.mnstatus->read();
mnstatus_val = set_field(mnstatus_val, MNSTATUS_MNPP, state.prv);
mnstatus_val = set_field(mnstatus_val, MNSTATUS_MNPV, curr_virt);
mnstatus_val = set_field(mnstatus_val, MNSTATUS_NMIE, 0);
state.mnstatus->bare_write(mnstatus_val);
#ifdef CPU_ROCKET_CHIP
state.mnepc->write(encode_vaddr(epc));
#else
state.mnepc->write(epc);
#endif
state.mncause->write(t.cause());
set_privilege(PRV_M, false);
return;
} else {
s = set_field(s, MSTATUS_MDT, 1);
}
}

#if defined(DIFFTEST) && defined(CPU_XIANGSHAN)
state.pc = trap_handler_address;
#else
state.pc = !nmie ? rnmi_trap_handler_address : trap_handler_address;
#endif
#ifdef CPU_ROCKET_CHIP
state.mepc->write(encode_vaddr(epc));
#else
Expand Down
3 changes: 2 additions & 1 deletion riscv/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,9 @@ struct state_t
csr_t_p mideleg;
csr_t_p mcounteren;
csr_t_p mevent[N_HPMCOUNTERS];
csr_t_p mnstatus;
mnstatus_csr_t_p mnstatus;
csr_t_p mnepc;
csr_t_p mncause;
csr_t_p scounteren;
csr_t_p sepc;
csr_t_p stval;
Expand Down

0 comments on commit 366757c

Please sign in to comment.