diff mbox series

[16/18] htm: Add record command

Message ID 20180619052535.24043-16-mikey@neuling.org
State Accepted
Headers show
Series [01/18] Make -a the default for probe | expand

Commit Message

Michael Neuling June 19, 2018, 5:25 a.m. UTC
This starts the trace, waits for it to complete (ie fill the buffer),
then stops the trace and dumps out the file.

Signed-off-by: Michael Neuling <mikey@neuling.org>
---
 libpdbg/htm.c     | 50 +++++++++++++++++++++++++++++++++++++++++++++++
 libpdbg/libpdbg.h |  1 +
 libpdbg/target.h  |  1 +
 src/htm.c         | 32 ++++++++++++++++++++++++++++++
 4 files changed, 84 insertions(+)
diff mbox series

Patch

diff --git a/libpdbg/htm.c b/libpdbg/htm.c
index 9c229dc99f..a6445c2420 100644
--- a/libpdbg/htm.c
+++ b/libpdbg/htm.c
@@ -227,6 +227,16 @@  int htm_dump(struct pdbg_target *target, uint64_t size, char *filename)
 	return htm->dump(htm, 0, filename);
 }
 
+int htm_record(struct pdbg_target *target, char *filename)
+{
+	struct htm *htm = check_and_convert(target);
+
+	if (!htm || !filename)
+		return -1;
+
+	return htm->record(htm, filename);
+}
+
 static int get_status(struct htm *htm, struct htm_status *status)
 {
 	uint64_t val;
@@ -825,6 +835,26 @@  static uint64_t htm_trace_size(struct htm_status *status)
 	return size << 20;
 }
 
+static bool htm_complete(struct htm_status *status)
+{
+	return (status->state == COMPLETE);
+}
+
+static int htm_wait_complete(struct htm *htm)
+{
+	struct htm_status status;
+
+	while (1) {
+		if (HTM_ERR(get_status(htm, &status)))
+			return -1;
+		PR_DEBUG("loop curr:0x%016" PRIx64 "\n", status.mem_last);
+		if (htm_complete(&status))
+			break;
+		usleep(100000);
+	}
+	return 0;
+}
+
 static int do_htm_status(struct htm *htm)
 {
 	struct htm_status status;
@@ -976,6 +1006,24 @@  static int do_htm_dump(struct htm *htm, uint64_t size, char *filename)
 	return 1;
 }
 
+static int do_htm_record(struct htm *htm, char *filename)
+{
+	if (do_htm_start(htm) < 0)
+		return -1;
+
+	if (htm_wait_complete(htm))
+		return -1;
+
+	if (do_htm_stop(htm) < 0)
+		return -1;
+
+	if (do_htm_dump(htm, 0, filename) < 0)
+		return -1;
+
+
+	return 1;
+}
+
 static bool is_debugfs_memtrace_ok(void)
 {
 	return access(DEBUGFS_MEMTRACE, F_OK) == 0;
@@ -1018,6 +1066,7 @@  static struct htm nhtm = {
 	},
 	.start = do_htm_start,
 	.stop = do_htm_stop,
+	.record = do_htm_record,
 	.status = do_htm_status,
 	.dump = do_htm_dump,
 };
@@ -1032,6 +1081,7 @@  static struct htm chtm = {
 	},
 	.start = do_htm_start,
 	.stop = do_htm_stop,
+	.record = do_htm_record,
 	.status = do_htm_status,
 	.dump = do_htm_dump,
 };
diff --git a/libpdbg/libpdbg.h b/libpdbg/libpdbg.h
index 21e10c61b1..6b635a9b78 100644
--- a/libpdbg/libpdbg.h
+++ b/libpdbg/libpdbg.h
@@ -166,6 +166,7 @@  int htm_start(struct pdbg_target *target);
 int htm_stop(struct pdbg_target *target);
 int htm_status(struct pdbg_target *target);
 int htm_dump(struct pdbg_target *target, uint64_t size, char *filename);
+int htm_record(struct pdbg_target *target, char *filename);
 
 int adu_getmem(struct pdbg_target *target, uint64_t addr, uint8_t *ouput, uint64_t size);
 int adu_putmem(struct pdbg_target *target, uint64_t addr, uint8_t *input, uint64_t size);
diff --git a/libpdbg/target.h b/libpdbg/target.h
index 6f8d4b8b08..9d2ad90bcf 100644
--- a/libpdbg/target.h
+++ b/libpdbg/target.h
@@ -95,6 +95,7 @@  struct htm {
 	int (*stop)(struct htm *);
 	int (*status)(struct htm *);
 	int (*dump)(struct htm *, uint64_t, char *);
+	int (*record)(struct htm *, char *);
 };
 #define target_to_htm(x) container_of(x, struct htm, target)
 
diff --git a/src/htm.c b/src/htm.c
index ae7e1ea1e2..eff46a6c93 100644
--- a/src/htm.c
+++ b/src/htm.c
@@ -177,6 +177,37 @@  static int run_dump(enum htm_type type)
 	return rc;
 }
 
+static int run_record(enum htm_type type)
+{
+	struct pdbg_target *target;
+	char *filename;
+	int rc = 0;
+
+	pdbg_for_each_class_target(HTM_ENUM_TO_STRING(type), target) {
+		if (!target_selected(target))
+			continue;
+		pdbg_target_probe(target);
+		if (target_is_disabled(target))
+			continue;
+
+		filename = get_htm_dump_filename(target);
+		if (!filename)
+			return 0;
+
+		/* size = 0 will dump everything */
+		printf("Recording HTM@");
+		print_htm_address(type, target);
+		if (htm_record(target, filename) != 1) {
+			printf("Couldn't record HTM@");
+			print_htm_address(type, target);
+		}
+		rc++;
+		free(filename);
+	}
+
+	return rc;
+}
+
 static struct {
 	const char *name;
 	const char *args;
@@ -187,6 +218,7 @@  static struct {
 	{ "stop",   "", "Stop %s HTM",                &run_stop   },
 	{ "status", "", "Get %s HTM status",          &run_status },
 	{ "dump",   "", "Dump %s HTM buffer to file", &run_dump   },
+	{ "record", "", "Start, wait & dump %s HTM",  &run_record },
 };
 
 static void print_usage(enum htm_type type)