How to use CSAT CoreSight Components
Introduction
CSAT includes something called a CoreSight component to provide a convenient way to access and control particular CoreSight devices on the debug bus. A CoreSight device is a device which adheres to the Arm CoreSight Architecture Specification.
In this tutorial, we are going to look at:
- What CoreSight Components are available in CSAT
- What the CSAT CoreSight Component commands are and how to use them
- How to access memory using a CSAT CoreSight Component
- How to access the debug registers of a CoreSight device using a CSAT CoreSight Component
- How to create multiple CSAT CoreSight Components of the same type
- How to create an alias for a CSAT CoreSight Component so it is easier to tell the different CSAT CoreSight Components apart
The main documentation resource for CSAT CoreSight Components is the CSAT User Manual. A link to the CSAT User Manual can be found in the Resource section at the bottom of this tutorial.
Available CoreSight Components
The below table lists from left to right:
- The different CSAT CoreSight components available
- Which CoreSight devices you use the different CSAT CoreSight components with
- The architecture of the system or core the CSAT component is appropriate for
- Whether you can use the CSAT CoreSight component to access the CoreSight device's registers
- Whether you can use the CSAT CoreSight component to access memory via the CoreSight device
CSAT CoreSight Component |
CoreSight device the component is used for |
System Architecture or Core that applies |
CSAT Register access support |
CSAT Memory access support |
|
Cross Trigger Interface (CTI) |
Armv7-A/R |
Yes |
No |
|
Embedded Trace Buffer (ETB) |
Armv7-A/R and Armv8-A |
Yes |
No |
|
Embedded Trace Macrocell v3 and later |
Armv7-A/R |
Yes |
No |
|
Embedded Trace Macrocell v4 |
Armv8-A |
Yes |
No |
|
Instrumentation Trace Macrocell (ITM) |
Armv7-A/R and Armv8-A |
Yes |
No |
|
Cortex-A9 Performance Monitor Unit (PMU) |
Cortex-A9 |
Yes |
No |
|
Program Trace Macrocell |
Armv7-A/R and Armv8-A |
Yes |
No |
|
Trace Funnel (FUNNEL) |
Armv7-A/R and Armv8-A |
Yes |
No |
|
Trace Port Interface Unit (TPIU) |
Armv7-A/R and Armv8-A |
Yes |
No |
|
Armv7-A/R debug interface |
Armv7-A/R |
Yes |
Yes |
|
System Trace Macrocell |
Armv7-A/R and Armv8-A |
Yes |
No |
|
Cortex-M3 debug registers |
Armv7-M |
Yes |
No |
|
Cortex-M3 Data Watchpoint Trace Unit (DWT) |
Cortex-M3 |
Yes |
No |
|
Cortex-M3 Embedded Trace Macrocell |
Cortex-M3 |
Yes |
No |
|
Cortex-M3 Trace Port Interface Unit |
Cortex-M3 |
Yes |
No |
|
Armv8-A debug interface |
Armv8-A |
Yes |
Yes |
|
Armv8-A Cross Trigger Interface |
Armv8-A |
Yes |
No |
|
Armv8-A Performance Monitor Unit |
Armv8-A |
Yes |
No |
|
Trace Replicator |
Armv7-A/R and Armv8-A |
Yes |
No |
|
Granular Power Requester |
Armv7-A/R and Armv8-A |
Yes |
No |
|
Standard ROM Table |
Armv7-A/R and Armv8-A |
Yes |
No |
|
Timestamp unit – control access |
Armv7-A/R and Armv8-A |
Yes |
No |
|
Timestamp unit – read only access |
Armv7-A/R and Armv8-A |
Yes |
No |
|
Trace Memory Controller (TMC, ETF, ETR) |
Armv7-A/R and Armv8-A |
Yes |
No |
Looking at the above table, you can conclude all the defined CSAT CoreSight components can be used to access the corresponding CoreSight device’s registers. However, only the v7dbg and v8cs components can utilize the corresponding CoreSight device to access memory.
There are Armv8 versions for some of the CSAT CoreSight components because the architecture changed between Armv8-A and Armv7-A/R.
NOTE: The v8cs, v8cti, v8pmu, gpr, romtable, tstmp_ctrl, tstmp_ro, tmc, and trep components are only available in CSAT version 2 and later. CSAT version 2.x ships with DS-5 version 5.24 and later.
For the remainder of this tutorial, we will refer to “CSAT CoreSight component” or “CoreSight component” as just “component”.
Test Platform Information
Testing Information
The CSAT scripts in this tutorial have been tested with the Arm Versatile Express with the CoreTile Express A15x2 A7x3 (V2P-CA15_A7) and the Juno R2 Arm Development Board (Juno R2). CSAT version 2.6.3 which ships with DS-5 5.24.1 was used. Links to the board documentation can be found in the Resource section at the bottom of this tutorial.
The scripts make use of:
- The V2P-CA15_A7 Cortex-A7_0 and Cortex-A7_1 cores to exercise the CoreSight architecture implemented by the Armv7-A
- The Juno R2 Cortex-A72_0 and Cortex-A72_1 cores to exercise the CoreSight architecture implemented by the Armv8-A
The V2P-CA15_A7 and Juno R2 CSAT scripts assume that the board has been stopped before Linux boots, DS-5 is already connected to the above mentioned processors, the processors are halted in DS-5, and ETM DSTREAM tracing is enabled. The CSAT scripts can be run from “<DS-5 installation directory>\bin”.
The below information details what the different addresses used in the scripts are:
V2P-CA15_A7 scripts
Device | CoreSight base address |
Cortex-A7_0 | 0x82030000 |
Cortex-A7_1 | 0x82032000 |
TPIU | 0x80030000 |
ETM_0 | 0x8203C000 |
ETM_1 | 0x8203D000 |
DDR memory is located at address 0x80000000
on the V2P-CA15_A7 board.
Juno R2 scripts
Device | CoreSight base address |
Cortex-A72_0 | 0x82010000 |
Cortex-A72_1 | 0x82110000 |
TPIU | 0x80030000 |
ETM_0 | 0x82040000 |
ETM_1 | 0x82140000 |
SRAM memory is located at address 0x2E000000
on the Juno R2 board.
All the CoreSight devices for both boards are attached to the Debug Access Port (DAP) AMBA Peripheral Bus Access Port (APB-AP) at index 1.
Debug Register Information
The CSAT scripts in this tutorial access particular CoreSight debug registers to exercise some CSAT commands. Below is a listing of the different debug registers accessed, which architecture the debug register belongs to, the register name used by CSAT to reference the register, and the debug register offset.
Component |
Full Debug Register Name |
Debug Register Name |
CSAT Register Name |
Debug Register Offset |
Armv7-A/R and Armv8-A cores |
(External) Debug Device ID (Register 0) |
|
devid |
|
Armv7-A/R and Armv8-A cores |
OS Lock Access |
|
oslar for v7-A and oslar_el1 for v8-A |
|
Armv7-A/R core |
Multiprocessor Affinity |
|
- |
|
Armv8-A core |
External Debug Device Affinity |
|
devaff0 |
|
ETM |
ID |
|
etmid |
|
ETM |
CoreSight Trace ID |
|
cstid |
|
ETM4 |
Trace Device Type |
|
devtypeid |
|
ETM4 |
Trace ID |
|
traceidr |
|
TPIU |
Current Port Size |
|
currportsize |
|
A full listing of the registers accessible via the components can be found in the included cscompdata.dat file or by executing the “<component>.n rlist” CSAT command. The cscompdata.data file can be found in DS-5 in the “<DS_5 installation directory>\sw\debughw\tools2” directory.
NOTE: The CSAT register names used may not exactly match the register names listed in the device’s TRM.
Component Commands
You characterize a component using <component> commands. Below are the different variants of the <component> commands:
-
<component>.n baseaddr <address_value>
-
<component>.n [fastwordaccess={true|false}]
-
<component>.n active
-
<component>.n
Set the CoreSight base address to the address provided for the specified component (<address_value>). You should use the CoreSight base address of the CoreSight device you want to work with.
Set the fastwordaccess setting of the specified component. The fastwordaccess setting determines whether the Debug Status and Control Register (DSCR) Debug Communications Channel (DCC) transfer mode bits are set to “fast” for memory operations. More information about about DSCR DCC can be found in the Arm Reference Manual for the core you are using. The fastwordaccess setting is set to true by default.
Set the active setting of the specified component. The active setting determines which component is used when performing a memory read command using the v7dbg or v8cs option for <ap_no>.
View the current settings for the specified component.
NOTE: For all the above commands, .n specifies the component instances you wish to work with. Not specifying .n (i.e using just v7dbg, v8cs, etb, etc…) will cause the <component>.0 instance to be used.
You will need to set the AP index for the component to the DAP AP index the CoreSight device is attached to.
You can globally set all components to the same AP index by using the below cscomp command:
cscomp def_apidx <val>
<val> is the AP index number.
If not all the CoreSight devices are connected to the same AP, you can override the AP index for the device by using the below command:
<component>.n apidx <val>
<val> is the AP index number.
In order to create a component instance, you will need to:
- Setup the base address
- Setup the DAP AP index
Accessing Memory
Using the v7dbg or v8cs option instead of the AP number (<ap_no>) when performing a memory operation (like dmr and dmw) causes the memory access to be performed using the core rather than the DAP AP. This is useful for systems where the desired AP is not attached to system memory.
Note: 64 bit addressing is not possible if the v7dbg option is used for the AP number
Below are two example CSAT scripts which define and use a v7dbg and v8cs component to load memory from RAM.
V2P-CA15_A7 script
csat
con USB
chain dev=?
dvo 0
dpe
v7dbg baseaddr 0x82030000 #
cscomp def_apidx 1 # set the dep_apidx setting to the AP number for the DAP’s APB-AP
dmr v7dbg 0x80000000 1
dmw v7dbg 0x80000000 0xDEADBEEF
dmr v7dbg 0x80000000 1
exit
Juno R2 Script
csat
con USB
chain dev=?
dvo 0
dpe
v8cs baseaddr 0x82010000
cscomp def_apidx 1
dmr v8cs 0x2E000000 1
dmw v8cs 0x2E000000 0xDEADBEEF
dmr v8cs 0x2E000000 1
exit
Accessing Debug Registers
You can use the <component> command to access the CoreSight device’s debug registers. Below are the component register access commands:
-
Register Read
-
Register Write
-
Register Read-Modify-Write
<component>.n rr <offset>|<reg_name>|<group_name>| all
where
<offset> = Offset of the CoreSight debug register to be read
<reg_name> = the CSAT name for the CoreSight debug register to be read
<group_name> = request a group of debug registers to be read. A listing of the available <group_name> values can be found in the cscompdata.dat file.
all = requests all available debug registers for the component to be read
<component>.n rw <offset>|<reg_name> <value>
where
<offset> = Offset of the CoreSight debug register to be written
<reg_name> = the CSAT name of the CoreSight debug register to be written
<value> = value to be written
<component>.n rmw <offset>|<reg_name> <reg_write_value> <mask>
where
<offset> = Offset of the CoreSight debug register to be written
<reg_name> = the CSAT name of the CoreSight debug register to be written
<reg_write_value> = value to be written
<mask> = mask value to be ANDed with <reg_write_value> to determine the bits to be altered
The below scripts creates v7dbg, v8cs, tpiu, and etm component instances to access the debug registers for a v7-A core, a v8-A core, a TPIU, and an ETM respectively.
V2P-CA15_A7 script
csat
con USB
chain dev=?
dvo 0
dpe
v7dbg baseaddr 0x82030000
tpiu baseaddr 0x80030000
etm baseaddr 0x8203C000
cscomp def_apidx 1
v7dbg rr devid # reads the components Device ID
v7dbg rw oslar 0xC5ACCE55
etm rr etmid
etm rw cstid 0x2
tpiu rw currportsize 0x8000 # set port size to 16 bits
tpiu rr currportsize
exit
JUNO R2 Script
csat
con USB
chain dev=?
dvo 0
dpe
v8cs baseaddr 0x82010000
tpiu baseaddr 0x80030000
etm4 baseaddr 0x82040000
cscomp def_apidx 1
v8cs rr devid # reads the components Device ID
v8cs rw oslar_el1 0xC5ACCE55
etm4 rr devtypeid
etm4 rw traceidr 0x2
tpiu rw currportsize 0x8000 # set port size to 16 bits
tpiu rr currportsize
exit
Having Multiple Components of the Same Type
You can have more than one instance of a particular component. The first component of a particular type is <component>.0 or <component>.0 by default. Any additional components needed to be marked with a .n identifier.
The below scripts create two v7dbg or v8cs component instances and two etm component instances and reads and writes to the different debug registers for the different instances.
V2P-CA15_A7 script
csat
con USB
chain dev=?
dvo 0
dpe
v7dbg baseaddr 0x82030000
v7dbg.1 baseaddr 0x82032000
etm.0 baseaddr 0x8203C000
etm.1 baseaddr 0x8203D000
cscomp def_apidx 1
dmr v7dbg.0 0x80000000 1
dmw v7dbg.0 0x80000000 0x0
dmr v7dbg.0 0x80000000 1
dmr v7dbg.1 0x80000000 1
dmw v7dbg.1 0x80000000 0xDEADBEEF
dmr v7dbg.1 0x80000000 1
etm.0 rw cstid 0x2
etm.1 rw cstid 0x4
etm.0 rr cstid # should be 0x2
etm.1 rr cstid # should be 0x4
exit
Juno R2 Script
csat
con USB
chain dev=?
dvo 0
dpe
v8cs baseaddr 0x82010000
v8cs.1 baseaddr 0x82110000
etm4.0 baseaddr 0x82040000
etm4.1 baseaddr 0x82140000
cscomp def_apidx 1
dmr v8cs.0 0x2E000000 1
dmw v8cs.0 0x2E000000 0x0
dmr v8cs.0 0x2E000000 1
dmr v8cs.1 0x2E000000 1
dmw v8cs.1 0x2E000000 0xDEADBEEF
dmr v8cs.1 0x2E000000 1
etm4.0 rw traceidr 0x2
etm4.1 rw traceidr 0x4
etm4.0 rr traceidr # should be 0x2
etm4.1 rr traceidr # should be 0x4
exit
Alias Command
You can use the alias command (alias) to make the created v7dbg or v8cs component names more meaningful.
The below scripts create two v7dbg or v8cs component instances and two etm component instances, creates alias for the different v7dbg, v8cs, and etms, and reads and writes to the different debug registers for the different instances.
V2P-CA15_A7 script
csat
con USB
chain dev=?
dvo 0
dpe
v7dbg baseaddr 0x82030000
v7dbg.1 baseaddr 0x82032000
etm.0 baseaddr 0x8203C000
etm.1 baseaddr 0x8203D000
cscomp def_apidx 1
alias v7dbg.0 A70 # A70 = v7dbg.0
alias v7dbg.1 A71 # A71 = v7dbg.1
alias etm.0 etm_A70 # etm_A70 = etm.0
alias etm.1 etm_A71 # etm_A71 = etm.1
A70 rr 0xD14 # read MPIDR from v7dbg.0 (bottom byte should be 0)
A71 rr 0xD14 # read MPIDR from v7dbg.1 (bottom byte should be 1)
etm_A70 rw cstid 0x2
etm_A71 rw cstid 0x4
etm_A70 rr cstid # should be 0x2
etm_A71 rr cstid # should be 0x4
exit
Juno R2 script
csat
con USB
chain dev=?
dvo 0
dpe
v8cs baseaddr 0x82010000
v8cs.1 baseaddr 0x82110000
etm4.0 baseaddr 0x82040000
etm4.1 baseaddr 0x82140000
cscomp def_apidx 1
alias v8cs.0 A720 # A720 = v8cs.0
alias v8cs.1 A721 # A721 = v8cs.1
alias etm4.0 etm_A720 # etm_A720 = etm.0
alias etm4.1 etm_A721 # etm_A721 = etm.1
A720 rr 0xFA8 # read EDDEVAFF0 from v8cs.0 (bottom byte should be 0)
A721 rr 0xFA8 # read EDDEVAFF0 from v8cs.1 (bottom byte should be 1)
etm_A720 rw traceidr 0x2
etm_A721 rw traceidr 0x4
etm_A720 rr traceidr # should be 0x2
etm_A721 rr traceidr # should be 0x4
exit
Conclusion
This tutorial goes through the available CSAT CoreSight Components and provides examples for accessing memory and debug registers with certain components. The tutorial also explains how to create multiple instances of the same CSAT CoreSight Component and how to create aliases for the different component instances. Additional or different steps may be required to perform the operations perform by the different CSAT scripts if you are using different boards.
Resources
Cortex-A7 MPCore Technical Reference Manual
Arm Cortex-A72 MPCore Processor Technical Reference Manual
Embedded Trace Macrocell (ETMv4) Architecture Specification
Embedded Trace Macrocell Architecture Specification ETMv1.0 to ETMv3.5
CoreSight Components Technical Reference Manual
CoreSight Access Tool (CSAT) User Guide
Juno r2 Arm Development Platform SoC Technical Reference Manual