@@ -906,13 +906,13 @@ bool debug_module_t::perform_abstract_memory_access() {
906906 return true ;
907907 }
908908
909- if (aamvirtual || aamsize > 3 || aamsize > idx (xlen)) {
909+ if (aamsize > idx (xlen)) {
910910 abstractcs.cmderr = CMDERR_NOTSUP;
911911 return true ;
912912 }
913913
914914 unsigned offset = 0 ;
915- generate_initial_sequence (offset);
915+ generate_initial_sequence (aamvirtual, offset);
916916 is_write ? handle_memory_write (xlen, aamsize, offset)
917917 : handle_memory_read (xlen, aamsize, offset);
918918
@@ -927,8 +927,10 @@ bool debug_module_t::perform_abstract_memory_access() {
927927}
928928
929929using handle_memory_func = uint32_t (*)(unsigned rd_src, unsigned base, uint16_t offset);
930+ using handle_mstatus_func = uint32_t (*)(unsigned rd, unsigned rs1, unsigned csr);
930931static constexpr std::array<handle_memory_func, 4 > lx = {&lb, &lh, &lw, &ld};
931932static constexpr std::array<handle_memory_func, 4 > sx = {&sb, &sh, &sw, &sd};
933+ static constexpr std::array<handle_mstatus_func, 2 > csrrx = {&csrrc, &csrrs};
932934
933935unsigned debug_module_t::arg (unsigned xlen, unsigned idx)
934936{
@@ -937,16 +939,21 @@ unsigned debug_module_t::arg(unsigned xlen, unsigned idx)
937939
938940void debug_module_t::handle_memory_read (size_t xlen, unsigned aamsize, unsigned &offset)
939941{
940- write32 (debug_abstract, offset++, lx[idx (xlen)](S0 , ZERO, arg (xlen, 1 )));
941- write32 (debug_abstract, offset++, lx[aamsize](S0, S0 , 0 ));
942- write32 (debug_abstract, offset++, sx[idx (xlen)](S0 , ZERO, arg (xlen, 0 )));
942+ write32 (debug_abstract, offset++, lx[idx (xlen)](S1 , ZERO, arg (xlen, 1 )));
943+ write32 (debug_abstract, offset++, lx[aamsize](S1, S1 , 0 ));
944+ write32 (debug_abstract, offset++, sx[idx (xlen)](S1 , ZERO, arg (xlen, 0 )));
943945}
944946
945947void debug_module_t::handle_memory_write (size_t xlen, unsigned aamsize, unsigned &offset)
946948{
947- write32 (debug_abstract, offset++, lx[idx (xlen)](S0, ZERO, arg (xlen, 0 )));
948- write32 (debug_abstract, offset++, lx[idx (xlen)](S1, ZERO, arg (xlen, 1 )));
949+ // Use Arg1 as temporary storage for old mstatus value
950+ write32 (debug_abstract, offset++, lx[idx (xlen)](S1, ZERO, arg (xlen, 1 ))); // Arg1 -> S1
951+ write32 (debug_abstract, offset++, sx[idx (xlen)](S0, ZERO, arg (xlen, 1 ))); // S0 -> Arg1
952+ write32 (debug_abstract, offset++, lx[idx (xlen)](S0, ZERO, arg (xlen, 0 ))); // Arg0 -> S0
953+
949954 write32 (debug_abstract, offset++, sx[aamsize](S0, S1, 0 ));
955+
956+ write32 (debug_abstract, offset++, lx[idx (xlen)](S0, ZERO, arg (xlen, 1 ))); // Restore S0
950957}
951958
952959void debug_module_t::handle_post_increment (size_t xlen, unsigned aamsize, unsigned &offset)
@@ -956,14 +963,21 @@ void debug_module_t::handle_post_increment(size_t xlen, unsigned aamsize, unsign
956963 write32 (debug_abstract, offset++, sx[idx (xlen)](S1, ZERO, arg (xlen, 1 )));
957964}
958965
959- void debug_module_t::generate_initial_sequence (unsigned &offset)
966+ void debug_module_t::generate_initial_sequence (bool aamvirtual, unsigned &offset)
960967{
961968 write32 (debug_abstract, offset++, csrw (S0, CSR_DSCRATCH0));
962969 write32 (debug_abstract, offset++, csrw (S1, CSR_DSCRATCH1));
970+
971+ // Modify mstatus.mprv and save old mstatus
972+ write32 (debug_abstract, offset++, lui (S0, MSTATUS_MPRV >> 12 ));
973+ write32 (debug_abstract, offset++, csrrx[aamvirtual](S0, S0, CSR_MSTATUS));
963974}
964975
965976void debug_module_t::generate_termination_sequence (unsigned &offset)
966977{
978+ // Restore mstatus
979+ write32 (debug_abstract, offset++, csrw (S0, CSR_MSTATUS));
980+
967981 write32 (debug_abstract, offset++, csrr (S0, CSR_DSCRATCH0));
968982 write32 (debug_abstract, offset++, csrr (S1, CSR_DSCRATCH1));
969983 write32 (debug_abstract, offset++, ebreak ());
0 commit comments