Hi Mike,

thanks for your feedback, I went through the opencsal code and it's a very good reference design, following the implementation done there will make the work much easier. Thanks for the hint!

Here is a small introduction to how OpenOcd operates:

OpenOcd offers a command interface to the user, it can can be used in configuration script files and though a telnet/tcl sockets.

The commands specified below can be used though this interface.

It offers also a "GDB Server" interface to interact with the commands issued by GDB.

here is how the Coresight part is designed:

The usage flow is that the user instantiates and initializes the CoreSight device though the command interface, so that the traces can be used in different use cases: debugging with GDB for ETM and PTM, or streaming the traces to a socket for ITM and STM or saving it into a file to record it in the case of streamed traces (ETM, PTM or or STM or ITM).

Internally, /struct arm_cs_device_ops/ in addition to the context is used to manage the Coresight IPs.

The topology support is designed to be manually configurable. The user has to define the traces path from trace sources to trace sinks including routing them via funnels/replicators though the command interface. /arm-cs-device path (add|remove) device_name/ and /arm-cs-device path list/  are provided to let the user define a trace path. The path is implemented as a list of pointers to /arm_cs_device_object/. to know the order in which the devices have to be enabled/disabled/flushed. We can manage enabling/disabling/flushing the traces of all devices on a path though commands (path enable, path disable ). For the time being I am only offering this functionality through API level (only GDB needs it programmatically, other use cases can use the device specific commands).

Dynamic path calculation at run time can be added once a mean for unambiguously describing the topology is added.

Even-though I am designing a generic way for configuring and handling the traces, the first implementation will focus on cortex M devices, where the solution using the linux kernel perf interface in GDB is not applicable. The same design can be used with Cortex A where a bare metal or an RTOS firmware is traced, once other devices are supported.

Kind Regards

Zied Guermazi

On 27.04.21 11:23, Mike Leach wrote:
HI Zied,

I am not familiar with OpenOCD but I have a few initial general comments:-

1) I would mention STM and ETR as separate devices in terms of the
device specific command sets.
STM is a superset of ITM with more capabilities.
ETR needs additional configuration, but also offers alternate means of
accessing trace data. Accessing the memory buffer used by the ETR is
faster than reading through the register interface.

2) Consider the concept of a trace path. Starting, then stopping and
flushing in the correct order is vital to avoid loss of trace data /
incomplete trace packets. This could be left to the client of the API
to enforce, but providing API calls to define a path from source to
sink, then start / stop that path then allows the library to get the
ordering correct. The value of this does depend on the complexity of
the systems targeted.

3) When implementing you may wish to look if any of the functionality
provided by  CSAL (CoreSight access library) could be re-used. CSAL
provides a lot of the functionality you want so using relevant parts
of this library as a backend for the new API may save time.

Regards

Mike



On Mon, 26 Apr 2021 at 11:46, Zied Guermazi <[email protected]> wrote:
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


--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK
--

*Zied Guermazi*
founder

Trande UG
Leuschnerstraße 2
69469 Weinheim/Germany

Mobile: +491722645127
mailto:[email protected]

*Trande UG*
Leuschnerstraße 2, D-69469 Weinheim; Telefon: +491722645127
Sitz der Gesellschaft: Weinheim- Registergericht: AG Mannheim HRB 736209 - Geschäftsführung: Zied Guermazi

*Confidentiality Note*
This message is intended only for the use of the named recipient(s) and may contain confidential and/or privileged information. If you are not the intended recipient, please contact the sender and delete the message. Any unauthorized use of the information contained in this message is prohibited.




Reply via email to