Skip to content

Commit 9143106

Browse files
committed
Add Smdbltrp
1 parent 0ba0b2b commit 9143106

File tree

3 files changed

+39
-11
lines changed

3 files changed

+39
-11
lines changed

riscv/csrs.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@ bool mstatus_csr_t::unlogged_write(const reg_t val) noexcept {
505505
| (has_page ? MSTATUS_TVM : 0)
506506
| (has_gva ? MSTATUS_GVA : 0)
507507
| (has_mpv ? MSTATUS_MPV : 0)
508+
| (proc->extension_enabled(EXT_SMDBLTRP) ? MSTATUS_MDT : 0)
508509
| (proc->extension_enabled(EXT_ZICFILP) ? (MSTATUS_SPELP | MSTATUS_MPELP) : 0)
509510
;
510511

@@ -525,6 +526,7 @@ reg_t mstatus_csr_t::compute_mstatus_initial_value() const noexcept {
525526
| (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)
526527
| (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)
527528
| (proc->get_mmu()->is_target_big_endian() ? big_endian_bits : 0)
529+
| (proc->extension_enabled(EXT_SMDBLTRP) ? MSTATUS_MDT : 0)
528530
| 0; // initial value for mstatus
529531
}
530532

@@ -1295,6 +1297,8 @@ dcsr_csr_t::dcsr_csr_t(processor_t* const proc, const reg_t addr):
12951297
halt(false),
12961298
v(false),
12971299
cause(0),
1300+
ext_cause(0),
1301+
cetrig(0),
12981302
pelp(elp_t::NO_LP_EXPECTED) {
12991303
}
13001304

@@ -1315,6 +1319,9 @@ reg_t dcsr_csr_t::read() const noexcept {
13151319
result = set_field(result, DCSR_STOPCOUNT, 0);
13161320
result = set_field(result, DCSR_STOPTIME, 0);
13171321
result = set_field(result, DCSR_CAUSE, cause);
1322+
result = set_field(result, DCSR_EXTCAUSE, ext_cause);
1323+
if (proc->extension_enabled(EXT_SMDBLTRP))
1324+
result = set_field(result, DCSR_CETRIG, cetrig);
13181325
result = set_field(result, DCSR_STEP, step);
13191326
result = set_field(result, DCSR_PRV, prv);
13201327
result = set_field(result, CSR_DCSR_V, v);
@@ -1335,12 +1342,14 @@ bool dcsr_csr_t::unlogged_write(const reg_t val) noexcept {
13351342
v = proc->extension_enabled('H') ? get_field(val, CSR_DCSR_V) : false;
13361343
pelp = proc->extension_enabled(EXT_ZICFILP) ?
13371344
static_cast<elp_t>(get_field(val, DCSR_PELP)) : elp_t::NO_LP_EXPECTED;
1345+
cetrig = proc->extension_enabled(EXT_SMDBLTRP) ? get_field(val, DCSR_CETRIG) : false;
13381346
return true;
13391347
}
13401348

1341-
void dcsr_csr_t::update_fields(const uint8_t cause, const reg_t prv,
1349+
void dcsr_csr_t::update_fields(const uint8_t cause, uint8_t ext_cause, const reg_t prv,
13421350
const bool v, const elp_t pelp) noexcept {
13431351
this->cause = cause;
1352+
this->ext_cause = ext_cause;
13441353
this->prv = prv;
13451354
this->v = v;
13461355
this->pelp = pelp;

riscv/execute.cc

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -213,12 +213,12 @@ void processor_t::step(size_t n)
213213
{
214214
if (!state.debug_mode) {
215215
if (halt_request == HR_REGULAR) {
216-
enter_debug_mode(DCSR_CAUSE_DEBUGINT);
216+
enter_debug_mode(DCSR_CAUSE_DEBUGINT, 0);
217217
} else if (halt_request == HR_GROUP) {
218-
enter_debug_mode(DCSR_CAUSE_GROUP);
218+
enter_debug_mode(DCSR_CAUSE_GROUP, 0);
219219
} // !!!The halt bit in DCSR is deprecated.
220220
else if (state.dcsr->halt) {
221-
enter_debug_mode(DCSR_CAUSE_HALT);
221+
enter_debug_mode(DCSR_CAUSE_HALT, 0);
222222
}
223223
}
224224

@@ -257,7 +257,7 @@ void processor_t::step(size_t n)
257257
if (unlikely(!state.serialized && state.single_step == state.STEP_STEPPED)) {
258258
state.single_step = state.STEP_NONE;
259259
if (!state.debug_mode) {
260-
enter_debug_mode(DCSR_CAUSE_STEP);
260+
enter_debug_mode(DCSR_CAUSE_STEP, 0);
261261
// enter_debug_mode changed state.pc, so we can't just continue.
262262
break;
263263
}
@@ -311,13 +311,23 @@ void processor_t::step(size_t n)
311311
take_trap(t, pc);
312312
n = instret;
313313

314+
// If critical error then enter debug mode critical error trigger enabled
315+
if (state.critical_error) {
316+
if (state.dcsr->read() & DCSR_CETRIG) {
317+
enter_debug_mode(DCSR_CAUSE_EXTCAUSE, DCSR_EXTCAUSE_CRITERR);
318+
} else {
319+
// Handling of critical error is implementation defined
320+
// For now just enter debug mode
321+
enter_debug_mode(DCSR_CAUSE_HALT, 0);
322+
}
323+
}
314324
// Trigger action takes priority over single step
315325
auto match = TM.detect_trap_match(t);
316326
if (match.has_value())
317327
take_trigger_action(match->action, 0, state.pc, 0);
318328
else if (unlikely(state.single_step == state.STEP_STEPPED)) {
319329
state.single_step = state.STEP_NONE;
320-
enter_debug_mode(DCSR_CAUSE_STEP);
330+
enter_debug_mode(DCSR_CAUSE_STEP, 0);
321331
}
322332
}
323333
catch (triggers::matched_t& t)
@@ -330,7 +340,7 @@ void processor_t::step(size_t n)
330340
}
331341
catch(trap_debug_mode&)
332342
{
333-
enter_debug_mode(DCSR_CAUSE_SWBP);
343+
enter_debug_mode(DCSR_CAUSE_SWBP, 0);
334344
}
335345
catch (wait_for_interrupt_t &t)
336346
{

riscv/processor.cc

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,7 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
549549
last_inst_flen = 0;
550550

551551
elp = elp_t::NO_LP_EXPECTED;
552+
critical_error = false;
552553
}
553554

554555
void processor_t::set_debug(bool value)
@@ -767,11 +768,11 @@ const char* processor_t::get_privilege_string()
767768
abort();
768769
}
769770

770-
void processor_t::enter_debug_mode(uint8_t cause)
771+
void processor_t::enter_debug_mode(uint8_t cause, uint8_t extcause)
771772
{
772773
const bool has_zicfilp = extension_enabled(EXT_ZICFILP);
773774
state.debug_mode = true;
774-
state.dcsr->update_fields(cause, state.prv, state.v, state.elp);
775+
state.dcsr->update_fields(cause, extcause, state.prv, state.v, state.elp);
775776
state.elp = elp_t::NO_LP_EXPECTED;
776777
set_privilege(PRV_M, false);
777778
state.dpc->write(state.pc);
@@ -875,6 +876,15 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
875876
// Handle the trap in M-mode
876877
const reg_t vector = (state.mtvec->read() & 1) && interrupt ? 4 * bit : 0;
877878
const reg_t trap_handler_address = (state.mtvec->read() & ~(reg_t)1) + vector;
879+
reg_t s = state.mstatus->read();
880+
if ( extension_enabled(EXT_SMDBLTRP)) {
881+
if (get_field(s, MSTATUS_MDT)) {
882+
// Critical error - Double trap in M-mode
883+
state.critical_error = 1;
884+
return;
885+
}
886+
s = set_field(s, MSTATUS_MDT, 1);
887+
}
878888
// RNMI exception vector is implementation-defined. Since we don't model
879889
// RNMI sources, the feature isn't very useful, so pick an invalid address.
880890
const reg_t rnmi_trap_handler_address = 0;
@@ -886,7 +896,6 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
886896
state.mtval2->write(t.get_tval2());
887897
state.mtinst->write(t.get_tinst());
888898

889-
reg_t s = state.mstatus->read();
890899
s = set_field(s, MSTATUS_MPIE, get_field(s, MSTATUS_MIE));
891900
s = set_field(s, MSTATUS_MPP, state.prv);
892901
s = set_field(s, MSTATUS_MIE, 0);
@@ -912,7 +921,7 @@ void processor_t::take_trigger_action(triggers::action_t action, reg_t breakpoin
912921

913922
switch (action) {
914923
case triggers::ACTION_DEBUG_MODE:
915-
enter_debug_mode(DCSR_CAUSE_HWBP);
924+
enter_debug_mode(DCSR_CAUSE_HWBP, 0);
916925
break;
917926
case triggers::ACTION_DEBUG_EXCEPTION: {
918927
trap_breakpoint trap(virt, breakpoint_tval);

0 commit comments

Comments
 (0)