Five EmbedDev logo Five EmbedDev

An Embedded RISC-V Blog
RISC-V External Debug Support , task_group_vote-4-g4e0bb0f 2019/03/25

Hardware Implementations

Below are two possible implementations. A designer could choose one, mix and match, or come up with their own design.

Abstract Command Based

Halting happens by stalling the hart execution pipeline.

Muxes on the register file(s) allow for accessing GPRs and CSRs using the Access Register abstract command.

Memory is accessed using the Abstract Access Memory command or through System Bus Access.

This implementation could allow a debugger to collect information from the hart even when that hart is unable to execute instructions.

Execution Based

This implementation only implements the Access Register abstract command for GPRs on a halted hart, and relies on the Program Buffer for all other operations. It uses the hart’s existing pipeline and ability to execute from arbitrary memory locations to avoid modifications to a hart’s datapath.

When the halt request bit is set, the Debug Module raises a special interrupt to the selected harts. This interrupt causes each hart to enter Debug Mode and jump to a defined memory region that is serviced by the DM. When taking this exception, pcis saved to dpcand causeis updated in dcsr.

The code in the Debug Module causes the hart to execute a “park loop.” In the park loop the hart writes its mhartidto a memory location within the Debug Module to indicate that it is halted. To allow the DM to individually control one out of several halted harts, each hart polls for flags in a DM-controlled memory location to determine whether the debugger wants it to execute the Program Buffer or perform a resume.

To execute an abstract command, the DM first populates some internal words of program buffer according to command. When transferis set, the DM populates these words with lw <gpr>, 0x400(zero) or sw 0x400(zero), <gpr>. 64- and 128-bit accesses use ld/sd and lq/sq respectively. If transferis not set, the DM populates these instructions as nops. If executeis set, execution continues to the debugger-controlled Program Buffer, otherwise the DM causes a ebreak to execute immediately.

When ebreak is executed (indicating the end of the Program Buffer code) the hart returns to its park loop. If an exception is encountered, the hart jumps to a debug exception address within the Debug Module. The code at that address causes the hart to write to an address in the Debug Module which indicates exception. This address is considered I/O for fence instructions (see #[fence] on page ). Then the hart jumps back to the park loop. The DM infers from the write that there was an exception, and sets cmderrappropriately.

To resume execution, the debug module sets a flag which causes the hart to execute a dret. When dret is executed, pcis restored from dpcand normal execution resumes at the privilege set by prv.

data0etc. are mapped into regular memory at an address relative to zero with only a 12-bit imm. The exact address is an implementation detail that a debugger must not rely on. For example, the data registers might be mapped to 0x400.

For additional flexibility, progbuf0, etc. are mapped into regular memory immediately preceding data0, in order to form a contiguous region of memory which can be used for either program execution or data transfer.