Fixed up logic for "Non-Debug-Module reset" request/response from the Debug Module

Now able to run multiple ISA tests in a single simulation run
connected to remote debugger DSharp, using either hart_reset or
ndm_reset between tests to bring the system back into reset state.
All Debug Module commands working:
 - dm_reset, hart_reset, ndm_reset
 - break    (set breakpoint)
 - step
 - continue (until breakpoint of 'halt' command)
 - halt
 - read/write GPR, FPR, CSR, memory
 - elf_load
This commit is contained in:
rsnikhil
2020-02-04 16:02:53 -05:00
parent 4960a59da0
commit 83829590dd
70 changed files with 94735 additions and 89999 deletions

View File

@@ -58,18 +58,18 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
Reg #(Bool) rg_start_reg_access <- mkReg (False);
// FIFOs for request/response to access GPRs
FIFOF #(DM_CPU_Req #(5, XLEN)) f_hart0_gpr_reqs <- mkFIFOF1;
FIFOF #(DM_CPU_Rsp #(XLEN)) f_hart0_gpr_rsps <- mkFIFOF1;
FIFOF #(DM_CPU_Req #(5, XLEN)) f_hart0_gpr_reqs <- mkFIFOF;
FIFOF #(DM_CPU_Rsp #(XLEN)) f_hart0_gpr_rsps <- mkFIFOF;
// FIFOs for request/response to access FPRs
`ifdef ISA_F
FIFOF #(DM_CPU_Req #(5, FLEN)) f_hart0_fpr_reqs <- mkFIFOF1;
FIFOF #(DM_CPU_Rsp #(FLEN)) f_hart0_fpr_rsps <- mkFIFOF1;
FIFOF #(DM_CPU_Req #(5, FLEN)) f_hart0_fpr_reqs <- mkFIFOF;
FIFOF #(DM_CPU_Rsp #(FLEN)) f_hart0_fpr_rsps <- mkFIFOF;
`endif
// FIFOs for request/response to access CSRs
FIFOF #(DM_CPU_Req #(12, XLEN)) f_hart0_csr_reqs <- mkFIFOF1;
FIFOF #(DM_CPU_Rsp #(XLEN)) f_hart0_csr_rsps <- mkFIFOF1;
FIFOF #(DM_CPU_Req #(12, XLEN)) f_hart0_csr_reqs <- mkFIFOF;
FIFOF #(DM_CPU_Rsp #(XLEN)) f_hart0_csr_rsps <- mkFIFOF;
// ----------------------------------------------------------------
// rg_data0
@@ -89,15 +89,18 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
Reg #(Bool) rg_abstractcs_busy <- mkRegU;
Reg #(DM_abstractcs_cmderr) rg_abstractcs_cmderr <- mkRegU;
Bit #(5) abstractcs_progsize = 0;
Bit #(5) abstractcs_datacount = 0;
// Size of program buffer, in 32b words
Bit #(5) abstractcs_progbufsize = 0;
// Number of data registers implemented (rg_data0, rg_data1)
Bit #(4) abstractcs_datacount = ((xlen == 32) ? 1 : 2);
DM_Word virt_rg_abstractcs = {3'b0,
abstractcs_progsize,
abstractcs_progbufsize,
11'b0,
pack (rg_abstractcs_busy),
1'b0,
pack (rg_abstractcs_cmderr),
3'b0,
4'b0,
abstractcs_datacount};
function Action fa_rg_abstractcs_write (DM_Word dm_word);

View File

@@ -9,9 +9,15 @@ package DM_Run_Control;
// ================================================================
// BSV library imports
import FIFOF :: *;
import GetPut :: *;
import ClientServer :: *;
import FIFOF :: *;
import GetPut :: *;
import ClientServer :: *;
// ----------------
// Other library imports
import Cur_Cycle :: *;
import GetPut_Aux :: *;
// ================================================================
// Project imports
@@ -33,13 +39,14 @@ interface DM_Run_Control_IFC;
// ----------------
// Facing a hart: reset and run-control
interface Get #(Token) hart0_get_reset_req;
interface Client #(Bool, Bool) hart0_reset_client;
interface Client #(Bool, Bool) hart0_client_run_halt;
interface Get #(Bit #(4)) hart0_get_other_req;
// ----------------
// Facing Platform: Non-Debug-Module Reset (reset all except DM)
interface Get #(Token) get_ndm_reset_req;
// Bool indicates 'running' hart state.
interface Client #(Bool, Bool) ndm_reset_client;
endinterface
// ================================================================
@@ -52,7 +59,8 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
// ----------------------------------------------------------------
// NDM Reset
FIFOF #(Token) f_ndm_reset_reqs <- mkFIFOF;
FIFOF #(Bool) f_ndm_reset_reqs <- mkFIFOF;
FIFOF #(Bool) f_ndm_reset_rsps <- mkFIFOF;
// ----------------------------------------------------------------
// Hart0 run control
@@ -60,7 +68,8 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
Reg #(Bool) rg_hart0_running <- mkRegU;
// Reset requests to hart
FIFOF #(Token) f_hart0_reset_reqs <- mkFIFOF;
FIFOF #(Bool) f_hart0_reset_reqs <- mkFIFOF;
FIFOF #(Bool) f_hart0_reset_rsps <- mkFIFOF;
// Run/halt requests to hart and responses
FIFOF #(Bool) f_hart0_run_halt_reqs <- mkFIFOF;
@@ -81,7 +90,13 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
// 'anyXX' = 'allXX'
// 'allrunning' = NOT 'allhalted'
Reg#(Bool) rg_dmstatus_allresumeack <- mkRegU;
Bool dmstatus_impebreak = False;
Reg #(Bool) rg_hart0_hasreset <- mkRegU;
Bool dmstatus_allhavereset = rg_hart0_hasreset;
Bool dmstatus_anyhavereset = rg_hart0_hasreset;
Reg #(Bool) rg_dmstatus_allresumeack <- mkRegU;
Bool dmstatus_allresumeack = rg_dmstatus_allresumeack;
Bool dmstatus_anyresumeack = rg_dmstatus_allresumeack;
@@ -89,8 +104,9 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
Bool dmstatus_allnonexistent = False;
Bool dmstatus_anynonexistent = dmstatus_allnonexistent;
Bool dmstatus_allunavail = False;
Bool dmstatus_anyunavail = dmstatus_allunavail;
Reg #(Bool) rg_dmstatus_allunavail <- mkReg (False);
Bool dmstatus_allunavail = rg_dmstatus_allunavail;
Bool dmstatus_anyunavail = rg_dmstatus_allunavail;
Bool dmstatus_allrunning = rg_hart0_running;
Bool dmstatus_anyrunning = dmstatus_allrunning;
@@ -98,7 +114,11 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
Bool dmstatus_allhalted = (! rg_hart0_running);
Bool dmstatus_anyhalted = dmstatus_allhalted;
DM_Word virt_rg_dmstatus = {14'b0,
DM_Word virt_rg_dmstatus = {9'b0,
pack (dmstatus_impebreak),
2'b0,
pack (dmstatus_allhavereset),
pack (dmstatus_anyhavereset),
pack (dmstatus_allresumeack),
pack (dmstatus_anyresumeack),
pack (dmstatus_allnonexistent),
@@ -151,19 +171,17 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
// Debug Module reset
if (! dmactive) begin
// Reset the DM module itself
$display ("DM_Run_Control.write: dmcontrol 0x%08h (dmactive=0): resetting Debug Module",
dm_word);
$display ("%0d: %m.dmcontrol_write 0x%08h (dmactive=0): resetting Debug Module",
cur_cycle, dm_word);
// Error-checking
if (ndmreset) begin
$display ("DM_Run_Control.write: WARNING: in word written to dmcontrol (0x%08h):",
dm_word);
$display (" WARNING: DM_Run_Control: dmcontrol_write 0x%08h:", dm_word);
$display (" [1] (ndmreset) and [0] (dmactive) both asserted");
$display (" dmactive has priority; ignoring ndmreset");
end
if (hartreset) begin
$display ("DM_Run_Control.write: WARNING: in word written to dmcontrol (0x%08h):",
dm_word);
$display (" WARNING: DM_Run_Control: dmcontrol_write 0x%08h:", dm_word);
$display (" [29] (hartreset) and [0] (dmactive) both asserted");
$display (" dmactive has priority; ignoring hartreset");
end
@@ -172,63 +190,84 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
noAction;
end
// Platform reset (non-Debug Module)
else if (ndmreset) begin
$display ("DM_Run_Control.write: dmcontrol 0x%08h: ndmreset=1: resetting platform",
dm_word);
f_ndm_reset_reqs.enq (?);
rg_hart0_running <= True; // Must be same as run/halt state of CPU after hart_reset!
// Ignore if NDM reset is in progress
else if (rg_dmstatus_allunavail) begin
$display ("%0d: %m.dmcontrol_write 0x%0h: ndm reset in progress; ignoring this write",
cur_cycle, dm_word);
end
// Non-Debug-Module reset (platform reset) posedge: ignore
else if ((! rg_dmcontrol_ndmreset) && ndmreset) begin
if (verbosity != 0)
$display ("%0d: %m.dmcontrol_write 0x%08h: ndmreset: 0->1: ignoring",
cur_cycle, dm_word);
end
// Non-Debug-Module reset (platform reset) negedge: do it
else if (rg_dmcontrol_ndmreset && (! ndmreset)) begin
Bool running = (! haltreq);
if (verbosity != 0) begin
$display ("%0d: %m.dmcontrol_write 0x%08h: ndmreset: 1->0: resetting platform",
cur_cycle, dm_word);
$display (" Requested 'running' state = ", fshow (running));
end
f_ndm_reset_reqs.enq (running);
rg_dmstatus_allunavail <= True;
// Error-checking
if (hartreset) begin
$display ("DM_Run_Control.write: WARNING: in word written to dmcontrol (0x%08h):",
dm_word);
$display (" Both ndmreset (bit 1) and hartreset (bit 29) are asserted");
$display (" WARNING: %m.dmcontrol_write 0x%08h:", dm_word);
$display (" Both ndmreset [1] and hartreset [29] are asserted");
$display (" ndmreset has priority; ignoring hartreset");
end
end
else begin
// Hart reset
else if (hartreset) begin
Bool running = (! haltreq);
f_hart0_reset_reqs.enq (running);
rg_hart0_hasreset <= True;
// Deassert platform reset
if ((verbosity != 0) && rg_dmcontrol_ndmreset)
$display ("DM_Run_Control.write: dmcontrol 0x%08h: clearing ndmreset", dm_word);
// Hart reset
if (hartreset) begin
if (verbosity != 0)
$display ("DM_Run_Control.write: dmcontrol 0x%08h: hartreset=1: resetting hart",
dm_word);
f_hart0_reset_reqs.enq (?);
rg_hart0_running <= True; // Must be same as run/halt state of CPU after hart_reset!
if (verbosity != 0) begin
$display ("%0d: %m.dmcontrol_write 0x%08h: hartreset=1: resetting hart",
cur_cycle, dm_word);
$display (" Requested 'running' state = ", fshow (running));
end
else begin
// Deassert hart reset
if ((verbosity != 0) && rg_dmcontrol_hartreset)
$display ("DM_Run_Control.write: dmcontrol 0x%08h: clearing hartreset", dm_word);
end
if (hasel)
$display ("DM_Run_Control.write: ERROR: dmcontrol 0x%08h: 'hasel' is not supported",
dm_word);
// run/halt commands
else begin
// Deassert hart reset
if ((verbosity != 0) && rg_dmcontrol_hartreset)
$display ("%0d: %m.dmcontrol_write 0x%08h: clearing hartreset",
cur_cycle, dm_word);
if (hartsel != 0)
$display ("DM_Run_Control.write: ERROR: dmcontrol 0x%08h: hartsel 0x%0h not supported",
dm_word, hartsel);
if (hasel)
$display ("%0d:ERROR: %m.dmcontrol_write 0x%08h: hasel is not supported",
cur_cycle, dm_word);
if (haltreq && resumereq) begin
$display ("DM_Run_Control.write: ERROR: dmcontrol 0x%08h: haltreq=1 and resumereq=1",
dm_word);
$display (" This behavior is 'undefined' in the spec; ignoring");
end
// Resume hart(s) if not running
else if (resumereq && (! rg_hart0_running)) begin
f_hart0_run_halt_reqs.enq (True);
rg_dmstatus_allresumeack <= False;
$display ("DM_Run_Control.write: hart0 resume request");
end
// Halt hart(s)
else if (haltreq && rg_hart0_running) begin
f_hart0_run_halt_reqs.enq (False);
$display ("DM_Run_Control.write: hart0 halt request");
end
if (hartsel != 0)
$display ("%0d:ERROR: %m.dmcontrol_write 0x%08h: hartsel 0x%0h not supported",
cur_cycle, dm_word, hartsel);
if (haltreq && resumereq) begin
$display ("%0d:ERROR: %m.dmcontrol_write 0x%08h: haltreq=1 and resumereq=1",
cur_cycle, dm_word);
$display (" This behavior is 'undefined' in the spec; ignoring");
end
// Resume hart(s) if not running
else if (resumereq && (! rg_hart0_running)) begin
f_hart0_run_halt_reqs.enq (True);
rg_dmstatus_allresumeack <= False;
$display ("%0d: %m.dmcontrol_write: hart0 resume request", cur_cycle);
end
// Halt hart(s)
else if (haltreq && rg_hart0_running) begin
f_hart0_run_halt_reqs.enq (False);
$display ("%0d: %m.dmcontrol_write: hart0 halt request", cur_cycle);
end
end
endaction
@@ -250,19 +289,37 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
Reg #(Bit #(4)) rg_verbosity <- mkRegU;
// ----------------------------------------------------------------
// System responses
rule rl_hart0_run_rsp;
let x = f_hart0_run_halt_rsps.first;
f_hart0_run_halt_rsps.deq;
// Response from system for hart0 reset
rule rl_hart0_reset_rsp;
Bool running <- pop (f_hart0_reset_rsps);
rg_hart0_hasreset <= False;
rg_hart0_running <= running;
rg_hart0_running <= x;
if (x) begin
if (verbosity != 0)
$display ("%0d: %m.rl_hart0_reset_rsp: hart running = ", cur_cycle, fshow (running));
endrule
// Response from system for NDM reset
rule rl_ndm_reset_rsp;
Bool running <- pop (f_ndm_reset_rsps);
rg_hart0_running <= running;
rg_dmstatus_allunavail <= False;
// if (verbosity != 0) TODO: UNCOMMENT AFTER DEBUGGING
$display ("%0d: %m.rl_ndm_reset_rsp: hart running = ", cur_cycle, fshow (running));
endrule
// Response from system for run/halt request
rule rl_hart0_run_rsp (! f_ndm_reset_rsps.notEmpty);
let running <- pop (f_hart0_run_halt_rsps);
rg_hart0_running <= running;
if (running)
rg_dmstatus_allresumeack <= True;
$display ("DM_Run_Control: hart0 running");
end
else begin
$display ("DM_Run_Control: hart0 halted");
end
if (verbosity != 0)
$display ("%0d: %m.rl_hart0_run_rsp: 'running' = ", cur_cycle, fshow (running));
endrule
// ----------------------------------------------------------------
@@ -274,9 +331,12 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
method Action reset;
f_ndm_reset_reqs.clear;
f_ndm_reset_rsps.clear;
rg_hart0_running <= True; // Must be same as run/halt state of CPU after hart_reset!
f_hart0_reset_reqs.clear;
f_hart0_reset_rsps.clear;
rg_hart0_running <= True; // Safe approximation of whether the CPU is running or not
f_hart0_run_halt_reqs.clear;
f_hart0_run_halt_rsps.clear;
@@ -285,12 +345,14 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
rg_dmcontrol_ndmreset <= False;
rg_dmcontrol_dmactive <= True; // DM module is now active
rg_hart0_hasreset <= False;
rg_dmstatus_allresumeack <= False;
rg_dmstatus_allunavail <= False; // NDM not in progress
rg_verbosity <= 0;
if (verbosity != 0)
$display ("DM_Run_Control: reset");
$display ("%0d: %m.reset", cur_cycle);
endmethod
// ----------------
@@ -307,7 +369,7 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
endcase;
if (verbosity != 0)
$display ("DM_Run_Control.av_read: [", fshow_dm_addr (dm_addr), "] => 0x%08h", dm_word);
$display ("%0d: %m.av_read: [", cur_cycle, fshow_dm_addr (dm_addr), "] => 0x%08h", dm_word);
return dm_word;
endactionvalue
@@ -316,7 +378,7 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
method Action write (DM_Addr dm_addr, DM_Word dm_word);
action
if (verbosity != 0)
$display ("DM_Run_Control.write: [", fshow_dm_addr (dm_addr), "] <= 0x%08h", dm_word);
$display ("%0d: %m.write: [", cur_cycle, fshow_dm_addr (dm_addr), "] <= 0x%08h", dm_word);
case (dm_addr)
dm_addr_dmcontrol: fa_rg_dmcontrol_write (dm_word);
@@ -331,13 +393,13 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
// ----------------
// Facing Hart: Reset, Run-control, etc.
interface Get hart0_get_reset_req = toGet (f_hart0_reset_reqs);
interface Client hart0_reset_client = toGPClient (f_hart0_reset_reqs, f_hart0_reset_rsps);
interface Client hart0_client_run_halt = toGPClient (f_hart0_run_halt_reqs, f_hart0_run_halt_rsps);
interface Get hart0_get_other_req = toGet (f_hart0_other_reqs);
// ----------------
// Facing Platform: Non-Debug-Module Reset (reset all except DM)
interface Get get_ndm_reset_req = toGet (f_ndm_reset_reqs);
interface Client ndm_reset_client = toGPClient (f_ndm_reset_reqs, f_ndm_reset_rsps);
endmodule
// ================================================================

View File

@@ -179,7 +179,7 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
// ----------------------------------------------------------------
// Interface to memory fabric
AXI4_Master_Xactor_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) master_xactor <- mkAXI4_Master_Xactor_2;
AXI4_Master_Xactor_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) master_xactor <- mkAXI4_Master_Xactor;
// ----------------------------------------------------------------
// System Bus state
@@ -318,8 +318,7 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
awuser: fabric_default_user};
master_xactor.i_wr_addr.enq (wra);
let wrd = AXI4_Wr_Data {wid: fabric_default_id,
wdata: fabric_data,
let wrd = AXI4_Wr_Data {wdata: fabric_data,
wstrb: fabric_strb,
wlast: True,
wuser: fabric_default_user};

View File

@@ -96,7 +96,7 @@ interface Debug_Module_IFC;
// This section replicated for additional harts.
// Reset and run-control
interface Get #(Token) hart0_get_reset_req;
interface Client #(Bool, Bool) hart0_reset_client;
interface Client #(Bool, Bool) hart0_client_run_halt;
interface Get #(Bit #(4)) hart0_get_other_req;
@@ -115,7 +115,8 @@ interface Debug_Module_IFC;
// Facing Platform
// Non-Debug-Module Reset (reset all except DM)
interface Get #(Token) get_ndm_reset_req;
// Bool indicates 'running' hart state.
interface Client #(Bool, Bool) ndm_reset_client;
// Read/Write RISC-V memory
interface AXI4_Master_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) master;
@@ -126,6 +127,9 @@ endinterface
(* synthesize *)
module mkDebug_Module (Debug_Module_IFC);
// Local verbosity: 0 = quiet; 1 = print DMI transactions
Integer verbosity = 0;
// The three parts
DM_Run_Control_IFC dm_run_control <- mkDM_Run_Control;
DM_Abstract_Commands_IFC dm_abstract_commands <- mkDM_Abstract_Commands;
@@ -152,6 +156,9 @@ module mkDebug_Module (Debug_Module_IFC);
interface DMI dmi;
method Action read_addr (DM_Addr dm_addr);
f_read_addr.enq(dm_addr);
if (verbosity != 0)
$display ("%0d: %m.DMI read: dm_addr 0x%0h", cur_cycle, dm_addr);
endmethod
method ActionValue #(DM_Word) read_data;
@@ -209,6 +216,10 @@ module mkDebug_Module (Debug_Module_IFC);
dm_word = 0;
end
if (verbosity != 0)
$display ("%0d: %m.DMI read response: dm_addr 0x%0h, dm_word 0x%0h",
cur_cycle, dm_addr, dm_word);
return dm_word;
endmethod
@@ -261,6 +272,10 @@ module mkDebug_Module (Debug_Module_IFC);
// TODO: set error status?
noAction;
end
if (verbosity != 0)
$display ("%0d: %m.DMI write: dm_addr 0x%0h, dm_word 0x%0h",
cur_cycle, dm_addr, dm_word);
endmethod
endinterface
@@ -268,7 +283,7 @@ module mkDebug_Module (Debug_Module_IFC);
// Facing CPU/hart0
// Reset and run-control
interface Get hart0_get_reset_req = dm_run_control.hart0_get_reset_req;
interface Client hart0_reset_client = dm_run_control.hart0_reset_client;
interface Client hart0_client_run_halt = dm_run_control.hart0_client_run_halt;
interface Get hart0_get_other_req = dm_run_control.hart0_get_other_req;
@@ -287,7 +302,7 @@ module mkDebug_Module (Debug_Module_IFC);
// Facing Platform
// Non-Debug-Module Reset (reset all except DM)
interface Get get_ndm_reset_req = dm_run_control.get_ndm_reset_req;
interface Client ndm_reset_client = dm_run_control.ndm_reset_client;
// Read/Write RISC-V memory
interface AXI4_Master_IFC master = dm_system_bus.master;

View File

@@ -1,3 +1,206 @@
'Debug_Module' implements a Debug Module for RISC-V processors in
accordance with the RISC-V standard "External Debug Support" spec:
RISC-V External Debug Support
Version 0.13.2
d5029366d59e8563c08b6b9435f82573b603e48e
Fri Mar 22 09:06:04 2019 -0700
Note: the spec is independent of any particular RISC-V CPU
implementation. It just specifies the standard registers in the Debug
Module that can be read and written by an external debugger (such as
GDB). It specifies the address map of these registers, and the
semantics, i.e., what happens when one reads or writes these
registers. The spec does not say anything about how this spec is
implemented.
Please see comments in Debug_Module.bsv for more details on our
implementation of the Debug Module spec. This implementation is also
not specific to any particular CPU implementation. We use it in
multiple Bluespec RISC-V CPU implementations, and it could be used
with other CPU implementations as well.
// ================================================================
What follows is a concise cheat-sheet for the registers in the Debug Module.
DM_Addr dm_addr_data0 = 'h04;
DM_Addr dm_addr_data1 = 'h05;
DM_Addr dm_addr_data2 = 'h06;
DM_Addr dm_addr_data3 = 'h07;
DM_Addr dm_addr_data4 = 'h08;
DM_Addr dm_addr_data5 = 'h09;
DM_Addr dm_addr_data6 = 'h0a;
DM_Addr dm_addr_data7 = 'h0b;
DM_Addr dm_addr_data8 = 'h0c;
DM_Addr dm_addr_data9 = 'h0d;
DM_Addr dm_addr_data10 = 'h0d;
DM_Addr dm_addr_data11 = 'h0f;
// ----------------
// Run Control
DM_Addr dm_addr_dmcontrol = 'h10;
31.30.29.28| 27.26.25.24| 23.22.21.20| 19.18.17.16| 15.14.13.12| 11.10.9.8| 7.6.5.4| 3.2.1.0|
| | | | 0 | | | | | 0 0 | | | |dmactive
| | | | | | | | | | | |ndmreset
| | | | | | | | | | |clrresethaltreq
| | | | | | | | | |setresethaltreq
| | | | | | | |-----------10-----------|hartselhi
| | | | | |------------10--------------|hartsello
| | | | |hasel
| | | | 0: Single hart selected (hartsel)
| | | | 1: Multiple harts selected (hartsel + hart array mask)
| | | |ackhavereset
| | |hartreset
| |resumereq
|haltreq
DM_Addr dm_addr_dmstatus = 'h11;
31.30.29.28| 27.26.25.24| 23.22.21.20| 19.18.17.16| 15.14.13.12| 11.10.9.8| 7.6.5.4| 3.2.1.0|
0 0 0 0 0 0 0 0 | | 0 0 | | | | | | | | | | | | | | | | |--4--|version
| | | | | | | | | | | | | | | | | | | 0: no DM present
| | | | | | | | | | | | | | | | | | | 1: DM v011
| | | | | | | | | | | | | | | | | | | 2: DM v013
| | | | | | | | | | | | | | | | | | | 15: DM vUnknown
| | | | | | | | | | | | | | | | | |confstrptrvalid
| | | | | | | | | | | | | | | | |hasresethaltreq
| | | | | | | | | | | | | | | |authbusy
| | | | | | | | | | | | | | |authenticated
| | | | | | | | | | | | | |anyhalted
| | | | | | | | | | | | |allhalted
| | | | | | | | | | | |anyrunning
| | | | | | | | | | |allrunning
| | | | | | | | | |anyunavail
| | | | | | | | |allunavail
| | | | | | | |anynonexistent
| | | | | | |allnonexistent
| | | | | |anyresumeack
| | | | |allresumeack
| | | |anyhavereset
| | |allhavereset
| |impebreak
| 0 No implicit EBREAK at end of PB
| 1 Implicit EBREAK at end of PB
DM_Addr dm_addr_hartinfo = 'h12;
31.30.29.28| 27.26.25.24| 23.22.21.20| 19.18.17.16| 15.14.13.12| 11.10.9.8| 7.6.5.4| 3.2.1.0|
0 0 0 0 0 0 0 0 | | 0 0 0 | | | |-----------12-----------|dataaddr
| | | |----4---|datasize
|----4---|nscratch |dataaccess
DM_Addr dm_addr_haltsum1 = 'h13;
DM_Addr dm_addr_hawindowsel = 'h14;
DM_Addr dm_addr_hawindow = 'h15;
// ----------------
// Abstract commands (read/write RISC-V registers and RISC-V CSRs)
DM_Addr dm_addr_abstractcs = 'h16;
31.30.29.28| 27.26.25.24| 23.22.21.20| 19.18.17.16| 15.14.13.12| 11.10.9.8| 7.6.5.4| 3.2.1.0|
0 0 0 | | 0 0 0 0 0 0 0 0 0 0 0 | 0 | | 0 0 0 0 |--4--|datacount
0 0 0 |-----5------|progbufsize |busy |-3-|cmderr
DM_Addr dm_addr_command = 'h17;
31.30.29.28| 27.26.25.24| 23.22.21.20| 19.18.17.16| 15.14.13.12| 11.10.9.8| 7.6.5.4| 3.2.1.0|
| 0 | | | | | | |-----------------16------------------|regno
| | | | | | | | 0x0000-0x0FFF CSRs (dpc => PC)
| | | | | | | | 0x1000-0x101F GPRs
| | | | | | | | 0x1020-0x103F Floating Point Regs
| | | | | | | | 0xC000-0xFFFF Reserved
| | | | | | |write
| | | | | | 0: specified reg -> arg0 of data
| | | | | | 1: specified reg <- arg0 of data
| | | | | |transfer
| | | | | 0 Don't do the 'write' op
| | | | | 1 Do the 'write' op
| | | | | Allows exec of PB without valid vals in 'size' and 'regno'
| | | | |postexec
| | | | 1 exec Program Buffer exactly once after the xfer
| | | |aarpostincrement
| |--3--|aarsize
| 2 Lowest 32b of reg
| 3 Lowest 64b of reg
| 4 Lowest 128b of reg
|---------8-----------|cmdtype
0 ACCESS_REG
1 QUICK_ACCESS
DM_Addr dm_addr_abstractauto = 'h18;
DM_Addr dm_addr_confstrptr0 = 'h19;
DM_Addr dm_addr_confstrptr1 = 'h1a;
DM_Addr dm_addr_confstrptr2 = 'h1b;
DM_Addr dm_addr_confstrptr3 = 'h1c;
DM_Addr dm_addr_nextdm = 'h1d;
DM_Addr dm_addr_progbuf0 = 'h20;
DM_Addr dm_addr_progbuf1 = 'h21;
DM_Addr dm_addr_progbuf2 = 'h22;
DM_Addr dm_addr_progbuf3 = 'h23;
DM_Addr dm_addr_progbuf4 = 'h24;
DM_Addr dm_addr_progbuf5 = 'h25;
DM_Addr dm_addr_progbuf6 = 'h26;
DM_Addr dm_addr_progbuf7 = 'h27;
DM_Addr dm_addr_progbuf8 = 'h28;
DM_Addr dm_addr_progbuf9 = 'h29;
DM_Addr dm_addr_progbuf10 = 'h2a;
DM_Addr dm_addr_progbuf11 = 'h2b;
DM_Addr dm_addr_progbuf12 = 'h2c;
DM_Addr dm_addr_progbuf13 = 'h2d;
DM_Addr dm_addr_progbuf14 = 'h2e;
DM_Addr dm_addr_progbuf15 = 'h2f;
DM_Addr dm_addr_authdata = 'h30;
DM_Addr dm_addr_haltsum2 = 'h34;
DM_Addr dm_addr_haltsum3 = 'h35;
DM_Addr dm_addr_sbaddress3 = 'h37;
// ----------------
// System Bus access (read/write RISC-V memory/devices)
DM_Addr dm_addr_sbcs = 'h38;
31.30.29.28| 27.26.25.24| 23.22.21.20| 19.18.17.16| 15.14.13.12| 11.10.9.8| 7.6.5.4| 3.2.1.0|
| | 0 0 0 0 0 0 | | | | | | | | | | | | | | | |sbaccess8
| | | | | | | | | | | | | | | | |sbaccess16
| | | | | | | | | | | | | | | |sbaccess32
| | | | | | | | | | | | | | |sbaccess64
| | | | | | | | | | | | | |sbaccess128
| | | | | | | | | | | |-----7-------|sbasize
| | | | | | | | | |--3--|sberror
| | | | | | | | | 0: no bus err
| | | | | | | | | 1: timeout
| | | | | | | | | 2: bad addr
| | | | | | | | | 3: alignment err
| | | | | | | | | 4: unsupported size
| | | | | | | | | 7: other
| | | | | | | | |sbreadondata: read on sbdata0 triggers sb read
| | | | | | | |sbautoincrement
| | | | | |--3--|sbaccess
| | | | | 0:8b, 1:16b, 2:32b, 3:64b, 4:128b
| | | | |sbreadonaddr
| | | | 1 Every write to sbaddress0 triggers sb read at new addr
| | | |sbbusy
| | |sbbusyerror
|--3--|sbversion
0: System Bus interface spec version < 2018-01-01
1: This System Bus interface spec version
DM_Addr dm_addr_sbaddress0 = 'h39;
DM_Addr dm_addr_sbaddress1 = 'h3a;
DM_Addr dm_addr_sbaddress2 = 'h3b;
DM_Addr dm_addr_sbdata0 = 'h3c;
DM_Addr dm_addr_sbdata1 = 'h3d;
DM_Addr dm_addr_sbdata2 = 'h3e;
DM_Addr dm_addr_sbdata3 = 'h3f;
DM_Addr dm_addr_haltsum0 = 'h40;
// ================================================================
// ================================================================
// OLDER VERSIONS OF THE DEBUG MODULE SPEC
// ================================================================
// ================================================================
'Debug_Module' implements a Debug Module for RISC-V processors in
accordance with the RISC-V standard "External Debug Support" spec: