mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-20 03:47:15 -04:00
[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:
parent
e38f534ac2
commit
4effc487e0
2 changed files with 44 additions and 3 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue