|
@@ -45,6 +45,66 @@ struct cs_etm_decoder {
|
|
|
struct cs_etm_packet packet_buffer[MAX_BUFFER];
|
|
|
};
|
|
|
|
|
|
+static u32
|
|
|
+cs_etm_decoder__mem_access(const void *context,
|
|
|
+ const ocsd_vaddr_t address,
|
|
|
+ const ocsd_mem_space_acc_t mem_space __maybe_unused,
|
|
|
+ const u32 req_size,
|
|
|
+ u8 *buffer)
|
|
|
+{
|
|
|
+ struct cs_etm_decoder *decoder = (struct cs_etm_decoder *) context;
|
|
|
+
|
|
|
+ return decoder->mem_access(decoder->data,
|
|
|
+ address,
|
|
|
+ req_size,
|
|
|
+ buffer);
|
|
|
+}
|
|
|
+
|
|
|
+int cs_etm_decoder__add_mem_access_cb(struct cs_etm_decoder *decoder,
|
|
|
+ u64 start, u64 end,
|
|
|
+ cs_etm_mem_cb_type cb_func)
|
|
|
+{
|
|
|
+ decoder->mem_access = cb_func;
|
|
|
+
|
|
|
+ if (ocsd_dt_add_callback_mem_acc(decoder->dcd_tree, start, end,
|
|
|
+ OCSD_MEM_SPACE_ANY,
|
|
|
+ cs_etm_decoder__mem_access, decoder))
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int cs_etm_decoder__reset(struct cs_etm_decoder *decoder)
|
|
|
+{
|
|
|
+ ocsd_datapath_resp_t dp_ret;
|
|
|
+
|
|
|
+ dp_ret = ocsd_dt_process_data(decoder->dcd_tree, OCSD_OP_RESET,
|
|
|
+ 0, 0, NULL, NULL);
|
|
|
+ if (OCSD_DATA_RESP_IS_FATAL(dp_ret))
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int cs_etm_decoder__get_packet(struct cs_etm_decoder *decoder,
|
|
|
+ struct cs_etm_packet *packet)
|
|
|
+{
|
|
|
+ if (!decoder || !packet)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ /* Nothing to do, might as well just return */
|
|
|
+ if (decoder->packet_count == 0)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ *packet = decoder->packet_buffer[decoder->head];
|
|
|
+
|
|
|
+ decoder->head = (decoder->head + 1) & (MAX_BUFFER - 1);
|
|
|
+
|
|
|
+ decoder->packet_count--;
|
|
|
+
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
static void cs_etm_decoder__gen_etmv4_config(struct cs_etm_trace_params *params,
|
|
|
ocsd_etmv4_cfg *config)
|
|
|
{
|