[cosim] Implement double fault detection

This adds an implementation of the double_fault_seen and sync_exc_seen
fields in cpuctrlsts.
This commit is contained in:
Greg Chadwick 2022-09-09 18:52:55 +01:00 committed by Greg Chadwick
parent e38f534ac2
commit 4effc487e0
2 changed files with 44 additions and 3 deletions

View file

@ -233,6 +233,9 @@ bool SpikeCosim::step(uint32_t write_reg, uint32_t write_reg_data,
if (!check_sync_trap(write_reg, pc, initial_spike_pc)) {
return false;
}
handle_cpuctrl_exception_entry();
// This is all the checking possible when consider a
// synchronously-trapping instruction that never retired.
return true;
@ -242,9 +245,13 @@ bool SpikeCosim::step(uint32_t write_reg, uint32_t write_reg_data,
// We reached a retired instruction, so check spike and the dut behaved
// consistently.
if (!sync_trap && pc_is_mret(pc) && nmi_mode) {
// Do handling for recoverable NMI
leave_nmi_mode();
if (!sync_trap && pc_is_mret(pc)) {
change_cpuctrlsts_sync_exc_seen(false);
if (nmi_mode) {
// Do handling for recoverable NMI
leave_nmi_mode();
}
}
if (pending_iside_error) {
@ -440,6 +447,36 @@ void SpikeCosim::leave_nmi_mode() {
#endif
}
void SpikeCosim::handle_cpuctrl_exception_entry() {
bool old_sync_exc_seen = change_cpuctrlsts_sync_exc_seen(true);
if (old_sync_exc_seen) {
set_cpuctrlsts_double_fault_seen();
}
}
bool SpikeCosim::change_cpuctrlsts_sync_exc_seen(bool flag) {
bool old_flag = false;
uint32_t cpuctrlsts = processor->get_csr(CSR_CPUCTRLSTS);
// If sync_exc_seen (bit 6) is already set update old_flag to match
if (cpuctrlsts & 0x40) {
old_flag = true;
}
cpuctrlsts = (cpuctrlsts & 0x1bf) | (flag ? 0x40 : 0);
processor->put_csr(CSR_CPUCTRLSTS, cpuctrlsts);
return old_flag;
}
void SpikeCosim::set_cpuctrlsts_double_fault_seen() {
uint32_t cpuctrlsts = processor->get_csr(CSR_CPUCTRLSTS);
// Set double_fault_seen (bit 7)
cpuctrlsts = (cpuctrlsts & 0x17f) | 0x80;
processor->put_csr(CSR_CPUCTRLSTS, cpuctrlsts);
}
void SpikeCosim::initial_proc_setup(uint32_t start_pc, uint32_t start_mtvec,
uint32_t mhpm_counter_num) {
processor->get_state()->pc = start_pc;

View file

@ -69,6 +69,10 @@ class SpikeCosim : public simif_t, public Cosim {
void leave_nmi_mode();
bool change_cpuctrlsts_sync_exc_seen(bool flag);
void set_cpuctrlsts_double_fault_seen();
void handle_cpuctrl_exception_entry();
void initial_proc_setup(uint32_t start_pc, uint32_t start_mtvec,
uint32_t mhpm_counter_num);