diff --git a/debugger_implementation.adoc b/debugger_implementation.adoc index 85e39ad4..c6a96248 100644 --- a/debugger_implementation.adoc +++ b/debugger_implementation.adoc @@ -1,3 +1,4 @@ +[appendix] == Debugger Implementation === C Header File diff --git a/implementations.adoc b/implementations.adoc index 21f70eb2..48fef449 100644 --- a/implementations.adoc +++ b/implementations.adoc @@ -1,3 +1,4 @@ +[appendix] [[sec:implementations]] == Hardware Implementations @@ -22,57 +23,57 @@ the hart even when that hart is unable to execute instructions. 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 +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. +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 and is only accessible to the harts in Debug Mode. Accesses to this memory should be uncached to avoid side effects from debugging -operations. When taking this jump, is saved to and is updated in . This +operations. When taking this jump, is saved to {csr-dpc} and {dcsr-cause} is updated in {csr-dcsr}. This jump is similar to a trap but it is not architecturally considered a -trap, so for instance doesn’t count as a trap for trigger behavior. +trap, so for instance doesn't count as a trap for trigger behavior. -The code in the Debug Module causes the hart to execute a ``park loop.'' -In the park loop the hart writes its to a memory location within the +The code in the Debug Module causes the hart to execute a "park loop." +In the park loop the hart writes its `mhartid` to 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 . When is set, the DM populates +words of program buffer according to {dm-command}. When {accessregister-transfer} is set, the DM populates these words with `lw , 0x400(zero)` or `sw 0x400(zero), `. 64- -and 128-bit accesses use `ld`/`sd` and `lq`/`sq` respectively. If is not -set, the DM populates these instructions as `nop`s. If is set, execution +and 128-bit accesses use `ld`/`sd` and `lq`/`sq` respectively. If {accessregister-transfer} is not +set, the DM populates these instructions as `nop's`. If {accessregister-postexec} is set, execution continues to the debugger-controlled Program Buffer, otherwise the DM -causes a `ebreak` to execute immediately. +causes an `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 an address within the Debug Module. The code there causes the hart to write to the Debug Module indicating an exception. Then the hart jumps back to the park loop. The DM infers from the write -that there was an exception, and sets appropriately. Typically the hart +that there was an exception, and sets {abstractcs-cmderr} appropriately. Typically the hart will execute a `fence` instruction before entering the park loop, to -ensure that any effects from the abstract command, such as a write to , -take effect before the DM returns to 0. +ensure that any effects from the abstract command, such as a write to {dm-data0}, +take effect before the DM returns {abstractcs-busy} to 0. To resume execution, the debug module sets a flag which causes the hart to execute a `dret`. `dret` is an instruction that only has meaning while in Debug Mode and not executing from the Program Buffer. Its recommended encoding is 0x7b200073. When `dret` is executed, is restored -from and normal execution resumes at the privilege set by and . +from {csr-dpc} and normal execution resumes at the privilege set by {dcsr-prv} and {dcsr-v}. -etc. are mapped into regular memory at an address relative to with only +{dm-data0} etc. are mapped into regular memory at an address relative to 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, , etc. are mapped into regular memory -immediately preceding , in order to form a contiguous region of memory +For additional flexibility, {dm-progbuf0}, etc. are mapped into regular memory +immediately preceding {dm-data0}, in order to form a contiguous region of memory which can be used for either program execution or data transfer. The PMP must not disallow fetches, loads, or stores in the address range @@ -84,10 +85,10 @@ traps and debug would not be possible. [[dmi_signals]] === Debug Module Interface Signals -As stated in section link:#dmi[[dmi]] the details of the DMI are left to +As stated in section <> the details of the DMI are left to the system designer. It is quite often the case that only one DTM and one DM is implemented. In this case it might be useful to comply with -the signals suggested in table #tab:dmi_signals[1.1], which is the +the signals suggested in <>, which is the implementation used in the open-source https://github.com/chipsalliance/rocket-chip/blob/375045a7db1bdc7b4f7851f1a59b3f10a2b922ff/src/main/scala/devices/debug/Debug.scala#L170[rocket-chip] RISC-V core. @@ -99,22 +100,22 @@ REQ_VALID is set high, indicating to the DM that a valid request is pending. The DM must respond to a request from the DTM when RSP_READY is high. -The status of the response is indicated by the RSP_OP signal (see ). The +The status of the response is indicated by the RSP_OP signal (see {dmi-op}). The data of the response is driven to RSP_DATA. A pending response is signalled by setting RSP_VALID. [[tab:dmi_signals]] .Signals for the suggested DMI between one DTM and one DM -[cols="<,<,<,<",options="header",] +[%autowidth,align="center",float="center",cols="<,<,<,<",options="header",frame=ends] |=== |Signal |Width |Source |Description |REQ_VALID |1 |DTM |Indicates that a valid request is pending |REQ_READY |1 |DM |Indicates that the DM is able to process a request -|REQ_ADDRESS | |DTM |Requested address +|REQ_ADDRESS |{dtmcs-abits} |DTM |Requested address |REQ_DATA |32 |DTM |Requested data -|REQ_OP |2 |DTM |Same meaning as the field +|REQ_OP |2 |DTM |Same meaning as the {dmi-op} field |RSP_VALID |1 |DM |Indicates that a valid respond is pending |RSP_READY |1 |DTM |Indicates that the DTM is able to process a respond |RSP_DATA |32 |DM |Response data -|RSP_OP |2 |DM |Same meaning as the field +|RSP_OP |2 |DM |Same meaning as the {dmi-op} field |===