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



Reply via email to