aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Schink <swo-dev@marcschink.de>2015-12-23 15:06:09 +0100
committerMarc Schink <swo-dev@marcschink.de>2015-12-27 17:17:41 +0100
commitdf1ff24e0c45ae71cfdf8f1bd96258de14cc4e9f (patch)
tree9aead6093104e5f10a26f08e9caf87ab4893b5a7
parent55e75873ef9d36b93057045397430dc7b7396794 (diff)
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.
-rw-r--r--man/swodec.123
-rw-r--r--src/dwt.c21
-rw-r--r--src/main.c31
-rw-r--r--src/swodec.h45
4 files changed, 109 insertions, 11 deletions
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 <stdint.h>
#include <glib.h>
-#include <libswo/libswo.h>
+#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 <string.h>
#include <glib.h>
-#include <libswo/libswo.h>
-
#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 <swo-dev@marcschink.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SWODEC_SWODEC_H
+#define SWODEC_SWODEC_H
+
+#include <libswo/libswo.h>
+
+/* 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 */