From df1ff24e0c45ae71cfdf8f1bd96258de14cc4e9f Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Wed, 23 Dec 2015 15:06:09 +0100 Subject: [PATCH] Add filter support for DWT packets The packet type 'hw' from now on filters only for hardware source packets which could not be decoded as DWT packets. --- man/swodec.1 | 23 +++++++++++++++++++++-- src/dwt.c | 21 ++++++++++++++++++++- src/main.c | 31 +++++++++++++++++++++++-------- src/swodec.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 11 deletions(-) create mode 100644 src/swodec.h diff --git a/man/swodec.1 b/man/swodec.1 index 11252c6..6cd1f88 100644 --- a/man/swodec.1 +++ b/man/swodec.1 @@ -1,4 +1,4 @@ -.TH swodec 1 "May 20, 2015" +.TH swodec 1 "Dec 23, 2015" .SH NAME swodec \- decode SWO trace data @@ -55,7 +55,26 @@ Extension Instrumentation .TP .B hw -Hardware source +Hardware source. This is for hardware source packets which could not be decoded +as Data Watchpoint and Trace (DWT) packets. +.TP +.B evcnt +Event counter +.TP +.B exc +Exception trace +.TP +.B pc +Periodic PC sample +.TP +.B dtpc +Data trace PC value +.TP +.B dtaddr +Data trace address offset +.TP +.B dtval +Data trace data value .TP .B unknown Unknown data diff --git a/src/dwt.c b/src/dwt.c index b05c70c..c0b3411 100644 --- a/src/dwt.c +++ b/src/dwt.c @@ -21,7 +21,7 @@ #include #include -#include +#include "swodec.h" /* Event counter packet discriminator ID. */ #define EVCNT_ID 0 @@ -152,6 +152,9 @@ static void handle_evcnt_packet(const struct libswo_packet_hw *packet) unsigned int fold; unsigned int cyc; + if (!(packet_type_filter & (1 << DWT_PACKET_TYPE_EVENT_COUNTER))) + return; + if (packet->size != EVCNT_SIZE) { g_warning("Event counter packet with invalid size of " "%zu bytes.", packet->size); @@ -200,6 +203,9 @@ static void handle_extrace_packet(const struct libswo_packet_hw *packet) const char *name; char buf[23]; + if (!(packet_type_filter & (1 << DWT_PACKET_TYPE_EXCEPTION_TRACE))) + return; + if (packet->size != EXTRACE_SIZE) { g_warning("Exception trace packet with invalid size of " "%zu bytes.", packet->size); @@ -238,6 +244,10 @@ static void handle_extrace_packet(const struct libswo_packet_hw *packet) static void handle_pc_sample_packet(const struct libswo_packet_hw *packet) { + + if (!(packet_type_filter & (1 << DWT_PACKET_TYPE_PC_SAMPLE))) + return; + if (packet->size == PC_SAMPLE_SLEEP_SIZE) { if (packet->value > 0) { g_warning("Periodic PC sleep packet contains invalid " @@ -258,6 +268,9 @@ static void handle_pc_value_packet(const struct libswo_packet_hw *packet) { unsigned int cmpn; + if (!(packet_type_filter & (1 << DWT_PACKET_TYPE_DT_PC_VALUE))) + return; + if (packet->size != PC_VALUE_SIZE) { g_warning("Data trace PC value packet with invalid size of " "%zu bytes.", packet->size); @@ -274,6 +287,9 @@ static void handle_address_offset_packet(const struct libswo_packet_hw *packet) { unsigned int cmpn; + if (!(packet_type_filter & (1 << DWT_PACKET_TYPE_DT_ADDR_OFFSET))) + return; + if (packet->size != ADDR_OFFSET_SIZE) { g_warning("Data trace address offset packet with invalid size " "of %zu bytes.", packet->size); @@ -291,6 +307,9 @@ static void handle_data_value_packet(const struct libswo_packet_hw *packet) unsigned int wnr; unsigned int cmpn; + if (!(packet_type_filter & (1 << DWT_PACKET_TYPE_DT_DATA_VALUE))) + return; + wnr = packet->address & WNR_MASK; cmpn = (packet->address & CMPN_MASK) >> CMPN_OFFSET; diff --git a/src/main.c b/src/main.c index 4ca166c..eb33472 100644 --- a/src/main.c +++ b/src/main.c @@ -23,20 +23,17 @@ #include #include -#include - #include "config.h" +#include "swodec.h" #define BUFFER_SIZE 1024 static gboolean opt_version; static gchar *input_file = NULL; -static uint16_t packet_type_filter; +uint16_t packet_type_filter; static uint32_t inst_address_filter; static gboolean opt_dump_inst; -gboolean dwt_handle_packet(const struct libswo_packet_hw *packet); - static gboolean parse_filter_option(const gchar *option_name, const gchar *value, gpointer data, GError **error) { @@ -90,6 +87,18 @@ static gboolean parse_filter_option(const gchar *option_name, tmp |= (1 << LIBSWO_PACKET_TYPE_INST); } else if (!g_ascii_strcasecmp(tokens[i], "hw")) { tmp |= (1 << LIBSWO_PACKET_TYPE_HW); + } else if (!g_ascii_strcasecmp(tokens[i], "evcnt")) { + tmp |= (1 << DWT_PACKET_TYPE_EVENT_COUNTER); + } else if (!g_ascii_strcasecmp(tokens[i], "exc")) { + tmp |= (1 << DWT_PACKET_TYPE_EXCEPTION_TRACE); + } else if (!g_ascii_strcasecmp(tokens[i], "pc")) { + tmp |= (1 << DWT_PACKET_TYPE_PC_SAMPLE); + } else if (!g_ascii_strcasecmp(tokens[i], "dtpc")) { + tmp |= (1 << DWT_PACKET_TYPE_DT_PC_VALUE); + } else if (!g_ascii_strcasecmp(tokens[i], "dtaddr")) { + tmp |= (1 << DWT_PACKET_TYPE_DT_ADDR_OFFSET); + } else if (!g_ascii_strcasecmp(tokens[i], "dtval")) { + tmp |= (1 << DWT_PACKET_TYPE_DT_DATA_VALUE); } else if (!g_ascii_strcasecmp(tokens[i], "unknown")) { tmp |= (1 << LIBSWO_PACKET_TYPE_UNKNOWN); } else { @@ -202,10 +211,10 @@ static GOptionEntry entries[] = { static void handle_hw_packet(const union libswo_packet *packet) { - if (!(packet_type_filter & (1 << LIBSWO_PACKET_TYPE_HW))) + if (dwt_handle_packet(&packet->hw)) return; - if (dwt_handle_packet(&packet->hw)) + if (!(packet_type_filter & (1 << LIBSWO_PACKET_TYPE_HW))) return; printf("Hardware source (address = %u, value = %x, size = %zu bytes)\n", @@ -437,7 +446,13 @@ int main(int argc, char **argv) (1 << LIBSWO_PACKET_TYPE_EXT) | \ (1 << LIBSWO_PACKET_TYPE_INST) | \ (1 << LIBSWO_PACKET_TYPE_HW) | \ - (1 << LIBSWO_PACKET_TYPE_UNKNOWN); + (1 << LIBSWO_PACKET_TYPE_UNKNOWN) | \ + (1 << DWT_PACKET_TYPE_EVENT_COUNTER) | \ + (1 << DWT_PACKET_TYPE_EXCEPTION_TRACE) | \ + (1 << DWT_PACKET_TYPE_PC_SAMPLE) | \ + (1 << DWT_PACKET_TYPE_DT_PC_VALUE) | \ + (1 << DWT_PACKET_TYPE_DT_ADDR_OFFSET) | \ + (1 << DWT_PACKET_TYPE_DT_DATA_VALUE); /* Disable instrumentation source address filtering by default. */ inst_address_filter = 0xffffffff; diff --git a/src/swodec.h b/src/swodec.h new file mode 100644 index 0000000..f44a46a --- /dev/null +++ b/src/swodec.h @@ -0,0 +1,45 @@ +/* + * This file is part of the swodec project. + * + * Copyright (C) 2015 Marc Schink + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef SWODEC_SWODEC_H +#define SWODEC_SWODEC_H + +#include + +/* Data Watchpoint and Trace (DWT) packet types. */ +enum dwt_packet_type { + /* Event counter packet. */ + DWT_PACKET_TYPE_EVENT_COUNTER = LIBSWO_PACKET_TYPE_UNKNOWN + 1, + /* Exception trace packet. */ + DWT_PACKET_TYPE_EXCEPTION_TRACE, + /* Periodic PC sample packet. */ + DWT_PACKET_TYPE_PC_SAMPLE, + /* Data trace PC value packet. */ + DWT_PACKET_TYPE_DT_PC_VALUE, + /* Data trace address offset packet. */ + DWT_PACKET_TYPE_DT_ADDR_OFFSET, + /* Data trace data value packet. */ + DWT_PACKET_TYPE_DT_DATA_VALUE +}; + +extern uint16_t packet_type_filter; + +gboolean dwt_handle_packet(const struct libswo_packet_hw *packet); + +#endif /* SWODEC_SWODEC_H */ -- 2.11.4.GIT