Difference between revisions of "J-Link RISC-V"
(→RISC-V behind a CoreSight DAP) |
|||
Line 72: | Line 72: | ||
<source> |
<source> |
||
JTAG/SWD -> SWJ-DP -> APB-AP -> DMI registers |
JTAG/SWD -> SWJ-DP -> APB-AP -> DMI registers |
||
+ | or |
||
+ | JTAG/SWD -> SWJ-DP -> AHB-AP -> DMI registers |
||
</source> |
</source> |
||
+ | When using RISC-V behind a DAP, some considerations need to be taken into account: |
||
− | === Considerations === |
||
+ | * There is no ROM table scan available for RISC-V |
||
− | When using RISC-V behind a DAP, some considerations need to be taken into account. |
||
+ | * J-Link cannot auto-detect behind which AP the RISC-V can be found |
||
− | |||
+ | * J-Link cannot auto-detect where in the AP address space the RISC-V DMI registers can be found |
||
− | ==== DMI registers base address ==== |
||
+ | * For such setups, the user needs to manually specify where to find the RISC-V core in the DAP setup |
||
− | In contrast to an ARM core, for the RISC-V there are no ROM tables etc. from which J-Link could determine the base address of the DMI registers. By default, J-Link will assume 0x00000000 as the base address for the DMI registers if a RISC-V behind a DAP is found. You may specify a different base address via J-Link script files. Such a script file would look like this: |
||
+ | Example script file to specify location of RISC-V in DAP setup: |
||
− | <source> |
||
+ | <source lang="C"> |
||
− | int InitTarget(void) { |
||
+ | void ConfigTargetSettings(void) { |
||
− | JLINK_ExecCommand("CORESIGHT_SetCoreBaseAddr = 0x0"); // Base address where DMI registers can be found in the APB address space |
||
+ | // |
||
− | JLINK_ExecCommand("CORESIGHT_SetIndexAPBAPToUse = 0"); // Use AP[x] to communicate with the RISC-V |
||
+ | // Specify AP map and where to find each AP in the CoreSight address space: |
||
+ | // |
||
+ | JLINK_ExecCommand("CORESIGHT_AddAP = Index=0 Type=AHB-AP BaseAddr=0x00002000"); // AP0: AHB-AP that connects to Cortex-M4 core in chip |
||
+ | JLINK_ExecCommand("CORESIGHT_AddAP = Index=1 Type=APB-AP BaseAddr=0x00004000"); // AP1: APB-AP that connects to RISC-V core in chip |
||
+ | JLINK_ExecCommand("CORESIGHT_AddAP = Index=2 Type=AXI-AP BaseAddr=0x00006000"); // AP2: AXI-AP that allows DMA like access to system memories |
||
+ | // |
||
+ | // Setup parameters for RISC-V connection |
||
+ | // If RISC-V is behind an APB-AP, use "CORESIGHT_SetIndexAPBAPToUse" |
||
+ | // If RISC-V is behind an AHB-AP, use "CORESIGHT_SetIndexAHBAPToUse" |
||
+ | // |
||
+ | JLINK_ExecCommand("CORESIGHT_SetIndexAPBAPToUse = 1"); // AP (from previously specified AP map) that connects to the RISC-V DMI registers |
||
+ | JLINK_ExecCommand("CORESIGHT_SetCoreBaseAddr = 0x0"); // Address in AP address space where DMI registers can be found |
||
return 0; |
return 0; |
||
} |
} |
||
</source> |
</source> |
||
+ | |||
+ | '''Note:''' If a specific device (manufacturer + name) is selected in the J-Link software and not a generic RV32 / RV64,<br> |
||
+ | J-Link usually has a compiled-in script available for that device which already specifies the parameters from above, so the user does not need to create such a script file. |
||
+ | |||
For more information about J-Link script files and how to use them, please refer to the wiki article: [[J-Link script files]] |
For more information about J-Link script files and how to use them, please refer to the wiki article: [[J-Link script files]] |
||
Revision as of 12:02, 14 March 2023
This article handles J-Link related RISC-V specifics. It is assumed that RISC-V as a term is already known. For more generic information about RISC-V, please refer to the RISC-V knowledge base article
Contents
Memory accesses
The RISC-V debug specification defines multiple ways to access memory on a RISC-V based core:
- Via program + data buffers (using program buffers to feed load / store instructions to the core)
- Via system bus access (DMA-like access to memory)
- Via abstract commands
When connecting to a RISC-V based core, J-Link will auto-detect which of the afore-mentioned memory access types are implemented and decides what access types to use by default.
The logic in J-Link is as follows:
//
// Determine memory access support on target side
//
if (NumDataBuf > 0) {
SupportProgBuf = TRUE;
}
if (sbcs.sbasize > 0) {
SupportSBA = TRUE;
}
SupportAAM = TRUE;
//
// Determine defaults used by J-Link while core is halted
//
if (SupportProgBuf == TRUE) {
UseMemAccTypeWhileCoreHalted = MEM_ACC_PROG_BUF;
} else if (SupportSBA == TRUE) {
UseMemAccTypeWhileCoreHalted = MEM_ACC_SBA;
} else {
UseMemAccTypeWhileCoreHalted = MEM_ACC_AAM;
}
//
// Determine defaults used by J-Link while core is running
//
if (SupportSBA == TRUE) {
UseMemAccTypeWhileCoreRunning = MEM_ACC_SBA;
} else {
UseMemAccTypeWhileCoreRunning = MEM_ACC_NONE;
}
Implementation examples:
- If an implementation supports SBA only, it should implement NumProgBuf = 0 and NumDataBuf = 0
- If an implementation supports AAM only, it should implement NumProgBuf = 0 and NumDataBuf = 0 and sbcs.sbasize = 0.
Force default memory access type
Currently, there is no way to force J-Link to use a certain memory access type by default. This is planned for a future version of the J-Link software.
Watchpoint support
J-Link supports data breakpoints (watchpoints) for RISC-V CPUs which are based on the V0.13 standard of the RISC-V debug spec. In general, the following combinations are possible for a watchpoint:
- Addr == EXACT, Data == EXACT
- Addr == EXACT, Data == ANY
- Addr == EXACT, Data == RANGE
- Addr == RANGE, Data == EXACT
- Addr == RANGE, Data == ANY
- Addr == RANGE, Data == RANGE
- Addr == ANY, Data == EXACT
- Addr == ANY, Data == ANY
- Addr == ANY, Data == RANGE
Note: Right now, only the ones shown in bold are supported by J-Link
RISC-V behind a CoreSight DAP
The official debug spec. for RISC-V only describes how to implement a RISC-V debug interface via JTAG and a DM. The topology looks like this:
JTAG TAP -> DM -> DMI registers
However, for hybrid designs where there are for example ARM cores next to the RISC-V in the same system, it makes sense to put the RISC-V behind a DAP; so the ARM cores and the RISC-V can be accessed via the same debug connector and also other protocols like SWD can be supported this way. The topology looks like this:
JTAG/SWD -> SWJ-DP -> APB-AP -> DMI registers
or
JTAG/SWD -> SWJ-DP -> AHB-AP -> DMI registers
When using RISC-V behind a DAP, some considerations need to be taken into account:
- There is no ROM table scan available for RISC-V
- J-Link cannot auto-detect behind which AP the RISC-V can be found
- J-Link cannot auto-detect where in the AP address space the RISC-V DMI registers can be found
- For such setups, the user needs to manually specify where to find the RISC-V core in the DAP setup
Example script file to specify location of RISC-V in DAP setup:
void ConfigTargetSettings(void) {
//
// Specify AP map and where to find each AP in the CoreSight address space:
//
JLINK_ExecCommand("CORESIGHT_AddAP = Index=0 Type=AHB-AP BaseAddr=0x00002000"); // AP0: AHB-AP that connects to Cortex-M4 core in chip
JLINK_ExecCommand("CORESIGHT_AddAP = Index=1 Type=APB-AP BaseAddr=0x00004000"); // AP1: APB-AP that connects to RISC-V core in chip
JLINK_ExecCommand("CORESIGHT_AddAP = Index=2 Type=AXI-AP BaseAddr=0x00006000"); // AP2: AXI-AP that allows DMA like access to system memories
//
// Setup parameters for RISC-V connection
// If RISC-V is behind an APB-AP, use "CORESIGHT_SetIndexAPBAPToUse"
// If RISC-V is behind an AHB-AP, use "CORESIGHT_SetIndexAHBAPToUse"
//
JLINK_ExecCommand("CORESIGHT_SetIndexAPBAPToUse = 1"); // AP (from previously specified AP map) that connects to the RISC-V DMI registers
JLINK_ExecCommand("CORESIGHT_SetCoreBaseAddr = 0x0"); // Address in AP address space where DMI registers can be found
return 0;
}
Note: If a specific device (manufacturer + name) is selected in the J-Link software and not a generic RV32 / RV64,
J-Link usually has a compiled-in script available for that device which already specifies the parameters from above, so the user does not need to create such a script file.
For more information about J-Link script files and how to use them, please refer to the wiki article: J-Link script files
JTAG chains
When using cJTAG / JTAG as target interface, J-Link by default tries to identify the CPU-TAP by its TAPId to know which TAP to communicate with to control the RISC-V core. While for most cores like ARM, the TAPId is more or less standardized, for RISC-V almost every vendor does their own TAPId.
If for example the JTAG chain consists of a single TAP with IRLen == 5, J-Link assumes that this TAP is the CPU-TAP. However, in case there is a JTAG chain with multiple TAPs that have IRLen == 5 but none of the TAPIds is known to J-Link, the TAP to connect to needs to be manually specified by the user.
The easiest way to manually specify the JTAG chain and TAP to connect to is a J-Link script file. Below are two example script for a JTAG chain that consists of 2 CPU-TAPs (each a RISC-V with IRLen == 5) that specifies to connect to TAP #0 or #1 resprectively.