@@ -463,7 +463,7 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
463463 // An unexpected trap - a trap when SDT is 1 - traps to M-mode
464464 if ((state.prv <= PRV_S && bit < max_xlen) &&
465465 (((vsdeleg >> bit) & 1 ) || ((hsdeleg >> bit) & 1 ))) {
466- reg_t s = curr_virt ? state. nonvirtual_sstatus -> read () : state.sstatus ->read ();
466+ reg_t s = state.sstatus ->read ();
467467 supv_double_trap = get_field (s, MSTATUS_SDT);
468468 if (supv_double_trap)
469469 vsdeleg = hsdeleg = 0 ;
@@ -534,17 +534,38 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
534534
535535 reg_t s = state.mstatus ->read ();
536536 if ( extension_enabled (EXT_SMDBLTRP)) {
537- if (get_field (s, MSTATUS_MDT) || !nmie) {
537+ bool m_double_trap = get_field (s, MSTATUS_MDT);
538+ if (!nmie) {
538539 // Critical error - Double trap in M-mode or trap when nmie is 0
539540 // RNMI is not modeled else double trap in M-mode would trap to
540541 // RNMI handler instead of leading to a critical error
541542 state.critical_error = 1 ;
542543 return ;
543544 }
544- s = set_field (s, MSTATUS_MDT, 1 );
545+ if (m_double_trap) {
546+ state.pc = trap_handler_address;
547+ reg_t mnstatus_val = state.mnstatus ->read ();
548+ mnstatus_val = set_field (mnstatus_val, MNSTATUS_MNPP, state.prv );
549+ mnstatus_val = set_field (mnstatus_val, MNSTATUS_MNPV, curr_virt);
550+ mnstatus_val = set_field (mnstatus_val, MNSTATUS_NMIE, 0 );
551+ state.mnstatus ->bare_write (mnstatus_val);
552+ #ifdef CPU_ROCKET_CHIP
553+ state.mnepc ->write (encode_vaddr (epc));
554+ #else
555+ state.mnepc ->write (epc);
556+ #endif
557+ state.mncause ->write (t.cause ());
558+ set_privilege (PRV_M, false );
559+ return ;
560+ } else {
561+ s = set_field (s, MSTATUS_MDT, 1 );
562+ }
545563 }
546-
564+ #if defined(DIFFTEST) && defined(CPU_XIANGSHAN)
565+ state.pc = trap_handler_address;
566+ #else
547567 state.pc = !nmie ? rnmi_trap_handler_address : trap_handler_address;
568+ #endif
548569#ifdef CPU_ROCKET_CHIP
549570 state.mepc ->write (encode_vaddr (epc));
550571#else
0 commit comments