This patchset introduces initial concepts in CoreSight complex configuration support - the device "feature", which is a method of programming the device to perform a specific function.
A built-in feature is provided - the ETM strobing function, which programs the ETM to switch trace on and off in a specific mark / space ratio to effectively sample the program being traced. This feature is essential for the Auto-FDO flow using CoreSight trace.
Features are declared as a data table, a set of register, resource and parameter requirements. A feature can then be loaded into a device, when the requirements are validated. Once loaded a feature can be enabled for a specific trace run.
A feature appears in the sysfs file for the device, as a directory of form 'name.feat', with parameters 'enable', 'description' and any input parameters that may be used to control the operation.
For example the ETM strobing feature provided has parameters of 'window' and 'period' to control the sampling mark / space ratio. The representation in sysfs for the ETMv4 is therefore:- etmX/strobing.feat/ /enable /window /period
Future developments will introduce resource management, and allow for the runtime loading of additional features, and the setting of features across an entire CoreSight system.
Mike Leach (3): coresight: etmv4: Fix resource selector constant. coresight: etmv4: Counter values not saved on disable. coresight: etmv4: Adds initial complex config with ETM4 strobe feature.
drivers/hwtracing/coresight/Makefile | 7 +- .../hwtracing/coresight/coresight-config.c | 380 ++++++++++++++++++ .../hwtracing/coresight/coresight-config.h | 156 +++++++ .../hwtracing/coresight/coresight-etm4x-cfg.c | 325 +++++++++++++++ .../hwtracing/coresight/coresight-etm4x-cfg.h | 29 ++ .../coresight/coresight-etm4x-sysfs.c | 3 + drivers/hwtracing/coresight/coresight-etm4x.c | 24 +- drivers/hwtracing/coresight/coresight-etm4x.h | 4 +- drivers/hwtracing/coresight/coresight.c | 1 + include/linux/coresight.h | 2 + 10 files changed, 925 insertions(+), 6 deletions(-) create mode 100644 drivers/hwtracing/coresight/coresight-config.c create mode 100644 drivers/hwtracing/coresight/coresight-config.h create mode 100644 drivers/hwtracing/coresight/coresight-etm4x-cfg.c create mode 100644 drivers/hwtracing/coresight/coresight-etm4x-cfg.h
ETMv4 max resource selector constant incorrectly set to 16. Updated to the correct 32 value, and adjustments made to limited code using it.
Signed-off-by: Mike Leach mike.leach@linaro.org --- drivers/hwtracing/coresight/coresight-etm4x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h index 4a695bf90582..b0d633daf716 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.h +++ b/drivers/hwtracing/coresight/coresight-etm4x.h @@ -133,7 +133,7 @@ #define ETMv4_MAX_CTXID_CMP 8 #define ETM_MAX_VMID_CMP 8 #define ETM_MAX_PE_CMP 8 -#define ETM_MAX_RES_SEL 16 +#define ETM_MAX_RES_SEL 32 #define ETM_MAX_SS_CMP 8
#define ETM_ARCH_V4 0x40 @@ -325,7 +325,7 @@ struct etmv4_save_state { u32 trccntctlr[ETMv4_MAX_CNTR]; u32 trccntvr[ETMv4_MAX_CNTR];
- u32 trcrsctlr[ETM_MAX_RES_SEL * 2]; + u32 trcrsctlr[ETM_MAX_RES_SEL];
u32 trcssccr[ETM_MAX_SS_CMP]; u32 trcsscsr[ETM_MAX_SS_CMP];
The counter value registers change during operation, however this change is not reflected in the values seen by the user in sysfs.
This fixes the issue by reading back the values on disable.
Signed-off-by: Mike Leach mike.leach@linaro.org --- drivers/hwtracing/coresight/coresight-etm4x.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 747afc875f91..60a5133d801c 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -507,6 +507,12 @@ static void etm4_disable_hw(void *info) readl_relaxed(drvdata->base + TRCSSCSRn(i)); }
+ /* read back the current counter values */ + for (i = 0; i < drvdata->nr_cntr; i++) { + config->cntr_val[i] = + readl_relaxed(drvdata->base + TRCCNTVRn(i)); + } + coresight_disclaim_device_unlocked(drvdata->base);
CS_LOCK(drvdata->base);
This set introduces the concept of complex features for CoreSight devices, and adds a feature to ETMv4 to enable strobing of the etm capture.
1) Complex Features: These are programming settings for devices, especially ETM which have many programmable register that can be combined to create complex functionality. Features appear as sub-directories in sysfs, having an enable parameter to set the full program setting.
2) ETM strobing. This feature is introduced to ETMv4 to allow the trace capture to be periodically switched on and off - strobed - to a given mark / space ratio to generate statistical trace data for workflows such as auto-fdo.
Signed-off-by: Mike Leach mike.leach@linaro.org --- drivers/hwtracing/coresight/Makefile | 7 +- .../hwtracing/coresight/coresight-config.c | 380 ++++++++++++++++++ .../hwtracing/coresight/coresight-config.h | 156 +++++++ .../hwtracing/coresight/coresight-etm4x-cfg.c | 325 +++++++++++++++ .../hwtracing/coresight/coresight-etm4x-cfg.h | 29 ++ .../coresight/coresight-etm4x-sysfs.c | 3 + drivers/hwtracing/coresight/coresight-etm4x.c | 18 +- drivers/hwtracing/coresight/coresight.c | 1 + include/linux/coresight.h | 2 + 9 files changed, 917 insertions(+), 4 deletions(-) create mode 100644 drivers/hwtracing/coresight/coresight-config.c create mode 100644 drivers/hwtracing/coresight/coresight-config.h create mode 100644 drivers/hwtracing/coresight/coresight-etm4x-cfg.c create mode 100644 drivers/hwtracing/coresight/coresight-etm4x-cfg.h
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile index 19497d1d92bf..b6c28f4cfca7 100644 --- a/drivers/hwtracing/coresight/Makefile +++ b/drivers/hwtracing/coresight/Makefile @@ -3,7 +3,8 @@ # Makefile for CoreSight drivers. # obj-$(CONFIG_CORESIGHT) += coresight.o coresight-etm-perf.o \ - coresight-platform.o coresight-sysfs.o + coresight-platform.o coresight-sysfs.o \ + coresight-config.o obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o \ coresight-tmc-etf.o \ coresight-tmc-etr.o @@ -14,7 +15,9 @@ obj-$(CONFIG_CORESIGHT_LINKS_AND_SINKS) += coresight-funnel.o \ obj-$(CONFIG_CORESIGHT_SOURCE_ETM3X) += coresight-etm3x.o coresight-etm-cp14.o \ coresight-etm3x-sysfs.o obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o \ - coresight-etm4x-sysfs.o + coresight-etm4x-sysfs.o \ + coresight-etm4x-cfg.o + obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o obj-$(CONFIG_CORESIGHT_CATU) += coresight-catu.o diff --git a/drivers/hwtracing/coresight/coresight-config.c b/drivers/hwtracing/coresight/coresight-config.c new file mode 100644 index 000000000000..10c2d546ca82 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-config.c @@ -0,0 +1,380 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright(C) 2020 Linaro Limited. All rights reserved. + * Author: Mike Leach mike.leach@linaro.org + */ + +#include <linux/sysfs.h> +#include "coresight-config.h" +#include "coresight-priv.h" + +static DEFINE_MUTEX(coresight_cfg_mutex); + +/* + * Handlers for creating and manipulating the feature representation + * in sysfs. + */ + +/* base feature attribute info */ +struct feat_attr_info { + const char *name; + ssize_t (*show)(struct device *dev, struct device_attribute *attr, + char *buf); + ssize_t (*store)(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count); +}; + +static ssize_t cs_cfg_enable_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct dev_ext_attribute *eattr = + container_of(attr, struct dev_ext_attribute, attr); + struct cs_cfg_feature *feat = (struct cs_cfg_feature *)eattr->var; + int val; + + spin_lock(feat->dev_spinlock); + val = feat->enabled; + spin_unlock(feat->dev_spinlock); + + return scnprintf(buf, PAGE_SIZE, "%d\n", val); +} + +static ssize_t cs_cfg_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct dev_ext_attribute *eattr = + container_of(attr, struct dev_ext_attribute, attr); + struct cs_cfg_feature *feat = (struct cs_cfg_feature *)eattr->var; + + int val; + + spin_lock(feat->dev_spinlock); + if (!kstrtoint(buf, 0, &val)) + feat->enabled = val; + spin_unlock(feat->dev_spinlock); + + return size; +} + +static ssize_t cs_cfg_desc_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct dev_ext_attribute *eattr = + container_of(attr, struct dev_ext_attribute, attr); + struct cs_cfg_feature *feat = (struct cs_cfg_feature *)eattr->var; + + return scnprintf(buf, PAGE_SIZE, "%s\n", feat->desc->brief); +} + +struct feat_attr_info feature_std_attr[] = { + { + .name = "enable", + .show = cs_cfg_enable_show, + .store = cs_cfg_enable_store, + }, + { + .name = "description", + .show = cs_cfg_desc_show, + }, + { 0 }, +}; + +static ssize_t cs_cfg_param_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct dev_ext_attribute *eattr = + container_of(attr, struct dev_ext_attribute, attr); + struct cs_cfg_parameter *param = (struct cs_cfg_parameter *)eattr->var; + u64 val; + + spin_lock(param->feat->dev_spinlock); + val = param->current_value; + spin_unlock(param->feat->dev_spinlock); + + return scnprintf(buf, PAGE_SIZE, "%lld\n", val); +} + +static ssize_t cs_cfg_param_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct dev_ext_attribute *eattr = + container_of(attr, struct dev_ext_attribute, attr); + struct cs_cfg_parameter *param = (struct cs_cfg_parameter *)eattr->var; + u64 val; + + spin_lock(param->feat->dev_spinlock); + if (!kstrtoull(buf, 0, &val)) + param->current_value = val; + spin_unlock(param->feat->dev_spinlock); + + return size; +} + +static struct attribute * +cs_cfg_sysfs_create_feat_attr(struct device *dev, struct cs_cfg_feature *feat, + struct feat_attr_info *info) +{ + struct dev_ext_attribute *eattr; + + eattr = devm_kzalloc(dev, sizeof(struct dev_ext_attribute), + GFP_KERNEL); + if (!eattr) + return NULL; + eattr->attr.attr.name = devm_kstrdup(dev, info->name, GFP_KERNEL); + eattr->attr.attr.mode = info->store ? 0644 : 0444; + eattr->attr.show = info->show; + eattr->attr.store = info->store; + eattr->var = feat; + return &eattr->attr.attr; +} + +static struct attribute * +cs_cfg_sysfs_create_param_attr(struct device *dev, const char *name, + struct cs_cfg_parameter *param) +{ + struct dev_ext_attribute *eattr; + + eattr = devm_kzalloc(dev, sizeof(struct dev_ext_attribute), + GFP_KERNEL); + if (!eattr) + return NULL; + + eattr->attr.attr.name = devm_kstrdup(dev, name, GFP_KERNEL); + eattr->attr.attr.mode = 0644; + eattr->attr.show = cs_cfg_param_show; + eattr->attr.store = cs_cfg_param_store; + eattr->var = param; + return &eattr->attr.attr; +} + +int coresight_cfg_sysfs_add_grp(struct cs_cfg_feature *feat) +{ + int p, attr_idx = 0; + struct attribute **attrs; + const char *name; + struct feat_attr_info *info; + struct device *dev = feat->csdev->dev.parent; + + /* create sysfs group in csdev */ + feat->param_group = devm_kzalloc(dev, sizeof(struct attribute_group), + GFP_KERNEL); + if (!feat->param_group) + return -ENOMEM; + + feat->param_group->name = devm_kasprintf(dev, GFP_KERNEL, "%s.feat", + feat->desc->name); + if (!feat->param_group->name) + return -ENOMEM; + + /* attributes - nr_params + enable + desc */ + attrs = devm_kcalloc(dev, feat->nr_params + 2, + sizeof(struct attribute *), GFP_KERNEL); + if (!attrs) + return -ENOMEM; + + /* create base attributes in group */ + while (feature_std_attr[attr_idx].name) { + info = &feature_std_attr[attr_idx]; + attrs[attr_idx] = cs_cfg_sysfs_create_feat_attr(dev, feat, + info); + if (!attrs[attr_idx]) + return -ENOMEM; + attr_idx++; + } + + /* create params in group */ + for (p = 0; p < feat->nr_params; p++) { + name = feat->desc->params[p].name; + attrs[attr_idx] = + cs_cfg_sysfs_create_param_attr(dev, name, + &feat->params[p]); + if (!attrs[attr_idx]) + return -ENOMEM; + attr_idx++; + } + feat->param_group->attrs = attrs; + + return sysfs_create_group(&feat->csdev->dev.kobj, feat->param_group); +} + +/* + * standard routines to set/save/reset enabled features, and iterate + * groups of features on a device. + */ + +void coresight_cfg_list_add_feat(struct cs_cfg_feature *feat) +{ + mutex_lock(&coresight_cfg_mutex); + list_add(&feat->node, &feat->csdev->feat_list); + mutex_unlock(&coresight_cfg_mutex); +} + +inline void coresight_cfg_set_reg(struct cs_cfg_reg *reg, u32 flags) +{ + u32 *p_val32 = (u32 *)reg->drv_store; + u32 tmp32; + + if (!(flags & CS_CFG_REG_VAL_64BIT)) { + if (flags & CS_CFG_REG_VAL_MASK) { + tmp32 = *p_val32; + tmp32 &= ~reg->value.mask32; + tmp32 |= reg->value.val32 & reg->value.mask32; + *p_val32 = tmp32; + } else + *p_val32 = reg->value.val32; + } else + *((u64 *)reg->drv_store) = reg->value.val64; +} + +inline void coresight_cfg_save_reg(struct cs_cfg_reg *reg, u32 flags) +{ + if (flags & CS_CFG_REG_VAL_64BIT) + reg->value.val64 = *(u64 *)(reg->drv_store); + else + reg->value.val32 = *(u32 *)(reg->drv_store); +} + +inline void coresight_cfg_init_reg(struct cs_cfg_reg *reg, + const struct cs_cfg_reg_desc *desc) +{ + reg->value.val64 = desc->value.val64; +} + +inline void coresight_cfg_init_reg_param(struct cs_cfg_reg *reg, u32 flags, + struct cs_cfg_parameter *param) +{ + if (flags & CS_CFG_REG_VAL_64BIT) + reg->value.val64 = param->current_value; + else + reg->value.val32 = (u32)param->current_value; +} + +/* default set - will set values without resource checking */ +static int cs_cfg_set_on_enable(struct cs_cfg_feature *feat) +{ + int i; + u32 flags; + + spin_lock(feat->dev_spinlock); + if (feat->enabled) { + for (i = 0; i < feat->nr_regs; i++) { + flags = feat->desc->regs[i].flags; + coresight_cfg_set_reg(&feat->regs[i], flags); + } + } + dev_dbg(&feat->csdev->dev, "Feature %s: %s", feat->desc->name, + feat->enabled ? "Set enabled" : "Skip disabled"); + spin_unlock(feat->dev_spinlock); + return 0; +} + +static void cs_cfg_save_on_disable(struct cs_cfg_feature *feat) +{ + int i; + u32 flags; + + spin_lock(feat->dev_spinlock); + if (feat->enabled) { + for (i = 0; i < feat->nr_regs; i++) { + flags = feat->desc->regs[i].flags; + if (flags & CS_CFG_REG_VAL_SAVE) + coresight_cfg_save_reg(&feat->regs[i], flags); + } + } + spin_unlock(feat->dev_spinlock); +} + +/* default reset - restore default values, disable feature */ +static void cs_cfg_reset_feat(struct cs_cfg_feature *feat) +{ + const struct cs_cfg_feature_desc *feat_desc = feat->desc; + struct cs_cfg_reg_desc *reg_desc; + struct cs_cfg_parameter *param; + struct cs_cfg_reg *reg; + int i; + u32 flags; + + spin_lock(feat->dev_spinlock); + feat->enabled = false; + + /* + * set the default values for all parameters and regs from the + * relevant static descriptors. + */ + for (i = 0; i < feat->nr_params; i++) + feat->params[i].current_value = feat_desc->params[i].value; + + for (i = 0; i < feat->nr_regs; i++) { + reg_desc = &feat_desc->regs[i]; + flags = reg_desc->flags; + reg = &feat->regs[i]; + + /* check if reg set from a parameter otherwise desc default */ + if (flags & CS_CFG_REG_VAL_PARAM) { + param = &feat->params[reg_desc->value.val32]; + coresight_cfg_init_reg_param(reg, flags, param); + } else + coresight_cfg_init_reg(reg, reg_desc); + } + spin_unlock(feat->dev_spinlock); +} + +void coresight_cfg_set_def_ops(struct cs_cfg_feature *feat) +{ + feat->ops.set_on_enable = cs_cfg_set_on_enable; + feat->ops.save_on_disable = cs_cfg_save_on_disable; + feat->ops.reset = cs_cfg_reset_feat; +} + +int coresight_cfg_set_feats_on_ena(struct coresight_device *csdev) +{ + struct cs_cfg_feature *feat; + int err = 0; + + if (list_empty(&csdev->feat_list)) + return 0; + + list_for_each_entry(feat, &csdev->feat_list, node) { + dev_dbg(&csdev->dev, "Found feature:%s", feat->desc->name); + + if (feat->ops.set_on_enable) { + err = feat->ops.set_on_enable(feat); + dev_dbg(&csdev->dev, "Feature %s: %s", + feat->desc->name, err ? "Set failed" : "OK"); + if (!err) + break; + } + } + return err; +} + +void coresight_cfg_save_feats_on_dis(struct coresight_device *csdev) +{ + struct cs_cfg_feature *feat; + + if (list_empty(&csdev->feat_list)) + return; + + list_for_each_entry(feat, &csdev->feat_list, node) { + if (feat->ops.save_on_disable) + feat->ops.save_on_disable(feat); + } +} + +void coresight_cfg_reset_feats(struct coresight_device *csdev) +{ + struct cs_cfg_feature *feat; + + if (list_empty(&csdev->feat_list)) + return; + + list_for_each_entry(feat, &csdev->feat_list, node) { + if (feat->ops.reset) + feat->ops.reset(feat); + } +} diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h new file mode 100644 index 000000000000..ce69ad5d2bbf --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -0,0 +1,156 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 Linaro Limited, All rights reserved. + * Author: Mike Leach mike.leach@linaro.org + */ + +#ifndef _CORESIGHT_CORESIGHT_CONFIG_H +#define _CORESIGHT_CORESIGHT_CONFIG_H + +/* CoreSight Configuration - complex component and system config handling */ + +/* generic register flags */ +#define CS_CFG_REG_STD 0x80000000 /* reg is standard reg */ +#define CS_CFG_REG_RESOURCE 0x40000000 /* reg is a resource */ +#define CS_CFG_REG_VAL_PARAM 0x08000000 /* reg value uses param */ +#define CS_CFG_REG_VAL_MASK 0x04000000 /* reg value bit masked */ +#define CS_CFG_REG_VAL_64BIT 0x02000000 /* reg value 64 bit */ +#define CS_CFG_REG_VAL_SAVE 0x01000000 /* reg value save on disable */ +#define CS_CFG_REG_ID_MASK 0x00000FFF /* reg offset / id in device */ +#define CS_CFG_REG_DEV_MASK 0x00FFF000 /* device specific flags */ + +/** + * Parameter descriptor for a device feature. + * + * @name: Name of parameter. + * @value: Initial or default value. + */ +struct cs_cfg_parameter_desc { + const char *name; + const u64 value; +}; + +/** + * Representation of register value. + * Supports full 64 bit register value, or 32 bit value with optional mask + * value. + */ +union cs_cfg_regval { + u64 val64; + struct { + u32 val32; + u32 mask32; + }; +}; + +/** + * Register descriptor for a device feature + * + * @flags: flags defining the handling of the register. + * @value: Initial value & optional mask. + */ +struct cs_cfg_reg_desc { + const u32 flags; + const union cs_cfg_regval value; +}; + +/** + * Device feature descriptor - combination of registers and parameters to + * program a device to implement a specific complex function. + * + * @name: feature name. + * @brief: brief description of the feature. + * @params: list of parameters used - 0 terminated. + * @reg: list of registers used. + */ +struct cs_cfg_feature_desc { + const char *name; + const char *brief; + struct cs_cfg_parameter_desc *params; + struct cs_cfg_reg_desc *regs; +}; + +/** + * config parameter instance - part of a loaded feature. + * + * @feat: parent feature + * @current_value: current value of parameter - may be set by user via + * sysfs, or modified during device operation. + */ +struct cs_cfg_parameter { + struct cs_cfg_feature *feat; + u64 current_value; +}; + +/** + * config register instance - part of a loaded feature. + * maps register values to driver structures + * + * @value: value to use when setting feature on device / store for + * readback of volatile values. + * @drv_store: pointer to internal driver element used to set the value + * in hardware. + */ +struct cs_cfg_reg { + union cs_cfg_regval value; + void *drv_store; +}; + +/** + * cs_cfg_ops - standard operations for features. + * + * CS config core provides basic defaults for these, which can be overridden by + * device specific versions. + * + * @set_on_enable: Set the feature on the driver before hw enable. + * @save_on_disable: Save any volatile register values after hw disable. + * @reset: Reset feature to default values. + */ +struct cs_cfg_ops { + int (*set_on_enable)(struct cs_cfg_feature *feat); + void (*save_on_disable)(struct cs_cfg_feature *feat); + void (*reset)(struct cs_cfg_feature *feat); +}; + +/** + * Feature instance loaded into a CoreSight device driver. + * + * @desc: pointer to the static descriptor for this feature. + * @csdev: parent CoreSight device instance. + * @node: list entry into feature list for this device. + * @dev_spinlock: device spinlock. + * @enabled: feature is enabled on this device. + * @nr_params: number of parameters. + * @params: current parameter values on this device + * @param_group: sysfs group for feature parameters. + * @ops: standard ops to enable and disable features on devices. + */ +struct cs_cfg_feature { + const struct cs_cfg_feature_desc *desc; + struct coresight_device *csdev; + struct list_head node; + spinlock_t *dev_spinlock; + bool enabled; + int nr_params; + struct cs_cfg_parameter *params; + struct attribute_group *param_group; + int nr_regs; + struct cs_cfg_reg *regs; + struct cs_cfg_ops ops; +}; + +/* coresight config API functions */ +int coresight_cfg_sysfs_add_grp(struct cs_cfg_feature *feat); +int coresight_cfg_set_feats_on_ena(struct coresight_device *csdev); +void coresight_cfg_save_feats_on_dis(struct coresight_device *csdev); +void coresight_cfg_reset_feats(struct coresight_device *csdev); +void coresight_cfg_set_def_ops(struct cs_cfg_feature *feat); +void coresight_cfg_list_add_feat(struct cs_cfg_feature *feat); +void coresight_cfg_set_reg(struct cs_cfg_reg *reg, u32 flags); +void coresight_cfg_save_reg(struct cs_cfg_reg *reg, u32 flags); +void coresight_cfg_init_reg(struct cs_cfg_reg *reg, + const struct cs_cfg_reg_desc *desc); +void coresight_cfg_init_reg_param(struct cs_cfg_reg *reg, u32 flags, + struct cs_cfg_parameter *param); + +#endif /* _CORESIGHT_CORESIGHT_CONFIG_H */ diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c new file mode 100644 index 000000000000..240e0235c130 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c @@ -0,0 +1,325 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright(C) 2020 Linaro Limited. All rights reserved. + * Author: Mike Leach mike.leach@linaro.org + */ + +#include "coresight-etm4x.h" +#include "coresight-etm4x-cfg.h" +#include "coresight-priv.h" + +/* built in features for ETMv4 */ + +/* strobe feature */ + +/* register defines */ +#define STRB_REG_CTR (CS_CFG_REG_RESOURCE | ETM4_CFG_RES_CTR) +#define STRB_REG_CTR_RB (STRB_REG_CTR | CS_CFG_REG_VAL_SAVE) +#define STRB_REG_CTR_PRM (STRB_REG_CTR | CS_CFG_REG_VAL_PARAM) +#define STRB_REG_SEQ (CS_CFG_REG_RESOURCE | ETM4_CFG_RES_SEQ) +#define STRB_REG_SEL (CS_CFG_REG_RESOURCE | ETM4_CFG_RES_SEL) +#define STRB_REG_VI (CS_CFG_REG_STD | CS_CFG_REG_VAL_MASK) + +static struct cs_cfg_parameter_desc strobe_params[] = { + { + .name = "window", + .value = 1000, + }, + { + .name = "period", + .value = 10000, + }, + { 0 }, +}; + +static struct cs_cfg_reg_desc strob_regs[] = { + /* resource selectors */ + { + .flags = STRB_REG_SEL | TRCRSCTLRn(2), + .value = { + .val32 = 0x20001, + }, + }, + { + .flags = STRB_REG_SEQ | TRCRSCTLRn(3), + .value = { + .val32 = 0x20002, + } + }, + /* strobe window counter 0 - reload from param 0 */ + { + .flags = STRB_REG_CTR_RB | TRCCNTVRn(0), + }, + { + .flags = STRB_REG_CTR_PRM | TRCCNTRLDVRn(0), + .value = { + .val32 = 0, + }, + }, + { + .flags = STRB_REG_CTR | TRCCNTCTLRn(0), + .value = { + .val32 = 0x10001, + }, + }, + /* strobe period counter 1 - reload from param 1 */ + { + .flags = STRB_REG_CTR_RB | TRCCNTVRn(1), + }, + { + .flags = STRB_REG_CTR_PRM | TRCCNTRLDVRn(1), + .value = { + .val32 = 1, + }, + }, + { + .flags = STRB_REG_CTR | TRCCNTCTLRn(1), + .value = { + .val32 = 0x8102, + }, + }, + /* sequencer */ + { + .flags = STRB_REG_SEQ | TRCSEQEVRn(0), + .value = { + .val32 = 0x0081, + }, + }, + { + .flags = STRB_REG_SEQ | TRCSEQEVRn(1), + .value = { + .val32 = 0x0000, + }, + }, + /* view-inst */ + { + .flags = STRB_REG_VI | TRCVICTLR, + .value = { + .val32 = 0x0003, + .mask32 = 0x0003, + }, + }, + /* end of regs */ + { 0 }, +}; + +static struct cs_cfg_feature_desc strobe = { + .name = "strobing", + .brief = "Generate periodic trace capture windows.", + .params = strobe_params, + .regs = strob_regs, +}; + +static struct cs_cfg_feature_desc *built_in_feats[] = { + &strobe, + 0 +}; + +/** + * etm4_cfg_map_reg_offset - validate and map the register offset into a + * location in the driver config struct. + * + * Limits the number of registers that can be accessed and programmed in + * features, to those which are used to control the trace capture parameters. + * + * Omits or limits access to those which the driver must use exclusively. + * + * Invalid offsets will result in fail code return and feature load failure. + * + * @drvdata: driver data to map into. + * @reg: register to map. + * @offset: device offset for the register + */ +static int etm4_cfg_map_reg_offset(struct etmv4_drvdata *drvdata, + struct cs_cfg_reg *reg, u32 offset) +{ + int err = 0, idx; + struct etmv4_config *drvcfg = &drvdata->config; + + #define MAPREG(cval, elem) \ + case cval: \ + reg->drv_store = &drvcfg->elem; \ + break; + + #define MAPREGIDX(cval, elem, off_idx) \ + case cval: \ + reg->drv_store = &drvcfg->elem[off_idx]; \ + break; + + if (((offset >= TRCEVENTCTL0R) && (offset <= TRCVIPCSSCTLR)) || + ((offset >= TRCSEQRSTEVR) && (offset <= TRCEXTINSELR)) || + ((offset >= TRCCIDCCTLR0) && (offset <= TRCVMIDCCTLR1))) { + switch (offset) { + /* 32 bit single control and filter registers */ + MAPREG(TRCEVENTCTL0R, eventctrl0); + MAPREG(TRCEVENTCTL1R, eventctrl1); + MAPREG(TRCSTALLCTLR, stall_ctrl); + MAPREG(TRCTSCTLR, ts_ctrl); + MAPREG(TRCSYNCPR, syncfreq); + MAPREG(TRCCCCTLR, ccctlr); + MAPREG(TRCBBCTLR, bb_ctrl); + MAPREG(TRCVICTLR, vinst_ctrl); + MAPREG(TRCVIIECTLR, viiectlr); + MAPREG(TRCVISSCTLR, vissctlr); + MAPREG(TRCVIPCSSCTLR, vipcssctlr); + MAPREG(TRCSEQRSTEVR, seq_rst); + MAPREG(TRCSEQSTR, seq_state); + MAPREG(TRCEXTINSELR, ext_inp); + MAPREG(TRCCIDCCTLR0, ctxid_mask0); + MAPREG(TRCCIDCCTLR1, ctxid_mask1); + MAPREG(TRCVMIDCCTLR0, vmid_mask0); + MAPREG(TRCVMIDCCTLR1, vmid_mask1); + default: + err = -EINVAL; + break; + } + } else if ((offset & GENMASK(11, 4)) == TRCSEQEVRn(0)) { + /* sequencer state control registers */ + idx = (offset & GENMASK(3, 0)) / 4; + if (idx < ETM_MAX_SEQ_STATES) + reg->drv_store = &drvcfg->seq_ctrl[idx]; + else + err = -EINVAL; + } else if ((offset >= TRCSSCCRn(0)) && (offset <= TRCSSPCICRn(7))) { + /* 32 bit, 8 off indexed register sets */ + idx = (offset & GENMASK(4, 0)) / 4; + switch (offset & GENMASK(11, 5)) { + MAPREGIDX(TRCSSCCRn(0), ss_ctrl, idx); + MAPREGIDX(TRCSSCSRn(0), ss_status, idx); + MAPREGIDX(TRCSSPCICRn(0), ss_pe_cmp, idx); + default: + err = -EINVAL; + break; + } + } else if ((offset >= TRCCIDCVRn(0)) && (offset <= TRCVMIDCVRn(7))) { + /* 64 bit, 8 off indexed register sets */ + idx = (offset & GENMASK(5, 0)) / 8; + switch (offset & GENMASK(11, 6)) { + MAPREGIDX(TRCCIDCVRn(0), ctxid_pid, idx); + MAPREGIDX(TRCVMIDCVRn(0), vmid_val, idx); + default: + err = -EINVAL; + break; + } + } else if ((offset >= TRCRSCTLRn(2)) && + (offset <= TRCRSCTLRn((ETM_MAX_RES_SEL - 1)))) { + /* 32 bit resource selection regs, 32 off, skip fixed 0,1 */ + idx = (offset & GENMASK(6, 0)) / 4; + if (idx < ETM_MAX_RES_SEL) + reg->drv_store = &drvcfg->res_ctrl[idx]; + else + err = -EINVAL; + } else if ((offset >= TRCACVRn(0)) && + (offset <= TRCACATRn((ETM_MAX_SINGLE_ADDR_CMP - 1)))) { + /* 64 bit addr cmp regs, 16 off */ + idx = (offset & GENMASK(6, 0)) / 8; + switch (offset & GENMASK(11, 7)) { + MAPREGIDX(TRCACVRn(0), addr_val, idx); + MAPREGIDX(TRCACATRn(0), addr_acc, idx); + default: + err = -EINVAL; + break; + } + + } else if ((offset >= TRCCNTRLDVRn(0)) && + (offset <= TRCCNTVRn((ETMv4_MAX_CNTR - 1)))) { + /* 32 bit counter regs, 4 off (ETMv4_MAX_CNTR - 1) */ + idx = (offset & GENMASK(3, 0)) / 4; + switch (offset & GENMASK(11, 4)) { + MAPREGIDX(TRCCNTRLDVRn(0), cntrldvr, idx); + MAPREGIDX(TRCCNTCTLRn(0), cntr_ctrl, idx); + MAPREGIDX(TRCCNTVRn(0), cntr_val, idx); + default: + err = -EINVAL; + break; + } + } else { + err = -EINVAL; + } + + return err; +} + +/** + * etm4_cfg_load_feature - load a feature into a device instance. + * + * @csdev: An ETMv4 CoreSight device. + * @feat_desc: The static feature descriptor to be loaded. + * + * The function will load a feature instance into the device, based on the + * supplied descriptor. The descriptor will be checked to ensure a valid + * feature can be loaded for this ETMv4 device. + * + * Parameter and register definitions will be converted into internal + * structures that are used to set the values in the driver when the + * feature is enabled for the device. + */ +int etm4_cfg_load_feature(struct coresight_device *csdev, + const struct cs_cfg_feature_desc *feat_desc) +{ + struct device *dev = csdev->dev.parent; + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev); + struct cs_cfg_feature *feat; + u32 offset; + int i = 0, err = 0; + + feat = devm_kzalloc(dev, sizeof(struct cs_cfg_feature), GFP_KERNEL); + if (!feat) + return -ENOMEM; + + feat->desc = feat_desc; + feat->dev_spinlock = &drvdata->spinlock; + feat->csdev = csdev; + + /* count the params regs and allocate space. */ + while (feat_desc->params[i++].name) + feat->nr_params++; + + i = 0; + while (feat_desc->regs[i++].flags) + feat->nr_regs++; + + feat->params = devm_kcalloc(dev, feat->nr_params, + sizeof(struct cs_cfg_parameter), + GFP_KERNEL); + if (!feat->params) + return -ENOMEM; + + feat->regs = devm_kcalloc(dev, feat->nr_regs, + sizeof(struct cs_cfg_reg), GFP_KERNEL); + if (!feat->regs) + return -ENOMEM; + + /* load the parameters default values */ + for (i = 0; i < feat->nr_params; i++) + feat->params[i].feat = feat; + + /* process the register descriptions */ + for (i = 0; i < feat->nr_regs; i++) { + offset = feat_desc->regs[i].flags & CS_CFG_REG_ID_MASK; + err = etm4_cfg_map_reg_offset(drvdata, &feat->regs[i], offset); + if (err) + return err; + } + + /* set sysfs representation of the feature */ + err = coresight_cfg_sysfs_add_grp(feat); + + /* add the feature to the device list and init default values */ + if (!err) { + coresight_cfg_list_add_feat(feat); + coresight_cfg_set_def_ops(feat); + feat->ops.reset(feat); + } + return err; +} + +/* load up the list of builtin features */ +int etm4_cfg_load_builtins(struct coresight_device *csdev) +{ + int idx = 0, err = 0; + + while (built_in_feats[idx] && !err) + err = etm4_cfg_load_feature(csdev, built_in_feats[idx++]); + return err; +} diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.h b/drivers/hwtracing/coresight/coresight-etm4x-cfg.h new file mode 100644 index 000000000000..703657cac2fc --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + */ + +#ifndef _CORESIGHT_CORESIGHT_ETM4X_CFG_H +#define _CORESIGHT_CORESIGHT_ETM4X_CFG_H + +#include "coresight-config.h" + +/* ETMv4 specific config defines */ + +/* resource IDs */ + +#define ETM4_CFG_RES_CTR 0x00001000 +#define ETM4_CFG_RES_CMP 0x00002000 +#define ETM4_CFG_RES_CMP_PAIR0 0x00003000 +#define ETM4_CFG_RES_CMP_PAIR1 0x00004000 +#define ETM4_CFG_RES_SEL 0x00005000 +#define ETM4_CFG_RES_SEL_PAIR0 0x00006000 +#define ETM4_CFG_RES_SEL_PAIR1 0x00007000 +#define ETM4_CFG_RES_SEQ 0x00008000 +#define ETM4_CFG_RES_TS 0x00009000 +#define ETM4_CFG_RES_MASK 0x0000F000 + +/* ETM4 configuration handlers */ +int etm4_cfg_load_builtins(struct coresight_device *csdev); + +#endif /* _CORESIGHT_CORESIGHT_ETM4X_CFG_H */ diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c index b673e738bc9a..ec182544a064 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c @@ -9,6 +9,7 @@ #include <linux/sysfs.h> #include "coresight-etm4x.h" #include "coresight-priv.h" +#include "coresight-config.h"
static int etm4_set_mode_exclude(struct etmv4_drvdata *drvdata, bool exclude) { @@ -269,6 +270,8 @@ static ssize_t reset_store(struct device *dev,
spin_unlock(&drvdata->spinlock);
+ coresight_cfg_reset_feats(to_coresight_device(dev)); + return size; } static DEVICE_ATTR_WO(reset); diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 60a5133d801c..e69dbcf5cd4d 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -34,6 +34,7 @@
#include "coresight-etm4x.h" #include "coresight-etm-perf.h" +#include "coresight-etm4x-cfg.h"
static int boot_enable; module_param(boot_enable, int, 0444); @@ -320,10 +321,11 @@ static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata) return ret; }
-static int etm4_parse_event_config(struct etmv4_drvdata *drvdata, +static int etm4_parse_event_config(struct coresight_device *csdev, struct perf_event *event) { int ret = 0; + struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); struct etmv4_config *config = &drvdata->config; struct perf_event_attr *attr = &event->attr;
@@ -383,6 +385,9 @@ static int etm4_parse_event_config(struct etmv4_drvdata *drvdata, /* bit[12], Return stack enable bit */ config->cfg |= BIT(12);
+ /* set any enabled features */ + ret = coresight_cfg_set_feats_on_ena(csdev); + out: return ret; } @@ -399,7 +404,7 @@ static int etm4_enable_perf(struct coresight_device *csdev, }
/* Configure the tracer based on the session's specifics */ - ret = etm4_parse_event_config(drvdata, event); + ret = etm4_parse_event_config(csdev, event); if (ret) goto out; /* And enable it */ @@ -415,6 +420,8 @@ static int etm4_enable_sysfs(struct coresight_device *csdev) struct etm4_enable_arg arg = { }; int ret;
+ coresight_cfg_set_feats_on_ena(csdev); + spin_lock(&drvdata->spinlock);
/* @@ -532,6 +539,7 @@ static int etm4_disable_perf(struct coresight_device *csdev, return -EINVAL;
etm4_disable_hw(drvdata); + coresight_cfg_save_feats_on_dis(csdev);
/* * Check if the start/stop logic was active when the unit was stopped. @@ -566,6 +574,7 @@ static void etm4_disable_sysfs(struct coresight_device *csdev) smp_call_function_single(drvdata->cpu, etm4_disable_hw, drvdata, 1);
spin_unlock(&drvdata->spinlock); + coresight_cfg_save_feats_on_dis(csdev); cpus_read_unlock();
dev_dbg(&csdev->dev, "ETM tracing disabled\n"); @@ -1510,6 +1519,11 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) goto err_arch_supported; }
+ /* load builtin features */ + ret = etm4_cfg_load_builtins(drvdata->csdev); + if (ret) + goto err_arch_supported; + pm_runtime_put(&adev->dev); dev_info(&drvdata->csdev->dev, "CPU%d: ETM v%d.%d initialized\n", drvdata->cpu, drvdata->arch >> 4, drvdata->arch & 0xf); diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index f3efbb3b2b4d..ac16d96124f6 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -1335,6 +1335,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) ret = coresight_fixup_orphan_conns(csdev); if (!ret) cti_add_assoc_to_csdev(csdev); + INIT_LIST_HEAD(&csdev->feat_list);
mutex_unlock(&coresight_mutex); if (ret) { diff --git a/include/linux/coresight.h b/include/linux/coresight.h index e3e9f0e3a878..0e8d529282dd 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -204,6 +204,8 @@ struct coresight_device { /* sysfs links between components */ int nr_links; bool has_conns_grp; + /* feature list */ + struct list_head feat_list; };
/*
From: Mike Leach mike.leach@linaro.org Sent: 09 June 2020 17:37 To: coresight@lists.linaro.org Cc: Al Grant Al.Grant@arm.com; mathieu.piorier@linaro.org; Andrea Brunato Andrea.Brunato@arm.com; Suzuki Poulose Suzuki.Poulose@arm.com; Mike Leach mike.leach@linaro.org Subject: [RFC PATCH 0/3] CoreSight complex config support; ETM strobing.
This patchset introduces initial concepts in CoreSight complex configuration support - the device "feature", which is a method of programming the device to perform a specific function.
A built-in feature is provided - the ETM strobing function, which programs the ETM to switch trace on and off in a specific mark / space ratio to effectively sample the program being traced. This feature is essential for the Auto-FDO flow using CoreSight trace.
Features are declared as a data table, a set of register, resource and parameter requirements. A feature can then be loaded into a device, when the requirements are validated. Once loaded a feature can be enabled for a specific trace run.
A feature appears in the sysfs file for the device, as a directory of form 'name.feat', with parameters 'enable', 'description' and any input parameters that may be used to control the operation.
For example the ETM strobing feature provided has parameters of 'window' and 'period' to control the sampling mark / space ratio. The representation in sysfs for the ETMv4 is therefore:- etmX/strobing.feat/ /enable /window /period
Future developments will introduce resource management, and allow for the runtime loading of additional features, and the setting of features across an entire CoreSight system.
Will it be possible to set the strobing parameters per session? Or at least select (per session) between some predefined configurations with different strobing parameters?
We've had some partner feedback that it's important for people to be able to open perf sessions with different strobing parameters, without being able to write sysfs.
Al
Mike Leach (3): coresight: etmv4: Fix resource selector constant. coresight: etmv4: Counter values not saved on disable. coresight: etmv4: Adds initial complex config with ETM4 strobe feature.
drivers/hwtracing/coresight/Makefile | 7 +- .../hwtracing/coresight/coresight-config.c | 380 ++++++++++++++++++ .../hwtracing/coresight/coresight-config.h | 156 +++++++ .../hwtracing/coresight/coresight-etm4x-cfg.c | 325 +++++++++++++++ .../hwtracing/coresight/coresight-etm4x-cfg.h | 29 ++ .../coresight/coresight-etm4x-sysfs.c | 3 + drivers/hwtracing/coresight/coresight-etm4x.c | 24 +- drivers/hwtracing/coresight/coresight-etm4x.h | 4 +- drivers/hwtracing/coresight/coresight.c | 1 + include/linux/coresight.h | 2 + 10 files changed, 925 insertions(+), 6 deletions(-) create mode 100644 drivers/hwtracing/coresight/coresight-config.c create mode 100644 drivers/hwtracing/coresight/coresight-config.h create mode 100644 drivers/hwtracing/coresight/coresight-etm4x-cfg.c create mode 100644 drivers/hwtracing/coresight/coresight-etm4x-cfg.h
-- 2.17.1
Hi Al,
-----Original Message----- From: CoreSight coresight-bounces@lists.linaro.org On Behalf Of Al Grant Sent: 10 June 2020 18:48 To: Mike Leach mike.leach@linaro.org; coresight@lists.linaro.org Cc: mathieu.piorier@linaro.org; Andrea Brunato Andrea.Brunato@arm.com Subject: RE: [RFC PATCH 0/3] CoreSight complex config support; ETM strobing.
From: Mike Leach mike.leach@linaro.org Sent: 09 June 2020 17:37 To: coresight@lists.linaro.org Cc: Al Grant Al.Grant@arm.com; mathieu.piorier@linaro.org; Andrea Brunato Andrea.Brunato@arm.com; Suzuki Poulose Suzuki.Poulose@arm.com; Mike Leach mike.leach@linaro.org Subject: [RFC PATCH 0/3] CoreSight complex config support; ETM strobing.
This patchset introduces initial concepts in CoreSight complex configuration support - the device "feature", which is a method of programming the device to perform a specific function.
A built-in feature is provided - the ETM strobing function, which programs the ETM to switch trace on and off in a specific mark / space ratio to effectively sample the program being traced. This feature is essential for the Auto-FDO flow using CoreSight trace.
Features are declared as a data table, a set of register, resource and parameter requirements. A feature can then be loaded into a device, when the requirements are validated. Once loaded a feature can be enabled for a specific trace run.
A feature appears in the sysfs file for the device, as a directory of form 'name.feat', with parameters 'enable', 'description' and any input parameters that may be used to control the operation.
For example the ETM strobing feature provided has parameters of 'window' and 'period' to control the sampling mark / space ratio. The representation in sysfs for the ETMv4 is therefore:- etmX/strobing.feat/ /enable /window /period
Future developments will introduce resource management, and allow for the runtime loading of additional features, and the setting of features across an entire CoreSight system.
Will it be possible to set the strobing parameters per session? Or at least select (per session) between some predefined configurations with different strobing parameters?
Ultimately - yes.
Complex config has two essential components: 1) features - a way of programming a device to perform a specific function 2) configurations - a description of a programmed system consisting of enabling features on various devices.
So a named configuration might be described as:-
afdo-1 { etm4 strobing window=5000 period=10000 }
Selected by the user as
perf record -e cs_etm/@afdo-1/ <rest of perf command line>
We will need to extend the feature support to associate the parameters / volatile elements with a specific perf event - so they are recalled when that event is on the device.
I think the concept of pre-sets may be very useful. I have been trying to find a way of specifying parameter values on the perf command line, but that gets very messy quite quickly. However if a feature / config has a set of presets, then passing a single preset number is suddenly much easier. 4 bits - which could be in part of the unused perf config vars we currently use to pass bits for timestamps etc, could give us up to 16 presets per configuration.
So if the feature description schema is extended to allow sets of presets for parameters, then we could acheive much of what you require.
Regards
Mike
We've had some partner feedback that it's important for people to be able to open perf sessions with different strobing parameters, without being able to write sysfs.
Al
Mike Leach (3): coresight: etmv4: Fix resource selector constant. coresight: etmv4: Counter values not saved on disable. coresight: etmv4: Adds initial complex config with ETM4 strobe feature.
drivers/hwtracing/coresight/Makefile | 7 +- .../hwtracing/coresight/coresight-config.c | 380 ++++++++++++++++++ .../hwtracing/coresight/coresight-config.h | 156 +++++++ .../hwtracing/coresight/coresight-etm4x-cfg.c | 325 +++++++++++++++ .../hwtracing/coresight/coresight-etm4x-cfg.h | 29 +++++++++++++++ ++ .../coresight/coresight-etm4x-sysfs.c | 3 + drivers/hwtracing/coresight/coresight-etm4x.c | 24 +- drivers/hwtracing/coresight/coresight-etm4x.h | 4 +- drivers/hwtracing/coresight/coresight.c | 1 + include/linux/coresight.h | 2 + 10 files changed, 925 insertions(+), 6 deletions(-) create mode 100644 drivers/hwtracing/coresight/coresight-config.c create mode 100644 drivers/hwtracing/coresight/coresight-config.h create mode 100644 drivers/hwtracing/coresight/coresight-etm4x-cfg.c create mode 100644 drivers/hwtracing/coresight/coresight-etm4x-cfg.h
-- 2.17.1
CoreSight mailing list CoreSight@lists.linaro.org https://lists.linaro.org/mailman/listinfo/coresight