hi,
This is a request for comments for adapting arm coresight tracing in
openocd. It is motivated by :
- Current implementation of CoreSight tracing on ARM was developed
for ARM7, ARM9 and ARM11. this is now outdated and few developers are
using it.
- Currently, there is an ongoing work on GDB to use CoreSight ETM
traces to provide branch traces (btrace). This will offer instructions
and functions histories, as well as execution record and replay in
forwards and backwards direction.
This RFC is to discuss upgrading Support for ARM CoreSight tracing to:
- Support interfacing with GDB for using the ETM traces
- Support saving traces in a file
- Support streaming traces to the TCL server
*Current status:*
- ETM IP configuration is outdated: On Cortex devices, access to
CoreSight trace IPs (ETM, ITM ...) is not done directly through JTAG
anymore, but rather though MEM-AP
- ETM traces parsing is outdated: it is not compatible with ETMv3
and ETMv4
*Proposal:*
- Provide device discovery with three classes of CoreSight tracing
devices: trace sources (ETM, PTM, ITM..), trace links (funnels) and
trace sinks (ETB, TMC, TPIU ...) with well defined interfaces for using
them.
- Provide two ways for collecting the traces: though MEM-AP for
internal sinks (ETB, TMC) and through TPA (traces port analyzer) for
external sinks (TPIU) with well defined interfaces for using them.
- Provide a mean for specifying what to do with the traces ( use in
GDB, save to a file, steam to TCL server).
This will imply:
- Creating dedicated "drivers" for ITM IP, ETMv3 IP, ETMv4 IP,
Funnel IP, ETB IP, TMC IP and TPIU IP resp cs_itm.c, cs_etmv3.c,
cs_etm_v4.c, cs_funnel.c, cs_etb.c, cs_tmc.c, cs_tpiu.c.
- Update drivers for collecting traces either though MEM-AP or
through TPA (trace port analyzer).
- Creating needed commands for configuring the IPs in order to use
them and integrate them in the targets configuration scripts.
- Create a driver for TPA
*User interface
*
*GENERIC CORESIGHT DEVICES*
- arm-cs-device create device_name -target target_name -dap
dap_name -ap-num apn -baseaddr base_address -type type : create a
coresight device, with generic coresight registers only
- arm-cs-device init : initialize coresight devices. detect device
type, append device specific register and assign device operations and
context
- arm-cs-device list: list coresight devices with their dap names,
ap, base addresses and types
- arm-cs-device path (add|remove) device_name: add or remove a
device to trace path, the order is important since it will be followed
in the enable/disable order. it should be sources then links then sinks
- arm-cs-device path list : list the devices in trace path.
/ - cs-device//_name/ dump: dumps the registers of a cs device.
*Device specific commands*
*ETM*
- /etm_name/ info: gives info about the etm block, version, IP
configuration and availability of features.
- /etm_name/ status: gives the status of the etm block (started,
stopped, current config etc..)
- /etm_name /config -trace_id trace_id [type context_id_bits
cycle_accurate timestamp ...] : change the configuration of etm, the
list can be extended as needed to support traces filtering and triggering.
- /etm_name/ start : applies the configuration to the hardware and
starts emitting etm traces.
- /etm_name/ stop : stop emitting etm traces.
*ITM*
- /itm_name/ info: gives info about the itm block, version, IP
configuration and availability of features.
- /itm_name/ status
- /itm_name/ config -trace-id trace_id -enable-port port_number
-disable-port port_number -timestamp-prescaler prescaler -enable-dwt
(on|off) -enable-sync (on|off) -sync-count sync_count etc...
- /itm_name /start : start emitting itm traces
- /itm_name/ stop : stop emitting itm traces
*ETB*
- /etb_name /info: gives info about the etb block, version, IP
configuration and availability of features.
- /etb_name /status
- /etb_name /start//: start collecting CoreSight traces
- /etb_name /stop//: stop collecting CoreSight traces
*TPIU*
- /tpiu_name /info : gives info about the tpiu block, version, IP
configuration and availability of features.
- /tpiu_name/ status
- /tpiu_name /config -pin_protocol (parallel| manchester | nrz)
-port_size port_size -formatter (0|1) -prescaler prescaler
-pin_frequency pin_frequency etc ...
- /tpiu_name /start : start collecting CoreSight traces
- /tpiu_name /stop : stop collecting CoreSight traces
*other devices
*
*TPA*
- tpa info
- tpa status
- tpa config -pin_protocol (parallel| manchester | nrz) -port_size
port_size -pin_frequency pin_frequency -mode (streamed|buffered)
- tpa start
- tpa stop
N.B. config commands modify internal context values. The configuration
will be applied to the hardware in the next start command
*Traces processing*
*CS_TRACES*
- cs_traces output -file filename -tcl_trace -socket port -gdb :
set the destination of collected traces
- cs_traces read -poll (on|off): set traces reading policy
(continuous polling vs on demand)
*Software interfaces*
*Generic interface for coresight device drivers*
struct arm_cs_device {
target_addr_t base;
struct adiv5_ap *ap;
};
enum arm_cs_device_type {
DEV_UNKNOWN, /**< Unknown device */
DEV_ROM, /**< ROM TABLE */
DEV_ETM, /**< ETM (v3 or v4), or PTM */
DEV_ITM, /**< ITM - Software trace stimulus */
DEV_STM, /**< STM - Software trace stimulus */
DEV_FUNNEL, /**< Trace Funnel */
DEV_REPLICATOR, /**< Trace Replicator */
DEV_ETF, /**< Embedded Trace FIFO - Trace memory controller
in ETF mode. */
DEV_ETB, /**< Embedded Trace Buffer - legacy trace buffer or
TMC in ETB/ETR */
DEV_TPIU, /**< Trace Port Interface - external interface to
trace system */
DEV_SWO, /**< Serial Wire Output */
DEV_CTI, /**< Cross Trigger Interface*/
DEV_CPU_DEBUG, /**< Core Debug registers */
DEV_CPU_PMU, /**< Core PMU registers */
DEV_TS, /**< Timestamp generator */
DEV_ELA, /**< Embedded logic analyzer */
DEV_MAX /**< End of type list */
};
struct arm_cs_device_object;
struct arm_cs_device_ops {
int (*init) (struct arm_cs_device_object * self); //initialize a
cs device
int (*configure) (uint32_t what, void * value, struct
arm_cs_device_object * self); //change the context of the device with
new configuration parameters
int (*start) (struct arm_cs_device_object * self); //apply
configuration and start tracing
int (*stop) (struct arm_cs_device_object * self); //stop tracing
int (*status) (struct arm_cs_device_object * self); //get tracing
status
int (*read_traces) (struct arm_cs_device_object * self); //retrieve
the traces
};
#define CS_DEVICE_MAX_OFFSET (0xFFFFFFFF)
struct arm_cs_device_reg_cache{
uint32_t offset;
const char *label;
uint32_t value;
};
struct arm_cs_device_object {
struct list_head lh; //head of the devices list.
struct arm_cs_device cs_device; // to hold info relevant for
accessing the device.
int ap_num; // ap number for accessing this device.
char *name; //name of the device, it will be used afterward for
issuing commands to the device.
enum arm_cs_device_type cs_device_type; //type of the device (etm,
itm, funnel, etb, tpiu etc ...).
struct arm_cs_device_ops *cs_device_ops; // pointer to the
implementation of the operations on the device.
struct arm_cs_device_reg_cache *reg_cache; // cache of device
registers this a pointer to an array ending with a CS_DEVICE_MAX_OFFSET
entry.
void *context; // device specific structure to hold the
configuration and the state of the device.
};
/** Writes a value to register at a given offset from device base address.
* write is using mem-ap to access the device */
extern int arm_cs_device_write_reg(struct arm_cs_device_object *self,
unsigned int offset, uint32_t value);
/** Reads a value from register at a given offset from device base address.
* read is using mem-ap to access the device */
extern int arm_cs_device_read_reg(struct arm_cs_device_object *self,
unsigned int offset, uint32_t *value);
/** Unlocks a CoreSight device. */
extern int arm_cs_device_unlock(struct arm_cs_device_object *self);
/** Locks a CoreSight device. */
extern int arm_cs_device_lock(struct arm_cs_device_object *self);
/** registers arm cs device commands to the openocds command list. */
extern int arm_cs_register_commands(struct command_context *cmd_ctx);
/** append a device specific registers to the generic coresight
registers. */
extern int arm_cs_append_register_cache(struct arm_cs_device_object
*self, struct arm_cs_device_reg_cache *cache_template);
Your feedback and comments are welcome.
Kind Regards
Zied Guermazi