@@ -295,7 +295,7 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
295295 nonvirtual_scause = std::make_shared<cause_csr_t >(proc, CSR_SCAUSE);
296296 csrmap[CSR_VSCAUSE] = vscause = std::make_shared<cause_csr_t >(proc, CSR_VSCAUSE);
297297 csrmap[CSR_SCAUSE] = scause = std::make_shared<virtualized_csr_t >(proc, nonvirtual_scause, vscause);
298- csrmap[CSR_MTVAL2] = mtval2 = std::make_shared<hypervisor_csr_t >(proc, CSR_MTVAL2);
298+ csrmap[CSR_MTVAL2] = mtval2 = std::make_shared<mtval2_csr_t >(proc, CSR_MTVAL2);
299299 csrmap[CSR_MTINST] = mtinst = std::make_shared<hypervisor_csr_t >(proc, CSR_MTINST);
300300 const reg_t hstatus_init = set_field ((reg_t )0 , HSTATUS_VSXL, xlen_to_uxl (proc->get_const_xlen ()));
301301 const reg_t hstatus_mask = HSTATUS_VTSR | HSTATUS_VTW
@@ -391,7 +391,8 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
391391 (proc->extension_enabled (EXT_SVPBMT) ? MENVCFG_PBMTE : 0 ) |
392392 (proc->extension_enabled (EXT_SSTC) ? MENVCFG_STCE : 0 ) |
393393 (proc->extension_enabled (EXT_ZICFILP) ? MENVCFG_LPE : 0 ) |
394- (proc->extension_enabled (EXT_ZICFISS) ? MENVCFG_SSE : 0 );
394+ (proc->extension_enabled (EXT_ZICFISS) ? MENVCFG_SSE : 0 ) |
395+ (proc->extension_enabled (EXT_SSDBLTRP) ? MENVCFG_DTE : 0 );
395396 const reg_t menvcfg_init = (proc->extension_enabled (EXT_SVPBMT) ? MENVCFG_PBMTE : 0 );
396397 menvcfg = std::make_shared<envcfg_csr_t >(proc, CSR_MENVCFG, menvcfg_mask, menvcfg_init);
397398 if (xlen == 32 ) {
@@ -411,7 +412,8 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
411412 (proc->extension_enabled (EXT_SVPBMT) ? HENVCFG_PBMTE : 0 ) |
412413 (proc->extension_enabled (EXT_SSTC) ? HENVCFG_STCE : 0 ) |
413414 (proc->extension_enabled (EXT_ZICFILP) ? HENVCFG_LPE : 0 ) |
414- (proc->extension_enabled (EXT_ZICFISS) ? HENVCFG_SSE : 0 );
415+ (proc->extension_enabled (EXT_ZICFISS) ? HENVCFG_SSE : 0 ) |
416+ (proc->extension_enabled (EXT_SSDBLTRP) ? HENVCFG_DTE : 0 );
415417 const reg_t henvcfg_init = (proc->extension_enabled (EXT_SVPBMT) ? HENVCFG_PBMTE : 0 );
416418 henvcfg = std::make_shared<henvcfg_csr_t >(proc, CSR_HENVCFG, henvcfg_mask, henvcfg_init, menvcfg);
417419 if (xlen == 32 ) {
@@ -820,6 +822,7 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
820822 bool curr_virt = state.v ;
821823 const reg_t interrupt_bit = (reg_t )1 << (max_xlen - 1 );
822824 bool interrupt = (bit & interrupt_bit) != 0 ;
825+ bool supv_double_trap = false ;
823826 if (interrupt) {
824827 vsdeleg = (curr_virt && state.prv <= PRV_S) ? state.hideleg ->read () : 0 ;
825828 hsdeleg = (state.prv <= PRV_S) ? state.mideleg ->read () : 0 ;
@@ -828,6 +831,14 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
828831 vsdeleg = (curr_virt && state.prv <= PRV_S) ? (state.medeleg ->read () & state.hedeleg ->read ()) : 0 ;
829832 hsdeleg = (state.prv <= PRV_S) ? state.medeleg ->read () : 0 ;
830833 }
834+ // An unexpected trap - a trap when SDT is 1 - traps to M-mode
835+ if ((state.prv <= PRV_S && bit < max_xlen) &&
836+ (((vsdeleg >> bit) & 1 ) || ((hsdeleg >> bit) & 1 ))) {
837+ reg_t s = curr_virt ? state.nonvirtual_sstatus ->read () : state.sstatus ->read ();
838+ supv_double_trap = get_field (s, MSTATUS_SDT);
839+ if (supv_double_trap)
840+ vsdeleg = hsdeleg = 0 ;
841+ }
831842 if (state.prv <= PRV_S && bit < max_xlen && ((vsdeleg >> bit) & 1 )) {
832843 // Handle the trap in VS-mode
833844 const reg_t adjusted_cause = interrupt ? bit - 1 : bit; // VSSIP -> SSIP, etc
@@ -842,6 +853,8 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
842853 s = set_field (s, MSTATUS_SPP, state.prv );
843854 s = set_field (s, MSTATUS_SIE, 0 );
844855 s = set_field (s, MSTATUS_SPELP, state.elp );
856+ if ((state.menvcfg ->read () & MENVCFG_DTE) && (state.henvcfg ->read () & HENVCFG_DTE))
857+ s = set_field (s, MSTATUS_SDT, 1 );
845858 state.elp = elp_t ::NO_LP_EXPECTED;
846859 state.sstatus ->write (s);
847860 set_privilege (PRV_S, true );
@@ -860,6 +873,8 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
860873 s = set_field (s, MSTATUS_SPP, state.prv );
861874 s = set_field (s, MSTATUS_SIE, 0 );
862875 s = set_field (s, MSTATUS_SPELP, state.elp );
876+ if (state.menvcfg ->read () & MENVCFG_DTE)
877+ s = set_field (s, MSTATUS_SDT, 1 );
863878 state.elp = elp_t ::NO_LP_EXPECTED;
864879 state.nonvirtual_sstatus ->write (s);
865880 if (extension_enabled (' H' )) {
@@ -881,9 +896,9 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
881896 const bool nmie = !(state.mnstatus && !get_field (state.mnstatus ->read (), MNSTATUS_NMIE));
882897 state.pc = !nmie ? rnmi_trap_handler_address : trap_handler_address;
883898 state.mepc ->write (epc);
884- state.mcause ->write (t.cause ());
899+ state.mcause ->write (supv_double_trap ? CAUSE_DOUBLE_TRAP : t.cause ());
885900 state.mtval ->write (t.get_tval ());
886- state.mtval2 ->write (t.get_tval2 ());
901+ state.mtval2 ->write (supv_double_trap ? t. cause () : t.get_tval2 ());
887902 state.mtinst ->write (t.get_tinst ());
888903
889904 reg_t s = state.mstatus ->read ();
0 commit comments