diff mbox series

[5/6] coresight: samples: Add coresight file reader sample program

Message ID 20211101224731.27870-6-mike.leach@linaro.org (mailing list archive)
State New, archived
Headers show
Series coresight: syscfg: Extend configfs for config load. | expand

Commit Message

Mike Leach Nov. 1, 2021, 10:47 p.m. UTC
Add a userspace program to read and print a configuration generated
for loading via the configfs attributes.

Signed-off-by: Mike Leach <mike.leach@linaro.org>
---
 samples/coresight/Makefile                  |  20 +-
 samples/coresight/Makefile.host             |  39 ++++
 samples/coresight/coresight-cfg-file-read.c | 191 ++++++++++++++++++++
 3 files changed, 248 insertions(+), 2 deletions(-)
 create mode 100644 samples/coresight/Makefile.host
 create mode 100644 samples/coresight/coresight-cfg-file-read.c
diff mbox series

Patch

diff --git a/samples/coresight/Makefile b/samples/coresight/Makefile
index 07bfd99d7a68..ad8f29a77881 100644
--- a/samples/coresight/Makefile
+++ b/samples/coresight/Makefile
@@ -4,8 +4,24 @@ 
 obj-$(CONFIG_SAMPLE_CORESIGHT_SYSCFG) += coresight-cfg-sample.o
 ccflags-y += -I$(srctree)/drivers/hwtracing/coresight
 
-# coresight config - configfs loadable binary config generator
-userprogs-always-y += coresight-cfg-filegen
+# coresight config - configfs loadable binary config generator & reader
+userprogs-always-y += coresight-cfg-filegen coresight-cfg-file-read
 
 coresight-cfg-filegen-objs := coresight-cfg-filegen.o coresight-cfg-bufw.o
+coresight-cfg-file-read-objs := coresight-cfg-file-read.o coresight-config-file.o
+
+# pull in the coresight headers
 userccflags += -I$(srctree)/drivers/hwtracing/coresight
+
+# need to copy over the reader source from the driver tree - to build separately
+CORESIGHT_SRC_PATH := $(abspath $(srctree)/$(src))
+
+$(src)/coresight-config-file.c: copy_coresight_source
+
+.PHONY: copy_coresight_source
+
+copy_coresight_source:
+	@cp $(CORESIGHT_SRC_PATH)/../../drivers/hwtracing/coresight/coresight-config-file.c $(CORESIGHT_SRC_PATH)/.
+
+# clean up the copy after use.
+clean-files += coresight-config-file.c
diff --git a/samples/coresight/Makefile.host b/samples/coresight/Makefile.host
new file mode 100644
index 000000000000..068cc2ca6ece
--- /dev/null
+++ b/samples/coresight/Makefile.host
@@ -0,0 +1,39 @@ 
+# SPDX-License-Identifier: GPL-2.0-only
+
+# Makefile to build just the example userspace programs on host m/c
+
+this-makefile := $(lastword $(MAKEFILE_LIST))
+sample-src := $(realpath $(dir $(this-makefile)))
+srctree := $(realpath $(dir $(sample-src)/../../.))
+
+include Makefile
+
+# compile flags
+CFLAGS += $(CPPFLAGS) -c -Wall -DLINUX -Wno-switch -Wlogical-op -fPIC $(userccflags)
+
+# debug variant
+ifdef DEBUG
+CFLAGS += -g -O0 -DDEBUG
+else
+CFLAGS += -O2 -DNDEBUG
+endif
+
+all: coresight-cfg-filegen coresight-cfg-file-read
+
+coresight-config-file.o: src_copy
+	$(CC) $(CFLAGS) coresight-config-file.c -o coresight-config-file.o
+
+.PHONY: src_copy
+src_copy:
+	@cp $(srctree)/drivers/hwtracing/coresight/coresight-config-file.c $(sample-src)/.
+
+coresight-cfg-filegen: $(coresight-cfg-filegen-objs)
+	$(CC) $(LDFLAGS) $(coresight-cfg-filegen-objs) -o coresight-cfg-filegen
+
+coresight-cfg-file-read: $(coresight-cfg-file-read-objs)
+	$(CC) $(LDFLAGS) $(coresight-cfg-file-read-objs) -o coresight-cfg-file-read
+
+clean:
+	rm -f $(userprogs-always-y)
+	rm -f *.o
+	rm -f $(clean-files)
diff --git a/samples/coresight/coresight-cfg-file-read.c b/samples/coresight/coresight-cfg-file-read.c
new file mode 100644
index 000000000000..4e0fd840428f
--- /dev/null
+++ b/samples/coresight/coresight-cfg-file-read.c
@@ -0,0 +1,191 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 Linaro Limited, All rights reserved.
+ * Author: Mike Leach <mike.leach@linaro.org>
+ */
+
+#include <linux/types.h>
+#include <linux/unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "coresight-config-file.h"
+
+/*
+ * tool to read and print a generated configuration
+ * re-uses the read code source from the driver.
+ */
+
+static void print_configs(struct cscfg_fs_load_descs *load_descs)
+{
+	struct cscfg_config_desc *config_desc = load_descs->config_descs[0];
+	int i, j, p;
+
+	if (!config_desc) {
+		printf("File contains no configurations.\n\n");
+		return;
+	}
+
+	printf("Configuration name : %s\n", config_desc->name);
+	printf("Uses %d features:-\n", config_desc->nr_feat_refs);
+	for (i = 0; i < config_desc->nr_feat_refs; i++)
+		printf("Feature-%d: %s\n", i + 1, config_desc->feat_ref_names[i]);
+
+	printf("\nProvides %d sets of preset values, %d presets per set\n", config_desc->nr_presets,
+	       config_desc->nr_total_params);
+	if (config_desc->nr_presets) {
+		for (i = 0; i < config_desc->nr_presets; i++) {
+			printf("set[%d]: ", i);
+			for (j = 0; j < config_desc->nr_total_params; j++) {
+				p = (i * config_desc->nr_total_params) + j;
+				printf("0x%llx, ",  config_desc->presets[p]);
+			}
+			printf("\n");
+		}
+	}
+	printf("\n\n");
+}
+
+static void print_reg_type_info(u8 type)
+{
+	if (type & CS_CFG_REG_TYPE_STD)
+		printf("std_reg ");
+	if (type & CS_CFG_REG_TYPE_RESOURCE)
+		printf("resource ");
+	if (type & CS_CFG_REG_TYPE_VAL_PARAM)
+		printf("param_index ");
+	if (type & CS_CFG_REG_TYPE_VAL_64BIT)
+		printf("64_bit ");
+	else
+		printf("32_bit ");
+	if (type & CS_CFG_REG_TYPE_VAL_MASK)
+		printf("masked ");
+	if (type & CS_CFG_REG_TYPE_VAL_SAVE)
+		printf("save_on_disable ");
+
+}
+
+static void print_regs(int nr, struct cscfg_regval_desc *regs_desc_array)
+{
+	int i;
+	struct cscfg_regval_desc *reg_desc;
+	u8 type;
+	u16 offset;
+	u16 info;
+
+	for (i = 0; i < nr; i++) {
+		reg_desc = &regs_desc_array[i];
+		type = (u8)reg_desc->type;
+		offset = (u16)reg_desc->offset;
+		info = (u16)reg_desc->hw_info;
+
+		printf("Reg(%d): Type 0x%x: ", i, type);
+		print_reg_type_info(type);
+		printf("\nOffset: 0x%03x; HW Info: 0x%03x\n", offset, info);
+		printf("Value: ");
+		if (type & CS_CFG_REG_TYPE_VAL_64BIT)
+			printf("0x%llx\n", reg_desc->val64);
+		else if (type & CS_CFG_REG_TYPE_VAL_PARAM)
+			printf("idx = %d\n", reg_desc->param_idx);
+		else {
+			printf("0x%x ", reg_desc->val32);
+			if (type & CS_CFG_REG_TYPE_VAL_MASK)
+				printf(" mask: 0x%x", reg_desc->mask32);
+			printf("\n");
+		}
+	}
+}
+
+static void print_params(int nr, struct cscfg_parameter_desc *params_desc)
+{
+	int i;
+
+	for (i = 0; i < nr; i++)
+		printf("Param(%d) : %s; Init value 0x%llx\n", i,
+		       params_desc[i].name, params_desc[i].value);
+}
+
+static void print_features(struct cscfg_fs_load_descs *load_descs)
+{
+	struct cscfg_feature_desc *feat_desc = 0;
+	int idx = 0;
+
+	feat_desc = load_descs->feat_descs[idx];
+	if (!feat_desc) {
+		printf("File contains no features\n\n");
+		return;
+	}
+
+	while (feat_desc) {
+		printf("Feature %d name : %s\n", idx+1, feat_desc->name);
+		printf("Description: %s\n", feat_desc->description);
+		printf("Match flags: 0x%x\n", feat_desc->match_flags);
+		printf("Number of Paraneters: %d\n", feat_desc->nr_params);
+		if (feat_desc->nr_params)
+			print_params(feat_desc->nr_params, feat_desc->params_desc);
+		printf("Number of Registers: %d\n", feat_desc->nr_regs);
+		if (feat_desc->nr_regs)
+			print_regs(feat_desc->nr_regs, feat_desc->regs_desc);
+		printf("\n\n");
+
+		/* next feature */
+		idx++;
+		feat_desc = load_descs->feat_descs[idx];
+	}
+}
+
+int main(int argc, char **argv)
+{
+	FILE *fp;
+	struct cscfg_fs_load_descs *load_descs;
+	int err, fsize;
+	u8 buffer[CSCFG_FILE_MAXSIZE];
+
+	printf("CoreSight Configuration file reader\n\n");
+
+	/* need a filename */
+	if (argc <= 1) {
+		printf("Please provide filename on command line\n");
+		return -EINVAL;
+	}
+
+	/* open file and read into the buffer. */
+	fp = fopen(argv[1], "rb");
+	if (fp == NULL) {
+		printf("Error opening file %s\n", argv[1]);
+		return -EINVAL;
+	}
+
+	fseek(fp, 0, SEEK_END);
+	fsize = ftell(fp);
+	rewind(fp);
+	if (fsize > CSCFG_FILE_MAXSIZE) {
+		printf("Error: Input file too large.");
+		fclose(fp);
+		return -EINVAL;
+	}
+	fread(buffer, sizeof(u8), fsize, fp);
+	fclose(fp);
+
+	/* allocate the descriptor structures to be populated by read operation */
+	load_descs = malloc(sizeof(struct cscfg_fs_load_descs));
+	if (!load_descs) {
+		printf("Error allocating load descs structure.\n");
+		return -ENOMEM;
+	}
+
+	/* read the buffer and create the configuration and feature structures */
+	err = cscfg_file_read_buffer(buffer, fsize, load_descs);
+	if (err) {
+		printf("Error reading configuration file\n");
+		goto exit_free_mem;
+	}
+	/* print the contents of the structures */
+	print_configs(load_descs);
+	print_features(load_descs);
+
+exit_free_mem:
+	free(load_descs);
+	return err;
+}