2023-05-11 06:57:32

by Mike Leach

[permalink] [raw]
Subject: [PATCH v6 0/6] coresight: syscfg: Add config table load via configfs

This set extends the configuration management support to allow loading and
unloading of configurations as structured tables.

The existing coresight configuration configfs API is additionally extended
to use this table functionality to load and unload configuration tables
as binary files.

This allows coresight configurations to be loaded at runtime, and independently
of kernel version, without the requirement to re-compile as built in kernel
modules.

Additional attributes - load and unload are provided to in the
/config/cs-syscfg subsytem base group to implement the load functionality.

The load attribute is a configfs binary attribute, loading the configuration
table in a similar way as the ACPI table binary attribute for that sub-system.

The configfs binary attribute mechanism supplies a strictly size limited
kernel buffer, providing better safety than other mechnisms, and also has
the advantage of being accessible directly from the command line, and being
part of the existing upstream coresight configuration mechanism in configfs

Configurations loaded in this way are validated and loaded across the entire
system of components atomically. If any part fails to load then the whole
configuration load will be cancelled.

Routines to generate binary configuration table files are supplied in
./tools/coresight.

Example generator and reader applications are provided.

Tools may be cross compiled or built for use on host system.

Documentation is updated to describe feature usage.

Changes since v5:
1) Possible memory leak removed.
Reported-by: kernel test robot <[email protected]>
Reported-by: Dan Carpenter <[email protected]>
2) Reuse mechanism for reader code revised. (Christoph)
3) Unload mechnism now by name in standard attribute, rather than
entire file
4) Mechanism to check last loaded configuration can be unloaded.
5) Documentation updates.

Changes since v4:
1) Update coresight/next - 6.1-rc3
2) Update to lockdep fixes to avoid read lock race in configfs.

Changes since v3:
1) Rebase & tested on coresight/next - 5.19-rc3 - which includes the
fix patch for earlier configfs works.
2) Lockdep investigations resulted in re-design of some of the code
accessing configfs.
3) moved load and unload attributes to root of cs-syscfg. (Mathieu)
4) Additional minor fixes suggested by Mathieu.
5) Memory for configfs loaded and unloaded configurations is now
explicitly freed.
6) LOCKDEP nesting fix for configfs base code (fs/configfs/dir.c)

Changes since v2:
1) Rebased & tested on coresight/next - 5.18-rc2
2) Moved coresight config generator and reader programs from samples to
tools/coresight. Docs updated to match. (suggested by Mathieu)
3) userspace builds now use userspace headers from tools/...
4) Other minor fixes from Mathieu's review.

Changes since v1:
1) Rebased to coresight/next - 5.16-rc1 with previous coresight config
set applied.
2) Makefile.host fixed to default to all target.

Mike Leach (6):
coresight: config: add config table runtime load functionality
coresight: configfs: Update memory allocation / free for configfs
elements
coresight: configfs: Add attributes to load config tables at runtime
coresight: config: extract shared structures to common header file
coresight: tools: Add config table file write and reader tools
Documentation: coresight: docs for config load via configfs

.../trace/coresight/coresight-config.rst | 265 ++++++++-
MAINTAINERS | 1 +
drivers/hwtracing/coresight/Makefile | 3 +-
.../coresight/coresight-config-desc.h | 105 ++++
.../coresight/coresight-config-table.c | 431 +++++++++++++++
.../coresight/coresight-config-table.h | 151 ++++++
.../hwtracing/coresight/coresight-config.h | 98 +---
.../coresight/coresight-syscfg-configfs.c | 513 ++++++++++++++++--
.../coresight/coresight-syscfg-configfs.h | 5 +
.../hwtracing/coresight/coresight-syscfg.c | 101 +++-
.../hwtracing/coresight/coresight-syscfg.h | 6 +-
tools/coresight/Makefile | 56 ++
tools/coresight/coresight-cfg-bufw.c | 309 +++++++++++
tools/coresight/coresight-cfg-bufw.h | 26 +
tools/coresight/coresight-cfg-example1.c | 62 +++
tools/coresight/coresight-cfg-example2.c | 95 ++++
tools/coresight/coresight-cfg-examples.h | 25 +
tools/coresight/coresight-cfg-file-gen.c | 61 +++
tools/coresight/coresight-cfg-file-read.c | 227 ++++++++
tools/coresight/coresight-config-uapi.h | 105 ++++
20 files changed, 2503 insertions(+), 142 deletions(-)
create mode 100644 drivers/hwtracing/coresight/coresight-config-desc.h
create mode 100644 drivers/hwtracing/coresight/coresight-config-table.c
create mode 100644 drivers/hwtracing/coresight/coresight-config-table.h
create mode 100644 tools/coresight/Makefile
create mode 100644 tools/coresight/coresight-cfg-bufw.c
create mode 100644 tools/coresight/coresight-cfg-bufw.h
create mode 100644 tools/coresight/coresight-cfg-example1.c
create mode 100644 tools/coresight/coresight-cfg-example2.c
create mode 100644 tools/coresight/coresight-cfg-examples.h
create mode 100644 tools/coresight/coresight-cfg-file-gen.c
create mode 100644 tools/coresight/coresight-cfg-file-read.c
create mode 100644 tools/coresight/coresight-config-uapi.h

--
2.17.1



2023-05-11 06:57:47

by Mike Leach

[permalink] [raw]
Subject: [PATCH v6 2/6] coresight: configfs: Update memory allocation / free for configfs elements

Previously, the objects backing the configfs directories and files were
created using devm managed memory on the coresight device.

Now we are adding configfs load/unload, configurations can be loaded
many times over the lifetime of the device, so it is more appropriate to
use normally allocated and freed memory.

Signed-off-by: Mike Leach <[email protected]>
---
.../coresight/coresight-syscfg-configfs.c | 119 +++++++++++++-----
1 file changed, 88 insertions(+), 31 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
index 433ede94dd63..6e8c8db52d39 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
@@ -14,7 +14,7 @@ static inline struct config_item_type *cscfg_create_ci_type(void)
{
struct config_item_type *ci_type;

- ci_type = devm_kzalloc(cscfg_device(), sizeof(*ci_type), GFP_KERNEL);
+ ci_type = kzalloc(sizeof(*ci_type), GFP_KERNEL);
if (ci_type)
ci_type->ct_owner = THIS_MODULE;

@@ -175,6 +175,19 @@ static struct config_item_type cscfg_config_preset_type = {
.ct_attrs = cscfg_config_preset_attrs,
};

+
+/* walk list of presets and free the previously allocated memory */
+static void cscfg_destroy_preset_groups(struct config_group *cfg_view_group)
+{
+ struct cscfg_fs_preset *cfg_fs_preset;
+ struct config_group *p_group;
+
+ list_for_each_entry(p_group, &cfg_view_group->default_groups, default_groups) {
+ cfg_fs_preset = container_of(p_group, struct cscfg_fs_preset, group);
+ kfree(cfg_fs_preset);
+ }
+}
+
static int cscfg_add_preset_groups(struct cscfg_fs_config *cfg_view)
{
int preset_num;
@@ -186,11 +199,12 @@ static int cscfg_add_preset_groups(struct cscfg_fs_config *cfg_view)
return 0;

for (preset_num = 1; preset_num <= config_desc->nr_presets; preset_num++) {
- cfg_fs_preset = devm_kzalloc(cscfg_device(),
- sizeof(struct cscfg_fs_preset), GFP_KERNEL);
+ cfg_fs_preset = kzalloc(sizeof(struct cscfg_fs_preset), GFP_KERNEL);

- if (!cfg_fs_preset)
+ if (!cfg_fs_preset) {
+ cscfg_destroy_preset_groups(&cfg_view->group);
return -ENOMEM;
+ }

snprintf(name, CONFIGFS_ITEM_NAME_LEN, "preset%d", preset_num);
cfg_fs_preset->preset_num = preset_num;
@@ -204,14 +218,10 @@ static int cscfg_add_preset_groups(struct cscfg_fs_config *cfg_view)

static struct config_group *cscfg_create_config_group(struct cscfg_config_desc *config_desc)
{
- struct cscfg_fs_config *cfg_view;
- struct device *dev = cscfg_device();
+ struct cscfg_fs_config *cfg_view = NULL;
int err;

- if (!dev)
- return ERR_PTR(-EINVAL);
-
- cfg_view = devm_kzalloc(dev, sizeof(struct cscfg_fs_config), GFP_KERNEL);
+ cfg_view = kzalloc(sizeof(struct cscfg_fs_config), GFP_KERNEL);
if (!cfg_view)
return ERR_PTR(-ENOMEM);

@@ -220,12 +230,21 @@ static struct config_group *cscfg_create_config_group(struct cscfg_config_desc *

/* add in a preset<n> dir for each preset */
err = cscfg_add_preset_groups(cfg_view);
- if (err)
+ if (err) {
+ kfree(cfg_view);
return ERR_PTR(err);
-
+ }
return &cfg_view->group;
}

+static void cscfg_destroy_config_group(struct config_group *group)
+{
+ struct cscfg_fs_config *cfg_view = container_of(group, struct cscfg_fs_config, group);
+
+ cscfg_destroy_preset_groups(&cfg_view->group);
+ kfree(cfg_view);
+}
+
/* attributes for features view */

static ssize_t cscfg_feat_description_show(struct config_item *item, char *page)
@@ -314,6 +333,17 @@ static struct config_item_type cscfg_param_view_type = {
.ct_attrs = cscfg_param_view_attrs,
};

+/* walk the list of default groups - which were set as param items and remove */
+static void cscfg_destroy_params_group_items(struct config_group *params_group)
+{
+ struct cscfg_fs_param *param_item;
+ struct config_group *p_group;
+
+ list_for_each_entry(p_group, &params_group->default_groups, default_groups) {
+ param_item = container_of(p_group, struct cscfg_fs_param, group);
+ kfree(param_item);
+ }
+}
/*
* configfs has far less functionality provided to add attributes dynamically than sysfs,
* and the show and store fns pass the enclosing config_item so the actual attribute cannot
@@ -322,15 +352,16 @@ static struct config_item_type cscfg_param_view_type = {
static int cscfg_create_params_group_items(struct cscfg_feature_desc *feat_desc,
struct config_group *params_group)
{
- struct device *dev = cscfg_device();
struct cscfg_fs_param *param_item;
int i;

/* parameter items - as groups with default_value attribute */
for (i = 0; i < feat_desc->nr_params; i++) {
- param_item = devm_kzalloc(dev, sizeof(struct cscfg_fs_param), GFP_KERNEL);
- if (!param_item)
+ param_item = kzalloc(sizeof(struct cscfg_fs_param), GFP_KERNEL);
+ if (!param_item) {
+ cscfg_destroy_params_group_items(params_group);
return -ENOMEM;
+ }
param_item->feat_desc = feat_desc;
param_item->param_idx = i;
config_group_init_type_name(&param_item->group,
@@ -343,27 +374,22 @@ static int cscfg_create_params_group_items(struct cscfg_feature_desc *feat_desc,

static struct config_group *cscfg_create_feature_group(struct cscfg_feature_desc *feat_desc)
{
- struct cscfg_fs_feature *feat_view;
- struct config_item_type *params_group_type;
+ struct cscfg_fs_feature *feat_view = NULL;
+ struct config_item_type *params_group_type = NULL;
struct config_group *params_group = NULL;
- struct device *dev = cscfg_device();
- int item_err;
-
- if (!dev)
- return ERR_PTR(-EINVAL);
+ int err = -ENOMEM;

- feat_view = devm_kzalloc(dev, sizeof(struct cscfg_fs_feature), GFP_KERNEL);
+ feat_view = kzalloc(sizeof(struct cscfg_fs_feature), GFP_KERNEL);
if (!feat_view)
return ERR_PTR(-ENOMEM);

if (feat_desc->nr_params) {
- params_group = devm_kzalloc(dev, sizeof(struct config_group), GFP_KERNEL);
+ params_group = kzalloc(sizeof(struct config_group), GFP_KERNEL);
if (!params_group)
- return ERR_PTR(-ENOMEM);
-
+ goto exit_err_free_mem;
params_group_type = cscfg_create_ci_type();
if (!params_group_type)
- return ERR_PTR(-ENOMEM);
+ goto exit_err_free_mem;
}

feat_view->feat_desc = feat_desc;
@@ -373,11 +399,36 @@ static struct config_group *cscfg_create_feature_group(struct cscfg_feature_desc
if (params_group) {
config_group_init_type_name(params_group, "params", params_group_type);
configfs_add_default_group(params_group, &feat_view->group);
- item_err = cscfg_create_params_group_items(feat_desc, params_group);
- if (item_err)
- return ERR_PTR(item_err);
+ err = cscfg_create_params_group_items(feat_desc, params_group);
+ if (err)
+ goto exit_err_free_mem;
}
return &feat_view->group;
+
+exit_err_free_mem:
+ kfree(feat_view);
+ kfree(params_group_type);
+ kfree(params_group);
+ return ERR_PTR(err);
+}
+
+static void cscfg_destroy_feature_group(struct config_group *feat_group)
+{
+ struct cscfg_fs_feature *feat_view;
+ struct config_group *params_group = NULL;
+
+ feat_view = container_of(feat_group, struct cscfg_fs_feature, group);
+
+ /* params group is the first item on the default group list */
+ if (!list_empty(&feat_group->default_groups)) {
+ params_group = list_first_entry(&feat_group->default_groups,
+ struct config_group, default_groups);
+ cscfg_destroy_params_group_items(params_group);
+ /* free the item type, then the group */
+ kfree(params_group->cg_item.ci_type);
+ kfree(params_group);
+ }
+ kfree(feat_view);
}

static struct config_item_type cscfg_configs_type = {
@@ -403,6 +454,8 @@ int cscfg_configfs_add_config(struct cscfg_config_desc *config_desc)
err = configfs_register_group(&cscfg_configs_grp, new_group);
if (!err)
config_desc->fs_group = new_group;
+ else
+ cscfg_destroy_config_group(new_group);
return err;
}

@@ -410,6 +463,7 @@ void cscfg_configfs_del_config(struct cscfg_config_desc *config_desc)
{
if (config_desc->fs_group) {
configfs_unregister_group(config_desc->fs_group);
+ cscfg_destroy_config_group(config_desc->fs_group);
config_desc->fs_group = NULL;
}
}
@@ -434,9 +488,11 @@ int cscfg_configfs_add_feature(struct cscfg_feature_desc *feat_desc)
new_group = cscfg_create_feature_group(feat_desc);
if (IS_ERR(new_group))
return PTR_ERR(new_group);
- err = configfs_register_group(&cscfg_features_grp, new_group);
+ err = configfs_register_group(&cscfg_features_grp, new_group);
if (!err)
feat_desc->fs_group = new_group;
+ else
+ cscfg_destroy_feature_group(new_group);
return err;
}

@@ -444,6 +500,7 @@ void cscfg_configfs_del_feature(struct cscfg_feature_desc *feat_desc)
{
if (feat_desc->fs_group) {
configfs_unregister_group(feat_desc->fs_group);
+ cscfg_destroy_feature_group(feat_desc->fs_group);
feat_desc->fs_group = NULL;
}
}
--
2.17.1


2023-05-11 06:57:56

by Mike Leach

[permalink] [raw]
Subject: [PATCH v6 4/6] coresight: config: extract shared structures to common header file

Extract shared user space and kernel common structures from
coresight-config.h into common header file coresight-config-desc.h

Abstract memory allocation in coresight-config-table.c to allow read
table functions to be run in userspace and kernel drivers.

Signed-off-by: Mike Leach <[email protected]>
---
.../coresight/coresight-config-desc.h | 105 ++++++++++++++++
.../coresight/coresight-config-table.c | 66 +++++-----
.../hwtracing/coresight/coresight-config.h | 119 ++++--------------
3 files changed, 165 insertions(+), 125 deletions(-)
create mode 100644 drivers/hwtracing/coresight/coresight-config-desc.h

diff --git a/drivers/hwtracing/coresight/coresight-config-desc.h b/drivers/hwtracing/coresight/coresight-config-desc.h
new file mode 100644
index 000000000000..4a487743d7e2
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-config-desc.h
@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020-2022 Linaro Limited, All rights reserved.
+ * Author: Mike Leach <[email protected]>
+ */
+
+#ifndef _CORESIGHT_CORESIGHT_CONFIG_DESC_H
+#define _CORESIGHT_CORESIGHT_CONFIG_DESC_H
+
+/* Coresight Descriptors common to kernel and userspace applications */
+/*
+ * Register type flags for register value descriptor:
+ * describe how the value is interpreted, and handled.
+ */
+#define CS_CFG_REG_TYPE_STD 0x80 /* reg is standard reg */
+#define CS_CFG_REG_TYPE_RESOURCE 0x40 /* reg is a resource */
+#define CS_CFG_REG_TYPE_VAL_PARAM 0x08 /* reg value uses param */
+#define CS_CFG_REG_TYPE_VAL_MASK 0x04 /* reg value bit masked */
+#define CS_CFG_REG_TYPE_VAL_64BIT 0x02 /* reg value 64 bit */
+#define CS_CFG_REG_TYPE_VAL_SAVE 0x01 /* reg value save on disable */
+
+/*
+ * flags defining what device class a feature will match to when processing a
+ * system configuration - used by config data and devices.
+ */
+#define CS_CFG_MATCH_CLASS_SRC_ALL 0x0001 /* match any source */
+#define CS_CFG_MATCH_CLASS_SRC_ETM4 0x0002 /* match any ETMv4 device */
+
+/* flags defining device instance matching - used in config match desc data. */
+#define CS_CFG_MATCH_INST_ANY 0x80000000 /* any instance of a class */
+
+/*
+ * Limit number of presets in a configuration
+ * This is related to the number of bits (4) we use to select the preset on
+ * the perf command line. Preset 0 is always none selected.
+ * See PMU_FORMAT_ATTR(preset, "config:0-3") in coresight-etm-perf.c
+ */
+#define CS_CFG_CONFIG_PRESET_MAX 15
+
+/**
+ * Parameter descriptor for a device feature.
+ *
+ * @name: Name of parameter.
+ * @value: Initial or default value.
+ */
+struct cscfg_parameter_desc {
+ const char *name;
+ u64 value;
+};
+
+/**
+ * Representation of register value and a descriptor of register usage.
+ *
+ * Used as a descriptor in the feature descriptors.
+ * Used as a value in when in a feature loading into a csdev.
+ *
+ * Supports full 64 bit register value, or 32 bit value with optional mask
+ * value.
+ *
+ * @type: define register usage and interpretation.
+ * @offset: the address offset for register in the hardware device (per device specification).
+ * @hw_info: optional hardware device type specific information. (ETM / CTI specific etc)
+ * @val64: 64 bit value.
+ * @val32: 32 bit value.
+ * @mask32: 32 bit mask when using 32 bit value to access device register - if mask type.
+ * @param_idx: parameter index value into parameter array if param type.
+ */
+struct cscfg_regval_desc {
+ struct {
+ u32 type:8;
+ u32 offset:12;
+ u32 hw_info:12;
+ };
+ union {
+ u64 val64;
+ struct {
+ u32 val32;
+ u32 mask32;
+ };
+ u32 param_idx;
+ };
+};
+
+/**
+ * Dynamically loaded descriptor arrays.
+ *
+ * For builtin or module loaded configurations / features these are
+ * statically defined at compile time.
+
+ * For a dynamic load at runtime, using a config table, (e.g. load from
+ * configfs) we create the arrays dynamically so need a structure to
+ * manage these.
+ *
+ * @config_descs: array of config descriptor pointers.
+ * @feat_descs: array of feature descriptor pointers.
+ * @load_name: user readable name which may be used to unload later.
+ * Will be name of first config if present, or first feature.
+ */
+struct cscfg_table_load_descs {
+ struct cscfg_config_desc **config_descs;
+ struct cscfg_feature_desc **feat_descs;
+ char *load_name;
+};
+
+#endif /* _CORESIGHT_CORESIGHT_CONFIG_DESC_H */
diff --git a/drivers/hwtracing/coresight/coresight-config-table.c b/drivers/hwtracing/coresight/coresight-config-table.c
index 0a8f017d76d2..6216dffc9f9e 100644
--- a/drivers/hwtracing/coresight/coresight-config-table.c
+++ b/drivers/hwtracing/coresight/coresight-config-table.c
@@ -79,6 +79,7 @@ static int cscfg_table_read_elem_str(const u8 *buffer, const int buflen, int *bu
struct cscfg_table_elem_str *elem_str)
{
int used = *buf_used;
+ const u8 *str;

if ((buflen - used) < sizeof(u16))
return -EINVAL;
@@ -88,11 +89,13 @@ static int cscfg_table_read_elem_str(const u8 *buffer, const int buflen, int *bu
if ((buflen - used) < elem_str->str_len)
return -EINVAL;

+ str = buffer + used;
+
/* check for 0 termination */
- if (buffer[used + (elem_str->str_len - 1)] != 0)
+ if (str[elem_str->str_len - 1] != 0)
return -EINVAL;

- elem_str->str = kstrdup((char *)(buffer + used), GFP_KERNEL);
+ elem_str->str = cscfg_strdup((char *)str);
used += elem_str->str_len;

*buf_used = used;
@@ -103,12 +106,13 @@ static int cscfg_table_alloc_desc_arrays(struct cscfg_table_load_descs *desc_arr
int nr_features, int nr_configs)
{
/* arrays are 0 terminated - nr_configs & nr_features elements */
- desc_arrays->config_descs = kcalloc(nr_configs + 1, sizeof(struct cscfg_config_desc *),
- GFP_KERNEL);
+ desc_arrays->config_descs = cscfg_calloc(nr_configs + 1,
+ sizeof(struct cscfg_config_desc *));
if (!desc_arrays->config_descs)
return -ENOMEM;
- desc_arrays->feat_descs = kcalloc(nr_features + 1, sizeof(struct cscfg_feature_desc *),
- GFP_KERNEL);
+
+ desc_arrays->feat_descs = cscfg_calloc(nr_features + 1,
+ sizeof(struct cscfg_feature_desc *));
if (!desc_arrays->feat_descs)
return -ENOMEM;
return 0;
@@ -123,24 +127,24 @@ static void cscfg_table_free_config_desc(struct cscfg_config_desc *config_desc)
return;

/* free presets */
- kfree(config_desc->presets);
+ cscfg_free((void *)config_desc->presets);

/* free feat ref strings */
if (config_desc->nr_feat_refs) {
/* each string */
for (i = 0; i < config_desc->nr_feat_refs; i++)
- kfree(config_desc->feat_ref_names[i]);
+ cscfg_free((void *)config_desc->feat_ref_names[i]);

/* and the char * array */
- kfree(config_desc->feat_ref_names);
+ cscfg_free((void *)config_desc->feat_ref_names);
}

/* next the strings */
- kfree(config_desc->name);
- kfree(config_desc->description);
+ cscfg_free((void *)config_desc->name);
+ cscfg_free((void *)config_desc->description);

/* finally the struct itself */
- kfree(config_desc);
+ cscfg_free((void *)config_desc);
}

static int cscfg_table_read_elem_config(const u8 *buffer, const int buflen, int *buf_used,
@@ -165,7 +169,7 @@ static int cscfg_table_read_elem_config(const u8 *buffer, const int buflen, int
return 0;

/* we have a config - allocate the descriptor */
- config_desc = kzalloc(sizeof(struct cscfg_config_desc), GFP_KERNEL);
+ config_desc = cscfg_zalloc(sizeof(struct cscfg_config_desc));
if (!config_desc)
return -ENOMEM;

@@ -177,7 +181,7 @@ static int cscfg_table_read_elem_config(const u8 *buffer, const int buflen, int

/* allocate load name if not set */
if (!desc_arrays->load_name)
- desc_arrays->load_name = kstrdup(config_desc->name, GFP_KERNEL);
+ desc_arrays->load_name = cscfg_strdup(config_desc->name);

/* read the description string */
err = cscfg_table_read_elem_str(buffer, buflen, &used, &elem_str);
@@ -195,7 +199,7 @@ static int cscfg_table_read_elem_config(const u8 *buffer, const int buflen, int
/* read the array of 64bit presets if present */
nr_preset_vals = config_desc->nr_total_params * config_desc->nr_presets;
if (nr_preset_vals) {
- presets = kcalloc(nr_preset_vals, sizeof(u64), GFP_KERNEL);
+ presets = cscfg_calloc(nr_preset_vals, sizeof(u64));
if (!presets)
return -ENOMEM;

@@ -210,8 +214,8 @@ static int cscfg_table_read_elem_config(const u8 *buffer, const int buflen, int

/* read the array of feature names referenced by the config */
if (config_desc->nr_feat_refs) {
- config_desc->feat_ref_names = kcalloc(config_desc->nr_feat_refs,
- sizeof(char *), GFP_KERNEL);
+ config_desc->feat_ref_names = cscfg_calloc(config_desc->nr_feat_refs,
+ sizeof(char *));
if (!config_desc->feat_ref_names)
return -ENOMEM;

@@ -255,17 +259,17 @@ static void cscfg_table_free_feat_desc(struct cscfg_feature_desc *feat_desc)
return;

/* free up the register descriptor array */
- kfree(feat_desc->regs_desc);
+ cscfg_free((void *)feat_desc->regs_desc);

/* free up the parameters array */
- kfree(feat_desc->params_desc);
+ cscfg_free((void *)feat_desc->params_desc);

/* name and description strings */
- kfree(feat_desc->name);
- kfree(feat_desc->description);
+ cscfg_free((void *)feat_desc->name);
+ cscfg_free((void *)feat_desc->description);

/* finally the struct itself */
- kfree(feat_desc);
+ cscfg_free((void *)feat_desc);
}

static int cscfg_table_read_elem_feature(const u8 *buffer, const int buflen, int *buf_used,
@@ -280,7 +284,7 @@ static int cscfg_table_read_elem_feature(const u8 *buffer, const int buflen, int
u32 val32;

/* allocate the feature descriptor object */
- feat_desc = kzalloc(sizeof(struct cscfg_feature_desc), GFP_KERNEL);
+ feat_desc = cscfg_zalloc(sizeof(struct cscfg_feature_desc));
if (!feat_desc)
return -ENOMEM;

@@ -300,7 +304,7 @@ static int cscfg_table_read_elem_feature(const u8 *buffer, const int buflen, int

/* allocate load name if not set previously by config */
if (!desc_arrays->load_name)
- desc_arrays->load_name = kstrdup(feat_desc->name, GFP_KERNEL);
+ desc_arrays->load_name = cscfg_strdup(feat_desc->name);

/* read the description string */
err = cscfg_table_read_elem_str(buffer, buflen, &used, &elem_str);
@@ -323,8 +327,8 @@ static int cscfg_table_read_elem_feature(const u8 *buffer, const int buflen, int
nr_regs_bytes = ((sizeof(u32) + sizeof(u64)) * feat_desc->nr_regs);
if ((buflen - used) < nr_regs_bytes)
return -EINVAL;
- feat_desc->regs_desc = kcalloc(feat_desc->nr_regs,
- sizeof(struct cscfg_regval_desc), GFP_KERNEL);
+ feat_desc->regs_desc = cscfg_calloc(feat_desc->nr_regs,
+ sizeof(struct cscfg_regval_desc));
if (!feat_desc->regs_desc)
return -ENOMEM;

@@ -338,8 +342,8 @@ static int cscfg_table_read_elem_feature(const u8 *buffer, const int buflen, int

/* parameter descriptors - string + 64 bit value */
if (feat_desc->nr_params) {
- feat_desc->params_desc = kcalloc(feat_desc->nr_params,
- sizeof(struct cscfg_parameter_desc), GFP_KERNEL);
+ feat_desc->params_desc = cscfg_calloc(feat_desc->nr_params,
+ sizeof(struct cscfg_parameter_desc));
if (!feat_desc->params_desc)
return -ENOMEM;
for (i = 0; i < feat_desc->nr_params; i++) {
@@ -421,7 +425,7 @@ void cscfg_table_free_load_descs(struct cscfg_table_load_descs *desc_arrays)
}

/* finally free up the load descs pointer arrays */
- kfree(desc_arrays->config_descs);
- kfree(desc_arrays->feat_descs);
- kfree(desc_arrays->load_name);
+ cscfg_free(desc_arrays->config_descs);
+ cscfg_free(desc_arrays->feat_descs);
+ cscfg_free(desc_arrays->load_name);
}
diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
index ea3aaf0d129b..8b298e9a3776 100644
--- a/drivers/hwtracing/coresight/coresight-config.h
+++ b/drivers/hwtracing/coresight/coresight-config.h
@@ -10,101 +10,10 @@
#include <linux/coresight.h>
#include <linux/types.h>

-/* CoreSight Configuration Management - component and system wide configuration */
-
-/*
- * Register type flags for register value descriptor:
- * describe how the value is interpreted, and handled.
- */
-#define CS_CFG_REG_TYPE_STD 0x80 /* reg is standard reg */
-#define CS_CFG_REG_TYPE_RESOURCE 0x40 /* reg is a resource */
-#define CS_CFG_REG_TYPE_VAL_PARAM 0x08 /* reg value uses param */
-#define CS_CFG_REG_TYPE_VAL_MASK 0x04 /* reg value bit masked */
-#define CS_CFG_REG_TYPE_VAL_64BIT 0x02 /* reg value 64 bit */
-#define CS_CFG_REG_TYPE_VAL_SAVE 0x01 /* reg value save on disable */
-
-/*
- * flags defining what device class a feature will match to when processing a
- * system configuration - used by config data and devices.
- */
-#define CS_CFG_MATCH_CLASS_SRC_ALL 0x0001 /* match any source */
-#define CS_CFG_MATCH_CLASS_SRC_ETM4 0x0002 /* match any ETMv4 device */
-
-/* flags defining device instance matching - used in config match desc data. */
-#define CS_CFG_MATCH_INST_ANY 0x80000000 /* any instance of a class */
-
-/*
- * Limit number of presets in a configuration
- * This is related to the number of bits (4) we use to select the preset on
- * the perf command line. Preset 0 is always none selected.
- * See PMU_FORMAT_ATTR(preset, "config:0-3") in coresight-etm-perf.c
- */
-#define CS_CFG_CONFIG_PRESET_MAX 15
-
-/**
- * Parameter descriptor for a device feature.
- *
- * @name: Name of parameter.
- * @value: Initial or default value.
- */
-struct cscfg_parameter_desc {
- const char *name;
- u64 value;
-};
-
-/**
- * Representation of register value and a descriptor of register usage.
- *
- * Used as a descriptor in the feature descriptors.
- * Used as a value in when in a feature loading into a csdev.
- *
- * Supports full 64 bit register value, or 32 bit value with optional mask
- * value.
- *
- * @type: define register usage and interpretation.
- * @offset: the address offset for register in the hardware device (per device specification).
- * @hw_info: optional hardware device type specific information. (ETM / CTI specific etc)
- * @val64: 64 bit value.
- * @val32: 32 bit value.
- * @mask32: 32 bit mask when using 32 bit value to access device register - if mask type.
- * @param_idx: parameter index value into parameter array if param type.
- */
-struct cscfg_regval_desc {
- struct {
- u32 type:8;
- u32 offset:12;
- u32 hw_info:12;
- };
- union {
- u64 val64;
- struct {
- u32 val32;
- u32 mask32;
- };
- u32 param_idx;
- };
-};
-
-/**
- * Dynamically loaded descriptor arrays.
- *
- * For builtin or module loaded configurations / features these are
- * statically defined at compile time.
+/* common descriptor definitions */
+#include "coresight-config-desc.h"

- * For a dynamic load at runtime, using a config table, (e.g. load from
- * configfs) we create the arrays dynamically so need a structure to
- * manage these.
- *
- * @config_descs: array of config descriptor pointers.
- * @feat_descs: array of feature descriptor pointers.
- * @load_name: user readable name which may be used to unload later.
- * Will be name of first config if present, or first feature.
- */
-struct cscfg_table_load_descs {
- struct cscfg_config_desc **config_descs;
- struct cscfg_feature_desc **feat_descs;
- char *load_name;
-};
+/* CoreSight Configuration Management - component and system wide configuration */

/**
* Device feature descriptor - combination of registers and parameters to
@@ -280,4 +189,26 @@ void cscfg_csdev_disable_config(struct cscfg_config_csdev *config_csdev);
/* reset a feature to default values */
void cscfg_reset_feat(struct cscfg_feature_csdev *feat_csdev);

+
+/* Kernel allocators for descriptors in common config table read code */
+static inline void *cscfg_calloc(size_t num, size_t size)
+{
+ return kcalloc(num, size, GFP_KERNEL);
+}
+
+static inline char *cscfg_strdup(const char *str)
+{
+ return kstrdup(str, GFP_KERNEL);
+}
+
+static inline void *cscfg_zalloc(size_t size)
+{
+ return kzalloc(size, GFP_KERNEL);
+}
+
+static inline void cscfg_free(void *mem)
+{
+ kfree(mem);
+}
+
#endif /* _CORESIGHT_CORESIGHT_CONFIG_H */
--
2.17.1


2023-05-11 06:58:05

by Mike Leach

[permalink] [raw]
Subject: [PATCH v6 5/6] coresight: tools: Add config table file write and reader tools

Add an example config table generator to test loading configurations
via a binary attribute in configfs.

Provides a table buffer writer function that can be re-used in other
userspace programs.

Table write format matches that expected by the corresponding reader
in the configfs driver code.

Generates tables and outputs in form of binary files.

Add a config table file reader and printer. Takes in config table files
and prints the contents. Uses table reader source from kernel driver.

Signed-off-by: Mike Leach <[email protected]>
---
MAINTAINERS | 1 +
.../coresight/coresight-config-table.h | 5 +
tools/coresight/Makefile | 56 ++++
tools/coresight/coresight-cfg-bufw.c | 309 ++++++++++++++++++
tools/coresight/coresight-cfg-bufw.h | 26 ++
tools/coresight/coresight-cfg-example1.c | 62 ++++
tools/coresight/coresight-cfg-example2.c | 95 ++++++
tools/coresight/coresight-cfg-examples.h | 25 ++
tools/coresight/coresight-cfg-file-gen.c | 61 ++++
tools/coresight/coresight-cfg-file-read.c | 227 +++++++++++++
tools/coresight/coresight-config-uapi.h | 105 ++++++
11 files changed, 972 insertions(+)
create mode 100644 tools/coresight/Makefile
create mode 100644 tools/coresight/coresight-cfg-bufw.c
create mode 100644 tools/coresight/coresight-cfg-bufw.h
create mode 100644 tools/coresight/coresight-cfg-example1.c
create mode 100644 tools/coresight/coresight-cfg-example2.c
create mode 100644 tools/coresight/coresight-cfg-examples.h
create mode 100644 tools/coresight/coresight-cfg-file-gen.c
create mode 100644 tools/coresight/coresight-cfg-file-read.c
create mode 100644 tools/coresight/coresight-config-uapi.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 1dc8bd26b6cf..074989716fbf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2109,6 +2109,7 @@ F: drivers/hwtracing/coresight/*
F: include/dt-bindings/arm/coresight-cti-dt.h
F: include/linux/coresight*
F: samples/coresight/*
+F: tools/coresight/*
F: tools/perf/tests/shell/coresight/*
F: tools/perf/arch/arm/util/auxtrace.c
F: tools/perf/arch/arm/util/cs-etm.c
diff --git a/drivers/hwtracing/coresight/coresight-config-table.h b/drivers/hwtracing/coresight/coresight-config-table.h
index 2cd8fb0630e2..b9935bff7169 100644
--- a/drivers/hwtracing/coresight/coresight-config-table.h
+++ b/drivers/hwtracing/coresight/coresight-config-table.h
@@ -9,7 +9,12 @@

#include <linux/sizes.h>

+#ifdef __KERNEL__
#include "coresight-config.h"
+#else
+#include "coresight-config-uapi.h"
+#endif
+

/*
* Configurations and features can be dynamically loaded at runtime
diff --git a/tools/coresight/Makefile b/tools/coresight/Makefile
new file mode 100644
index 000000000000..175d2b45bb44
--- /dev/null
+++ b/tools/coresight/Makefile
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: GPL-2.0-only
+include ../scripts/Makefile.include
+include ../scripts/Makefile.arch
+
+# Makefile to build the coresight configuration table file reader and generator tools
+
+this-makefile := $(lastword $(MAKEFILE_LIST))
+tools-src := $(realpath $(dir $(this-makefile)))
+srctree := $(realpath $(dir $(tools-src)/../../.))
+
+# ensure we use all as the default - skip anything in included Makefile
+.DEFAULT_GOAL = all
+# MAKECMDGOALS isn't set if there's no explicit goal in the
+# command line, so set the default.
+MAKECMDGOALS ?= $(.DEFAULT_GOAL)
+
+# cs tools includes
+CS_TOOLS_INCLUDE = -I$(srctree)/drivers/hwtracing/coresight -I$(srctree)/tools/include/ \
+ -I$(srctree)/tools/include/uapi -I$(srctree)/tools/coresight
+
+# compile flags
+CFLAGS += $(CPPFLAGS) -c -Wall -DLINUX -Wno-switch -Wlogical-op -fPIC $(CS_TOOLS_INCLUDE)
+
+# object files
+coresight-cfg-file-gen-objs := coresight-cfg-file-gen.o coresight-cfg-bufw.o \
+ coresight-cfg-example1.o coresight-cfg-example2.o
+coresight-cfg-file-read-objs := coresight-cfg-file-read.o coresight-config-table.o
+
+# debug variant
+ifdef DEBUG
+CFLAGS += -g -O0 -DDEBUG
+else
+CFLAGS += -O2 -DNDEBUG
+endif
+
+.PHONY: all
+all: coresight-cfg-file-gen coresight-cfg-file-read
+
+coresight-config-table.o: src_copy
+ $(CC) $(CFLAGS) coresight-config-table.c -o coresight-config-table.o
+
+.PHONY: src_copy
+src_copy:
+ @cp $(srctree)/drivers/hwtracing/coresight/coresight-config-table.c $(srctree)/tools/coresight/.
+
+coresight-cfg-file-gen: $(coresight-cfg-file-gen-objs)
+ $(CC) $(LDFLAGS) $(coresight-cfg-file-gen-objs) -o coresight-cfg-file-gen
+
+coresight-cfg-file-read: $(coresight-cfg-file-read-objs)
+ $(CC) $(LDFLAGS) $(coresight-cfg-file-read-objs) -o coresight-cfg-file-read
+
+clean:
+ rm -f coresight-cfg-file-gen coresight-cfg-file-read
+ rm -f *.o
+ rm -f coresight-config-table.c
+ rm -f *.cscfg
diff --git a/tools/coresight/coresight-cfg-bufw.c b/tools/coresight/coresight-cfg-bufw.c
new file mode 100644
index 000000000000..23ec33781330
--- /dev/null
+++ b/tools/coresight/coresight-cfg-bufw.c
@@ -0,0 +1,309 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020-2022 Linaro Limited, All rights reserved.
+ * Author: Mike Leach <[email protected]>
+ */
+
+#include <string.h>
+
+#include "coresight-cfg-bufw.h"
+#include "coresight-config-uapi.h"
+
+/*
+ * Set of macros to make writing the buffer code easier.
+ *.
+ * Uses naming convention as 'buffer' for the buffer pointer and
+ * 'used' as the current bytes used by the encosing function.
+ */
+#define cscfg_write_u64(val64) { \
+ *(u64 *)(buffer + used) = val64; \
+ used += sizeof(u64); \
+ }
+
+#define cscfg_write_u32(val32) { \
+ *(u32 *)(buffer + used) = val32; \
+ used += sizeof(u32); \
+ }
+
+#define cscfg_write_u16(val16) { \
+ *(u16 *)(buffer + used) = val16; \
+ used += sizeof(u16); \
+ }
+
+#define cscfg_write_u8(val8) { \
+ *(buffer + used) = val8; \
+ used++; \
+ }
+
+#define CHECK_WRET(rval) { \
+ if (rval < 0) \
+ return rval; \
+ used += rval; \
+ }
+
+/* write the header at the start of the buffer */
+static int cscfg_table_write_fhdr(u8 *buffer, const int buflen,
+ const struct cscfg_table_header *fhdr)
+{
+ int used = 0;
+
+ cscfg_write_u32(fhdr->magic_version);
+ cscfg_write_u16(fhdr->length);
+ cscfg_write_u16(fhdr->nr_configs);
+ cscfg_write_u16(fhdr->nr_features);
+ return used;
+}
+
+static int cscfg_table_write_string(u8 *buffer, const int buflen, const char *string)
+{
+ int len, used = 0;
+
+ len = strlen(string);
+ if (len > CSCFG_TABLE_STR_MAXSIZE)
+ return -EINVAL;
+
+ if (buflen < (len + 1 + sizeof(u16)))
+ return -EINVAL;
+
+ cscfg_write_u16((u16)(len + 1));
+ strcpy((char *)(buffer + used), string);
+ used += (len + 1);
+
+ return used;
+}
+
+static int cscfg_table_write_elem_hdr(u8 *buffer, const int buflen,
+ struct cscfg_table_elem_header *ehdr)
+{
+ int used = 0;
+
+ if (buflen < (sizeof(u16) + sizeof(u8)))
+ return -EINVAL;
+
+ cscfg_write_u16(ehdr->elem_length);
+ cscfg_write_u8(ehdr->elem_type);
+
+ return used;
+}
+
+static int cscfg_table_write_config(u8 *buffer, const int buflen,
+ struct cscfg_config_desc *config_desc)
+{
+ int used = 0, bytes_w, space_req, preset_bytes, i;
+ struct cscfg_table_elem_header ehdr;
+
+ ehdr.elem_length = 0;
+ ehdr.elem_type = CSCFG_TABLE_ELEM_TYPE_CFG;
+
+ /* write element header at current buffer location */
+ bytes_w = cscfg_table_write_elem_hdr(buffer, buflen, &ehdr);
+ CHECK_WRET(bytes_w);
+
+ /* write out the configuration name */
+ bytes_w = cscfg_table_write_string(buffer + used, buflen - used,
+ config_desc->name);
+ CHECK_WRET(bytes_w);
+
+ /* write out the description string */
+ bytes_w = cscfg_table_write_string(buffer + used, buflen - used,
+ config_desc->description);
+ CHECK_WRET(bytes_w);
+
+ /*
+ * calculate the space needed for variables + presets
+ * [u16 value - nr_presets]
+ * [u32 value - nr_total_params]
+ * [u16 value - nr_feat_refs]
+ * [u64 values] * (nr_presets * nr_total_params)
+ */
+ preset_bytes = sizeof(u64) * config_desc->nr_presets * config_desc->nr_total_params;
+ space_req = (sizeof(u16) * 2) + sizeof(u32) + preset_bytes;
+
+ if ((buflen - used) < space_req)
+ return -EINVAL;
+
+ cscfg_write_u16((u16)config_desc->nr_presets);
+ cscfg_write_u32((u32)config_desc->nr_total_params);
+ cscfg_write_u16((u16)config_desc->nr_feat_refs);
+ if (preset_bytes) {
+ memcpy(buffer + used, (u8 *)config_desc->presets, preset_bytes);
+ used += preset_bytes;
+ }
+
+ /* now write the feature ref names */
+ for (i = 0; i < config_desc->nr_feat_refs; i++) {
+ bytes_w = cscfg_table_write_string(buffer + used, buflen - used,
+ config_desc->feat_ref_names[i]);
+ CHECK_WRET(bytes_w);
+ }
+
+ /* rewrite the element header with the correct length */
+ ehdr.elem_length = used;
+ bytes_w = cscfg_table_write_elem_hdr(buffer, buflen, &ehdr);
+ /* no CHECK_WRET as used must not be updated */
+ if (bytes_w < 0)
+ return bytes_w;
+
+ return used;
+}
+
+/*
+ * write a parameter structure into the buffer in following format:
+ * [cscfg_table_elem_str] - parameter name.
+ * [u64 value: param_value] - initial value.
+ */
+static int cscfg_table_write_param(u8 *buffer, const int buflen,
+ struct cscfg_parameter_desc *param_desc)
+{
+ int used = 0, bytes_w;
+
+ bytes_w = cscfg_table_write_string(buffer + used, buflen - used,
+ param_desc->name);
+ CHECK_WRET(bytes_w);
+
+ if ((buflen - used) < sizeof(u64))
+ return -EINVAL;
+
+ cscfg_write_u64(param_desc->value);
+ return used;
+}
+
+/*
+ * Write a feature element from cscfg_feature_desc in following format:
+ *
+ * [cscfg_table_elem_header] - header length is total bytes to end of param structures.
+ * [cscfg_table_elem_str] - feature name.
+ * [cscfg_table_elem_str] - feature description.
+ * [u32 value: match_flags]
+ * [u16 value: nr_regs] - number of registers.
+ * [u16 value: nr_params] - number of parameters.
+ * [cscfg_regval_desc struct] * nr_regs
+ * [PARAM_ELEM] * nr_params
+ */
+static int cscfg_table_write_feat(u8 *buffer, const int buflen,
+ struct cscfg_feature_desc *feat_desc)
+{
+ struct cscfg_table_elem_header ehdr;
+ struct cscfg_regval_desc *p_reg_desc;
+ int used = 0, bytes_w, i, space_req;
+ u32 val32;
+
+ ehdr.elem_length = 0;
+ ehdr.elem_type = CSCFG_TABLE_ELEM_TYPE_FEAT;
+
+ /* write element header at current buffer location */
+ bytes_w = cscfg_table_write_elem_hdr(buffer, buflen, &ehdr);
+ CHECK_WRET(bytes_w);
+
+ /* write out the name string */
+ bytes_w = cscfg_table_write_string(buffer + used, buflen - used,
+ feat_desc->name);
+ CHECK_WRET(bytes_w)
+
+ /* write out the description string */
+ bytes_w = cscfg_table_write_string(buffer + used, buflen - used,
+ feat_desc->description);
+ CHECK_WRET(bytes_w);
+
+ /* check for space for variables and register structures */
+ space_req = (sizeof(u16) * 2) + sizeof(u32) +
+ (sizeof(struct cscfg_regval_desc) * feat_desc->nr_regs);
+ if ((buflen - used) < space_req)
+ return -EINVAL;
+
+ /* write the variables */
+ cscfg_write_u32((u32)feat_desc->match_flags);
+ cscfg_write_u16((u16)feat_desc->nr_regs);
+ cscfg_write_u16((u16)feat_desc->nr_params);
+
+ /*write the registers */
+ for (i = 0; i < feat_desc->nr_regs; i++) {
+ p_reg_desc = (struct cscfg_regval_desc *)&feat_desc->regs_desc[i];
+ CSCFG_TABLE_REG_DESC_INFO_TO_U32(val32, p_reg_desc);
+ cscfg_write_u32(val32);
+ cscfg_write_u64(feat_desc->regs_desc[i].val64);
+ }
+
+ /* write any parameters */
+ for (i = 0; i < feat_desc->nr_params; i++) {
+ bytes_w = cscfg_table_write_param(buffer + used, buflen - used,
+ &feat_desc->params_desc[i]);
+ CHECK_WRET(bytes_w);
+ }
+
+ /*
+ * rewrite the element header at the start of the buffer block
+ * with the correct length
+ */
+ ehdr.elem_length = used;
+ bytes_w = cscfg_table_write_elem_hdr(buffer, buflen, &ehdr);
+ /* no CHECK_WRET as used must not be updated */
+ if (bytes_w < 0)
+ return bytes_w;
+
+ return used;
+}
+
+/*
+ * write a buffer from the configuration and feature
+ * descriptors to write into a file for configfs.
+ *
+ * Will only write one config, and/or a number of features,
+ * per the file standard.
+ */
+int cscfg_table_write_buffer(u8 *buffer, const int buflen,
+ struct cscfg_config_desc **config_descs,
+ struct cscfg_feature_desc **feat_descs)
+{
+ struct cscfg_table_header fhdr;
+ int used = 0, bytes_w, i;
+
+ /* init the file header */
+ fhdr.magic_version = CSCFG_TABLE_MAGIC_VERSION;
+ fhdr.length = 0;
+ fhdr.nr_configs = 0;
+ fhdr.nr_features = 0;
+
+ /* count the configs */
+ if (config_descs) {
+ while (config_descs[fhdr.nr_configs])
+ fhdr.nr_configs++;
+ }
+
+ /* count the features */
+ if (feat_descs) {
+ while (feat_descs[fhdr.nr_features])
+ fhdr.nr_features++;
+ }
+
+ /* need a buffer and at least one config or feature */
+ if ((!fhdr.nr_configs && !fhdr.nr_features) ||
+ !buffer || (buflen > CSCFG_TABLE_MAXSIZE))
+ return -EINVAL;
+
+ /* write a header at the start to get the length of the header */
+ bytes_w = cscfg_table_write_fhdr(buffer, buflen, &fhdr);
+ CHECK_WRET(bytes_w);
+
+ /* write configs */
+ for (i = 0; i < fhdr.nr_configs; i++) {
+ bytes_w = cscfg_table_write_config(buffer + used, buflen - used,
+ config_descs[i]);
+ CHECK_WRET(bytes_w);
+ }
+
+ /* write any features */
+ for (i = 0; i < fhdr.nr_features; i++) {
+ bytes_w = cscfg_table_write_feat(buffer + used, buflen - used,
+ feat_descs[i]);
+ CHECK_WRET(bytes_w);
+ }
+
+ /* finally re-write the header at the buffer start with the correct length */
+ fhdr.length = (u16)used;
+ bytes_w = cscfg_table_write_fhdr(buffer, buflen, &fhdr);
+ /* no CHECK_WRET as used must not be updated */
+ if (bytes_w < 0)
+ return bytes_w;
+ return used;
+}
diff --git a/tools/coresight/coresight-cfg-bufw.h b/tools/coresight/coresight-cfg-bufw.h
new file mode 100644
index 000000000000..2d6ce64220a4
--- /dev/null
+++ b/tools/coresight/coresight-cfg-bufw.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020-2022 Linaro Limited, All rights reserved.
+ * Author: Mike Leach <[email protected]>
+ */
+
+#ifndef _CORESIGHT_CFG_BUFW_H
+#define _CORESIGHT_CFG_BUFW_H
+
+#include <linux/types.h>
+
+#include "coresight-config-table.h"
+
+/*
+ * Function to take coresight configurations and features and
+ * write them into a supplied memory buffer for serialisation
+ * into a file.
+ *
+ * Resulting file can then be loaded into the coresight
+ * infrastructure via configfs.
+ */
+int cscfg_table_write_buffer(u8 *buffer, const int buflen,
+ struct cscfg_config_desc **config_descs,
+ struct cscfg_feature_desc **feat_descs);
+
+#endif /* _CORESIGHT_CFG_BUFW_H */
diff --git a/tools/coresight/coresight-cfg-example1.c b/tools/coresight/coresight-cfg-example1.c
new file mode 100644
index 000000000000..c562116ffc94
--- /dev/null
+++ b/tools/coresight/coresight-cfg-example1.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020-2022 Linaro Limited, All rights reserved.
+ * Author: Mike Leach <[email protected]>
+ */
+#include <linux/types.h>
+#include <linux/unistd.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "coresight-cfg-examples.h"
+
+/*
+ * create a configuration only example using the strobing feature
+ */
+
+/* we will provide 4 sets of preset parameter values */
+#define AFDO3_NR_PRESETS 4
+/* the total number of parameters in used features - strobing has 2 */
+#define AFDO3_NR_PARAM_SUM 2
+
+static const char *afdo3_ref_names[] = {
+ "strobing",
+};
+
+/*
+ * set of presets leaves strobing window constant while varying period to allow
+ * experimentation with mark / space ratios for various workloads
+ */
+static u64 afdo3_presets[AFDO3_NR_PRESETS][AFDO3_NR_PARAM_SUM] = {
+ { 2000, 100 },
+ { 2000, 1000 },
+ { 2000, 5000 },
+ { 2000, 10000 },
+};
+
+struct cscfg_config_desc afdo3 = {
+ .name = "autofdo3",
+ .description = "Setup ETMs with strobing for autofdo\n"
+ "Supplied presets allow experimentation with mark-space ratio for various loads\n",
+ .nr_feat_refs = ARRAY_SIZE(afdo3_ref_names),
+ .feat_ref_names = afdo3_ref_names,
+ .nr_presets = AFDO3_NR_PRESETS,
+ .nr_total_params = AFDO3_NR_PARAM_SUM,
+ .presets = &afdo3_presets[0][0],
+};
+
+static struct cscfg_feature_desc *sample_feats[] = {
+ NULL
+};
+
+static struct cscfg_config_desc *sample_cfgs[] = {
+ &afdo3,
+ NULL
+};
+
+struct cscfg_file_eg_info file_info_eg1 = {
+ .example_name = "example1",
+ .filename = "example1.cscfg",
+ .config_descs = sample_cfgs,
+ .feat_descs = sample_feats,
+};
diff --git a/tools/coresight/coresight-cfg-example2.c b/tools/coresight/coresight-cfg-example2.c
new file mode 100644
index 000000000000..6312a185bd46
--- /dev/null
+++ b/tools/coresight/coresight-cfg-example2.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020-2022 Linaro Limited, All rights reserved.
+ * Author: Mike Leach <[email protected]>
+ */
+#include <linux/types.h>
+#include <linux/unistd.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "coresight-cfg-examples.h"
+
+/*
+ * create a dual configuration only example using the strobing feature
+ */
+
+/* we will provide 10 sets of preset parameter values */
+#define AFDO_NR_PRESETS 10
+/* the total number of parameters in used features - strobing has 2 */
+#define AFDO_NR_PARAM_SUM 2
+
+static const char *afdo_ref_names[] = {
+ "strobing",
+};
+
+/*
+ * sets of presets leaves strobing window constant while varying period to allow
+ * experimentation with mark / space ratios for various workloads
+ */
+static u64 afdo_set_a_presets[AFDO_NR_PRESETS][AFDO_NR_PARAM_SUM] = {
+ { 2000, 100 },
+ { 2000, 1000 },
+ { 2000, 5000 },
+ { 2000, 10000 },
+ { 4000, 100 },
+ { 4000, 1000 },
+ { 4000, 5000 },
+ { 4000, 10000 },
+ { 6000, 100 },
+ { 6000, 1000 },
+};
+
+
+static u64 afdo_set_b_presets[AFDO_NR_PRESETS][AFDO_NR_PARAM_SUM] = {
+ { 6000, 5000 },
+ { 6000, 10000 },
+ { 8000, 100 },
+ { 8000, 1000 },
+ { 8000, 5000 },
+ { 8000, 10000 },
+ { 12000, 100 },
+ { 12000, 1000 },
+ { 12000, 5000 },
+ { 12000, 10000 },
+};
+/* two configurations with differing preset tables */
+struct cscfg_config_desc afdo_seta = {
+ .name = "autofdo_set_a",
+ .description = "Setup ETMs with strobing for autofdo\n"
+ "Supplied presets allow experimentation with mark-space ratio for various loads\n",
+ .nr_feat_refs = ARRAY_SIZE(afdo_ref_names),
+ .feat_ref_names = afdo_ref_names,
+ .nr_presets = AFDO_NR_PRESETS,
+ .nr_total_params = AFDO_NR_PARAM_SUM,
+ .presets = &afdo_set_a_presets[0][0],
+};
+
+struct cscfg_config_desc afdo_setb = {
+ .name = "autofdo_set_b",
+ .description = "Setup ETMs with strobing for autofdo\n"
+ "Supplied presets allow experimentation with mark-space ratio for various loads\n",
+ .nr_feat_refs = ARRAY_SIZE(afdo_ref_names),
+ .feat_ref_names = afdo_ref_names,
+ .nr_presets = AFDO_NR_PRESETS,
+ .nr_total_params = AFDO_NR_PARAM_SUM,
+ .presets = &afdo_set_b_presets[0][0],
+};
+
+
+static struct cscfg_feature_desc *sample_feats[] = {
+ NULL
+};
+
+static struct cscfg_config_desc *sample_cfgs[] = {
+ &afdo_seta,
+ &afdo_setb,
+ NULL
+};
+
+struct cscfg_file_eg_info file_info_eg2 = {
+ .example_name = "example2",
+ .filename = "example2.cscfg",
+ .config_descs = sample_cfgs,
+ .feat_descs = sample_feats,
+};
diff --git a/tools/coresight/coresight-cfg-examples.h b/tools/coresight/coresight-cfg-examples.h
new file mode 100644
index 000000000000..c9719e7b2233
--- /dev/null
+++ b/tools/coresight/coresight-cfg-examples.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020-2022 Linaro Limited, All rights reserved.
+ * Author: Mike Leach <[email protected]>
+ */
+
+#ifndef _CORESIGHT_CFG_EXAMPLES_H
+#define _CORESIGHT_CFG_EXAMPLES_H
+
+#include <linux/kernel.h>
+
+#include "coresight-config-uapi.h"
+
+/*
+ * structure to pass C configuration structure information to
+ * configuration table file generator program
+ */
+struct cscfg_file_eg_info {
+ const char *example_name;
+ const char *filename;
+ struct cscfg_config_desc **config_descs;
+ struct cscfg_feature_desc **feat_descs;
+};
+
+#endif /* _CORESIGHT_CFG_EXAMPLES_H */
diff --git a/tools/coresight/coresight-cfg-file-gen.c b/tools/coresight/coresight-cfg-file-gen.c
new file mode 100644
index 000000000000..3ee3cdc02c4f
--- /dev/null
+++ b/tools/coresight/coresight-cfg-file-gen.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020-2022 Linaro Limited, All rights reserved.
+ * Author: Mike Leach <[email protected]>
+ */
+
+#include <linux/types.h>
+#include <linux/unistd.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "coresight-cfg-examples.h"
+#include "coresight-cfg-bufw.h"
+
+/* references to the configuration and feature example structures */
+extern struct cscfg_file_eg_info file_info_eg1;
+extern struct cscfg_file_eg_info file_info_eg2;
+
+/* array of example table files to generate */
+struct cscfg_file_eg_info *info_ptrs[] = {
+ &file_info_eg1,
+ &file_info_eg2,
+ NULL,
+};
+
+int main(int argc, char **argv)
+{
+ struct cscfg_config_desc **config_descs;
+ struct cscfg_feature_desc **feat_descs;
+ u8 buffer[CSCFG_TABLE_MAXSIZE];
+ int used, idx = 0;
+ FILE *fp;
+ const char *filename;
+
+ printf("Coresight Configuration table file Generator\n\n");
+
+ while (info_ptrs[idx]) {
+ printf("Generating %s example\n", info_ptrs[idx]->example_name);
+ config_descs = info_ptrs[idx]->config_descs;
+ feat_descs = info_ptrs[idx]->feat_descs;
+ filename = info_ptrs[idx]->filename;
+ used = cscfg_table_write_buffer(buffer, CSCFG_TABLE_MAXSIZE,
+ config_descs, feat_descs);
+
+ if (used < 0) {
+ printf("Error %d writing configuration %s into buffer\n",
+ used, info_ptrs[idx]->example_name);
+ return used;
+ }
+
+ fp = fopen(filename, "wb");
+ if (fp == NULL) {
+ printf("Error opening file %s\n", filename);
+ return -1;
+ }
+ fwrite(buffer, used, sizeof(u8), fp);
+ fclose(fp);
+ idx++;
+ }
+ return 0;
+}
diff --git a/tools/coresight/coresight-cfg-file-read.c b/tools/coresight/coresight-cfg-file-read.c
new file mode 100644
index 000000000000..89dcca5e776f
--- /dev/null
+++ b/tools/coresight/coresight-cfg-file-read.c
@@ -0,0 +1,227 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020-2022 Linaro Limited, All rights reserved.
+ * Author: Mike Leach <[email protected]>
+ */
+
+#include <linux/types.h>
+#include <linux/unistd.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "coresight-config-table.h"
+#include "coresight-config-uapi.h"
+
+/*
+ * tool to read and print a generated configuration
+ * re-uses the read code source from the driver.
+ */
+
+static void validate_config_name(const char *name)
+{
+ int i, len = strlen(name);
+
+ for (i = 0; i < len; i++) {
+ if (!isalnum(name[i]) && !(name[i] == '_')) {
+ printf("\n************************************************\n");
+ printf("ERROR: Configuration name %s invalid character(s)\n", name);
+ printf(" : must contain only alphanumeric and _ only\n");
+ printf("************************************************\n");
+ }
+ }
+}
+
+static void print_configs(struct cscfg_table_load_descs *load_descs)
+{
+ struct cscfg_config_desc *config_desc;
+ int i, j, p, cfg_idx = 0;
+
+ config_desc = load_descs->config_descs[cfg_idx];
+ if (!config_desc) {
+ printf("File contains no configurations.\n\n");
+ return;
+ }
+
+ while (config_desc) {
+ printf("Configuration %d\nName:- %s\n", cfg_idx + 1, config_desc->name);
+ validate_config_name(config_desc->name);
+ printf("Description:-\n%s\n", config_desc->description);
+ 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%lx, ", config_desc->presets[p]);
+ }
+ printf("\n");
+ }
+ }
+ printf("\n============================================\n");
+ cfg_idx++;
+ config_desc = load_descs->config_descs[cfg_idx];
+ }
+}
+
+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%lx\n", reg_desc->val64);
+ else if (type & CS_CFG_REG_TYPE_VAL_PARAM) {
+ printf("param(%d) ", reg_desc->param_idx);
+ if (type & (CS_CFG_REG_TYPE_VAL_MASK))
+ printf(" mask: 0x%x", reg_desc->mask32);
+ printf("\n");
+ } 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%lx\n", i,
+ params_desc[i].name, params_desc[i].value);
+}
+
+static void print_features(struct cscfg_table_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\nName:- %s\n\n", idx + 1, feat_desc->name);
+ printf("Description:- %s\n", feat_desc->description);
+ printf("Match flags: 0x%x\n", feat_desc->match_flags);
+ printf("\nNumber of Paraneters: %d\n", feat_desc->nr_params);
+ if (feat_desc->nr_params)
+ print_params(feat_desc->nr_params, feat_desc->params_desc);
+ printf("\nNumber 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_table_load_descs *load_descs;
+ int err, fsize;
+ u8 buffer[CSCFG_TABLE_MAXSIZE];
+
+ printf("CoreSight Configuration table file reader");
+ printf("\n============================================\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_TABLE_MAXSIZE) {
+ printf("Error: Input file too large.");
+ fclose(fp);
+ return -EINVAL;
+ }
+ err = fread(buffer, sizeof(u8), fsize, fp);
+ fclose(fp);
+
+ if (err < fsize) {
+ printf("Error reading file %s\n", argv[1]);
+ return -EINVAL;
+ }
+
+ /* allocate the descriptor structures to be populated by read operation */
+ load_descs = malloc(sizeof(struct cscfg_table_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_table_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:
+ cscfg_table_free_load_descs(load_descs);
+ free(load_descs);
+ return err;
+}
diff --git a/tools/coresight/coresight-config-uapi.h b/tools/coresight/coresight-config-uapi.h
new file mode 100644
index 000000000000..f3698a5b10ef
--- /dev/null
+++ b/tools/coresight/coresight-config-uapi.h
@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 Linaro Limited, All rights reserved.
+ * Author: Mike Leach <[email protected]>
+ */
+
+#ifndef _CORESIGHT_CORESIGHT_CONFIG_UAPI_H
+#define _CORESIGHT_CORESIGHT_CONFIG_UAPI_H
+
+#include <linux/types.h>
+#include <asm-generic/errno-base.h>
+
+#include <stddef.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "coresight-config-desc.h"
+
+/*
+ * Userspace versions of the configuration and feature descriptors.
+ * Used in the tools/coresight programs.
+ *
+ * Compatible with structures in coresight-config.h for use in
+ * coresight-config-file.c common reader source file.
+ */
+
+/**
+ * Device feature descriptor - combination of registers and parameters to
+ * program a device to implement a specific complex function.
+ *
+ * UAPI version - removed kernel constructs.
+ *
+ * @name: feature name.
+ * @description: brief description of the feature.
+ * @match_flags: matching information if loading into a device
+ * @nr_params: number of parameters used.
+ * @params_desc: array of parameters used.
+ * @nr_regs: number of registers used.
+ * @regs_desc: array of registers used.
+ */
+struct cscfg_feature_desc {
+ const char *name;
+ const char *description;
+ u32 match_flags;
+ int nr_params;
+ struct cscfg_parameter_desc *params_desc;
+ int nr_regs;
+ struct cscfg_regval_desc *regs_desc;
+};
+
+/**
+ * Configuration descriptor - describes selectable system configuration.
+ *
+ * A configuration describes device features in use, and may provide preset
+ * values for the parameters in those features.
+ *
+ * A single set of presets is the sum of the parameters declared by
+ * all the features in use - this value is @nr_total_params.
+ *
+ * UAPI version - removed kernel constructs.
+ *
+ * @name: name of the configuration - used for selection.
+ * @description: description of the purpose of the configuration.
+ * @nr_feat_refs: Number of features used in this configuration.
+ * @feat_ref_names: references to features used in this configuration.
+ * @nr_presets: Number of sets of presets supplied by this configuration.
+ * @nr_total_params: Sum of all parameters declared by used features
+ * @presets: Array of preset values.
+ */
+struct cscfg_config_desc {
+ const char *name;
+ const char *description;
+ int nr_feat_refs;
+ const char **feat_ref_names;
+ int nr_presets;
+ int nr_total_params;
+ const u64 *presets; /* nr_presets * nr_total_params */
+};
+
+/* UAPI allocators for descriptors in common config file buffer read code */
+static inline void *cscfg_calloc(size_t num, size_t size)
+{
+ return calloc(num, size);
+}
+
+static inline char *cscfg_strdup(const char *str)
+{
+ return strdup(str);
+}
+
+static inline void *cscfg_zalloc(size_t size)
+{
+ void *ptr = malloc(size);
+
+ if (ptr)
+ memset(ptr, 0, size);
+ return ptr;
+}
+
+static inline void cscfg_free(void *mem)
+{
+ free(mem);
+}
+
+#endif /* _CORESIGHT_CORESIGHT_CONFIG_UAPI_H */
--
2.17.1


2023-05-24 04:59:23

by Linu Cherian

[permalink] [raw]
Subject: RE: [EXT] [PATCH v6 0/6] coresight: syscfg: Add config table load via configfs

Hi Mike,

> -----Original Message-----
> From: Mike Leach <[email protected]>
> Sent: Thursday, May 11, 2023 12:23 PM
> To: [email protected]; [email protected]; linux-
> [email protected]
> Cc: [email protected]; Mike Leach <[email protected]>
> Subject: [EXT] [PATCH v6 0/6] coresight: syscfg: Add config table load via
> configfs
>
> External Email
>
> ----------------------------------------------------------------------
> This set extends the configuration management support to allow loading and
> unloading of configurations as structured tables.
>
> The existing coresight configuration configfs API is additionally extended to
> use this table functionality to load and unload configuration tables as binary
> files.
>
> This allows coresight configurations to be loaded at runtime, and
> independently of kernel version, without the requirement to re-compile as
> built in kernel modules.
>
> Additional attributes - load and unload are provided to in the /config/cs-
> syscfg subsytem base group to implement the load functionality.
>
> The load attribute is a configfs binary attribute, loading the configuration
> table in a similar way as the ACPI table binary attribute for that sub-system.
>
> The configfs binary attribute mechanism supplies a strictly size limited kernel
> buffer, providing better safety than other mechnisms, and also has the
> advantage of being accessible directly from the command line, and being part
> of the existing upstream coresight configuration mechanism in configfs
>
> Configurations loaded in this way are validated and loaded across the entire
> system of components atomically. If any part fails to load then the whole
> configuration load will be cancelled.

Currently configuration load is restricted to ETMs alone, CMIIW. Do you have plans to
extend the generic configuration load support to CTI component as well ?

>
> Routines to generate binary configuration table files are supplied in
> ./tools/coresight.
>
> Example generator and reader applications are provided.
>
> Tools may be cross compiled or built for use on host system.
>
> Documentation is updated to describe feature usage.
>
> Changes since v5:
> 1) Possible memory leak removed.
> Reported-by: kernel test robot <[email protected]>
> Reported-by: Dan Carpenter <[email protected]>
> 2) Reuse mechanism for reader code revised. (Christoph)
> 3) Unload mechnism now by name in standard attribute, rather than entire
> file
> 4) Mechanism to check last loaded configuration can be unloaded.
> 5) Documentation updates.
>
> Changes since v4:
> 1) Update coresight/next - 6.1-rc3
> 2) Update to lockdep fixes to avoid read lock race in configfs.
>
> Changes since v3:
> 1) Rebase & tested on coresight/next - 5.19-rc3 - which includes the fix patch
> for earlier configfs works.
> 2) Lockdep investigations resulted in re-design of some of the code accessing
> configfs.
> 3) moved load and unload attributes to root of cs-syscfg. (Mathieu)
> 4) Additional minor fixes suggested by Mathieu.
> 5) Memory for configfs loaded and unloaded configurations is now explicitly
> freed.
> 6) LOCKDEP nesting fix for configfs base code (fs/configfs/dir.c)
>
> Changes since v2:
> 1) Rebased & tested on coresight/next - 5.18-rc2
> 2) Moved coresight config generator and reader programs from samples to
> tools/coresight. Docs updated to match. (suggested by Mathieu)
> 3) userspace builds now use userspace headers from tools/...
> 4) Other minor fixes from Mathieu's review.
>
> Changes since v1:
> 1) Rebased to coresight/next - 5.16-rc1 with previous coresight config set
> applied.
> 2) Makefile.host fixed to default to all target.
>
> Mike Leach (6):
> coresight: config: add config table runtime load functionality
> coresight: configfs: Update memory allocation / free for configfs
> elements
> coresight: configfs: Add attributes to load config tables at runtime
> coresight: config: extract shared structures to common header file
> coresight: tools: Add config table file write and reader tools
> Documentation: coresight: docs for config load via configfs
>
> .../trace/coresight/coresight-config.rst | 265 ++++++++-
> MAINTAINERS | 1 +
> drivers/hwtracing/coresight/Makefile | 3 +-
> .../coresight/coresight-config-desc.h | 105 ++++
> .../coresight/coresight-config-table.c | 431 +++++++++++++++
> .../coresight/coresight-config-table.h | 151 ++++++
> .../hwtracing/coresight/coresight-config.h | 98 +---
> .../coresight/coresight-syscfg-configfs.c | 513 ++++++++++++++++--
> .../coresight/coresight-syscfg-configfs.h | 5 +
> .../hwtracing/coresight/coresight-syscfg.c | 101 +++-
> .../hwtracing/coresight/coresight-syscfg.h | 6 +-
> tools/coresight/Makefile | 56 ++
> tools/coresight/coresight-cfg-bufw.c | 309 +++++++++++
> tools/coresight/coresight-cfg-bufw.h | 26 +
> tools/coresight/coresight-cfg-example1.c | 62 +++
> tools/coresight/coresight-cfg-example2.c | 95 ++++
> tools/coresight/coresight-cfg-examples.h | 25 +
> tools/coresight/coresight-cfg-file-gen.c | 61 +++
> tools/coresight/coresight-cfg-file-read.c | 227 ++++++++
> tools/coresight/coresight-config-uapi.h | 105 ++++
> 20 files changed, 2503 insertions(+), 142 deletions(-) create mode 100644
> drivers/hwtracing/coresight/coresight-config-desc.h
> create mode 100644 drivers/hwtracing/coresight/coresight-config-table.c
> create mode 100644 drivers/hwtracing/coresight/coresight-config-table.h
> create mode 100644 tools/coresight/Makefile create mode 100644
> tools/coresight/coresight-cfg-bufw.c
> create mode 100644 tools/coresight/coresight-cfg-bufw.h
> create mode 100644 tools/coresight/coresight-cfg-example1.c
> create mode 100644 tools/coresight/coresight-cfg-example2.c
> create mode 100644 tools/coresight/coresight-cfg-examples.h
> create mode 100644 tools/coresight/coresight-cfg-file-gen.c
> create mode 100644 tools/coresight/coresight-cfg-file-read.c
> create mode 100644 tools/coresight/coresight-config-uapi.h
>
> --
> 2.17.1
>
> _______________________________________________
> CoreSight mailing list -- [email protected] To unsubscribe send an
> email to [email protected]

2023-05-24 08:22:41

by Mike Leach

[permalink] [raw]
Subject: Re: [EXT] [PATCH v6 0/6] coresight: syscfg: Add config table load via configfs

Hi Linu



On Wed, 24 May 2023 at 05:48, Linu Cherian <[email protected]> wrote:
>
> Hi Mike,
>
> > -----Original Message-----
> > From: Mike Leach <[email protected]>
> > Sent: Thursday, May 11, 2023 12:23 PM
> > To: [email protected]; [email protected]; linux-
> > [email protected]
> > Cc: [email protected]; Mike Leach <[email protected]>
> > Subject: [EXT] [PATCH v6 0/6] coresight: syscfg: Add config table load via
> > configfs
> >
> > External Email
> >
> > ----------------------------------------------------------------------
> > This set extends the configuration management support to allow loading and
> > unloading of configurations as structured tables.
> >
> > The existing coresight configuration configfs API is additionally extended to
> > use this table functionality to load and unload configuration tables as binary
> > files.
> >
> > This allows coresight configurations to be loaded at runtime, and
> > independently of kernel version, without the requirement to re-compile as
> > built in kernel modules.
> >
> > Additional attributes - load and unload are provided to in the /config/cs-
> > syscfg subsytem base group to implement the load functionality.
> >
> > The load attribute is a configfs binary attribute, loading the configuration
> > table in a similar way as the ACPI table binary attribute for that sub-system.
> >
> > The configfs binary attribute mechanism supplies a strictly size limited kernel
> > buffer, providing better safety than other mechnisms, and also has the
> > advantage of being accessible directly from the command line, and being part
> > of the existing upstream coresight configuration mechanism in configfs
> >
> > Configurations loaded in this way are validated and loaded across the entire
> > system of components atomically. If any part fails to load then the whole
> > configuration load will be cancelled.
>
> Currently configuration load is restricted to ETMs alone, CMIIW. Do you have plans to
> extend the generic configuration load support to CTI component as well ?
>

Yes CTI support is in a follow up set.

This set enables the load mechanisms - there are two follow up sets -
the first that extends ETM support, and a second that allows
programming of CTIs and other components as well.

Regards

Mike

> >
> > Routines to generate binary configuration table files are supplied in
> > ./tools/coresight.
> >
> > Example generator and reader applications are provided.
> >
> > Tools may be cross compiled or built for use on host system.
> >
> > Documentation is updated to describe feature usage.
> >
> > Changes since v5:
> > 1) Possible memory leak removed.
> > Reported-by: kernel test robot <[email protected]>
> > Reported-by: Dan Carpenter <[email protected]>
> > 2) Reuse mechanism for reader code revised. (Christoph)
> > 3) Unload mechnism now by name in standard attribute, rather than entire
> > file
> > 4) Mechanism to check last loaded configuration can be unloaded.
> > 5) Documentation updates.
> >
> > Changes since v4:
> > 1) Update coresight/next - 6.1-rc3
> > 2) Update to lockdep fixes to avoid read lock race in configfs.
> >
> > Changes since v3:
> > 1) Rebase & tested on coresight/next - 5.19-rc3 - which includes the fix patch
> > for earlier configfs works.
> > 2) Lockdep investigations resulted in re-design of some of the code accessing
> > configfs.
> > 3) moved load and unload attributes to root of cs-syscfg. (Mathieu)
> > 4) Additional minor fixes suggested by Mathieu.
> > 5) Memory for configfs loaded and unloaded configurations is now explicitly
> > freed.
> > 6) LOCKDEP nesting fix for configfs base code (fs/configfs/dir.c)
> >
> > Changes since v2:
> > 1) Rebased & tested on coresight/next - 5.18-rc2
> > 2) Moved coresight config generator and reader programs from samples to
> > tools/coresight. Docs updated to match. (suggested by Mathieu)
> > 3) userspace builds now use userspace headers from tools/...
> > 4) Other minor fixes from Mathieu's review.
> >
> > Changes since v1:
> > 1) Rebased to coresight/next - 5.16-rc1 with previous coresight config set
> > applied.
> > 2) Makefile.host fixed to default to all target.
> >
> > Mike Leach (6):
> > coresight: config: add config table runtime load functionality
> > coresight: configfs: Update memory allocation / free for configfs
> > elements
> > coresight: configfs: Add attributes to load config tables at runtime
> > coresight: config: extract shared structures to common header file
> > coresight: tools: Add config table file write and reader tools
> > Documentation: coresight: docs for config load via configfs
> >
> > .../trace/coresight/coresight-config.rst | 265 ++++++++-
> > MAINTAINERS | 1 +
> > drivers/hwtracing/coresight/Makefile | 3 +-
> > .../coresight/coresight-config-desc.h | 105 ++++
> > .../coresight/coresight-config-table.c | 431 +++++++++++++++
> > .../coresight/coresight-config-table.h | 151 ++++++
> > .../hwtracing/coresight/coresight-config.h | 98 +---
> > .../coresight/coresight-syscfg-configfs.c | 513 ++++++++++++++++--
> > .../coresight/coresight-syscfg-configfs.h | 5 +
> > .../hwtracing/coresight/coresight-syscfg.c | 101 +++-
> > .../hwtracing/coresight/coresight-syscfg.h | 6 +-
> > tools/coresight/Makefile | 56 ++
> > tools/coresight/coresight-cfg-bufw.c | 309 +++++++++++
> > tools/coresight/coresight-cfg-bufw.h | 26 +
> > tools/coresight/coresight-cfg-example1.c | 62 +++
> > tools/coresight/coresight-cfg-example2.c | 95 ++++
> > tools/coresight/coresight-cfg-examples.h | 25 +
> > tools/coresight/coresight-cfg-file-gen.c | 61 +++
> > tools/coresight/coresight-cfg-file-read.c | 227 ++++++++
> > tools/coresight/coresight-config-uapi.h | 105 ++++
> > 20 files changed, 2503 insertions(+), 142 deletions(-) create mode 100644
> > drivers/hwtracing/coresight/coresight-config-desc.h
> > create mode 100644 drivers/hwtracing/coresight/coresight-config-table.c
> > create mode 100644 drivers/hwtracing/coresight/coresight-config-table.h
> > create mode 100644 tools/coresight/Makefile create mode 100644
> > tools/coresight/coresight-cfg-bufw.c
> > create mode 100644 tools/coresight/coresight-cfg-bufw.h
> > create mode 100644 tools/coresight/coresight-cfg-example1.c
> > create mode 100644 tools/coresight/coresight-cfg-example2.c
> > create mode 100644 tools/coresight/coresight-cfg-examples.h
> > create mode 100644 tools/coresight/coresight-cfg-file-gen.c
> > create mode 100644 tools/coresight/coresight-cfg-file-read.c
> > create mode 100644 tools/coresight/coresight-config-uapi.h
> >
> > --
> > 2.17.1
> >
> > _______________________________________________
> > CoreSight mailing list -- [email protected] To unsubscribe send an
> > email to [email protected]



--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK