Skip to content

Commit 9152a8f

Browse files
committed
Add aamvirtual support for abstract memory access
This commit implements support for the AAMVIRTUAL bit in the abstract memory access command. When enabled, this bit allows memory accesses to be performed in virtual address space rather than physical address space. Changes made: - Added aamvirtual flag parsing in perform_abstract_memory_access() - Updated assembly generation to properly handle virtual memory access by manipulating MSTATUS.MPRV bit - Added csrrc and csrrw helper functions Signed-off-by: Farid Khaydari <[email protected]>
1 parent 91300da commit 9152a8f

File tree

3 files changed

+34
-10
lines changed

3 files changed

+34
-10
lines changed

riscv/debug_module.cc

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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

929929
using 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);
930931
static constexpr std::array<handle_memory_func, 4> lx = {&lb, &lh, &lw, &ld};
931932
static 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

933935
unsigned debug_module_t::arg(unsigned xlen, unsigned idx)
934936
{
@@ -937,16 +939,21 @@ unsigned debug_module_t::arg(unsigned xlen, unsigned idx)
937939

938940
void 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

945947
void 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

952959
void 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

965976
void 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());

riscv/debug_module.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ class debug_module_t : public abstract_device_t
146146
static const unsigned debug_data_start = 0x380;
147147
unsigned debug_progbuf_start;
148148

149-
static const unsigned debug_abstract_size = 12;
149+
static const unsigned debug_abstract_size = 24;
150150
unsigned debug_abstract_start;
151151
// R/W this through custom registers, to allow debuggers to test that
152152
// functionality.
@@ -212,7 +212,7 @@ class debug_module_t : public abstract_device_t
212212
void handle_memory_read(size_t xlen, unsigned aamsize, unsigned &offset);
213213
void handle_memory_write(size_t xlen, unsigned aamsize, unsigned &offset);
214214

215-
void generate_initial_sequence(unsigned &offset);
215+
void generate_initial_sequence(bool aamvirtual, unsigned &offset);
216216
void generate_termination_sequence(unsigned &offset);
217217
void start_command_execution();
218218

riscv/opcodes.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ static uint32_t csrrs(unsigned int rd, unsigned int rs1, unsigned int csr) {
130130
return (csr << 20) | (rs1 << 15) | (rd << 7) | MATCH_CSRRS;
131131
}
132132

133+
static uint32_t csrrc(unsigned int rd, unsigned int rs1, unsigned int csr) __attribute__ ((unused));
134+
static uint32_t csrrc(unsigned int rd, unsigned int rs1, unsigned int csr) {
135+
return (csr << 20) | (rs1 << 15) | (rd << 7) | MATCH_CSRRC;
136+
}
137+
138+
static uint32_t csrrw(unsigned int rd, unsigned int rs1, unsigned int csr) __attribute__ ((unused));
139+
static uint32_t csrrw(unsigned int rd, unsigned int rs1, unsigned int csr) {
140+
return (csr << 20) | (rs1 << 15) | (rd << 7) | MATCH_CSRRW;
141+
}
142+
133143
static uint32_t fsw(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused));
134144
static uint32_t fsw(unsigned int src, unsigned int base, uint16_t offset)
135145
{

0 commit comments

Comments
 (0)