1OpenCSD Library - Programmers Guide {#prog_guide} 2=================================== 3 4@brief A guide to programming the OpenCSD library. 5 6Introduction and review of Coresight Hardware 7--------------------------------------------- 8 9The OpenCSD trace decode library is designed to allow programmers to decode ARM CoreSight trace 10data. This guide will describe the various stages of configuring and programming a decoder instance 11for a given CoreSight system. 12 13The diagram below shows a typical Coresight trace hardware arrangement 14 15 16 17The design shown has four Cortex cores, each with an ETM, along with a system STM all of which generate trace into the 18trace funnel. The output of the funnel is fed into a trace sink, which might be an ETB or ETR, saving the trace 19which is multiplexed into CoreSight trace frames in the trace sink memory. The colours represent the sources 20of trace data, each of which will be tagged with a CoreSight Trace ID. 21 22### CoreSight Trace ID ### 23The CoreSight Trace ID - also referred to as the Trace Source Channel ID - is a unique 8 bit number programmed 24into each trace source in a system (ETM,PTM,STM) which identifies the source to both the hardware components 25downstream and the software trace decoders. This ID is used 26 27Overview of Configuration and Decode 28------------------------------------ 29 30The OpenCSD library will take the trace data from the trace sink, and when correctly configured and programmed, will 31demultiplex and decode each of the trace sources. 32 33The library supports ETMV3, PTM, ETMv4 and STM trace protocols. The decode occurs in three stages: 34- __Demultiplex__ - the combined trace streams in CoreSight trace frame format are split into their constituent streams according to the CoreSight trace ID. 35- __Packet Processing__ - the individual trace ID streams are resolved into discrete trace packets. 36- __Packet Decode__ - the trace packets are interpreted to produce a decoded representation of instructions executed. 37 38There are input configuration requirements for each stage of the decode process - these allow the decode process to correctly 39interpret the incoming byte stream. 40- __Demultiplex__ - Input flags are set to indicate if the frames are 16 byte aligned or if the stream contains alignment 41bytes between frames. 42- __Packet Processing__ - The hardware configuration of the trace source must be provided. This consists of a sub-set of the 43hardware register values for the source. Each protocol has differing requirements, represented by an input structure of the 44register values. 45- __Packet Decode__ - For ETM/PTM packet decode, this stage requires the memory images of the code executed in order 46to determine the path through the code. These are provided either as memory dumps, or as links to binary code files. 47 48_Note_ : STM, being a largely software generated data trace, does not require memory images to recover the data written by the source 49processors. 50 51The diagram below shows the basic stages of decode for the library when used in a client application: 52 53 54 55The DecodeTree object is a representation of the structure of the CoreSight hardware, but in reverse in that the data is pushed into the 56tree, through the demultiplexor and then along the individual trace stream decode paths till the output decode packets are produced. 57 58These outpup packets are referred to as Generic Trace packets, and are at this stage protocol independent. They consist primarily of 59PE context information and address ranges representing the instructions processed. 60 61### Decode Tree ### 62 63The DecodeTree is the principal wrapper for all the decoders the library supports. This provides a programming 64API which allows the creation of protocol packet processors and decoders. 65 66The API allows the client application to configure the de-multiplexor, create and connect packet processors and 67packet decoders to the trace data streams and collect the output generic decoded trace packets. The DecodeTree 68provides a built in instruction decoder to allow correct trace decode, and an additional API through a memory 69access handler to allow the client applications to provide the images of the traced code in file or memory dump 70format. 71 72Once a DecodeTree is configured, then it can be re-used for multiple sets of captured trace data where the same 73set of applications has been traced, or by changing only the supplied memory images, different traced applications 74on the same hardware configuration. 75 76The process for programming a decode tree for a specific set of trace hardware is as follows;- 771. Create the decode tree and specify the de-multiplexor options. 782. For each trace protocol of interest, use the API to create a decoder, providing the hardware configuration, 79including the CoreSight trace ID for that trace stream. Specify packet processing only, or full decode. Client 80program must know the correct protocol to use for each trace stream. 813. Attach callback(s) to receive the decoded generic trace output (ITrcGenElemIn). 824. Provide the memory images if using full decode. 83 84The DecodeTree can now be used to process the trace data by pushing the captured trace data through the trace 85 data input API call (ITrcDataIn) and analyzing as required the resulting decoded trace (ITrcGenElemIn). 86 87 The objects and connections used for a single trace stream are shown below. 88 89  90 91 All these components can be created and used outside of a DecodeTree, but that is beyond the scope of this 92 guide and expected to be used for custom implementations only. 93 94Programming Examples - decoder configuration. 95--------------------------------------------- 96 97The remainder of this programming guide will provide programming exceprts for each of the required stages 98to get a working decode tree, capable of processing trace data. 99 100The guide will be based on an ETMv4 system, similar to the example above, using the C++ interface, but 101equivalent calls from the C-API wrapper library will also be provided. 102 103The source code for the two test applications `trc_pkt_lister` and `c_api_pkt_print_test` may be used as 104further programming guidance. 105 106### Create the decode tree ### 107 108The first step is to create the decode tree. Key choices here are the flags defining expected trace data 109input format and de-mux operations. 110 111~~~{.cpp} 112 uint32_t formatterCfgFlags = OCSD_DFRMTR_FRAME_MEM_ALIGN; /* basic operational mode for on-chip captured trace */ 113 DecodeTree *pTree = DecodeTree::CreateDecodeTree(OCSD_TRC_SRC_FRAME_FORMATTED, formatterCfgFlags); 114~~~ 115 116This creates a decode tree that is usable in the majority of cases - that is for trace captured in on chip 117RAM via ETB or ETR. Additional flags are available if a TPIU is used that will indicate to the frame de-mux 118that additional frame synchronisation data is present. 119 120In limited cases where the hardware has a single trace source, or only a single source is being used, then 121it is possible to switch off the hardware frame formatter in the ETB/ETR/TPIU. In this case @ref OCSD_TRC_SRC_SINGLE 122 (from enum @ref ocsd_dcd_tree_src_t) may be defined as the first parameter to the function. 123 124C-API version of above code: 125~~~{.c} 126 dcd_tree_handle_t dcdtree_handle = ocsd_create_dcd_tree(OCSD_TRC_SRC_FRAME_FORMATTED, OCSD_DFRMTR_FRAME_MEM_ALIGN); 127~~~ 128 129### Error loggers and printers ### 130 131The library defines a standard error logging interface ITraceErrorLog which many of the key components can register 132with to output errors. The process of registering the source means that errors can be tied to a particular component, 133or CoreSight Trace ID. The library provides a standard error logger object - ocsdDefaultErrorLogger - which 134keeps a copy of the last error logged, plus a copy of the last error logged for each data stream associated 135with a CoreSight trace ID. 136 137The error logger can be attached to an output logger - ocsdMsgLogger - which can print text versions of the 138error, or other error messages, out to screen or logging file. Errors can be filtered according to a severity rating, 139defined by @ref ocsd_err_severity_t. 140 141The DecodeTree will use a default error logger from the library - with a message logger 142that will output to `stderr`. Client applications can adjust the configuration of this error logger and 143message logger, or provide their own configured error logger / message logger pair. 144 145The test program `trc_pkt_lister` provides a customised version of an `ocsdMsgLogger` / `ocsdDefaultErrorLogger` pair 146to ensure that messages and errors are logged to the screen and a file of its choice. This logger is eventually 147passed through to the decode tree. 148 149Code excerpts below (trc_pkt_lister.cpp): 150 151~~~{.cpp} 152 static ocsdMsgLogger logger; 153 static int logOpts = ocsdMsgLogger::OUT_STDOUT | ocsdMsgLogger::OUT_FILE; 154 static std::string logfileName = "trc_pkt_lister.ppl"; 155 156 // ** other vars 157 158 main() { 159 160 // ** some init code 161 162 logger.setLogOpts(logOpts); 163 logger.setLogFileName(logfileName.c_str()); 164 165 166 ocsdDefaultErrorLogger err_log; 167 err_log.initErrorLogger(OCSD_ERR_SEV_INFO); 168 err_log.setOutputLogger(&logger); 169 170 // pass err_log reference into snapshot library code 171 SnapShotReader ss_reader; 172 ss_reader.setErrorLogger(&err_log); 173 174 // ** rest of program 175 } 176~~~ 177 178In the library code for the snapshot reader (ss_to_dcd_tree.cpp): 179 180~~~{.cpp} 181 bool CreateDcdTreeFromSnapShot::createDecodeTree() 182 { 183 // ** create a decode tree 184 185 // use our error logger - don't use the tree default. 186 m_pDecodeTree->setAlternateErrorLogger(m_pErrLogInterface); 187 } 188 189~~~ 190 191__Note__: The Snapshot reader library is test code designed to allow the test application read trace snapshots 192which are in the form defined by the open specification in `./decoder/docs/specs/ARM Trace and Debug Snapshot file format 0v2.pdf` 193 194This format is used in ARM's DS-5 debugger, and the open source CoreSight Access Library (CSAL). 195 196### Configuring decoders ### 197 198The next task is to configure the requried decoders. The client program must know the type of ETM/PTM in use 199to correctly set the decoder configuration. 200 201Each class of trace source has a specific set of register values that the decoder requires to correctly interpret the 202raw trace data and convert it to packets then fully decode. 203 204Configuration of an ETMv4 decoder requires initialisation of the EtmV4Config class, which is achieved by filling in a 205@ref ocsd_etmv4_cfg structure:- 206 207~~~{.c} 208 typedef struct _ocsd_etmv4_cfg 209 { 210 uint32_t reg_idr0; /**< ID0 register */ 211 uint32_t reg_idr1; /**< ID1 register */ 212 uint32_t reg_idr2; /**< ID2 register */ 213 uint32_t reg_idr8; 214 uint32_t reg_idr9; 215 uint32_t reg_idr10; 216 uint32_t reg_idr11; 217 uint32_t reg_idr12; 218 uint32_t reg_idr13; 219 uint32_t reg_configr; /**< Config Register */ 220 uint32_t reg_traceidr; /**< Trace Stream ID register */ 221 ocsd_arch_version_t arch_ver; /**< Architecture version */ 222 ocsd_core_profile_t core_prof; /**< Core Profile */ 223 } ocsd_etmv4_cfg; 224~~~ 225 226The structure contains a number of read-only ID registers, and key programmable control registers that define 227the trace output features - such as if the ETM will output timestamps or cycle counts - and the CoreSight Trace ID. 228 229Once this structure is filled in then the decoder can be configured in the decode tree:- 230 231~~~{.cpp} 232 ocsd_etmv4_cfg config; 233 234 // ... 235 // code to fill in config from programmed registers and id registers 236 // ... 237 238 EtmV4Config configObj(&config); // initialise decoder config class 239 std::string decoderName(OCSD_BUILTIN_DCD_ETMV4I); // use built in ETMv4 instruction decoder. 240 int decoderCreateFlags = OCSD_CREATE_FLG_FULL_DECODER; // decoder type to create - OCSD_CREATE_FLG_PACKET_PROC for packet processor only 241 ocsd_err_t err = pDecodeTree->createDecoder(decoderName, decoderCreateFlags,&configObj); 242~~~ 243 244This code creates a full trace decoder for an ETMv4 source, which consists of a packet processor and packet decoder pair. The decoder is automatically associated with the 245CoreSight Trace ID programmed into the register provided in the `config` structure. 246 247It is also possible to create a packet processor only decoder if the `OCSD_CREATE_FLG_PACKET_PROC` flag is 248used instead. These packet only decoders can be used to create a dump of the raw trace as discrete trace packets. 249 250All decoders a registered with the library using a name - the standard ARM protocols are considered built in 251decoders and are registered automatically. The library contains defined names for these decoders - `OCSD_BUILTIN_DCD_ETMV4I` 252 being the name used for ETMv4 protocol. 253 254The C-API uses the call create_generic_decoder() with the same configuration structure:- 255 256~~~{.c} 257 ocsd_etmv4_cfg config; 258 259 // ... 260 // code to fill in config from programmed registers and id registers 261 // ... 262 263 const char * decoderName = OCSD_BUILTIN_DCD_ETMV4I); // use built in ETMv4 instruction decoder. 264 int decoderCreateFlags = OCSD_CREATE_FLG_FULL_DECODER; // decoder type to create - OCSD_CREATE_FLG_PACKET_PROC for packet processor only 265 void *p_context = // <some_client_context> 266 ocsd_err_t err = create_generic_decoder(dcdtree_handle,decoderName,(void *)&config,p_context); 267~~~ 268 269The configuration must be completed for each trace source in the decode tree which requires decoding. 270 271The different trace source types have different configuration structures, classes and names 272 273| protocol | config struct | class | name define | 274|:----------|:--------------------|:------------|:-----------------------------| 275| __ETMv4__ | @ref ocsd_etmv4_cfg | EtmV4Config | @ref OCSD_BUILTIN_DCD_ETMV4I | 276| __ETMv3__ | @ref ocsd_etmv3_cfg | EtmV3Config | @ref OCSD_BUILTIN_DCD_ETMV3 | 277| __PTM__ | @ref ocsd_ptm_cfg | PtmConfig | @ref OCSD_BUILTIN_DCD_PTM | 278| __STM__ | @ref ocsd_stm_cfg | STMConfig | @ref OCSD_BUILTIN_DCD_STM | 279 280### Adding in Memory Images ### 281 282Memory images are needed when a full trace decode is required. Memory images consist of a base address and length, and 283contain instruction opcodes that may be executed during the operation of the traced program. The images are used by 284the decoder to follow the path of the traced program by interpreting the information contained within the trace that 285defines which program branches are taken and the target addresses of those branches. 286 287The library defined memory image accessor objects, which can be simple memory buffers, files containing the binary 288code image, or a callback that allows the client to handle memory accesses directly. When files are used, the 289 object may contain a set of base addresses and lengths, with offsets into the file - allowing the decoder 290 to directly access multiple code segments in executable image files. 291 292Memory image objects are collated by a memory mapper. This interfaces to the decoder through the ITargetMemAccess interface, 293and selects the correct image object for the address requested by the decoder. The memory mapper will also validate image 294objects as they are added to the decoder, and will not permit overlapping images. 295 296 297 298The client can add memory images to the decoder via API calls to the decode tree. These methods add memory image accessors of various 299types to be managed by a memory access mapper:- 300 301~~~{.cpp} 302 class DecodeTree { 303 ///... 304 ocsd_err_t addBufferMemAcc(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint8_t *p_mem_buffer, const uint32_t mem_length); 305 ocsd_err_t addBinFileMemAcc(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const std::string &filepath); 306 ocsd_err_t addBinFileRegionMemAcc(const ocsd_file_mem_region_t *region_array, const int num_regions, const ocsd_mem_space_acc_t mem_space, const std::string &filepath); */ 307 ocsd_err_t addCallbackMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, const ocsd_mem_space_acc_t mem_space, Fn_MemAcc_CB p_cb_func, const void *p_context); 308 ///... 309 } 310~~~ 311 312It is further possible to differentiate between memory image access objects by the memory space for which they are valid. If it is known that a certain code image 313is present in secure EL3, then an image can be associated with the @ref ocsd_mem_space_acc_t type value @ref OCSD_MEM_SPACE_EL3, which will allow another image to be 314present at the same address but a different exception level. However, for the majority of systems, such detailed knowledge of the code is not available, or 315overlaps across memory spaces do not occur. In these cases, and for general use (including Linux trace decode), @ref OCSD_MEM_SPACE_ANY should be used. 316 317The C-API contains a similar set of calls to set up memory access objects:- 318 319~~~{.c} 320 OCSD_C_API ocsd_err_t ocsd_dt_add_buffer_mem_acc(const dcd_tree_handle_t handle, const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint8_t *p_mem_buffer, const uint32_t mem_length); 321 OCSD_C_API ocsd_err_t ocsd_dt_add_binfile_mem_acc(const dcd_tree_handle_t handle, const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const char *filepath); 322 OCSD_C_API ocsd_err_t ocsd_dt_add_binfile_region_mem_acc(const dcd_tree_handle_t handle, const ocsd_file_mem_region_t *region_array, const int num_regions, const ocsd_mem_space_acc_t mem_space, const char *filepath); 323 OCSD_C_API ocsd_err_t ocsd_dt_add_callback_mem_acc(const dcd_tree_handle_t handle, const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, const ocsd_mem_space_acc_t mem_space, Fn_MemAcc_CB p_cb_func, const void *p_context); 324~~~ 325 326 327### Adding the output callbacks ### 328 329The decoded trace output ia collect by the client application through callback functions registered with the library. 330 331Depending on the decode configuration chosen, this can be in the form of the fully decoded trace output as generic trace 332packets, or discrete trace packets for each trace stream ID. 333 334__Full Decode__ 335 336When full decode is chosen then all output is via the generic packet interface: 337 338~~~{.cpp} 339 class ITrcGenElemIn 340 { 341 ///... 342 343 virtual ocsd_datapath_resp_t TraceElemIn(const ocsd_trc_index_t index_sop, 344 const uint8_t trc_chan_id, 345 const OcsdTraceElement &el); 346 } 347~~~ 348 349The client application registers a callback class or function with this signature. 350 351For each output packet the libary calls the registered function, providing the byte index into the raw trace for the first 352byte of the trace protocol packet that resulted in its generation, plus the CoreSight trace ID of the source stream, 353#and the output packet itself. 354 355The client callback must process the packet before returning the call - the reference to the packet data is only 356valid for the duration of the call. This means that the client will either have to copy and buffer packets for later 357processing if required, process immediately, or use an appropriate combination, dependent on the requirements of the 358client. 359 360The client callback provides a ocsd_datapath_resp_t response code to indicate to the input side of the library if decoding is to continue. 361 362~~~{.cpp} 363 DecodeTree *pTree; 364 TrcGenericElementPrinter genElemPrinter; // derived from ITrcGenElemIn, overrides TraceElemIn() to print incoming packet to logger. 365 366 ///... 367 368 pTree->setGenTraceElemOutI(genElemPrinter); 369 370~~~ 371 372Alternatively in C-API, the callback function pointer type is defined:- 373 374~~~{.c} 375 typedef ocsd_datapath_resp_t (* FnTraceElemIn)( const void *p_context, 376 const ocsd_trc_index_t index_sop, 377 const uint8_t trc_chan_id, 378 const ocsd_generic_trace_elem *elem); 379~~~ 380 381giving API calls to set up:- 382 383~~~{.c} 384 FnTraceElemIn gen_pkt_fn = &gen_trace_elem_analyze; // set to function matching signature. 385 dcd_tree_handle_t dcdtree_handle; 386 387 // ... 388 389 ret = ocsd_dt_set_gen_elem_outfn(dcdtree_handle, gen_pkt_fn, 0); 390~~~ 391 392The output packets and their intepretatation are described here [prog_guide_generic_pkts.md](@ref generic_pkts). 393 394__Packet Process only, or Monitor packets in Full Decode__ 395 396The client can set up the library for packet processing only, in which case the library output is 397the trace packets only, so these packets need a sink callback for each channel being output. 398 399When full decode is in operation, then the principle output is the generic packets that are output for 400all channels in operation to the single callback mentioned above. Additional callbacks can be added to 401each of the trace channels to monitor the packet processing stage as it happens at point that the packets 402are passed to the full decoder. 403 404Both methods of processing the discrete trace packets require callbacks to be registered on a 405per Trace ID / channel basis. The specifics of the callback and the resulting packet will vary according to 406the protocol of the trace source. 407 408The .cpp interface registers a packet sink / packet monitor object with the relevant decoder object. 409 410This sink object is based on the tempated IPktDataIn interface. 411 412~~~{.cpp} 413template<class P> class IPktDataIn : public ITrcTypedBase { 414 // ... 415 virtual ocsd_datapath_resp_t PacketDataIn( const ocsd_datapath_op_t op, 416 const ocsd_trc_index_t index_sop, 417 const P *p_packet_in) = 0; 418} 419~~~ 420 421The template type parameter will be the protocol type for the trace source in question - e.g. EtmV4ITrcPacket. 422This interface contains a method that will be called with trace packets. 423 424The monitor object must be based on the IPktRawDataMon class, with a similarly typed template parameter and callback 425function. 426 427~~~{.cpp} 428template<class P> class IPktRawDataMon : public ITrcTypedBase { 429 // ... 430 virtual void RawPacketDataMon( const ocsd_datapath_op_t op, 431 const ocsd_trc_index_t index_sop, 432 const P *pkt, 433 const uint32_t size, 434 const uint8_t *p_data) = 0; 435} 436~~~ 437 438Given a suitable callback object the process for attaching to the decode is as follows:- 439 440~~~{.cpp} 441 // client custom packet sink for ETMv4 - derived from IPktDataIn 442 class MyTracePacketSinkETMv4 : public IPktDataIn<EtmV4ITrcPacket> { 443 // ... 444 }; 445 446 uint8_t CSID; 447 DecodeTree *pTree; // pointer to decode tree 448 MyTracePacketSinkETMv4 *pSink; 449 450 // ... obtain CSID and decode tree object 451 452 // decode trees manage decode elements using a tree element object, registered against CSID. 453 DecodeTreeElement *pElement = pTree->getDecoderElement(CSID); 454 pSink = new MyTracePacketSinkETMv4(); 455 if (pElement && pSink) 456 err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), pSink); 457 458~~~ 459 460The decode tree object is used to obtain the decode tree element associated with the Coresight trace ID. 461The IDecoderMngr interface on this object is used to attach the packet sink object to the required decoder. 462 463For monitor objects use an attachPktMonitor() call with a suitably derived monitor sink object. 464 465The key difference between the packet sink, and the packet monitor is that the monitor is not in the trace decode 466data path, so does not return ocsd_datapath_resp_t values. The monitor callback also provides the raw trace byte 467data for the packet. 468 469Device tree call for registering a callback in C-API and the function signatures for each type of shown below.. 470The C-API code contains underlying managment code that connects the callback with the correct packet decoder object. 471 472~~~{.c} 473OCSD_C_API ocsd_err_t ocsd_dt_attach_packet_callback( const dcd_tree_handle_t handle, // decode tree handle 474 const unsigned char CSID, // trace channel ID 475 const ocsd_c_api_cb_types callback_type, // defines packet only processing sink or monitor function signature. 476 void *p_fn_callback_data, // pointer to the callback function for the packet data. 477 const void *p_context); // opaque context to use inside the callback. 478~~~ 479 480Callback definition for packet only sink callback type: 481~~~{.c} 482/** function pointer type for packet processor packet output sink, packet analyser/decoder input - generic declaration */ 483typedef ocsd_datapath_resp_t (* FnDefPktDataIn)(const void *p_context, 484 const ocsd_datapath_op_t op, 485 const ocsd_trc_index_t index_sop, 486 const void *p_packet_in 487 ); 488~~~ 489 490Callback definition for packet monitor callback type 491~~~{.c} 492/** function pointer type for packet processor packet monitor sink, raw packet monitor / display input - generic declaration */ 493typedef void (* FnDefPktDataMon)(const void *p_context, 494 const ocsd_datapath_op_t op, 495 const ocsd_trc_index_t index_sop, 496 const void *p_packet_in, 497 const uint32_t size, 498 const uint8_t *p_data 499 ); 500~~~ 501 502As with the `.cpp` code, the monitor callback does not have a return value, but also has the raw trace bytes for the packet as part of 503the monitor. 504 505In both cases in the C-API, the `void *p_packet_in` must be cast to packet structure appropriate to the trace protocol associated with the 506CSID value. e.g. for ETMv4 this would be @ref ocsd_etmv4_i_pkt. 507 508 509Programming Examples - using the configured Decode Tree. 510-------------------------------------------------------- 511 512Once the decode tree has been configured then data raw trace data can be processed through the decode tree. 513 514The client program will require two functions to use the library. The first is on the input side of the library 515which must be driven with raw data, until the data is complete, or an error occurs. This processing routine must 516check the library returns and respond appropriately. 517 518The second consists of output callback(s) which process the decoded generic packets, or trace packets. 519This routine will return response codes according to the needs of the client. 520 521 522 523The diagram shows the data input and response path. The data is driven into the decoding library by the client raw data input 524routine on the left. Processed packets are received by the client packet callback(s) on the right, and push response codes back 525through the library. 526 527The raw data input routine calls the standard ITrcDataIn interface with an operation code, and if appropriate some raw 528trace data. The input operation code will define how the library treats the input parameters. 529 530 531| Operation | Description | Trace Data provided | 532|:-------------------|:-----------------------------------------------------------------|:--------------------| 533| @ref OCSD_OP_DATA | Process data provided by data pointer parameters. | Yes | 534| @ref OCSD_OP_FLUSH | Call after prior wait response - finish processing previous data | No | 535| @ref OCSD_OP_EOT | End of trace data. Library will complete any pending decode. | No | 536| @ref OCSD_OP_RESET | Hard reset of decoder state - use current config for new data | No | 537 538A set of standard responses is used to indicate to the raw data input whether it should continue to push data through the library, 539pause and then flush, or if a fatal processing error has occurred. 540 541The response codes can come from the internal library decoder, or from the part of the client that is handling the processing of the 542output packets on the right of the diagram. 543 544_Response Codes_: The are contained in the @ref _ocsd_datapath_resp_t enum. 545 546- __OCSD_RESP_CONT, OCSD_RESP_CONT_xxx__: Indicates that processing is to continue. Generated either internally by the library if more data 547 is needed to generate an output packet, or by the output packet processors to indicate processing 548 is to continue. 549- __OCSD_RESP_WAIT, OCSD_RESP_WAIT_xxx:__ Sent by the client processors to pause processing. This will freeze the internal state of the library 550 and cause the WAIT response to be propogated through to the input side, with an indication of the number 551 of bytes processed. After a WAIT, the input side must respond with flush operations, until a CONT is 552 seen again and further data can then be input into the library. 553- __OCSR_RESP_FATAL_xxx__: Fatal processing error. No further processing can take place. See error response logger for reason. 554 Normally the result of corrupt or incorrect trace data. 555 556The user should note that the client program controls routines on both the input and output side of the library. The output routine may be buffering 557output packets, and when the buffer is full, returns a WAIT ressponse. This will be propgated through to the input routine. This should now terminate 558data processing, saving state and the client will run a routine to empty / process the full packet buffer. Once the necessary processing is done, 559then the input routine can be restarted, but __must__ follow the FLUSH operational rule described above. 560 561Excerpts from the data input routine used by the `trc_pkt_lister` program are shown below: 562 563~~~{.cpp} 564 // process the current buffer load until buffer done, or fatal error occurs 565 while((nBuffProcessed < nBuffRead) && !OCSD_DATA_RESP_IS_FATAL(dataPathResp)) 566 { 567 if(OCSD_DATA_RESP_IS_CONT(dataPathResp)) 568 { 569 dataPathResp = dcd_tree->TraceDataIn( 570 OCSD_OP_DATA, 571 trace_index, 572 (uint32_t)(nBuffRead - nBuffProcessed), 573 &(trace_buffer[0])+nBuffProcessed, 574 &nUsedThisTime); 575 576 nBuffProcessed += nUsedThisTime; 577 trace_index += nUsedThisTime; 578 579 } 580 else // last response was _WAIT 581 { 582 // may need to acknowledge a wait from the gen elem printer 583 if(genElemPrinter->needAckWait()) 584 genElemPrinter->ackWait(); 585 586 // dataPathResp not continue or fatal so must be wait... 587 dataPathResp = dcd_tree->TraceDataIn(OCSD_OP_FLUSH,0,0,0,0); 588 } 589 } 590 591~~~ 592 593_Note_: in this test program, the WAIT response is an artificial test condition, so the input routine does not terminate on seeing it - it is cleared down 594and FLUSH is immediately sent. Normal client routines would most likely drop out of the processing loop, take actions to clear the WAIT condition, then 595resume processing with a FLUSH. 596 597See the `trc_pkt_lister` and `c_api_pkt_print_test` test program source code for further examples of driving data through the library. 598