From 6656302a303be3360f016684db74e75f1ea3034c Mon Sep 17 00:00:00 2001
Message-Id:
From: Blue Swirl
Date: Tue, 23 Aug 2011 21:08:53 +0000
Subject: [PATCH] Introduce tracing system from QEMU
Instead of traditional debugging printf statements, which
have the bad habit of suffering from bit rot, introduce
tracepoints based on similar system in QEMU.
Only stderr (printk) and simpletrace (output via fw_cfg
device to QEMU) back ends are supported.
Signed-off-by: Blue Swirl
---
config/examples/sparc32_config.xml | 3 +-
config/scripts/tracetool | 692 ++++++++++++++++++++++++++++++++++++
drivers/esp.c | 3 +-
drivers/fw_cfg.c | 30 ++
include/arch/common/fw_cfg.h | 4 +
include/libopenbios/simpletrace.h | 31 ++
libopenbios/build.xml | 33 ++
libopenbios/simpletrace.c | 60 +++
trace-events | 1 +
9 files changed, 855 insertions(+), 2 deletions(-)
create mode 100644 config/scripts/tracetool
create mode 100644 include/libopenbios/simpletrace.h
create mode 100644 libopenbios/simpletrace.c
create mode 100644 trace-events
diff --git a/config/examples/sparc32_config.xml b/config/examples/sparc32_config.xml
index f2d6afc..2b449cc 100644
--- a/config/examples/sparc32_config.xml
+++ b/config/examples/sparc32_config.xml
@@ -19,7 +19,8 @@
-
+
+
diff --git a/config/scripts/tracetool b/config/scripts/tracetool
new file mode 100644
index 0000000..5c0534f
--- /dev/null
+++ b/config/scripts/tracetool
@@ -0,0 +1,692 @@
+#!/bin/sh
+#
+# Code generator for trace events
+#
+# Copyright IBM, Corp. 2010
+#
+# This work is licensed under the terms of the GNU GPL, version 2. See
+# the COPYING file in the top-level directory.
+
+# Disable pathname expansion, makes processing text with '*' characters simpler
+set -f
+
+usage()
+{
+ cat >&2 <"
+ ust_clean_namespace
+}
+
+linetoh_ust()
+{
+ local name args argnames
+ name=$(get_name "$1")
+ args=$(get_args "$1")
+ argnames=$(get_argnames "$1", ",")
+
+ cat <
+$(ust_clean_namespace)
+#include "trace.h"
+EOF
+}
+
+linetoc_ust()
+{
+ local name args argnames fmt
+ name=$(get_name "$1")
+ args=$(get_args "$1")
+ argnames=$(get_argnames "$1", ",")
+ [ -z "$argnames" ] || argnames=", $argnames"
+ fmt=$(get_fmt "$1")
+
+ cat <ll->regs[ESP_INTRPT];
- DPRINTF("do_command: id %d, cmd[0] 0x%x, status 0x%x\n", sd->id, esp->buffer[0], status);
+ trace_esp_do_command(sd->id, esp->buffer[0], status);
/* Target didn't want all command data? */
if ((status & ESP_STAT_TCNT) != ESP_STAT_TCNT) {
diff --git a/drivers/fw_cfg.c b/drivers/fw_cfg.c
index 4027570..7565c96 100644
--- a/drivers/fw_cfg.c
+++ b/drivers/fw_cfg.c
@@ -18,6 +18,17 @@ fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes)
for (i = 0; i < nbytes; i++)
buf[i] = *fw_cfg_data;
}
+
+void
+fw_cfg_write(uint16_t cmd, char *buf, unsigned int nbytes)
+{
+ unsigned int i;
+
+ *fw_cfg_cmd = cmd;
+ for (i = 0; i < nbytes; i++) {
+ *fw_cfg_data = buf[i];
+ }
+}
#else
// XXX depends on PCI bus location, should be removed
void
@@ -29,6 +40,17 @@ fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes)
for (i = 0; i < nbytes; i++)
buf[i] = inb(CONFIG_FW_CFG_ADDR + 1);
}
+
+void
+fw_cfg_write(uint16_t cmd, char *buf, unsigned int nbytes)
+{
+ unsigned int i;
+
+ outw(cmd, CONFIG_FW_CFG_ADDR);
+ for (i = 0; i < nbytes; i++) {
+ outb(buf[i], CONFIG_FW_CFG_ADDR + 1);
+ }
+}
#endif
uint64_t
@@ -62,6 +84,14 @@ fw_cfg_read_i16(uint16_t cmd)
}
void
+fw_cfg_write_i64(uint16_t cmd, uint64_t val)
+{
+ uint64_t buf = __cpu_to_le64(val);
+
+ fw_cfg_write(cmd, (char *)&buf, sizeof(uint64_t));
+}
+
+void
fw_cfg_init(void)
{
#if defined(CONFIG_SPARC32)
diff --git a/include/arch/common/fw_cfg.h b/include/arch/common/fw_cfg.h
index b0a23cd..8f08bb7 100644
--- a/include/arch/common/fw_cfg.h
+++ b/include/arch/common/fw_cfg.h
@@ -33,6 +33,8 @@
#define FW_CFG_MAX_ENTRY (FW_CFG_FILE_FIRST+FW_CFG_FILE_SLOTS)
#define FW_CFG_WRITE_CHANNEL 0x4000
+#define FW_CFG_GUEST_TRACE (FW_CFG_WRITE_CHANNEL + 0)
+
#define FW_CFG_ARCH_LOCAL 0x8000
#define FW_CFG_ENTRY_MASK ~(FW_CFG_WRITE_CHANNEL | FW_CFG_ARCH_LOCAL)
@@ -78,9 +80,11 @@ FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
#ifndef NO_OPENBIOS_PROTOS
void fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes);
+void fw_cfg_write(uint16_t cmd, char *buf, unsigned int nbytes);
uint64_t fw_cfg_read_i64(uint16_t cmd);
uint32_t fw_cfg_read_i32(uint16_t cmd);
uint16_t fw_cfg_read_i16(uint16_t cmd);
+void fw_cfg_write_i64(uint16_t cmd, uint64_t val);
void fw_cfg_init(void);
#endif /* NO_OPENBIOS_PROTOS */
diff --git a/include/libopenbios/simpletrace.h b/include/libopenbios/simpletrace.h
new file mode 100644
index 0000000..aa98ee3
--- /dev/null
+++ b/include/libopenbios/simpletrace.h
@@ -0,0 +1,31 @@
+/*
+ * Simple trace backend
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef SIMPLETRACE_H
+#define SIMPLETRACE_H
+
+#include "asm/types.h"
+
+typedef uint64_t TraceEventID;
+
+typedef struct {
+ const char *tp_name;
+ int state;
+} TraceEvent;
+
+void trace0(TraceEventID event);
+void trace1(TraceEventID event, uint64_t x1);
+void trace2(TraceEventID event, uint64_t x1, uint64_t x2);
+void trace3(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3);
+void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4);
+void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5);
+void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6);
+
+#endif /* SIMPLETRACE_H */
diff --git a/libopenbios/build.xml b/libopenbios/build.xml
index 04e3800..b16cd35 100644
--- a/libopenbios/build.xml
+++ b/libopenbios/build.xml
@@ -19,6 +19,39 @@
+
+
+ $@," GEN trace.h")
+ @cmp -s $@ $(ODIR)/target/include/trace.h || cp $@ $(ODIR)/target/include/trace.h]]>
+
+
+ $@," GEN trace.c")
+ @cmp -s $@ $(ODIR)/target/libopenbios/trace.c || cp $@ $(ODIR)/target/libopenbios/trace.c]]>
+
+
+ $@," GEN trace.h")
+ @cmp -s $@ $(ODIR)/target/include/trace.h || cp $@ $(ODIR)/target/include/trace.h]]>
+
+
+ $@," GEN trace.c")
+ @cmp -s $@ $(ODIR)/target/libopenbios/trace.c || cp $@ $(ODIR)/target/libopenbios/trace.c]]>
+
+
+
+
diff --git a/libopenbios/simpletrace.c b/libopenbios/simpletrace.c
new file mode 100644
index 0000000..4fb5b2e
--- /dev/null
+++ b/libopenbios/simpletrace.c
@@ -0,0 +1,60 @@
+/*
+ * Simple trace backend
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "trace.h"
+#define NO_QEMU_PROTOS
+#include "arch/common/fw_cfg.h"
+
+static void trace(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3,
+ uint64_t x4, uint64_t x5, uint64_t x6)
+{
+ fw_cfg_write_i64(FW_CFG_GUEST_TRACE, event);
+ fw_cfg_write_i64(FW_CFG_GUEST_TRACE, x1);
+ fw_cfg_write_i64(FW_CFG_GUEST_TRACE, x2);
+ fw_cfg_write_i64(FW_CFG_GUEST_TRACE, x3);
+ fw_cfg_write_i64(FW_CFG_GUEST_TRACE, x4);
+ fw_cfg_write_i64(FW_CFG_GUEST_TRACE, x5);
+ fw_cfg_write_i64(FW_CFG_GUEST_TRACE, x6);
+}
+
+void trace0(TraceEventID event)
+{
+ trace(event, 0, 0, 0, 0, 0, 0);
+}
+
+void trace1(TraceEventID event, uint64_t x1)
+{
+ trace(event, x1, 0, 0, 0, 0, 0);
+}
+
+void trace2(TraceEventID event, uint64_t x1, uint64_t x2)
+{
+ trace(event, x1, x2, 0, 0, 0, 0);
+}
+
+void trace3(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3)
+{
+ trace(event, x1, x2, x3, 0, 0, 0);
+}
+
+void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4)
+{
+ trace(event, x1, x2, x3, x4, 0, 0);
+}
+
+void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5)
+{
+ trace(event, x1, x2, x3, x4, x5, 0);
+}
+
+void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6)
+{
+ trace(event, x1, x2, x3, x4, x5, x6);
+}
diff --git a/trace-events b/trace-events
new file mode 100644
index 0000000..d433b02
--- /dev/null
+++ b/trace-events
@@ -0,0 +1 @@
+esp_do_command(int id, int cmd, int status) "id %d, cmd[0] 0x%x, status 0x%x"
--
1.7.2.5