From patchwork Thu Jan 28 17:09:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12054205 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9A24DC433DB for ; Thu, 28 Jan 2021 17:11:32 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4753364DA1 for ; Thu, 28 Jan 2021 17:11:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4753364DA1 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=4v62U96S4zPoBp7KMn+MCwffIxSR5659VORAfDo+nkk=; b=OlB4KnEdssmMKjCqUyAtisdWn8 NEsqHHhf8TCyNFgvIvFA+E39OqWWpaFpGaopfbHHZsDbpyBlmVx1P6yczCIf1lfesGav3CO6FzRtI Li4kbmWivR/zD8TKVUNrIZpJoyu4V23ER0R+7GWl1mx5thL6hAcywGtIDT9SRSHND6DGoUksXj54W qlSjIh/qMInchXF8I0cXKshovFx7bOdqHzn07pxiLtpcnrHXN5e3k+NeB2nQsopB3wHXKNPz+RHED 1YG54GVw7NAG/vO1ivk+0DjBk2utIqnEScZCK95ONOHmyE0Q04d+YVPpi2bf+nFI7iug2AyMkRMKf LeWA8lUw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5Anx-0000D2-MK; Thu, 28 Jan 2021 17:10:01 +0000 Received: from mail-wr1-x42b.google.com ([2a00:1450:4864:20::42b]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5Anj-00008C-6N for linux-arm-kernel@lists.infradead.org; Thu, 28 Jan 2021 17:09:51 +0000 Received: by mail-wr1-x42b.google.com with SMTP id 7so6190871wrz.0 for ; Thu, 28 Jan 2021 09:09:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+I84Ah9HAhQFQY+9ttYXjL9562Vmyn65bXiKqmg1hRw=; b=y8ci6GQd3Slwv2A7+rmC8thvr/qTmgEX0ZMe6/eK3DGQ+CO/lwEB+u1//Tpv4nF/L8 oePvv24cxhSh5RNhUbJJgTtIiSPU/bRaRFLXd5+OTY7cft3+H9bFHewID+I2bptTR9Lw U8PLV9ltG5/PAwC4f2FJSHCxpHyn7Jdm6rI6tR96GcwzoUJ+5wSVWnWFZbcAnqO1W1jf 4g7rBoucgslp31h+qPCaEwoLuVlp3rLyaDaVNfSc9KOTr4GYFTrmv4vSYInhyUhd96VG qshcqXqjQH2e6kVjgIULDLLg/E2DdMDvbKo9BP//TsCT1bHpqSlNw1U7Vs5GFr54T6Ty CVfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+I84Ah9HAhQFQY+9ttYXjL9562Vmyn65bXiKqmg1hRw=; b=pXB3oqBkOnOKUHu/2P+00HOmmVnblbeZxZ7eQQKXS3rldj+AN89FkKeWloplGsdwhD C+N8LfiKAU03YV0/sFCRCcVmaIY2YnVFz+vxJnaFLHqjtsQrWlqQmorqulpJgtMPAQf8 puoNCwywKw7Zmqjki2sLXAPCjb2CFomtDOhBOjgDejQjviJ04n+puHmR0c/N2D4WNgwz 5MEwUJwWirmQKy9KkQZtCYceKzHJyIgehh0rqb8ZEE85FOV8wbYZiXnBEt4cNSU3/AG6 B6GRUwVxYMlh7k0mPkbJU8JGRpH/4GUfwgMJnKQl3vqqvl1jM72JWMTzdkD7ATnFcnMI o12Q== X-Gm-Message-State: AOAM533q0rjyN9m9EFIG5IbzWhjSV4hctAMYNOmQ2o/H/DhnGWTbK0oY SMUiX6mgrVPfJhTu8kHV80rvW+7M4tvKDg== X-Google-Smtp-Source: ABdhPJyJkPW89dQwrN2i9PxaUDEvS6ZnIU355J4pfYr/VzvnZpIs6X7RP8mAdxZOYPDqFpoitmuaGw== X-Received: by 2002:a5d:58c2:: with SMTP id o2mr19164wrf.31.1611853785919; Thu, 28 Jan 2021 09:09:45 -0800 (PST) Received: from linaro.org ([2a00:23c5:6801:1801:40:2fca:953a:e6ba]) by smtp.gmail.com with ESMTPSA id p15sm7622355wrt.15.2021.01.28.09.09.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Jan 2021 09:09:45 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, mathieu.poirier@linaro.org, linux-doc@vger.kernel.org, suzuki.poulose@arm.com Subject: [PATCH v4 01/10] coresight: syscfg: Initial coresight system configuration Date: Thu, 28 Jan 2021 17:09:27 +0000 Message-Id: <20210128170936.9222-2-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210128170936.9222-1-mike.leach@linaro.org> References: <20210128170936.9222-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210128_120947_856748_82DD129F X-CRM114-Status: GOOD ( 36.63 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: gregkh@linuxfoundation.org, alexander.shishkin@linux.intel.com, yabinc@google.com, corbet@lwn.net, linux-kernel@vger.kernel.org, tingwei@codeaurora.org, leo.yan@linaro.org, Mike Leach MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Creates an system management API to allow complex configurations and features to be programmed into a CoreSight infrastructure. A feature is defined as a programming set for a device or class of devices. A configuration is a set of features across the system that are enabled for a trace session. The API will manage system wide configuration, and allow complex programmed features to be added to individual device instances, and provide for system wide configuration selection on trace capture operations. This patch creates the initial data object and the initial API for loading configurations and features. Signed-off-by: Mike Leach --- drivers/hwtracing/coresight/Makefile | 2 +- .../hwtracing/coresight/coresight-config.h | 167 +++++++++++++++ drivers/hwtracing/coresight/coresight-core.c | 12 +- .../hwtracing/coresight/coresight-etm-perf.c | 2 +- .../hwtracing/coresight/coresight-etm-perf.h | 2 +- .../hwtracing/coresight/coresight-syscfg.c | 197 ++++++++++++++++++ .../hwtracing/coresight/coresight-syscfg.h | 54 +++++ 7 files changed, 432 insertions(+), 4 deletions(-) create mode 100644 drivers/hwtracing/coresight/coresight-config.h create mode 100644 drivers/hwtracing/coresight/coresight-syscfg.c create mode 100644 drivers/hwtracing/coresight/coresight-syscfg.h diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile index f20e357758d1..4ce854c434b1 100644 --- a/drivers/hwtracing/coresight/Makefile +++ b/drivers/hwtracing/coresight/Makefile @@ -4,7 +4,7 @@ # obj-$(CONFIG_CORESIGHT) += coresight.o coresight-y := coresight-core.o coresight-etm-perf.o coresight-platform.o \ - coresight-sysfs.o + coresight-sysfs.o coresight-syscfg.o obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \ coresight-tmc-etr.o diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h new file mode 100644 index 000000000000..3fedf8ab3cee --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -0,0 +1,167 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#ifndef _CORESIGHT_CORESIGHT_CONFIG_H +#define _CORESIGHT_CORESIGHT_CONFIG_H + +#include +#include + +/* 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. + * + * 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. + */ +struct cscfg_regval_desc { + struct { + u32 type:8; + u32 offset:12; + u32 hw_info:12; + }; + union { + u64 val64; + struct { + u32 val32; + u32 mask32; + }; + }; +}; + +/** + * 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. + * @item: List entry. + * @match_flags: matching information if loading into a device + * @nr_params: number of parameters used. + * @params: array of parameters used. + * @nr_regs: number of registers used. + * @reg: array of registers used. + */ +struct cscfg_feature_desc { + const char *name; + const char *brief; + struct list_head item; + u32 match_flags; + int nr_params; + struct cscfg_parameter_desc *params; + int nr_regs; + struct cscfg_regval_desc *regs; +}; + +/** + * Match descriptor - Device / feature matching when loading into devices + * + * Used by loading configurations to define which class or specific devices + * they want to match used features to, and registered devices to specify which + * matching class and information they support. + * + * The load process uses these matching pairs to load feature instances into + * matching devices. + * + * @match_flags: used to match to a particular class of device. + * + */ +struct cscfg_match_desc { + u32 match_flags; +}; + +/** + * Descriptor for features referenced by a configuration. + * + * @name: name of feature to use. Match against the @name in struct + * cscfg_feature_desc. + * @match: match info for the feature when used in this configuration - + * may be all devices of a class or a specific device in that class. + */ +struct cscfg_config_feat_ref { + const char *name; + struct cscfg_match_desc match; +}; + +/** + * 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. + * + * @name: name of the configuration - used for selection. + * @brief: description of the purpose of the configuration. + * @item: list entry. + * @nr_refs: Number of features used in this configuration. + * @refs: 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 *brief; + struct list_head item; + int nr_refs; + struct cscfg_config_feat_ref *refs; + int nr_presets; + int nr_total_params; + const u64 *presets; /* nr_presets * nr_total_params */ +}; + +#endif /* _CORESIGHT_CORESIGHT_CONFIG_H */ diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 0062c8935653..6bd41de46648 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -21,6 +21,7 @@ #include "coresight-etm-perf.h" #include "coresight-priv.h" +#include "coresight-syscfg.h" static DEFINE_MUTEX(coresight_mutex); @@ -1739,13 +1740,22 @@ static int __init coresight_init(void) ret = etm_perf_init(); if (ret) - bus_unregister(&coresight_bustype); + goto exit_bus_unregister; + /* initialise the coresight syscfg API */ + ret = cscfg_init(); + if (!ret) + return 0; + + etm_perf_exit(); +exit_bus_unregister: + bus_unregister(&coresight_bustype); return ret; } static void __exit coresight_exit(void) { + cscfg_exit(); etm_perf_exit(); bus_unregister(&coresight_bustype); } diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index bdc34ca449f7..a608081bd446 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -627,7 +627,7 @@ int __init etm_perf_init(void) return ret; } -void __exit etm_perf_exit(void) +void etm_perf_exit(void) { perf_pmu_unregister(&etm_pmu); } diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.h b/drivers/hwtracing/coresight/coresight-etm-perf.h index 3e4f2ad5e193..29d90dfeba31 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.h +++ b/drivers/hwtracing/coresight/coresight-etm-perf.h @@ -83,6 +83,6 @@ static inline void *etm_perf_sink_config(struct perf_output_handle *handle) #endif /* CONFIG_CORESIGHT */ int __init etm_perf_init(void); -void __exit etm_perf_exit(void); +void etm_perf_exit(void); #endif diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c new file mode 100644 index 000000000000..f7e396a5f9cb --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#include + +#include "coresight-config.h" +#include "coresight-syscfg.h" + +/* + * cscfg_ API manages configurations and features for the entire coresight + * infrastructure. + * + * It allows the loading of configurations and features, and loads these into + * coresight devices as appropriate. + */ + +/* protect the cscsg_data and device */ +static DEFINE_MUTEX(cscfg_mutex); + +/* only one of these */ +static struct cscfg_manager *cscfg_mgr; + +/* load features and configuations into the lists */ + +/* check feature list for a named feature - call with mutex locked. */ +static bool cscfg_match_list_feat(const char *name) +{ + struct cscfg_feature_desc *curr_item; + + list_for_each_entry(curr_item, &cscfg_mgr->data.feat_desc_list, item) { + if (strcmp(curr_item->name, name) == 0) + return true; + } + return false; +} + +/* check all feat needed for cfg are in the list - call with mutex locked. */ +static int cscfg_check_feat_for_cfg(struct cscfg_config_desc *cfg_desc) +{ + int i; + + for (i = 0; i < cfg_desc->nr_refs; i++) + if (!cscfg_match_list_feat(cfg_desc->refs[i].name)) + return -EINVAL; + return 0; +} + +/* + * load feature - add to feature list. + */ +static int cscfg_load_feat(struct cscfg_feature_desc *feat_desc) +{ + list_add(&feat_desc->item, &cscfg_mgr->data.feat_desc_list); + + return 0; +} + +/* + * load config into the system - validate used features exist then add to + * config list. + */ +static int cscfg_load_config(struct cscfg_config_desc *cfg_desc) +{ + int err; + + /* validate features are present */ + err = cscfg_check_feat_for_cfg(cfg_desc); + if (err) + return err; + + list_add(&cfg_desc->item, &cscfg_mgr->data.config_desc_list); + + return 0; +} + +/* + * External API function to load feature and config sets. + * Take a 0 terminated array of feature descriptors and/or configuration + * descriptors and load into the system. + * Features are loaded first to ensure configuration dependencies can be met. + */ +int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs, + struct cscfg_feature_desc **feat_descs) +{ + int err, i = 0; + + mutex_lock(&cscfg_mutex); + + /* load features first */ + if (feat_descs) { + while (feat_descs[i]) { + err = cscfg_load_feat(feat_descs[i]); + if (err) { + pr_err("coresight-syscfg: Failed to load feature %s\n", + feat_descs[i]->name); + goto do_unlock; + } + i++; + } + } + + /* next any configurations to check feature dependencies */ + i = 0; + if (cfg_descs) { + while (cfg_descs[i]) { + err = cscfg_load_config(cfg_descs[i]); + if (err) { + pr_err("coresight-syscfg: Failed to load configuration %s\n", + cfg_descs[i]->name); + goto do_unlock; + } + i++; + } + } + +do_unlock: + mutex_unlock(&cscfg_mutex); + return err; +} +EXPORT_SYMBOL_GPL(cscfg_load_config_sets); + +/* Initialise system configuration management device. */ + +struct device *to_device_cscfg(void) +{ + return cscfg_mgr ? &cscfg_mgr->dev : NULL; +} + +/* Must have a release function or the kernel will complain on module unload */ +void cscfg_dev_release(struct device *dev) +{ + kfree(cscfg_mgr); + cscfg_mgr = NULL; +} + +/* a device is needed to "own" some kernel elements such as sysfs entries. */ +int cscfg_create_device(void) +{ + struct device *dev; + int err = -ENOMEM; + + mutex_lock(&cscfg_mutex); + if (cscfg_mgr) { + err = -EINVAL; + goto create_dev_exit_unlock; + } + + cscfg_mgr = kzalloc(sizeof(struct cscfg_manager), GFP_KERNEL); + if (!cscfg_mgr) + goto create_dev_exit_unlock; + + /* setup the device */ + dev = to_device_cscfg(); + dev->release = cscfg_dev_release; + dev->init_name = "system_cfg"; + + err = device_register(dev); + if (err) + cscfg_dev_release(dev); + +create_dev_exit_unlock: + mutex_unlock(&cscfg_mutex); + return err; +} + +void cscfg_clear_device(void) +{ + mutex_lock(&cscfg_mutex); + device_unregister(to_device_cscfg()); + mutex_unlock(&cscfg_mutex); +} + +/* Initialise system config management API device */ +int __init cscfg_init(void) +{ + int err = 0; + + err = cscfg_create_device(); + if (err) + return err; + + INIT_LIST_HEAD(&cscfg_mgr->data.csdev_desc_list); + INIT_LIST_HEAD(&cscfg_mgr->data.feat_desc_list); + INIT_LIST_HEAD(&cscfg_mgr->data.config_desc_list); + cscfg_mgr->data.nr_csdev = 0; + + dev_info(to_device_cscfg(), "CoreSight Configuration manager initialised"); + return 0; +} + +void __exit cscfg_exit(void) +{ + cscfg_clear_device(); +} diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h new file mode 100644 index 000000000000..907ba8d3efea --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-syscfg.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Coresight system configuration driver. + */ + +#ifndef CORESIGHT_SYSCFG_H +#define CORESIGHT_SYSCFG_H + +#include +#include + +#include "coresight-config.h" + +/** + * System configuration manager API data. + * + * @csdev_list: List of coresight devices registered with the configuration manager. + * @feat_desc_list: List of feature descriptors to load into registered devices. + * @config_desc_list: List of system configuration descriptors to load into registered devices. + * @nr_csdev: Number of registered devices with the cscfg system + */ +struct cscfg_api_data { + struct list_head csdev_desc_list; + struct list_head feat_desc_list; + struct list_head config_desc_list; + int nr_csdev; +}; + +/* internal core operations for cscfg */ +int __init cscfg_init(void); +void __exit cscfg_exit(void); + +/* syscfg manager external API */ +int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs, + struct cscfg_feature_desc **feat_descs); + +/** + * System configuration manager device. + * + * Need a device to 'own' some coresight system wide sysfs entries in + * perf events, configfs etc. + * + * @dev: The device. + * @data: The API data. + */ +struct cscfg_manager { + struct device dev; + struct cscfg_api_data data; +}; + +/* get reference to dev in cscfg_manager */ +struct device *to_device_cscfg(void); + +#endif /* CORESIGHT_SYSCFG_H */ From patchwork Thu Jan 28 17:09:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12054211 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05156C433DB for ; Thu, 28 Jan 2021 17:11:43 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8C10264DE2 for ; Thu, 28 Jan 2021 17:11:42 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8C10264DE2 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=JTIxTmHeidqmRmCh8YUq4f8Qy9W4op0LxB/2JbwjGTM=; b=Ro7aFTmwEichzeU0cj+B2uX9Y9 mjn+8eU2YL4wk7WSGhiyR4naBiKSHpYhcwK4iq8GZ6VghQoZSGQ3RJIbKc2KO3F7Lso34xceo6+U2 HBreGbFQrLVIfWlVpzRKUvQd0zyiyYd0NkTWlA0+zRW4hWA+W48+2SaX6rTdlx90w8th7AAuAgXYR Wi1M0KLQn6F1wlWh580sWB4PnjciZ0qLzaQvfBkWK/IJIMZWu7DuEBfT7j2K6d3wRiQUL8ssJ030V frKOdvTclY9EkklZf6a7V33unIbODOD5zxNBwo7pAkO0Ueid5te8+NzBwdylZ3/4mPZfdq6Fy+1bw u/wPuoXg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5Ao0-0000Dj-Op; Thu, 28 Jan 2021 17:10:04 +0000 Received: from mail-wm1-x330.google.com ([2a00:1450:4864:20::330]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5Ank-00008a-Hp for linux-arm-kernel@lists.infradead.org; Thu, 28 Jan 2021 17:09:53 +0000 Received: by mail-wm1-x330.google.com with SMTP id j18so4910155wmi.3 for ; Thu, 28 Jan 2021 09:09:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=WBMJjKwLmtSeS700sltQEAd7gwZv9CAX55ksnY87WLc=; b=LbTsJ4H8H0YDnpW1WBjcC4VcKibzRXfXGeZtIzy1MepjLHgBRB1zQAgahLxH9Jg2ra izXMFaG7GwHosbpmLGq+rdQabjXuPkk+nXiaktkO5KA+8S3MmBgL5P2B5Q6o0oXmvcXT WhGaea/OJfCS1dERandLRvXgzQ1SEUp+Cj3W8anPyoGZUinufJDJRQms7J4GokMgbwAY paULEDAVbIRHOPjfqR9YC0HflLbq6vBET9teYKe3/au9iyCEBDVD5hOtZbn83LDdVLRC kDwQ+kFpfzT17IeFrAHgIZvLCdT0KxW3+aoKu2/YxuE+DQ+A655D5pp1rSKMyqhFcvTH gRcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=WBMJjKwLmtSeS700sltQEAd7gwZv9CAX55ksnY87WLc=; b=jZeO1RO7dWzexDCB9cXlfQh6Zz5Zth0BUXR5ATztWyGuXBx6MUwsoo1nfQ+oSYZeAt LHnn0JisIx+VB06OXkDNTbzmjoPa3XLtVLrVrgv6RMFOX8ahtocOjWt8p8sdpciD7c0T rLDGLwzi89XJd4kY3+vbJebE+RO82MrtLlx13gyMX7G1T0m2/h5y+Wb51cFcM4JoX8c2 Q739j6pGdqT866tcocP2pvp6r+pbXNAl/39Ktjdk16+EuXwwtR4iEbRR06UQ2y5Qjncd o/1WV66pGj8cPi16vATrIMpXKFA1Pleu2pAZF8U45GNz6DiVc67Yqj0Wl5GNYmd4zVPy WNfA== X-Gm-Message-State: AOAM530nQYrDBqr1lGbTx6lNi/h05WTdH86ge4XBhwXWD3Yw1CDfxbG2 9BSzlScNk69/FBiEEQUuJuk1gfBvbRLkwg== X-Google-Smtp-Source: ABdhPJxVGC1hJAPqP9irGz3HLKRLWrX8JqHsr0MdZ33bX1eMslQS8dR2aLDIMni3XMMkHie/S4dDQQ== X-Received: by 2002:a05:600c:4f50:: with SMTP id m16mr181493wmq.175.1611853786894; Thu, 28 Jan 2021 09:09:46 -0800 (PST) Received: from linaro.org ([2a00:23c5:6801:1801:40:2fca:953a:e6ba]) by smtp.gmail.com with ESMTPSA id p15sm7622355wrt.15.2021.01.28.09.09.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Jan 2021 09:09:46 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, mathieu.poirier@linaro.org, linux-doc@vger.kernel.org, suzuki.poulose@arm.com Subject: [PATCH v4 02/10] coresight: syscfg: Add registration and feature loading for cs devices Date: Thu, 28 Jan 2021 17:09:28 +0000 Message-Id: <20210128170936.9222-3-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210128170936.9222-1-mike.leach@linaro.org> References: <20210128170936.9222-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210128_120948_750396_3EDA7DD1 X-CRM114-Status: GOOD ( 33.56 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: gregkh@linuxfoundation.org, alexander.shishkin@linux.intel.com, yabinc@google.com, corbet@lwn.net, linux-kernel@vger.kernel.org, tingwei@codeaurora.org, leo.yan@linaro.org, Mike Leach MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org API for individual devices to register with the syscfg management system is added. Devices register with matching information, and any features or configurations that match will be loaded into the device. The feature and configuration loading is extended so that on load these are loaded into any currently registered devices. This allows configuration loading after devices have been registered. Signed-off-by: Mike Leach --- .../hwtracing/coresight/coresight-config.h | 98 +++++ .../hwtracing/coresight/coresight-syscfg.c | 348 ++++++++++++++++++ .../hwtracing/coresight/coresight-syscfg.h | 20 + include/linux/coresight.h | 5 + 4 files changed, 471 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h index 3fedf8ab3cee..75ecdecf7013 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -164,4 +164,102 @@ struct cscfg_config_desc { const u64 *presets; /* nr_presets * nr_total_params */ }; +/** + * config register instance - part of a loaded feature. + * maps register values to csdev 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 cscfg_reg_csdev { + struct cscfg_regval_desc value; + void *drv_store; +}; + +/** + * config parameter instance - part of a loaded feature. + * + * @feat: parent feature + * @reg: register value updated by this parameter. + * @current_value: current value of parameter - may be set by user via + * sysfs, or modified during device operation. + * @val64: true if 64 bit value + */ +struct cscfg_parameter_csdev { + struct cscfg_feature_csdev *feat; + struct cscfg_reg_csdev *reg; + u64 current_value; + bool val64; +}; + +/** + * Feature instance loaded into a CoreSight device. + * + * When a feature is loaded into a specific device, then this structure holds + * the connections between the register / parameter values used and the + * internal data structures that are written when the feature is enabled. + * + * Since applying a feature modifies internal data structures in the device, + * then we have a reference to the device spinlock to protect access to these + * structures (@csdev_spinlock). + * + * @desc: pointer to the static descriptor for this feature. + * @csdev: parent CoreSight device instance. + * @node: list entry into feature list for this device. + * @csdev_spinlock: device spinlock from csdev instance.. + * @nr_params: number of parameters. + * @params: current parameter values on this device + * @nr_regs: number of registers to be programmed. + * @regs: Programming details for the registers + */ +struct cscfg_feature_csdev { + const struct cscfg_feature_desc *desc; + struct coresight_device *csdev; + struct list_head node; + spinlock_t *csdev_spinlock; + int nr_params; + struct cscfg_parameter_csdev *params; + int nr_regs; + struct cscfg_reg_csdev *regs; +}; + +/** + * Configuration instance when loaded into a CoreSight device. + * + * The instance contains references to loaded features on this device that are + * used by the configuration. + * + * @desc: reference to the descriptor for this configuration + * @csdev: parent coresight device for this configuration instance. + * @node: list entry within the coresight device + * @nr_feat: Number of features on this device that are used in the + * configuration. + * @feats: reference to the device features to enable. + * @enabled: true if configuration is enabled on this device. + */ +struct cscfg_config_csdev { + const struct cscfg_config_desc *desc; + struct coresight_device *csdev; + struct list_head node; + int nr_feat; + struct cscfg_feature_csdev **feats; + bool enabled; +}; + +/** + * Coresight device operations. + * + * Registered coresight devices provide these operations to manage feature + * instances compatible with the device hardware and drivers + * + * @load_feat: Pass a feature descriptor into the device and create the + * loaded feature instance (struct cscfg_feature_csdev). + */ +struct cscfg_csdev_feat_ops { + int (*load_feat)(struct coresight_device *csdev, + struct cscfg_feature_csdev *feat); +}; + #endif /* _CORESIGHT_CORESIGHT_CONFIG_H */ diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index f7e396a5f9cb..c04cea0c1db2 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -25,6 +25,212 @@ static struct cscfg_manager *cscfg_mgr; /* load features and configuations into the lists */ +/* protect the cfg lists in the csdev instances */ +static DEFINE_MUTEX(cscfg_csdev_mutex); + +/* get name feature instance from a coresight device list of features */ +static struct cscfg_feature_csdev * +cscfg_get_feat_csdev(struct coresight_device *csdev, const char *name) +{ + struct cscfg_feature_csdev *feat = NULL; + + list_for_each_entry(feat, &csdev->feature_csdev_list, node) { + if (strcmp(feat->desc->name, name) == 0) + return feat; + } + return NULL; +} + +/* allocate the device config instance - with max number of used features */ +static struct cscfg_config_csdev * +cscfg_alloc_csdev_cfg(struct coresight_device *csdev, int nr_feats) +{ + struct cscfg_config_csdev *dev_cfg = NULL; + struct device *dev = csdev->dev.parent; + + /* this is being allocated using the devm for the coresight device */ + dev_cfg = devm_kzalloc(dev, sizeof(struct cscfg_config_csdev), GFP_KERNEL); + if (!dev_cfg) + return NULL; + + dev_cfg->csdev = csdev; + dev_cfg->feats = devm_kcalloc(dev, nr_feats, + sizeof(struct cscfg_feature_csdev *), + GFP_KERNEL); + if (!dev_cfg->feats) + dev_cfg = NULL; + return dev_cfg; +} + +/* check match info between used feature from the config and a regisered device */ +static bool cscfg_match_feat_info(struct cscfg_match_desc *used_cmp, + struct cscfg_match_desc *reg_dev) +{ + /* if flags don't match then fail early */ + if (!(used_cmp->match_flags & reg_dev->match_flags)) + return false; + + return true; +} + +/* Load a config into a device if there are feature matches between config and device */ +static int cscfg_add_csdev_cfg(struct coresight_device *csdev, + struct cscfg_match_desc *match_info, + struct cscfg_config_desc *cfg_desc) +{ + struct cscfg_config_csdev *dev_cfg = NULL; + struct cscfg_config_feat_ref *feat_ref; + struct cscfg_feature_csdev *feat; + int checked; + + /* look at each required feature and see if it matches any feature on the device */ + for (checked = 0; checked < cfg_desc->nr_refs; checked++) { + feat_ref = &cfg_desc->refs[checked]; + if (cscfg_match_feat_info(&feat_ref->match, match_info)) { + /* device matched - get the feature */ + feat = cscfg_get_feat_csdev(csdev, feat_ref->name); + if (!feat) + return -EINVAL; + if (!dev_cfg) { + dev_cfg = cscfg_alloc_csdev_cfg(csdev, cfg_desc->nr_refs); + if (!dev_cfg) + return -ENOMEM; + dev_cfg->desc = cfg_desc; + } + dev_cfg->feats[dev_cfg->nr_feat++] = feat; + } + } + /* if matched features, add config to device.*/ + if (dev_cfg) { + mutex_lock(&cscfg_csdev_mutex); + list_add(&dev_cfg->node, &csdev->config_csdev_list); + mutex_unlock(&cscfg_csdev_mutex); + } + + return 0; +} + +/* + * Add the config to the set of registered devices - call with mutex locked. + * Iterates through devices - any device that matches one or more of the + * configuration features will load it, the others will ignore it. + */ +static int cscfg_add_cfg_to_csdevs(struct cscfg_config_desc *cfg_desc) +{ + struct cscfg_csdev_register *curr_item; + int err; + + list_for_each_entry(curr_item, &cscfg_mgr->data.csdev_desc_list, item) { + err = cscfg_add_csdev_cfg(curr_item->csdev, &curr_item->match_info, cfg_desc); + if (err) + return err; + } + return 0; +} + +/* + * Allocate a feature object for load into a csdev. + * memory allocated using the csdev->dev object using devm managed allocator. + */ +static struct cscfg_feature_csdev * +cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc *feat_desc) +{ + struct cscfg_feature_csdev *feat = NULL; + struct device *dev = csdev->dev.parent; + int i; + + feat = devm_kzalloc(dev, sizeof(struct cscfg_feature_csdev), GFP_KERNEL); + if (!feat) + return NULL; + + /* parameters are optional - could be 0 */ + feat->nr_params = feat_desc->nr_params; + + /* + * if we need parameters, zero alloc the space here, the load routine in + * the csdev device driver will fill out some information according to + * feature descriptor. + */ + if (feat->nr_params) { + feat->params = devm_kcalloc(dev, feat->nr_params, + sizeof(struct cscfg_parameter_csdev), + GFP_KERNEL); + if (!feat->params) + return NULL; + + /* + * fill in the feature reference in the param - other fields + * handled by loader in csdev. + */ + for (i = 0; i < feat->nr_params; i++) + feat->params[i].feat = feat; + } + + /* + * Always have registers to program - again the load routine in csdev device + * will fill out according to feature descriptor and device requirements. + */ + feat->nr_regs = feat_desc->nr_regs; + feat->regs = devm_kcalloc(dev, feat->nr_regs, + sizeof(struct cscfg_reg_csdev), GFP_KERNEL); + if (!feat->regs) + return NULL; + + /* load the feature default values */ + feat->desc = feat_desc; + feat->csdev = csdev; + + return feat; +} + +/* load one feature into one coresight device */ +static int cscfg_load_feat_csdev(struct coresight_device *csdev, + struct cscfg_feature_desc *feat_desc, + struct cscfg_csdev_feat_ops *ops) +{ + struct cscfg_feature_csdev *feat_csdev; + int err; + + if (!ops->load_feat) + return -EINVAL; + + feat_csdev = cscfg_alloc_csdev_feat(csdev, feat_desc); + if (!feat_csdev) + return -ENOMEM; + + /* load the feature into the device - may modify default ops*/ + err = ops->load_feat(csdev, feat_csdev); + if (err) + return err; + + /* add to internal csdev feature list */ + mutex_lock(&cscfg_csdev_mutex); + list_add(&feat_csdev->node, &csdev->feature_csdev_list); + mutex_unlock(&cscfg_csdev_mutex); + + return 0; +} + +/* + * Add feature to any matching devices - call with mutex locked. + * Iterates through devices - any device that matches the feature will be + * called to load it. + */ +static int cscfg_add_feat_to_csdevs(struct cscfg_feature_desc *feat_desc) +{ + struct cscfg_csdev_register *curr_item; + int err; + + list_for_each_entry(curr_item, &cscfg_mgr->data.csdev_desc_list, item) { + if (curr_item->match_info.match_flags & feat_desc->match_flags) { + err = cscfg_load_feat_csdev(curr_item->csdev, feat_desc, &curr_item->ops); + if (err) + return err; + } + } + return 0; +} + /* check feature list for a named feature - call with mutex locked. */ static bool cscfg_match_list_feat(const char *name) { @@ -53,6 +259,13 @@ static int cscfg_check_feat_for_cfg(struct cscfg_config_desc *cfg_desc) */ static int cscfg_load_feat(struct cscfg_feature_desc *feat_desc) { + int err; + + /* add feature to any matching registered devices */ + err = cscfg_add_feat_to_csdevs(feat_desc); + if (err) + return err; + list_add(&feat_desc->item, &cscfg_mgr->data.feat_desc_list); return 0; @@ -71,6 +284,11 @@ static int cscfg_load_config(struct cscfg_config_desc *cfg_desc) if (err) return err; + /* add config to any matching registered device */ + err = cscfg_add_cfg_to_csdevs(cfg_desc); + if (err) + return err; + list_add(&cfg_desc->item, &cscfg_mgr->data.config_desc_list); return 0; @@ -122,6 +340,136 @@ int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs, } EXPORT_SYMBOL_GPL(cscfg_load_config_sets); +/* Handle coresight device registration and add configs and features to devices */ + +/* iterate through config lists and load matching configs to device */ +static int cscfg_add_cfgs_csdev(struct coresight_device *csdev, + struct cscfg_match_desc *info) +{ + struct cscfg_config_desc *curr_item; + int err = 0; + + list_for_each_entry(curr_item, &cscfg_mgr->data.config_desc_list, item) { + err = cscfg_add_csdev_cfg(csdev, info, curr_item); + if (err) + break; + } + return err; +} + +/* iterate through feature lists and load matching features to device */ +static int cscfg_add_feats_csdev(struct coresight_device *csdev, + struct cscfg_match_desc *info, + struct cscfg_csdev_feat_ops *ops) +{ + struct cscfg_feature_desc *curr_item; + int err = 0; + + if (!ops->load_feat) + return -EINVAL; + + list_for_each_entry(curr_item, &cscfg_mgr->data.feat_desc_list, item) { + if (curr_item->match_flags & info->match_flags) { + err = cscfg_load_feat_csdev(csdev, curr_item, ops); + if (err) + break; + } + } + return err; +} + +/* Add coresight device to list and copy its matching info */ +static int cscfg_list_add_csdev(struct coresight_device *csdev, + struct cscfg_match_desc *info, + struct cscfg_csdev_feat_ops *ops) +{ + struct cscfg_csdev_register *list_entry; + + /* allocate the list entry structure */ + list_entry = kzalloc(sizeof(struct cscfg_csdev_register), GFP_KERNEL); + if (!list_entry) + return -ENOMEM; + + list_entry->csdev = csdev; + list_entry->match_info.match_flags = info->match_flags; + list_entry->ops.load_feat = ops->load_feat; + list_add(&list_entry->item, &cscfg_mgr->data.csdev_desc_list); + + INIT_LIST_HEAD(&csdev->feature_csdev_list); + INIT_LIST_HEAD(&csdev->config_csdev_list); + cscfg_mgr->data.nr_csdev++; + + return 0; +} + +/* remove a coresight device from the list and free data */ +static void cscfg_list_remove_csdev(struct coresight_device *csdev) +{ + struct cscfg_csdev_register *curr_item, *tmp; + + list_for_each_entry_safe(curr_item, tmp, &cscfg_mgr->data.csdev_desc_list, item) { + if (curr_item->csdev == csdev) { + list_del(&curr_item->item); + kfree(curr_item); + cscfg_mgr->data.nr_csdev--; + break; + } + } +} + +/* register a coresight device with the syscfg api */ +int cscfg_register_csdev(struct coresight_device *csdev, + struct cscfg_match_desc *info, + struct cscfg_csdev_feat_ops *ops) +{ + int ret = 0; + + mutex_lock(&cscfg_mutex); + + /* add device to list of registered devices */ + ret = cscfg_list_add_csdev(csdev, info, ops); + if (ret) + goto reg_csdev_unlock; + + /* now load any registered features and configs matching the device. */ + ret = cscfg_add_feats_csdev(csdev, info, ops); + if (ret) { + cscfg_list_remove_csdev(csdev); + goto reg_csdev_unlock; + } + + ret = cscfg_add_cfgs_csdev(csdev, info); + if (ret) { + cscfg_list_remove_csdev(csdev); + goto reg_csdev_unlock; + } + + pr_info("CSCFG registered %s", dev_name(&csdev->dev)); + +reg_csdev_unlock: + mutex_unlock(&cscfg_mutex); + return ret; +} +EXPORT_SYMBOL_GPL(cscfg_register_csdev); + +/* remove coresight device and update counts - syscfg device at 0 */ +void cscfg_unregister_csdev(struct coresight_device *csdev) +{ + struct cscfg_csdev_register *curr_item, *tmp; + + mutex_lock(&cscfg_mutex); + list_for_each_entry_safe(curr_item, tmp, &cscfg_mgr->data.csdev_desc_list, item) { + if (curr_item->csdev == csdev) { + list_del(&curr_item->item); + kfree(curr_item); + cscfg_mgr->data.nr_csdev--; + break; + } + } + mutex_unlock(&cscfg_mutex); +} +EXPORT_SYMBOL_GPL(cscfg_unregister_csdev); + /* Initialise system configuration management device. */ struct device *to_device_cscfg(void) diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h index 907ba8d3efea..ebf5e1491d86 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.h +++ b/drivers/hwtracing/coresight/coresight-syscfg.h @@ -26,6 +26,22 @@ struct cscfg_api_data { int nr_csdev; }; +/** + * List entry for Coresight devices that are registered as supporting complex + * config operations. + * + * @csdev: The registered device. + * @match_info: The matching type information. + * @ops: Operations supported by the registered device. + * @item: list entry. + */ +struct cscfg_csdev_register { + struct coresight_device *csdev; + struct cscfg_match_desc match_info; + struct cscfg_csdev_feat_ops ops; + struct list_head item; +}; + /* internal core operations for cscfg */ int __init cscfg_init(void); void __exit cscfg_exit(void); @@ -33,6 +49,10 @@ void __exit cscfg_exit(void); /* syscfg manager external API */ int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs, struct cscfg_feature_desc **feat_descs); +int cscfg_register_csdev(struct coresight_device *csdev, + struct cscfg_match_desc *info, + struct cscfg_csdev_feat_ops *ops); +void cscfg_unregister_csdev(struct coresight_device *csdev); /** * System configuration manager device. diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 976ec2697610..d0126ed326a6 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -219,6 +219,8 @@ struct coresight_sysfs_link { * @nr_links: number of sysfs links created to other components from this * device. These will appear in the "connections" group. * @has_conns_grp: Have added a "connections" group for sysfs links. + * @feature_csdev_list: List of complex feature programming added to the device. + * @config_csdev_list: List of system configurations added to the device. */ struct coresight_device { struct coresight_platform_data *pdata; @@ -240,6 +242,9 @@ struct coresight_device { int nr_links; bool has_conns_grp; bool ect_enabled; /* true only if associated ect device is enabled */ + /* system configuration and feature lists */ + struct list_head feature_csdev_list; + struct list_head config_csdev_list; }; /* From patchwork Thu Jan 28 17:09:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12054215 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3836CC433DB for ; Thu, 28 Jan 2021 17:11:56 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BF2C864DE2 for ; Thu, 28 Jan 2021 17:11:55 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BF2C864DE2 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=WAReP2/FvLTYUSTX8vlnqaDFwmkYGX851niaq1NJc6A=; b=DumdoG3JyynixwZnvgD5xSIzN5 3YXMBr6nofJ+klj5Jwfva54BJcPn9ESgWc2IqV4nm7k0ayO7G0MWLv9PXHzPf9SQamGrJztnBfwd+ l2CfN3pCWwmMs8ObvegNjL3NBY9CMszyK3rOavbA4oTXh0JNc0ixnlMHonsV1Kr3nlzcxv6JoAE6E aHUYcnNGSSobTb4Dwca009wjmjvgJBN1H1GuTNF8VPRByg6t8Nrncrx4RYZzS/LmujGh9AouZ8X2Q qr3Tx42wJF5qBlsStOJD5D5ZwsvQD0IJmZT45H0XK9uNpLKw4ayRDLMNvwq6YlZSRyGUHMzlU+Npy 1LUZS56g==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5AoJ-0000Ie-4i; Thu, 28 Jan 2021 17:10:23 +0000 Received: from mail-wm1-x331.google.com ([2a00:1450:4864:20::331]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5Ank-00009B-Vk for linux-arm-kernel@lists.infradead.org; Thu, 28 Jan 2021 17:09:55 +0000 Received: by mail-wm1-x331.google.com with SMTP id m2so4920391wmm.1 for ; Thu, 28 Jan 2021 09:09:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=s+5ZOcVrkMkSDksPoofX2PKXc6/0xVmgqp42EKYccvM=; b=F5y20DXl129ee2eQSw/9seNHN8aCXuQmIKBxTzW9tg07g7vDWHQuTKd5OAELmL9SQ5 gOi46HrADo4Np9X0LoIVBD5X33F7im0SPICNfDmM8LP3HLtmBBY/Ah3Bc6m7Mek2x6dK iVujCu2P22pDGHCoY2daFtkjoN4lOmQqxdM7FLMmju9BcuC0yd1EElh6IIGwkXqpgEWd p5+a0oGyff1pP2PmK5x9kCuTf94kd0Fk3jHUwUhp9LRABKf0RZDTcRAO+zzRUrYL7v7f be5/t/5ChEsZ61wjy8pKE8NQuXlwo6yTinRw5pAYyQ/xOrF3X0sDiz1PjREZ+0Ygvg/K WwdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=s+5ZOcVrkMkSDksPoofX2PKXc6/0xVmgqp42EKYccvM=; b=YR/a8A9/AMsUFX/O4DdObcsJsMVIln2ZbSXeOjLhYYLoicZeCxEYxYP09rIMCyZ4/Z swTK5C/5w+ZkiceN6sQ+fbn/vQV5rXB/2EMDPjPtekw9LYUVSD6wcBe1MpZ4ak1KBlpm X/OsOoVIMAkuiw/mJCRhFDlMsKHWGBhTCTOtBWncEcQWgnbifAYcrERyVRXj+gMxeech 3I2QXaLtdS6cgNN64i2trIWXHvukIj9LwLA36ejVyRqmwkUF2PGFfGvyCDyHJkVgkvFS XsXsUdzolAICAGl8MVz/ieHbn4OeORQHgfNmDLLmvwLtFMKEmjclL3bhcfPWnNgas4Wd uNzg== X-Gm-Message-State: AOAM532YOFE+9lQXfmCrk7jCDFwLX/vEAUjK17mSjYmhygcf+JhhjpC8 4I0oIqz7jYaB86ykrzV2dSjVZ2Lf5ejt7Q== X-Google-Smtp-Source: ABdhPJy2gfw2+pkkOOpwbCvQI6X4ajD5WkEe0lzZ6K6tNH0R/AQzszlGjHicUAqklPPfjLZZo7dmbg== X-Received: by 2002:a1c:3d56:: with SMTP id k83mr215079wma.25.1611853788018; Thu, 28 Jan 2021 09:09:48 -0800 (PST) Received: from linaro.org ([2a00:23c5:6801:1801:40:2fca:953a:e6ba]) by smtp.gmail.com with ESMTPSA id p15sm7622355wrt.15.2021.01.28.09.09.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Jan 2021 09:09:47 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, mathieu.poirier@linaro.org, linux-doc@vger.kernel.org, suzuki.poulose@arm.com Subject: [PATCH v4 03/10] coresight: config: Add configuration and feature generic functions Date: Thu, 28 Jan 2021 17:09:29 +0000 Message-Id: <20210128170936.9222-4-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210128170936.9222-1-mike.leach@linaro.org> References: <20210128170936.9222-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210128_120949_181725_35CF3B33 X-CRM114-Status: GOOD ( 31.03 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: gregkh@linuxfoundation.org, alexander.shishkin@linux.intel.com, yabinc@google.com, corbet@lwn.net, linux-kernel@vger.kernel.org, tingwei@codeaurora.org, leo.yan@linaro.org, Mike Leach MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Adds a set of generic support functions that allow devices to set and save features values on the device, and enable and disable configurations. Additional functions for other common operations including feature reset. Signed-off-by: Mike Leach --- drivers/hwtracing/coresight/Makefile | 2 +- .../hwtracing/coresight/coresight-config.c | 245 ++++++++++++++++++ .../hwtracing/coresight/coresight-config.h | 14 +- .../hwtracing/coresight/coresight-syscfg.c | 5 +- 4 files changed, 262 insertions(+), 4 deletions(-) create mode 100644 drivers/hwtracing/coresight/coresight-config.c diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile index 4ce854c434b1..daad9f103a78 100644 --- a/drivers/hwtracing/coresight/Makefile +++ b/drivers/hwtracing/coresight/Makefile @@ -4,7 +4,7 @@ # obj-$(CONFIG_CORESIGHT) += coresight.o coresight-y := coresight-core.o coresight-etm-perf.o coresight-platform.o \ - coresight-sysfs.o coresight-syscfg.o + coresight-sysfs.o coresight-syscfg.o coresight-config.o obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \ coresight-tmc-etr.o diff --git a/drivers/hwtracing/coresight/coresight-config.c b/drivers/hwtracing/coresight/coresight-config.c new file mode 100644 index 000000000000..6cc4b213d9b6 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-config.c @@ -0,0 +1,245 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright(C) 2020 Linaro Limited. All rights reserved. + * Author: Mike Leach + */ + +#include +#include "coresight-config.h" +#include "coresight-priv.h" + +/* + * Write the value held in the register structure into the driver internal memory + * location. + */ +static void cscfg_set_reg(struct cscfg_reg_csdev *reg) +{ + u32 *p_val32 = (u32 *)reg->drv_store; + u32 tmp32 = reg->value.val32; + + if (reg->value.type & CS_CFG_REG_TYPE_VAL_64BIT) { + *((u64 *)reg->drv_store) = reg->value.val64; + return; + } + + if (reg->value.type & CS_CFG_REG_TYPE_VAL_MASK) { + tmp32 = *p_val32; + tmp32 &= ~reg->value.mask32; + tmp32 |= reg->value.val32 & reg->value.mask32; + } + *p_val32 = tmp32; +} + +/* + * Read the driver value into the reg if this is marked as one we want to save. + */ +static void cscfg_save_reg(struct cscfg_reg_csdev *reg) +{ + if (!(reg->value.type & CS_CFG_REG_TYPE_VAL_SAVE)) + return; + if (reg->value.type & CS_CFG_REG_TYPE_VAL_64BIT) + reg->value.val64 = *(u64 *)(reg->drv_store); + else + reg->value.val32 = *(u32 *)(reg->drv_store); +} + +static void cscfg_init_reg_param(struct cscfg_parameter_csdev *param_csdev, + struct cscfg_reg_csdev *reg_csdev) +{ + param_csdev->reg = reg_csdev; + param_csdev->val64 = reg_csdev->value.type & CS_CFG_REG_TYPE_VAL_64BIT; + + if (param_csdev->val64) + param_csdev->reg->value.val64 = param_csdev->current_value; + else + param_csdev->reg->value.val32 = (u32)param_csdev->current_value; +} + +/* set values into the driver locations referenced in cscfg_reg_csdev */ +static int cscfg_set_on_enable(struct cscfg_feature_csdev *feat) +{ + int i; + + spin_lock(feat->csdev_spinlock); + for (i = 0; i < feat->nr_regs; i++) + cscfg_set_reg(&feat->regs[i]); + spin_unlock(feat->csdev_spinlock); + dev_dbg(&feat->csdev->dev, "Feature %s: %s", feat->desc->name, "set on enable"); + return 0; +} + +/* copy back values from the driver locations referenced in cscfg_reg_csdev */ +static void cscfg_save_on_disable(struct cscfg_feature_csdev *feat) +{ + int i; + + spin_lock(feat->csdev_spinlock); + for (i = 0; i < feat->nr_regs; i++) + cscfg_save_reg(&feat->regs[i]); + spin_unlock(feat->csdev_spinlock); + dev_dbg(&feat->csdev->dev, "Feature %s: %s", feat->desc->name, "save on disable"); +} + +/* default reset - restore default values */ +void cscfg_reset_feat(struct cscfg_feature_csdev *feat) +{ + struct cscfg_parameter_csdev *param_csdev; + struct cscfg_regval_desc *reg_desc; + struct cscfg_reg_csdev *reg_csdev; + int i; + + /* + * 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]; + reg_csdev = &feat->regs[i]; + reg_csdev->value.type = reg_desc->type; + + /* check if reg set from a parameter otherwise desc default */ + if (reg_desc->type & CS_CFG_REG_TYPE_VAL_PARAM) { + /* for param, reg_desc->val32 is an index */ + param_csdev = &feat->params[reg_desc->val32]; + cscfg_init_reg_param(param_csdev, reg_csdev); + } else + reg_csdev->value.val64 = reg_desc->val64; + } +} + +static int cscfg_update_presets(struct cscfg_config_csdev *cfg, int preset) +{ + int i, j, line_offset = 0, val_idx = 0, max_idx; + struct cscfg_parameter_csdev *param; + struct cscfg_feature_csdev *feat; + const char *name; + u64 val; + + if (preset > cfg->desc->nr_presets) + return -EINVAL; + /* + * Go through the array of features, assigning preset values to + * feature parameters in the order they appear. + * There should be precisely the same number of preset values as the + * sum of number of parameters over all the features - but we will + * ensure there is no overrun. + */ + line_offset = (preset-1) * cfg->desc->nr_total_params; + max_idx = cfg->desc->nr_total_params; + for (i = 0; i < cfg->nr_feat; i++) { + feat = cfg->feats[i]; + if (!feat->nr_params) + continue; + + for (j = 0; j < feat->nr_params; j++) { + param = &feat->params[j]; + name = feat->desc->params[j].name; + val = cfg->desc->presets[line_offset + val_idx++]; + if (param->val64) { + dev_dbg(&cfg->csdev->dev, + "set param %s (%lld)", name, val); + param->reg->value.val64 = val; + } else { + param->reg->value.val32 = (u32)val; + dev_dbg(&cfg->csdev->dev, + "set param %s (%d)", name, (u32)val); + } + if (val_idx >= max_idx) + break; + } + + /* don't overrun the preset array line */ + if (val_idx >= max_idx) + break; + } + return 0; +} + +/* + * if we are not using a preset, then need to update the feature params + * with current values. + */ +static int cscfg_update_curr_params(struct cscfg_config_csdev *cfg) +{ + int i, j; + struct cscfg_feature_csdev *feat; + struct cscfg_parameter_csdev *param; + const char *name; + u64 val; + + for (i = 0; i < cfg->nr_feat; i++) { + feat = cfg->feats[i]; + if (!feat->nr_params) + continue; + for (j = 0; j < feat->nr_params; j++) { + param = &feat->params[j]; + name = feat->desc->params[j].name; + val = param->current_value; + if (param->val64) { + dev_dbg(&cfg->csdev->dev, + "set param %s (%lld)", name, val); + param->reg->value.val64 = val; + } else { + param->reg->value.val32 = (u32)val; + dev_dbg(&cfg->csdev->dev, + "set param %s (%d)", name, (u32)val); + } + } + } + return 0; +} + +static int cscfg_prog_config(struct cscfg_config_csdev *cfg, bool enable) +{ + int i, err = 0; + struct cscfg_feature_csdev *feat; + struct coresight_device *csdev; + + for (i = 0; i < cfg->nr_feat; i++) { + feat = cfg->feats[i]; + csdev = feat->csdev; + dev_dbg(&csdev->dev, "cfg %s; %s feature:%s", cfg->desc->name, + enable ? "enable" : "disable", feat->desc->name); + + if (enable) + err = cscfg_set_on_enable(feat); + else + cscfg_save_on_disable(feat); + + if (err) + break; + } + return err; +} + +/** + * Enable configuration for the device. + * + * @cfg: config_csdev to set. + * @preset: preset values to use - 0 for default. + */ +int cscfg_csdev_enable_config(struct cscfg_config_csdev *cfg, int preset) +{ + int err = 0; + + if (preset) + err = cscfg_update_presets(cfg, preset); + else + err = cscfg_update_curr_params(cfg); + if (!err) + err = cscfg_prog_config(cfg, true); + if (!err) + cfg->enabled = true; + return err; +} + +void cscfg_csdev_disable_config(struct cscfg_config_csdev *cfg) +{ + if (cfg->enabled) { + cscfg_prog_config(cfg, false); + cfg->enabled = false; + } +} diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h index 75ecdecf7013..9d66e0071f38 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -53,7 +53,10 @@ struct cscfg_parameter_desc { }; /** - * Representation of register 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. @@ -262,4 +265,13 @@ struct cscfg_csdev_feat_ops { struct cscfg_feature_csdev *feat); }; +/* coresight config helper functions*/ + +/* enable / disable config on a device - called with appropriate locks set.*/ +int cscfg_csdev_enable_config(struct cscfg_config_csdev *cfg, int preset); +void cscfg_csdev_disable_config(struct cscfg_config_csdev *cfg); + +/* reset a feature to default values */ +void cscfg_reset_feat(struct cscfg_feature_csdev *feat); + #endif /* _CORESIGHT_CORESIGHT_CONFIG_H */ diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index c04cea0c1db2..4b8e4e35e3e7 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -198,14 +198,15 @@ static int cscfg_load_feat_csdev(struct coresight_device *csdev, if (!feat_csdev) return -ENOMEM; - /* load the feature into the device - may modify default ops*/ + /* load the feature into the device */ err = ops->load_feat(csdev, feat_csdev); if (err) return err; - /* add to internal csdev feature list */ + /* add to internal csdev feature list & initialise using reset call */ mutex_lock(&cscfg_csdev_mutex); list_add(&feat_csdev->node, &csdev->feature_csdev_list); + cscfg_reset_feat(feat_csdev); mutex_unlock(&cscfg_csdev_mutex); return 0; From patchwork Thu Jan 28 17:09:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12054217 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 34C4EC433E6 for ; Thu, 28 Jan 2021 17:11:58 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B80B964DA1 for ; Thu, 28 Jan 2021 17:11:57 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B80B964DA1 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=RaXi4nENi5awiRr07bnKwGLX+hQBQilFa+f2G9WE8t0=; b=uxE/eGM8A5p1uhcXS59XB3qofp CDWFl2j/x4CnwMG2+GmJ6tyXjvS+KF1gLuzveNeFPCYQix6729F0bdJNIMXaFBFiTTrjDaqpoW2Y/ G6v5TQVgrMvUq0+f7yk4wXutLnlnkJrObceaJQT91FiyIbLp8lJ8sTNJsxQe2GeNLPfdBQ7S3K7YY k07SmyxZsg2e7Xn94VRbb9BPPy5InNln+wxTMWzDEUPqOicfnP9B+xR/eVv6RzQHlMvMt02YDdv5B zPuGIaLKKTrUfXsJbk8zB36G7rmpFw+06MRDYXsAXN4KcilbBI8zb84FKYSX69DrrVBBOAzmtRNPH ZITHOhbA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5AoN-0000Ju-AW; Thu, 28 Jan 2021 17:10:27 +0000 Received: from mail-wm1-x331.google.com ([2a00:1450:4864:20::331]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5Anl-00009r-Os for linux-arm-kernel@lists.infradead.org; Thu, 28 Jan 2021 17:09:56 +0000 Received: by mail-wm1-x331.google.com with SMTP id i9so5184787wmq.1 for ; Thu, 28 Jan 2021 09:09:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=3UqDcOPos3RfyFog6UW+zpXtql+8t84NDiXfczxfeKg=; b=jRjBlriQ+CJYgP7CPPTZS5uoNI07sOKGBHjlotnAv2h1M4zMmmMLIRQWgZ+tqe/dBF 9vzqAcD8o8vFJGVDXO3UrALUhYZXcjfWQc2dPZwG+9BULpZF/TOvwYNz1Vb9lwihhBdS pUJskxNlUOJcuPZjYBHrPJCR3sBCtWvMul5+Nv0d4ykhDqvWZY5PRrOEKvwN39le1iUx J+MLwtj4DuStM8qYkZA9BiQriE32Nue/YsX4pk096tMk+1YsO/2x4/AsQybYfC3otTs1 G7x9gzKAwApw9VUNiBvT+IHhkk/TIK6hQR5GI7ZseJXLCOXzk3ubqlv80ulcIhXIGoJA m0eg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=3UqDcOPos3RfyFog6UW+zpXtql+8t84NDiXfczxfeKg=; b=GZLqOU9d7CgXur8t0GVg8jMttm/qyubOun8TvQ80FJ57jiOZ1AqwRSd6gQ6UtTY+Bu Kq009cgUB0/vdPmSYnVIdb1FXPeXcLMNMImbDe5+xwxWUeAlPLFpIx2Lo5zaDg2iqDjW ceRm8IK/WBrlP8msDkpxv5di1rul39penxX/IzcCT17UA43wvMjcOcaFNJHfvXN5QwJH KGtHwL5Q3ss6Pa6l5inKNcmcLFQZALlUFZJfsMK0WTTScwfdFhhheIRldk+5iAkpFIO6 gmBRmkvjvoGWeoZ5WvixdnPlGF2Hqof3zWyLrq1kgjIaKS5hceALnxwyYmdIgCqB0HiA 9AbQ== X-Gm-Message-State: AOAM53270jjimoDJPyPUarOT5SM1LfaMJxezO9UNAJs67EmaU6Xb4xi4 awTcJoaLowWdvg1iztHGRNin+SlZ7rlrMA== X-Google-Smtp-Source: ABdhPJwH8M2kw2DzpPtmxGhRqYuHFVbDz7fp3pV/wtovxXrcj6vFBydEdMimg+PImCFPOovhFgv29w== X-Received: by 2002:a1c:3286:: with SMTP id y128mr241008wmy.104.1611853788861; Thu, 28 Jan 2021 09:09:48 -0800 (PST) Received: from linaro.org ([2a00:23c5:6801:1801:40:2fca:953a:e6ba]) by smtp.gmail.com with ESMTPSA id p15sm7622355wrt.15.2021.01.28.09.09.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Jan 2021 09:09:48 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, mathieu.poirier@linaro.org, linux-doc@vger.kernel.org, suzuki.poulose@arm.com Subject: [PATCH v4 04/10] coresight: etm-perf: update to handle configuration selection Date: Thu, 28 Jan 2021 17:09:30 +0000 Message-Id: <20210128170936.9222-5-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210128170936.9222-1-mike.leach@linaro.org> References: <20210128170936.9222-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210128_120949_922619_B1FE3985 X-CRM114-Status: GOOD ( 30.29 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: gregkh@linuxfoundation.org, alexander.shishkin@linux.intel.com, yabinc@google.com, corbet@lwn.net, linux-kernel@vger.kernel.org, tingwei@codeaurora.org, leo.yan@linaro.org, Mike Leach MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Loaded coresight configurations are registered in the cs_etm\cs_config sub directory. This extends the etm-perf code to handle these registrations, and the cs_syscfg driver to perform the registration on load. Signed-off-by: Mike Leach --- .../hwtracing/coresight/coresight-config.h | 5 +- .../hwtracing/coresight/coresight-etm-perf.c | 164 +++++++++++++++--- .../hwtracing/coresight/coresight-etm-perf.h | 8 + .../hwtracing/coresight/coresight-syscfg.c | 13 +- 4 files changed, 166 insertions(+), 24 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h index 9d66e0071f38..98380b496046 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -154,7 +154,8 @@ struct cscfg_config_feat_ref { * @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. - * + * @id_ea: Extended attribute for perf configid value + * @event_ea: Extended attribute for perf event value */ struct cscfg_config_desc { const char *name; @@ -165,6 +166,8 @@ struct cscfg_config_desc { int nr_presets; int nr_total_params; const u64 *presets; /* nr_presets * nr_total_params */ + struct dev_ext_attribute *id_ea; + struct dev_ext_attribute *event_ea; }; /** diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index a608081bd446..e270bb1e0f7d 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -18,8 +18,10 @@ #include #include +#include "coresight-config.h" #include "coresight-etm-perf.h" #include "coresight-priv.h" +#include "coresight-syscfg.h" static struct pmu etm_pmu; static bool etm_perf_up; @@ -32,8 +34,13 @@ PMU_FORMAT_ATTR(cycacc, "config:" __stringify(ETM_OPT_CYCACC)); PMU_FORMAT_ATTR(contextid, "config:" __stringify(ETM_OPT_CTXTID)); PMU_FORMAT_ATTR(timestamp, "config:" __stringify(ETM_OPT_TS)); PMU_FORMAT_ATTR(retstack, "config:" __stringify(ETM_OPT_RETSTK)); +/* preset - if sink ID is used as a configuration selector */ +PMU_FORMAT_ATTR(preset, "config:0-3"); /* Sink ID - same for all ETMs */ PMU_FORMAT_ATTR(sinkid, "config2:0-31"); +/* config ID - set if a system configuration is selected */ +PMU_FORMAT_ATTR(configid, "config2:32-63"); + static struct attribute *etm_config_formats_attr[] = { &format_attr_cycacc.attr, @@ -41,6 +48,8 @@ static struct attribute *etm_config_formats_attr[] = { &format_attr_timestamp.attr, &format_attr_retstack.attr, &format_attr_sinkid.attr, + &format_attr_preset.attr, + &format_attr_configid.attr, NULL, }; @@ -58,9 +67,29 @@ static const struct attribute_group etm_pmu_sinks_group = { .attrs = etm_config_sinks_attr, }; +static struct attribute *etm_config_cscfg_attr[] = { + NULL, +}; + +static const struct attribute_group etm_pmu_cscfg_group = { + .name = "configurations", + .attrs = etm_config_cscfg_attr, +}; + +static struct attribute *etm_config_events_attr[] = { + NULL, +}; + +static const struct attribute_group etm_pmu_events_group = { + .name = "events", + .attrs = etm_config_events_attr, +}; + static const struct attribute_group *etm_pmu_attr_groups[] = { &etm_pmu_format_group, &etm_pmu_sinks_group, + &etm_pmu_cscfg_group, + &etm_pmu_events_group, NULL, }; @@ -219,7 +248,7 @@ static void *etm_setup_aux(struct perf_event *event, void **pages, INIT_WORK(&event_data->work, free_event_data); /* First get the selected sink from user space. */ - if (event->attr.config2) { + if (event->attr.config2 & GENMASK_ULL(31, 0)) { id = (u32)event->attr.config2; sink = coresight_get_sink_by_id(id); } @@ -537,21 +566,17 @@ static ssize_t etm_perf_sink_name_show(struct device *dev, return scnprintf(buf, PAGE_SIZE, "0x%lx\n", (unsigned long)(ea->var)); } -int etm_perf_add_symlink_sink(struct coresight_device *csdev) +int etm_perf_add_symlink_group(struct device *dev, + struct dev_ext_attribute **ext_attr, + const char *name, + const char *group_name) { - int ret; + struct dev_ext_attribute *ea; unsigned long hash; - const char *name; + int ret; struct device *pmu_dev = etm_pmu.dev; - struct device *dev = &csdev->dev; - struct dev_ext_attribute *ea; - if (csdev->type != CORESIGHT_DEV_TYPE_SINK && - csdev->type != CORESIGHT_DEV_TYPE_LINKSINK) - return -EINVAL; - - if (csdev->ea != NULL) - return -EINVAL; + *ext_attr = NULL; if (!etm_perf_up) return -EPROBE_DEFER; @@ -560,7 +585,6 @@ int etm_perf_add_symlink_sink(struct coresight_device *csdev) if (!ea) return -ENOMEM; - name = dev_name(dev); /* See function coresight_get_sink_by_id() to know where this is used */ hash = hashlen_hash(hashlen_string(NULL, name)); @@ -574,31 +598,127 @@ int etm_perf_add_symlink_sink(struct coresight_device *csdev) ea->var = (unsigned long *)hash; ret = sysfs_add_file_to_group(&pmu_dev->kobj, - &ea->attr.attr, "sinks"); - + &ea->attr.attr, group_name); if (!ret) - csdev->ea = ea; - + *ext_attr = ea; return ret; } -void etm_perf_del_symlink_sink(struct coresight_device *csdev) +int etm_perf_add_symlink_sink(struct coresight_device *csdev) +{ + const char *name; + struct device *dev = &csdev->dev; + + if (csdev->type != CORESIGHT_DEV_TYPE_SINK && + csdev->type != CORESIGHT_DEV_TYPE_LINKSINK) + return -EINVAL; + + if (csdev->ea != NULL) + return -EINVAL; + + name = dev_name(dev); + return etm_perf_add_symlink_group(dev, &csdev->ea, name, "sinks"); +} + +void etm_perf_del_symlink_group(struct dev_ext_attribute *ea, const char *group_name) { struct device *pmu_dev = etm_pmu.dev; - struct dev_ext_attribute *ea = csdev->ea; + sysfs_remove_file_from_group(&pmu_dev->kobj, + &ea->attr.attr, group_name); +} + +void etm_perf_del_symlink_sink(struct coresight_device *csdev) +{ if (csdev->type != CORESIGHT_DEV_TYPE_SINK && csdev->type != CORESIGHT_DEV_TYPE_LINKSINK) return; - if (!ea) + if (!csdev->ea) return; - sysfs_remove_file_from_group(&pmu_dev->kobj, - &ea->attr.attr, "sinks"); + etm_perf_del_symlink_group(csdev->ea, "sinks"); csdev->ea = NULL; } +/* string to contain the attribute value */ +#define CSCFG_EVENT_STR_SIZE 32 + +static ssize_t etm_perf_cscfg_event_show(struct device *dev, + struct device_attribute *dattr, + char *buf) +{ + struct dev_ext_attribute *ea; + + ea = container_of(dattr, struct dev_ext_attribute, attr); + return scnprintf(buf, PAGE_SIZE, "%s\n", (const char *)(ea->var)); +} + +static int etm_perf_add_cscfg_event(struct device *dev, struct cscfg_config_desc *cs_cfg) +{ + struct dev_ext_attribute *ea; + unsigned long hash; + int ret; + struct device *pmu_dev = etm_pmu.dev; + + ea = devm_kzalloc(dev, sizeof(*ea), GFP_KERNEL); + if (!ea) + return -ENOMEM; + + hash = (unsigned long)cs_cfg->id_ea->var; + + sysfs_attr_init(&ea->attr.attr); + ea->attr.attr.name = devm_kstrdup(dev, cs_cfg->name, GFP_KERNEL); + if (!ea->attr.attr.name) + return -ENOMEM; + + /* + * attribute value is "configid=". + * this will be what perf evaluates when the config name is used + * on the command line. + */ + ea->var = devm_kzalloc(dev, CSCFG_EVENT_STR_SIZE, GFP_KERNEL); + if (!ea->var) + return -ENOMEM; + + scnprintf(ea->var, CSCFG_EVENT_STR_SIZE, "configid=0x%lx", hash); + ea->attr.attr.mode = 0444; + ea->attr.show = etm_perf_cscfg_event_show; + + ret = sysfs_add_file_to_group(&pmu_dev->kobj, + &ea->attr.attr, "events"); + if (!ret) + cs_cfg->event_ea = ea; + return ret; +} + +int etm_perf_add_symlink_cscfg(struct device *dev, struct cscfg_config_desc *cs_cfg) +{ + int err; + + if (cs_cfg->id_ea != NULL) + return 0; + + err = etm_perf_add_symlink_group(dev, &cs_cfg->id_ea, + cs_cfg->name, "configurations"); + + if (!err) + err = etm_perf_add_cscfg_event(dev, cs_cfg); + + return err; +} + +void etm_perf_del_symlink_cscfg(struct cscfg_config_desc *cs_cfg) +{ + if (!cs_cfg->id_ea) + return; + + etm_perf_del_symlink_group(cs_cfg->id_ea, "configurations"); + etm_perf_del_symlink_group(cs_cfg->event_ea, "events"); + cs_cfg->id_ea = NULL; + cs_cfg->event_ea = NULL; +} + int __init etm_perf_init(void) { int ret; diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.h b/drivers/hwtracing/coresight/coresight-etm-perf.h index 29d90dfeba31..3646a3837a0b 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.h +++ b/drivers/hwtracing/coresight/coresight-etm-perf.h @@ -11,6 +11,7 @@ #include "coresight-priv.h" struct coresight_device; +struct cscfg_config_desc; /* * In both ETMv3 and v4 the maximum number of address comparator implentable @@ -69,6 +70,9 @@ static inline void *etm_perf_sink_config(struct perf_output_handle *handle) return data->snk_config; return NULL; } +int etm_perf_add_symlink_cscfg(struct device *dev, + struct cscfg_config_desc *cscfg_desc); +void etm_perf_del_symlink_cscfg(struct cscfg_config_desc *cscfg_desc); #else static inline int etm_perf_symlink(struct coresight_device *csdev, bool link) { return -EINVAL; } @@ -79,6 +83,10 @@ static inline void *etm_perf_sink_config(struct perf_output_handle *handle) { return NULL; } +int etm_perf_add_symlink_cscfg(struct device *dev, + struct cscfg_config_desc *cscfg_desc) +{ return -EINVAL; } +void etm_perf_del_symlink_cscfg(struct cscfg_config_desc *cscfg_desc) {} #endif /* CONFIG_CORESIGHT */ diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index 4b8e4e35e3e7..a070f135eca3 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -7,6 +7,7 @@ #include #include "coresight-config.h" +#include "coresight-etm-perf.h" #include "coresight-syscfg.h" /* @@ -100,6 +101,7 @@ static int cscfg_add_csdev_cfg(struct coresight_device *csdev, dev_cfg->feats[dev_cfg->nr_feat++] = feat; } } + /* if matched features, add config to device.*/ if (dev_cfg) { mutex_lock(&cscfg_csdev_mutex); @@ -290,8 +292,12 @@ static int cscfg_load_config(struct cscfg_config_desc *cfg_desc) if (err) return err; - list_add(&cfg_desc->item, &cscfg_mgr->data.config_desc_list); + /* add config to perf fs to allow selection */ + err = etm_perf_add_symlink_cscfg(to_device_cscfg(), cfg_desc); + if (err) + return err; + list_add(&cfg_desc->item, &cscfg_mgr->data.config_desc_list); return 0; } @@ -517,7 +523,12 @@ int cscfg_create_device(void) void cscfg_clear_device(void) { + struct cscfg_config_desc *cfg_desc; + mutex_lock(&cscfg_mutex); + list_for_each_entry(cfg_desc, &cscfg_mgr->data.config_desc_list, item) { + etm_perf_del_symlink_cscfg(cfg_desc); + } device_unregister(to_device_cscfg()); mutex_unlock(&cscfg_mutex); } From patchwork Thu Jan 28 17:09:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12054209 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 39D7EC433DB for ; Thu, 28 Jan 2021 17:11:38 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BFF7564DE2 for ; Thu, 28 Jan 2021 17:11:37 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BFF7564DE2 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=FvN97a2aFN1txkt9FsN3TVzlLg3MnPxUCSprV1FiSSo=; b=hkIHVKRElVi0H6D9otVjBEJSEI jkr5bOY4AcoROvRLXpIwJmS82pl6YyMhoo9xfDgyR9dgkM5DpTcZspZUwU9pwd8E8IDSwAWD1VjvE 21DDagrTtLahE68I0CVW/VzjsimD6AiDSZmQ3JZkABwR3G32He6yqQgOlHODvzzFFnKdE+lqUo5TU QOeUnP3zKVXUlKxZYfpMyHbXNuxWyW9kbNlR2ZzFGHTIXmR3oc1aiAiSRY1oP6/t4Upm9MBn7a/SA cjy1jVcPbZ8Kzn/P/CeD/x1pZpDFknhp8x8Oxt9cPhGSQxyi3NHFJIhOIp9tSfI3d/AGqhCZPLTja kT1dhQtg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5AoF-0000Hi-NJ; Thu, 28 Jan 2021 17:10:19 +0000 Received: from mail-wm1-x332.google.com ([2a00:1450:4864:20::332]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5Anm-0000A6-Ud for linux-arm-kernel@lists.infradead.org; Thu, 28 Jan 2021 17:09:55 +0000 Received: by mail-wm1-x332.google.com with SMTP id i9so5184832wmq.1 for ; Thu, 28 Jan 2021 09:09:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=SdaolgZ8umxvWIrsixiVmJfRgd3EaOoeeUES+E2W5FI=; b=nXqcB3dFVIWb7EP9jQyfBXuH2W9JTK7GZ+z8IOom347NgmOCOcHYje8ky8Ktb46KXH CNSxdff3g0dtnkQ5sYJ85w4+fg4PP1V622rehpIgybUTzL3ZQwfvTnLh7m3K3dqQGm8B VQUMTjAFR3nEoLqkz9Y7yOq6GA3x9X/T/kiTJx5gqIJs15iTLmDCbdfalfXjfcfclAhS hfUcrX42XLxaidQU21vivj9GU/SO2ETUPD3Yc9xedCKy0sUtC3En2s/Sddd1zTB7witT FKYf6BNYLozEXJ8A3JwG3WK23xQ1jRCr0aGoccZ8z5Ohjrfcj62A5me1+G/xU/eUiJVJ 1FtA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=SdaolgZ8umxvWIrsixiVmJfRgd3EaOoeeUES+E2W5FI=; b=Kdij6ndDyZFSzC8AYDFCh+o6cYAA+8X/yh2jjhWvbR0nPfIatwE3KoP3++Ps9W3Am3 HuOG/Yt3T089KdyyM0J/+YCcw7x9zQsBB6S9D5+TT7uU+HsB2jC2625WPPTU85ZSbu8N o6GUkBQ7QMgkO3/rMvJkPf4NbwZT3XR06EQ1ATXoGKJrFHDOYqBb4k8LvD9kGYWSbPmD lgn1+QpGicchFUbG78HDygRL4njoyWFgMcZxB69TeK81I+xWuaIwJxphjZ+uAuqYC0WZ wSJYwBHjYEnAKpDFY1UA2qXe2i0vE3EfLsLdP3s/+lrrZDn6GBlIzD0TVrHnYy/9UtiO 4tjw== X-Gm-Message-State: AOAM53346gaEQdTuHNgpNYat7sWQ568Eju0SE6gTg/m7AlMSil+Ae9mj egPpMtxfxLRMDy9jigD0MNfIbZEesApUOg== X-Google-Smtp-Source: ABdhPJzxNITKdrrLRtD1snawJDsZYJfX0r4PFaTtAFPC2jLJHXSqMQJTgB1YkH2pF4U9cA4tIcTfyw== X-Received: by 2002:a1c:4b14:: with SMTP id y20mr231864wma.166.1611853789733; Thu, 28 Jan 2021 09:09:49 -0800 (PST) Received: from linaro.org ([2a00:23c5:6801:1801:40:2fca:953a:e6ba]) by smtp.gmail.com with ESMTPSA id p15sm7622355wrt.15.2021.01.28.09.09.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Jan 2021 09:09:49 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, mathieu.poirier@linaro.org, linux-doc@vger.kernel.org, suzuki.poulose@arm.com Subject: [PATCH v4 05/10] coresight: syscfg: Add API to activate and enable configurations Date: Thu, 28 Jan 2021 17:09:31 +0000 Message-Id: <20210128170936.9222-6-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210128170936.9222-1-mike.leach@linaro.org> References: <20210128170936.9222-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210128_120951_098630_7EA937F5 X-CRM114-Status: GOOD ( 25.32 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: gregkh@linuxfoundation.org, alexander.shishkin@linux.intel.com, yabinc@google.com, corbet@lwn.net, linux-kernel@vger.kernel.org, tingwei@codeaurora.org, leo.yan@linaro.org, Mike Leach MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Configurations are first activated, then when any coresight device is enabled, the active configurations are checked and any matching one is enabled. This patch provides the activation / enable API. Signed-off-by: Mike Leach --- .../hwtracing/coresight/coresight-config.h | 2 + .../hwtracing/coresight/coresight-syscfg.c | 127 ++++++++++++++++++ .../hwtracing/coresight/coresight-syscfg.h | 10 +- include/linux/coresight.h | 2 + 4 files changed, 140 insertions(+), 1 deletion(-) diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h index 98380b496046..26396b70c826 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -156,6 +156,7 @@ struct cscfg_config_feat_ref { * @presets: Array of preset values. * @id_ea: Extended attribute for perf configid value * @event_ea: Extended attribute for perf event value + * @active_cnt: ref count for activate on this configuration. */ struct cscfg_config_desc { const char *name; @@ -168,6 +169,7 @@ struct cscfg_config_desc { const u64 *presets; /* nr_presets * nr_total_params */ struct dev_ext_attribute *id_ea; struct dev_ext_attribute *event_ea; + atomic_t active_cnt; }; /** diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index a070f135eca3..d79cf5b36758 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -298,6 +298,7 @@ static int cscfg_load_config(struct cscfg_config_desc *cfg_desc) return err; list_add(&cfg_desc->item, &cscfg_mgr->data.config_desc_list); + atomic_set(&cfg_desc->active_cnt, 0); return 0; } @@ -477,6 +478,131 @@ void cscfg_unregister_csdev(struct coresight_device *csdev) } EXPORT_SYMBOL_GPL(cscfg_unregister_csdev); +void cscfg_csdev_reset_feats(struct coresight_device *csdev) +{ + struct cscfg_feature_csdev *feat; + + mutex_lock(&cscfg_csdev_mutex); + if (list_empty(&csdev->feature_csdev_list)) + goto unlock_exit; + + list_for_each_entry(feat, &csdev->feature_csdev_list, node) + cscfg_reset_feat(feat); + +unlock_exit: + mutex_unlock(&cscfg_csdev_mutex); +} +EXPORT_SYMBOL_GPL(cscfg_csdev_reset_feats); + +/** + * Mark a config descriptor as active. + * This will be seen when csdev devices are activated in the system. + * + * Selection by hash value - generated from the configuration name when it + * was loaded and added to the cs_etm/configurations file system for selection + * by perf. + * + * @cfg_hash: Hash value of the selected configuration name. + */ +int cscfg_activate_config(unsigned long cfg_hash) +{ + struct cscfg_config_desc *curr_item, *match_item = 0; + + mutex_lock(&cscfg_mutex); + + list_for_each_entry(curr_item, &cscfg_mgr->data.config_desc_list, item) { + if ((unsigned long)curr_item->id_ea->var == cfg_hash) { + match_item = curr_item; + atomic_inc(&cscfg_mgr->data.sys_active_cnt); + break; + } + } + mutex_unlock(&cscfg_mutex); + + if (!match_item) + return -EINVAL; + + dev_dbg(to_device_cscfg(), "Activate config %s.\n", match_item->name); + + /* mark the descriptors as active so enable config will use them */ + mutex_lock(&cscfg_csdev_mutex); + atomic_inc(&match_item->active_cnt); + mutex_unlock(&cscfg_csdev_mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(cscfg_activate_config); + +void cscfg_deactivate_config(unsigned long cfg_hash) +{ + struct cscfg_config_desc *curr_item, *match_item = 0; + + mutex_lock(&cscfg_mutex); + + list_for_each_entry(curr_item, &cscfg_mgr->data.config_desc_list, item) { + if ((unsigned long)curr_item->id_ea->var == cfg_hash) { + match_item = curr_item; + break; + } + } + mutex_unlock(&cscfg_mutex); + if (!match_item) + return; + + dev_dbg(to_device_cscfg(), "Deactivate config %s.\n", match_item->name); + + mutex_lock(&cscfg_csdev_mutex); + atomic_dec(&match_item->active_cnt); + mutex_unlock(&cscfg_csdev_mutex); + + atomic_dec(&cscfg_mgr->data.sys_active_cnt); +} +EXPORT_SYMBOL_GPL(cscfg_deactivate_config); + +/* Find and program any active config for the supplied device.*/ +int cscfg_csdev_enable_active_config(struct coresight_device *csdev, + unsigned long id_hash, int preset) +{ + struct cscfg_config_csdev *cfg = NULL, *item; + const struct cscfg_config_desc *desc; + int err = 0; + + /* quickly check global count */ + if (!atomic_read(&cscfg_mgr->data.sys_active_cnt)) + return 0; + + mutex_lock(&cscfg_csdev_mutex); + list_for_each_entry(item, &csdev->config_csdev_list, node) { + desc = item->desc; + if ((atomic_read(&desc->active_cnt)) && + ((unsigned long)desc->id_ea->var == id_hash)) { + cfg = item; + break; + } + } + if (cfg) { + err = cscfg_csdev_enable_config(cfg, preset); + if (!err) + csdev->active_cfg_ctxt = (void *)cfg; + } + mutex_unlock(&cscfg_csdev_mutex); + return err; +} +EXPORT_SYMBOL_GPL(cscfg_csdev_enable_active_config); + +/* save and disable the active config for the device */ +void cscfg_csdev_disable_active_config(struct coresight_device *csdev) +{ + struct cscfg_config_csdev *cfg; + + mutex_lock(&cscfg_csdev_mutex); + cfg = (struct cscfg_config_csdev *)csdev->active_cfg_ctxt; + if (cfg) + cscfg_csdev_disable_config(cfg); + mutex_unlock(&cscfg_csdev_mutex); +} +EXPORT_SYMBOL_GPL(cscfg_csdev_disable_active_config); + /* Initialise system configuration management device. */ struct device *to_device_cscfg(void) @@ -546,6 +672,7 @@ int __init cscfg_init(void) INIT_LIST_HEAD(&cscfg_mgr->data.feat_desc_list); INIT_LIST_HEAD(&cscfg_mgr->data.config_desc_list); cscfg_mgr->data.nr_csdev = 0; + atomic_set(&cscfg_mgr->data.sys_active_cnt, 0); dev_info(to_device_cscfg(), "CoreSight Configuration manager initialised"); return 0; diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h index ebf5e1491d86..301e26e1e98f 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.h +++ b/drivers/hwtracing/coresight/coresight-syscfg.h @@ -17,13 +17,15 @@ * @csdev_list: List of coresight devices registered with the configuration manager. * @feat_desc_list: List of feature descriptors to load into registered devices. * @config_desc_list: List of system configuration descriptors to load into registered devices. - * @nr_csdev: Number of registered devices with the cscfg system + * @nr_csdev: Number of registered devices with the cscfg system + * @sys_active_cnt: Total number of active config descriptor references. */ struct cscfg_api_data { struct list_head csdev_desc_list; struct list_head feat_desc_list; struct list_head config_desc_list; int nr_csdev; + atomic_t sys_active_cnt; }; /** @@ -53,6 +55,12 @@ int cscfg_register_csdev(struct coresight_device *csdev, struct cscfg_match_desc *info, struct cscfg_csdev_feat_ops *ops); void cscfg_unregister_csdev(struct coresight_device *csdev); +int cscfg_activate_config(unsigned long cfg_hash); +void cscfg_deactivate_config(unsigned long cfg_hash); +void cscfg_csdev_reset_feats(struct coresight_device *csdev); +int cscfg_csdev_enable_active_config(struct coresight_device *csdev, + unsigned long id_hash, int preset); +void cscfg_csdev_disable_active_config(struct coresight_device *csdev); /** * System configuration manager device. diff --git a/include/linux/coresight.h b/include/linux/coresight.h index d0126ed326a6..3941854e8280 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -221,6 +221,7 @@ struct coresight_sysfs_link { * @has_conns_grp: Have added a "connections" group for sysfs links. * @feature_csdev_list: List of complex feature programming added to the device. * @config_csdev_list: List of system configurations added to the device. + * @active_cfg_ctxt: Context information for current active congfig. */ struct coresight_device { struct coresight_platform_data *pdata; @@ -245,6 +246,7 @@ struct coresight_device { /* system configuration and feature lists */ struct list_head feature_csdev_list; struct list_head config_csdev_list; + void *active_cfg_ctxt; }; /* From patchwork Thu Jan 28 17:09:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12054207 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 706D4C433E0 for ; Thu, 28 Jan 2021 17:11:35 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 17C4F64DE2 for ; Thu, 28 Jan 2021 17:11:35 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 17C4F64DE2 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=MBPU0BkoYpTJzEZohpwvClfNShD/fAWIutSo3Aw/CEI=; b=CCDt7aPO7un1R1YjxSUj1TfYMi GfPV3S8UiHRlYjpOUSHYmFuLvMB1W0XA3Yay7eNw6/MCll3vA4HRxBTfvgCUKqybIo9kxXjp0V1X9 rgOXvJ3a30otcQWQ90JQB2cY0nvhMhFhUWugB32vEJbrqozrdKgZTnvG3dnUlklMI5IiYyPDKJNjO 7aoAljR7eouJ3apw4411iNO49FrGwoAUNud/+2vdJoBnVu22rGRejmnzWOZXk5tzgo+7eF9ifKH+9 6AKu8BIvOY/CNUg/YsIq1ZT4hR81tv5XX0GCBXfmxkjcr1WFM4TD4eM+T962oFyA/ayd14o43IRa9 6BCR8dXw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5Ao3-0000EY-GJ; Thu, 28 Jan 2021 17:10:07 +0000 Received: from mail-wr1-x42c.google.com ([2a00:1450:4864:20::42c]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5Ann-0000A9-EQ for linux-arm-kernel@lists.infradead.org; Thu, 28 Jan 2021 17:09:55 +0000 Received: by mail-wr1-x42c.google.com with SMTP id v15so6183639wrx.4 for ; Thu, 28 Jan 2021 09:09:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=c+TM9hQ1DCJj1Sx/zagtZCNZZA06suw1HBUOznUqWnA=; b=xeH6+PqnSwdFzNGKTcQbFpzFKsvKrtJYhBbpBUoGwEoVk9Nu187EGduv0Val+EEydR FTbhLt+r55QSSFP3sBPaEooIRS66ZFU3ZCSi+KaKx3xQwNmZCAf/xOr9QPisBl+t7o51 ajxUggYGA/m+CcHHYfkbp8lljAGJXjNLOinVWRb5Lz5rQNxIYO/hrSIF9Y+X/AUQJoa5 sFVADuSotuGNMT3AAogpXpHEzT6Hi7kKIuymUyoYFUVWAZDmWIGvm8PXzyngPvw9+CbK JoshzZyyQjDgT83RoUhiFCEK0Jn0Cwoio2nRKezetqEaFBKDAC0ToGSZkdT7viGMeou7 WICg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=c+TM9hQ1DCJj1Sx/zagtZCNZZA06suw1HBUOznUqWnA=; b=oZbFpx4/YCurTMrakXJxJlZHS7AuQAxr9rhSuPVWBiF4HOs9e/QEg8Esii3/8S8fWC ZM/QCiRRCcstIvAn4YvBeGJG98B+e/rda566rDFV0cQZGhan1tMLIdLfHzwNWpE29xLn 0EseTliSMlA+ho3g5CYxTcm2eiGSys0B4oTPgMJcRjkbWANKwJ264uzfuH/NNzIqHk+e yoQGQbj3EfOMkS/FP5irpGfUBbJGqntO1Boa7WtOJ5QlIxl82ItkQsWNEUrofiaT9kVV kFXQe73RQ6NOXC4NvpzM6iYtbmBS1ebIK5IsNy5wXCgrQApdCVQmANH/wJmOe1Q9EATw WmIw== X-Gm-Message-State: AOAM530Ywk9nQ4uLYIj7qAxtnCNsFJVCDAXLoiSWLB0EmZvzXyQYcm4b BBNQEnwFdRfv/vKrMaukeJ+CXagRtuymCA== X-Google-Smtp-Source: ABdhPJx+v2AUO/iuiXfbbphnaUYMs9oQHxAlDN6mlYMQjMSSZnB+sJvQovAD9V+CE3S69fwEl2l9IQ== X-Received: by 2002:adf:e48b:: with SMTP id i11mr32322wrm.406.1611853790592; Thu, 28 Jan 2021 09:09:50 -0800 (PST) Received: from linaro.org ([2a00:23c5:6801:1801:40:2fca:953a:e6ba]) by smtp.gmail.com with ESMTPSA id p15sm7622355wrt.15.2021.01.28.09.09.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Jan 2021 09:09:50 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, mathieu.poirier@linaro.org, linux-doc@vger.kernel.org, suzuki.poulose@arm.com Subject: [PATCH v4 06/10] coresight: etm-perf: Update to activate selected configuration Date: Thu, 28 Jan 2021 17:09:32 +0000 Message-Id: <20210128170936.9222-7-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210128170936.9222-1-mike.leach@linaro.org> References: <20210128170936.9222-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210128_120951_634409_7B25FD22 X-CRM114-Status: GOOD ( 17.30 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: gregkh@linuxfoundation.org, alexander.shishkin@linux.intel.com, yabinc@google.com, corbet@lwn.net, linux-kernel@vger.kernel.org, tingwei@codeaurora.org, leo.yan@linaro.org, Mike Leach MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add calls to activate the selected configuration as perf starts and stops the tracing session. Signed-off-by: Mike Leach Reviewed-by: Suzuki K Poulose --- drivers/hwtracing/coresight/coresight-etm-perf.c | 14 +++++++++++++- drivers/hwtracing/coresight/coresight-etm-perf.h | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index e270bb1e0f7d..5c1aeddabc59 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -178,6 +178,10 @@ static void free_event_data(struct work_struct *work) /* Free the sink buffers, if there are any */ free_sink_buffer(event_data); + /* clear any configuration we were using */ + if (event_data->config_id_hash) + cscfg_deactivate_config(event_data->config_id_hash); + for_each_cpu(cpu, mask) { struct list_head **ppath; @@ -236,7 +240,7 @@ static void etm_free_aux(void *data) static void *etm_setup_aux(struct perf_event *event, void **pages, int nr_pages, bool overwrite) { - u32 id; + u32 id, config_id; int cpu = event->cpu; cpumask_t *mask; struct coresight_device *sink = NULL; @@ -253,6 +257,14 @@ static void *etm_setup_aux(struct perf_event *event, void **pages, sink = coresight_get_sink_by_id(id); } + /* check if user wants a coresight configuration selected */ + config_id = (u32)((event->attr.config2 & GENMASK_ULL(63, 32)) >> 32); + if (config_id) { + if (cscfg_activate_config(config_id)) + goto err; + event_data->config_id_hash = config_id; + } + mask = &event_data->mask; /* diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.h b/drivers/hwtracing/coresight/coresight-etm-perf.h index 3646a3837a0b..751d768939d8 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.h +++ b/drivers/hwtracing/coresight/coresight-etm-perf.h @@ -49,12 +49,14 @@ struct etm_filters { * @work: Handle to free allocated memory outside IRQ context. * @mask: Hold the CPU(s) this event was set for. * @snk_config: The sink configuration. + * @config_id_hash: The id of any coresight config selected. * @path: An array of path, each slot for one CPU. */ struct etm_event_data { struct work_struct work; cpumask_t mask; void *snk_config; + u32 config_id_hash; struct list_head * __percpu *path; }; From patchwork Thu Jan 28 17:09:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12054221 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6D61CC433DB for ; Thu, 28 Jan 2021 17:12:17 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0A87B64DA1 for ; Thu, 28 Jan 2021 17:12:16 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0A87B64DA1 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=pRFuUnUWiS8SbTpkRU4AuzlPfr3HG7WsOutn6Eu325w=; b=pRgngLwHcX76jR5i4Ix6QyGMbg kuWx/4NLtdOTGAlJW/KKQtEd4IJMhNP9K1+EDDWfM7oqgNDZldDxeEAjiDW5vCGUyjssJEcJCwlFi 91v8mFKlcwfsIiWncvuVgvD+mgmqoWFMd+weAXRI9wKNvNKOnO+uVVQkcfzHc/yu1LeRMU7ZtR4v8 eHTLI0scxokXBmKhq36nuSGQk4i4JiD7QGD5IEskWbOCX8bCaE4R2GxNoUmAijASwWGaJ9QqhA3Ro gsh8s1LZn/nw2DjrqAb0kmO7qG9Yee91dK2iLv0zvIZztc0PyQt7fFnVCFLoP+OqScTwx7zyPqrKA YNcWhElg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5AoS-0000MS-M5; Thu, 28 Jan 2021 17:10:32 +0000 Received: from mail-wm1-x333.google.com ([2a00:1450:4864:20::333]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5Ano-0000Ao-Sn for linux-arm-kernel@lists.infradead.org; Thu, 28 Jan 2021 17:09:57 +0000 Received: by mail-wm1-x333.google.com with SMTP id f16so4902589wmq.5 for ; Thu, 28 Jan 2021 09:09:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Q2UrR2obkBgpQyxeiFds34/sCZgXQe+6pIjLe0B9bGI=; b=i1Hds/vq8xjdyoGChM1YhMD31kBjaX3+kezn1NQa6u96TfFV/XBAiLu9d7c42o7F2w 2c+5qb/GwRvaDWaNszRm2h/qbyCnVUOgzx2j3dQokW7ZBozxgPsa/dqWkxqUsjCY7R+N K9DNk1Vvnr5Rqei4SUwrPFxjppJQvX2YFfnYyqq7Kj9gZuwqco4LZh05j2P51USYntQ2 z0S2FU4TmrH77WHgCxSEFLsvTEcIBXbA6334xPo6PRK5EGLYDw4eBxWjwG97bctalruq foLIdark9Kg7rWHimx56zn20oEN769FZ6c/sT9TsgyYOxzAVyODRDsqqcHyJnrt7K6cF gRIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Q2UrR2obkBgpQyxeiFds34/sCZgXQe+6pIjLe0B9bGI=; b=nPmB6cf26u5qnZG6a4V6EqAs5JPLFKmIX3BlwdQiskEtaXzs/+zwIzsmxCzrHA2dLE +3HZxCDEUosQaHSaLNpeVv41McbQrjYTJwAD1cX/85CSaIIh8YZAVdyq74jTuNqUDd31 mehjibBUnAWIqketm+vvJ5EuaD5sDZriE1zGlcs2Z/osYBicjYQNG2yInSTJZ+iA979b UpPBv2jnBkNgOW9mao2OdXBjglb5Ew1789fmmhwVsy/saBdwJZ+k0Du28OaZUyxqINJ/ TnbGRB5+sC/xHFkUzffAyPEH7AeAfVTMY+tx4ivhgOVoQAfCmb7+Myu5SQpNFpMcWS/+ MMjg== X-Gm-Message-State: AOAM5333nxlYW9lrwfs5VjhRDiUkQd1SirWAfBy3590QPdtk93rz66Uz 78ZR1nn9rTKfRBI88eNI0v7CR9jM5g03GA== X-Google-Smtp-Source: ABdhPJxqqzSWclc2c1bgRtpvhdR6E4QScyfHmd2a2uvzezUgcdTmNrHihfJpsJ8c4V8eCxohcE3L5g== X-Received: by 2002:a1c:5456:: with SMTP id p22mr200296wmi.81.1611853791571; Thu, 28 Jan 2021 09:09:51 -0800 (PST) Received: from linaro.org ([2a00:23c5:6801:1801:40:2fca:953a:e6ba]) by smtp.gmail.com with ESMTPSA id p15sm7622355wrt.15.2021.01.28.09.09.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Jan 2021 09:09:51 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, mathieu.poirier@linaro.org, linux-doc@vger.kernel.org, suzuki.poulose@arm.com Subject: [PATCH v4 07/10] coresight: etm4x: Add complex configuration handlers to etmv4 Date: Thu, 28 Jan 2021 17:09:33 +0000 Message-Id: <20210128170936.9222-8-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210128170936.9222-1-mike.leach@linaro.org> References: <20210128170936.9222-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210128_120953_122016_ACBFFD5A X-CRM114-Status: GOOD ( 37.05 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: gregkh@linuxfoundation.org, alexander.shishkin@linux.intel.com, yabinc@google.com, corbet@lwn.net, linux-kernel@vger.kernel.org, tingwei@codeaurora.org, leo.yan@linaro.org, Mike Leach MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Adds in handlers to allow the ETMv4 to use the complex configuration support. Features and configurations can be loaded and selected in the device. Signed-off-by: Mike Leach --- drivers/hwtracing/coresight/Makefile | 3 +- .../hwtracing/coresight/coresight-etm4x-cfg.c | 184 ++++++++++++++++++ .../hwtracing/coresight/coresight-etm4x-cfg.h | 29 +++ .../coresight/coresight-etm4x-core.c | 38 +++- .../coresight/coresight-etm4x-sysfs.c | 3 + 5 files changed, 254 insertions(+), 3 deletions(-) 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 daad9f103a78..ea544206204d 100644 --- a/drivers/hwtracing/coresight/Makefile +++ b/drivers/hwtracing/coresight/Makefile @@ -16,7 +16,8 @@ obj-$(CONFIG_CORESIGHT_SOURCE_ETM3X) += coresight-etm3x.o coresight-etm3x-y := coresight-etm3x-core.o coresight-etm-cp14.o \ coresight-etm3x-sysfs.o obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o -coresight-etm4x-y := coresight-etm4x-core.o coresight-etm4x-sysfs.o +coresight-etm4x-y := coresight-etm4x-core.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-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c new file mode 100644 index 000000000000..f237a8d02360 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright(C) 2020 Linaro Limited. All rights reserved. + * Author: Mike Leach + */ + +#include "coresight-etm4x.h" +#include "coresight-etm4x-cfg.h" +#include "coresight-priv.h" +#include "coresight-syscfg.h" + +/** + * 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 cscfg_reg_csdev *reg, u32 offset) +{ + int err = -EINVAL, idx; + struct etmv4_config *drvcfg = &drvdata->config; + u32 off_mask; + +#define CHECKREG(cval, elem) \ + { \ + if (offset == cval) { \ + reg->drv_store = &drvcfg->elem; \ + err = 0; \ + break; \ + } \ + } + +#define CHECKREGIDX(cval, elem, off_idx, mask) \ + { \ + if (mask == cval) { \ + reg->drv_store = &drvcfg->elem[off_idx]; \ + err = 0; \ + break; \ + } \ + } + + if (((offset >= TRCEVENTCTL0R) && (offset <= TRCVIPCSSCTLR)) || + ((offset >= TRCSEQRSTEVR) && (offset <= TRCEXTINSELR)) || + ((offset >= TRCCIDCCTLR0) && (offset <= TRCVMIDCCTLR1))) { + do { + CHECKREG(TRCEVENTCTL0R, eventctrl0); + CHECKREG(TRCEVENTCTL1R, eventctrl1); + CHECKREG(TRCSTALLCTLR, stall_ctrl); + CHECKREG(TRCTSCTLR, ts_ctrl); + CHECKREG(TRCSYNCPR, syncfreq); + CHECKREG(TRCCCCTLR, ccctlr); + CHECKREG(TRCBBCTLR, bb_ctrl); + CHECKREG(TRCVICTLR, vinst_ctrl); + CHECKREG(TRCVIIECTLR, viiectlr); + CHECKREG(TRCVISSCTLR, vissctlr); + CHECKREG(TRCVIPCSSCTLR, vipcssctlr); + CHECKREG(TRCSEQRSTEVR, seq_rst); + CHECKREG(TRCSEQSTR, seq_state); + CHECKREG(TRCEXTINSELR, ext_inp); + CHECKREG(TRCCIDCCTLR0, ctxid_mask0); + CHECKREG(TRCCIDCCTLR1, ctxid_mask1); + CHECKREG(TRCVMIDCCTLR0, vmid_mask0); + CHECKREG(TRCVMIDCCTLR1, vmid_mask1); + } while (0); + } 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]; + err = 0; + } + } else if ((offset >= TRCSSCCRn(0)) && (offset <= TRCSSPCICRn(7))) { + /* 32 bit, 8 off indexed register sets */ + idx = (offset & GENMASK(4, 0)) / 4; + off_mask = (offset & GENMASK(11, 5)); + do { + CHECKREGIDX(TRCSSCCRn(0), ss_ctrl, idx, off_mask); + CHECKREGIDX(TRCSSCSRn(0), ss_status, idx, off_mask); + CHECKREGIDX(TRCSSPCICRn(0), ss_pe_cmp, idx, off_mask); + } while (0); + } else if ((offset >= TRCCIDCVRn(0)) && (offset <= TRCVMIDCVRn(7))) { + /* 64 bit, 8 off indexed register sets */ + idx = (offset & GENMASK(5, 0)) / 8; + off_mask = (offset & GENMASK(11, 6)); + do { + CHECKREGIDX(TRCCIDCVRn(0), ctxid_pid, idx, off_mask); + CHECKREGIDX(TRCVMIDCVRn(0), vmid_val, idx, off_mask); + } while (0); + } 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]; + err = 0; + } + } 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; + off_mask = offset & GENMASK(11, 7); + do { + CHECKREGIDX(TRCACVRn(0), addr_val, idx, off_mask); + CHECKREGIDX(TRCACATRn(0), addr_acc, idx, off_mask); + } while (0); + } 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; + off_mask = offset & GENMASK(11, 4); + do { + CHECKREGIDX(TRCCNTRLDVRn(0), cntrldvr, idx, off_mask); + CHECKREGIDX(TRCCNTCTLRn(0), cntr_ctrl, idx, off_mask); + CHECKREGIDX(TRCCNTVRn(0), cntr_val, idx, off_mask); + } while (0); + } + return err; +} + +/** + * etm4_cfg_load_feature - load a feature into a device instance. + * + * @csdev: An ETMv4 CoreSight device. + * @feat: The feature to be loaded. + * + * The function will load a feature instance into the device, checking that + * the register definitions are valid for the 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. + * + * The feature spinlock pointer is initialised to the same spinlock + * that the driver uses to protect the internal register values. + */ +static int etm4_cfg_load_feature(struct coresight_device *csdev, + struct cscfg_feature_csdev *feat) +{ + struct device *dev = csdev->dev.parent; + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev); + const struct cscfg_feature_desc *feat_desc = feat->desc; + u32 offset; + int i = 0, err = 0; + + /* + * essential we set the device spinlock - this is used in the generic + * programming routines when copying values into the drvdata structures + * via the pointers setup in etm4_cfg_map_reg_offset(). + */ + feat->csdev_spinlock = &drvdata->spinlock; + + /* process the register descriptions */ + for (i = 0; i < feat->nr_regs && !err; i++) { + offset = feat_desc->regs[i].offset; + err = etm4_cfg_map_reg_offset(drvdata, &feat->regs[i], offset); + } + return err; +} + +/* match information when loading configurations */ +#define CS_CFG_ETM4_MATCH_FLAGS (CS_CFG_MATCH_CLASS_SRC_ALL | \ + CS_CFG_MATCH_CLASS_SRC_ETM4) + +int etm4_cscfg_register(struct coresight_device *csdev, const char *dev_name) +{ + struct cscfg_match_desc cfg_info; + struct cscfg_csdev_feat_ops ops; + + cfg_info.match_flags = CS_CFG_ETM4_MATCH_FLAGS; + + ops.load_feat = &etm4_cfg_load_feature; + + return cscfg_register_csdev(csdev, &cfg_info, &ops); +} diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.h b/drivers/hwtracing/coresight/coresight-etm4x-cfg.h new file mode 100644 index 000000000000..9e279c5da55d --- /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" +#include "coresight-etm4x.h" + +/* ETMv4 specific config defines */ + +/* resource IDs */ + +#define ETM4_CFG_RES_CTR 0x001 +#define ETM4_CFG_RES_CMP 0x002 +#define ETM4_CFG_RES_CMP_PAIR0 0x003 +#define ETM4_CFG_RES_CMP_PAIR1 0x004 +#define ETM4_CFG_RES_SEL 0x005 +#define ETM4_CFG_RES_SEL_PAIR0 0x006 +#define ETM4_CFG_RES_SEL_PAIR1 0x007 +#define ETM4_CFG_RES_SEQ 0x008 +#define ETM4_CFG_RES_TS 0x009 +#define ETM4_CFG_RES_MASK 0x00F + +int etm4_cscfg_register(struct coresight_device *csdev, const char *dev_name); + +#endif /* _CORESIGHT_CORESIGHT_ETM4X_CFG_H */ diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 473ab7480a36..5e501ce244dd 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -38,6 +38,8 @@ #include "coresight-etm4x.h" #include "coresight-etm-perf.h" +#include "coresight-etm4x-cfg.h" +#include "coresight-syscfg.h" static int boot_enable; module_param(boot_enable, int, 0444); @@ -491,12 +493,15 @@ 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; + unsigned long cfg_id; + int preset; if (!attr) { ret = -EINVAL; @@ -554,6 +559,20 @@ static int etm4_parse_event_config(struct etmv4_drvdata *drvdata, /* bit[12], Return stack enable bit */ config->cfg |= BIT(12); + /* + * Set any selected configuration and preset. + * + * This extracts the values of PMU_FORMAT_ATTR(configid) and PMU_FORMAT_ATTR(preset) + * in the perf attributes defined in coresight-etm-perf.c. + * configid uses bits 63:32 of attr->config2, preset uses bits 3:0 of attr->config. + * A zero configid means no configuration active, preset = 0 means no preset selected. + */ + if (attr->config2 & GENMASK_ULL(63, 32)) { + cfg_id = (u32)(attr->config2 >> 32); + preset = attr->config & 0xF; + ret = cscfg_csdev_enable_active_config(csdev, cfg_id, preset); + } + out: return ret; } @@ -570,7 +589,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 */ @@ -701,11 +720,18 @@ static int etm4_disable_perf(struct coresight_device *csdev, u32 control; struct etm_filters *filters = event->hw.addr_filters; struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + struct perf_event_attr *attr = &event->attr; if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id())) return -EINVAL; etm4_disable_hw(drvdata); + /* + * The config_id occupies bits 63:32 of the config2 perf event attr + * field. If this is non-zero then we will have enabled a config. + */ + if (attr->config2 & GENMASK_ULL(63, 32)) + cscfg_csdev_disable_active_config(csdev); /* * Check if the start/stop logic was active when the unit was stopped. @@ -1815,6 +1841,13 @@ static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid) return ret; } + /* register with config infrastructure & load any current features */ + ret = etm4_cscfg_register(drvdata->csdev, dev_name(dev)); + if (ret) { + coresight_unregister(drvdata->csdev); + return ret; + } + etmdrvdata[drvdata->cpu] = drvdata; dev_info(&drvdata->csdev->dev, "CPU%d: ETM v%d.%d initialized\n", @@ -1902,6 +1935,7 @@ static int __exit etm4_remove_dev(struct etmv4_drvdata *drvdata) cpus_read_unlock(); + cscfg_unregister_csdev(drvdata->csdev); coresight_unregister(drvdata->csdev); return 0; diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c index b646d53a3133..cf2a51113436 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c @@ -9,6 +9,7 @@ #include #include "coresight-etm4x.h" #include "coresight-priv.h" +#include "coresight-syscfg.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); + cscfg_csdev_reset_feats(to_coresight_device(dev)); + return size; } static DEVICE_ATTR_WO(reset); From patchwork Thu Jan 28 17:09:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12054219 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2CB2BC433E0 for ; Thu, 28 Jan 2021 17:12:17 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BA5E964DE2 for ; Thu, 28 Jan 2021 17:12:16 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BA5E964DE2 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=85Grgm9RVxBcK1WyQwA2ORGKWJjSQoXFrttQzqOeUIg=; b=MD3h1r0sqGBlW2snCsO1Jn1ZEE MuQc66bgCvf9VF5k8KJj8i5FV59gbHHOifxCRAITRwh1mO6IDOjI2qKcnIoBIKHiGFwu9Sm8sYW43 MiKWvvuaeSQ2N6iR103jQE3QDsdzFZOxK7bMPtN66Zx6bTQ77SP8RPFPnbZCo9L5GxMLGaSYpLKPr j2v1LpU9t6fChP+0cgCSonCSePjIpHGJvz3Ma3/fBhV1dPL9tzgiEZyh+tRAkDlAUt9J3X8NV73JF lo60cmI5y0nBx7o42kc7TFUeR5MOCA0MSmmaFJWnQxbcIwpTWSt347pEtqur/ntvBk88pXklrn41T pZdJhACQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5Aob-0000Pa-Og; Thu, 28 Jan 2021 17:10:41 +0000 Received: from mail-wm1-x32c.google.com ([2a00:1450:4864:20::32c]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5Anq-0000BC-Iu for linux-arm-kernel@lists.infradead.org; Thu, 28 Jan 2021 17:09:57 +0000 Received: by mail-wm1-x32c.google.com with SMTP id z16so2605566wml.2 for ; Thu, 28 Jan 2021 09:09:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7k84NxGmgQHdBpcBiXmHFImsSSte6bX98Pzv6KPogo0=; b=Nwcx584PZcKSO+bKQJR9lVOFY4/4E3WaZnj95B5bujuEp8qY0qjFzJScp/lwwWlU7r ZqG8DfjCEdVxKkSWE4xE25aeNXggQnQCLZiKYtOOghwyf+SkIrFqmWNGz1Yjdr8r6m1T QrZZG1bXsrc3/+ik2zNcwXHBNU9Un9QXDeWsHbievSL7L3FJJJZfOiBdZaIha0+13pDy K/vu16uETNeTe4iQn+Wahx9g9JBDTb4HQn7W63ZgWtvnxINWIXAAE/7RWnx8MkCLVPJl 0b4inVRu3V4xaBH4nlB6RtgV+CSdEzz7lc+dLeqFPSRZHRqXUXtu8dUZynfeQoUsn7mC wvVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7k84NxGmgQHdBpcBiXmHFImsSSte6bX98Pzv6KPogo0=; b=pHubLuvZb8iC5pTeSED860tGFUB7upf8ldWi35gK8YL+fa3nK+THJ0uRT3M8cojCBy eFuyumhJckb63BRxhHfNElV37sZfKnzGdIcoBN62J4tXhR/cG4mKLVfY5818az5G5s5d CuxcD8G9L/OlVts0P4Z5NlHBh4RDUtq0/6kE9w5xtxuC0yHfNiitY+gJWBVWCCGCzoZE TrO57e2Ftf9SJMmTpHISu8f1Vo70+wCiygXciGsVscmeCO9mf8wJ9lpX7/NRHhHD58ON JQPsraCPEnoAvaocqVLtGWsXeuhWGf8HCrmg4vYM71Y4H86NIbJCiPnkHTHATwu9gx3i iwPQ== X-Gm-Message-State: AOAM531oStiY7fun3qd9+Fl8h8Ng3zhIF5yu7iWakv2OfWkQ9YjXdsN1 EfrIQC/s8sPW0fNa78Mmjx2P8LARukaW/Q== X-Google-Smtp-Source: ABdhPJzRcLf9McTagMhsu71CPY7Z8uo+KFqh43MdDeUsMVYsOAt0NeOCq2TS834bbypUjocoX9vm2A== X-Received: by 2002:a1c:2d8a:: with SMTP id t132mr191611wmt.119.1611853792465; Thu, 28 Jan 2021 09:09:52 -0800 (PST) Received: from linaro.org ([2a00:23c5:6801:1801:40:2fca:953a:e6ba]) by smtp.gmail.com with ESMTPSA id p15sm7622355wrt.15.2021.01.28.09.09.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Jan 2021 09:09:52 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, mathieu.poirier@linaro.org, linux-doc@vger.kernel.org, suzuki.poulose@arm.com Subject: [PATCH v4 08/10] coresight: config: Add preloaded configurations Date: Thu, 28 Jan 2021 17:09:34 +0000 Message-Id: <20210128170936.9222-9-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210128170936.9222-1-mike.leach@linaro.org> References: <20210128170936.9222-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210128_120954_656377_E156279B X-CRM114-Status: GOOD ( 24.44 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: gregkh@linuxfoundation.org, alexander.shishkin@linux.intel.com, yabinc@google.com, corbet@lwn.net, linux-kernel@vger.kernel.org, tingwei@codeaurora.org, leo.yan@linaro.org, Mike Leach MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Preload set of configurations. This patch creates a small set of preloaded configurations and features that are available immediately after coresight has been initialised. The current set provides a strobing feature for ETMv4, that creates a periodic sampling of trace by switching trace generation on and off using counters in the ETM. A configuration called "autofdo" is also provided that uses the 'strobing' feature and provides a couple of preset values, selectable on the perf command line. Signed-off-by: Mike Leach --- drivers/hwtracing/coresight/Makefile | 3 +- .../hwtracing/coresight/coresight-cfg-afdo.c | 154 ++++++++++++++++++ .../coresight/coresight-cfg-preload.c | 25 +++ .../coresight/coresight-cfg-preload.h | 11 ++ drivers/hwtracing/coresight/coresight-core.c | 6 + .../hwtracing/coresight/coresight-syscfg.h | 1 + 6 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 drivers/hwtracing/coresight/coresight-cfg-afdo.c create mode 100644 drivers/hwtracing/coresight/coresight-cfg-preload.c create mode 100644 drivers/hwtracing/coresight/coresight-cfg-preload.h diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile index ea544206204d..2707bfef1b76 100644 --- a/drivers/hwtracing/coresight/Makefile +++ b/drivers/hwtracing/coresight/Makefile @@ -4,7 +4,8 @@ # obj-$(CONFIG_CORESIGHT) += coresight.o coresight-y := coresight-core.o coresight-etm-perf.o coresight-platform.o \ - coresight-sysfs.o coresight-syscfg.o coresight-config.o + coresight-sysfs.o coresight-syscfg.o coresight-config.o \ + coresight-cfg-preload.o coresight-cfg-afdo.o obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \ coresight-tmc-etr.o diff --git a/drivers/hwtracing/coresight/coresight-cfg-afdo.c b/drivers/hwtracing/coresight/coresight-cfg-afdo.c new file mode 100644 index 000000000000..ff69fb3f4434 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-cfg-afdo.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright(C) 2020 Linaro Limited. All rights reserved. + * Author: Mike Leach + */ + +#include "coresight-config.h" +#include "coresight-etm4x-cfg.h" + +/* preload configurations and features */ + +/* preload in features for ETMv4 */ + +/* strobe feature */ +static struct cscfg_parameter_desc strobe_params[] = { + { + .name = "window", + .value = 5000, + }, + { + .name = "period", + .value = 10000, + }, +}; + +static struct cscfg_regval_desc strobe_regs[] = { + /* resource selectors */ + { + .type = CS_CFG_REG_TYPE_RESOURCE, + .offset = TRCRSCTLRn(2), + .hw_info = ETM4_CFG_RES_SEL, + .val32 = 0x20001, + }, + { + .type = CS_CFG_REG_TYPE_RESOURCE, + .offset = TRCRSCTLRn(3), + .hw_info = ETM4_CFG_RES_SEQ, + .val32 = 0x20002, + }, + /* strobe window counter 0 - reload from param 0 */ + { + .type = CS_CFG_REG_TYPE_RESOURCE | CS_CFG_REG_TYPE_VAL_SAVE, + .offset = TRCCNTVRn(0), + .hw_info = ETM4_CFG_RES_CTR, + }, + { + .type = CS_CFG_REG_TYPE_RESOURCE | CS_CFG_REG_TYPE_VAL_PARAM, + .offset = TRCCNTRLDVRn(0), + .hw_info = ETM4_CFG_RES_CTR, + .val32 = 0, + }, + { + .type = CS_CFG_REG_TYPE_RESOURCE, + .offset = TRCCNTCTLRn(0), + .hw_info = ETM4_CFG_RES_CTR, + .val32 = 0x10001, + }, + /* strobe period counter 1 - reload from param 1 */ + { + .type = CS_CFG_REG_TYPE_RESOURCE | CS_CFG_REG_TYPE_VAL_SAVE, + .offset = TRCCNTVRn(1), + .hw_info = ETM4_CFG_RES_CTR, + }, + { + .type = CS_CFG_REG_TYPE_RESOURCE | CS_CFG_REG_TYPE_VAL_PARAM, + .offset = TRCCNTRLDVRn(1), + .hw_info = ETM4_CFG_RES_CTR, + .val32 = 1, + }, + { + .type = CS_CFG_REG_TYPE_RESOURCE, + .offset = TRCCNTCTLRn(1), + .hw_info = ETM4_CFG_RES_CTR, + .val32 = 0x8102, + }, + /* sequencer */ + { + .type = CS_CFG_REG_TYPE_RESOURCE, + .offset = TRCSEQEVRn(0), + .hw_info = ETM4_CFG_RES_SEQ, + .val32 = 0x0081, + }, + { + .type = CS_CFG_REG_TYPE_RESOURCE, + .offset = TRCSEQEVRn(1), + .hw_info = ETM4_CFG_RES_SEQ, + .val32 = 0x0000, + }, + /* view-inst */ + { + .type = CS_CFG_REG_TYPE_STD | CS_CFG_REG_TYPE_VAL_MASK, + .offset = TRCVICTLR, + .val32 = 0x0003, + .mask32 = 0x0003, + }, + /* end of regs */ +}; + +struct cscfg_feature_desc strobe = { + .name = "strobing", + .brief = "Generate periodic trace capture windows.\n" + "parameter \'window\': a number of CPU cycles (W)\n" + "parameter \'period\': trace enabled for W cycles every period x W cycles\n", + .match_flags = CS_CFG_MATCH_CLASS_SRC_ETM4, + .nr_params = ARRAY_SIZE(strobe_params), + .params = strobe_params, + .nr_regs = ARRAY_SIZE(strobe_regs), + .regs = strobe_regs, +}; + +/* create an autofdo configuration */ + +/* we will provide 9 sets of preset parameter values */ +#define AFDO_NR_PRESETS 9 +/* the total number of parameters in used features */ +#define AFDO_NR_PARAM_SUM ARRAY_SIZE(strobe_params) + +#define AFDO_MATCH_STROBING (CS_CFG_MATCH_INST_ANY | CS_CFG_MATCH_CLASS_SRC_ETM4) + +static struct cscfg_config_feat_ref afdo_refs[] = { + { + .name = "strobing", + .match = { + .match_flags = AFDO_MATCH_STROBING, + }, + }, +}; + +/* + * set of presets leaves strobing window constant while varying period to allow + * experimentation with mark / space ratios for various workloads + */ +static u64 afdo_presets[AFDO_NR_PRESETS][AFDO_NR_PARAM_SUM] = { + { 5000, 2 }, + { 5000, 4 }, + { 5000, 8 }, + { 5000, 16 }, + { 5000, 64 }, + { 5000, 128 }, + { 5000, 512 }, + { 5000, 1024 }, + { 5000, 4096 }, +}; + +struct cscfg_config_desc afdo = { + .name = "autofdo", + .brief = "Setup ETMs with strobing for autofdo\n" + "Supplied presets allow experimentation with mark-space ratio for various loads\n", + .nr_refs = ARRAY_SIZE(afdo_refs), + .refs = afdo_refs, + .nr_presets = AFDO_NR_PRESETS, + .nr_total_params = AFDO_NR_PARAM_SUM, + .presets = &afdo_presets[0][0], +}; diff --git a/drivers/hwtracing/coresight/coresight-cfg-preload.c b/drivers/hwtracing/coresight/coresight-cfg-preload.c new file mode 100644 index 000000000000..c7ec5cbdd990 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-cfg-preload.c @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright(C) 2020 Linaro Limited. All rights reserved. + * Author: Mike Leach + */ + +#include "coresight-cfg-preload.h" +#include "coresight-config.h" +#include "coresight-syscfg.h" + +static struct cscfg_feature_desc *preload_feats[] = { + &strobe, + 0 +}; + +static struct cscfg_config_desc *preload_cfgs[] = { + &afdo, + 0 +}; + +/* preload called with mutex locked */ +int cscfg_preload(void) +{ + return cscfg_load_config_sets(preload_cfgs, preload_feats); +} diff --git a/drivers/hwtracing/coresight/coresight-cfg-preload.h b/drivers/hwtracing/coresight/coresight-cfg-preload.h new file mode 100644 index 000000000000..fc4ac7faa93d --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-cfg-preload.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright(C) 2020 Linaro Limited. All rights reserved. + * Author: Mike Leach + */ + +/* declare preloaded configurations and features */ + +/* from coresight-cfg-afdo.c */ +extern struct cscfg_feature_desc strobe; +extern struct cscfg_config_desc afdo; diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 6bd41de46648..633ddcffc6c7 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -1744,9 +1744,15 @@ static int __init coresight_init(void) /* initialise the coresight syscfg API */ ret = cscfg_init(); + if (ret) + goto exit_perf_close; + + /* preload builtin configurations */ + ret = cscfg_preload(); if (!ret) return 0; +exit_perf_close: etm_perf_exit(); exit_bus_unregister: bus_unregister(&coresight_bustype); diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h index 301e26e1e98f..a8a6b21315d8 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.h +++ b/drivers/hwtracing/coresight/coresight-syscfg.h @@ -47,6 +47,7 @@ struct cscfg_csdev_register { /* internal core operations for cscfg */ int __init cscfg_init(void); void __exit cscfg_exit(void); +int cscfg_preload(void); /* syscfg manager external API */ int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs, From patchwork Thu Jan 28 17:09:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12054223 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 44476C433DB for ; Thu, 28 Jan 2021 17:12:27 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C70CC64E0E for ; Thu, 28 Jan 2021 17:12:26 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C70CC64E0E Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=DplafBc6M0TzLbqnCVjbNMWHUycQwnF15h+sV3rBQiI=; b=BrSDorjBe+f33xSOYWd33cGEPj 806eycvUe7iA5IE6roM2y0kn+9X0z4q2D0uQ9XoZg9aaqpkmmp6jdMquTkMDOpd+QnhoKRYCwRQwi vjGEMspPHvW0TOpVGMnis5+IMujVhidLAiVsvrkFM2cPQSPJXPNQw2Kx7yS01n00kdOKT7PR+9ZNl eZWD8vst4j6KVdHPyxZD1TfZjgL4MmCTMsaNS4L2jcKs9rwbtMapDcw15LjsVPhqeWhIwFQi/+6oE aFOaF/cXhgvJUKHVWmxSyitB6iy39Id6RT+NNLZ58gPEOw/5pK3wSDcsk/auHovBQeOX1RAoHuyew Cpk8aCfA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5Aon-0000UC-6m; Thu, 28 Jan 2021 17:10:53 +0000 Received: from mail-wr1-x42d.google.com ([2a00:1450:4864:20::42d]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5Ans-0000Ba-CX for linux-arm-kernel@lists.infradead.org; Thu, 28 Jan 2021 17:10:00 +0000 Received: by mail-wr1-x42d.google.com with SMTP id l12so6183491wry.2 for ; Thu, 28 Jan 2021 09:09:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=3wvG8bh/JYRBqGNJxAYIJXTQPoHuh5cic7AmCekPujY=; b=jBsQQky0mXcnUwm/Ye5E8bD+fedWAornJY53s/iZ/JVTOjzpA+qkQlwuFm+9zBag9F ohqKatPv23nG8nXG/MLAu8tMdWQF+jKti56BBzgGw7pjZA7BCJyclr8AkykeBGyL98gh K2bQy628aw0UwINir9tneU3VvI9DNi8FFurm2PzF3WHT2nJHzec8f2NRUV4U2q/u6jI1 RB0OGwNk1QnLHFL7B+KgXCfwvq8hoYDjtBJbkPzisCbHStMnVzsAo73b58dHHkAPZ6Qs sgDcnbAeZHhbOAWDxSLM7yl47CpdrGj++s4fxrsOHiYegs+mHuYx0c8tGnCEN7l5NaNv xUNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=3wvG8bh/JYRBqGNJxAYIJXTQPoHuh5cic7AmCekPujY=; b=s+05UVIre+TmUBU9yASMy7PbM9I0QqmbkJxCasa8MqZQDUWXYJSTgiGB6sBkVeZKMT te+SjjV4sJNWM8SQTJwk22OL/GpXwEOoxj8X0yBAxyWpYrrQGfucPU99+6ztSpUqPb1I VEJI8e9iIxJ+ilDPt+8wHJFdlFxTLDmHNo+Em2CGlmaOoImXfpzcR8GT3uxjPwAiG6hE ntRLKWq8sik/Q4PthJwKBRIswde+IdxRUqemDxnWze9CBrC2VyaWwd9C1KkGWOeIXhS4 e+Jo8+SyLoAQ+dXFkSeISxpqniUlMaLaVmiW9p1JxnvObwBVgUVR62Yu5cjFAJswtsG9 Vsrg== X-Gm-Message-State: AOAM530TDgTtVodOlD869PA6m1yJvDLDSXPL0L6ti8rYI5Af4zaaiAvi gYZGsWtA2VIt5deEkzGypgSSDz2F2CIPyQ== X-Google-Smtp-Source: ABdhPJw8xj3UsVhiYzXgcoFaNOqkZcqmfsxCn+o2UdyDKtaNQTy+rtyQGNS49DF8/wlEZMun3nhbSA== X-Received: by 2002:a5d:4d0b:: with SMTP id z11mr34026wrt.388.1611853795159; Thu, 28 Jan 2021 09:09:55 -0800 (PST) Received: from linaro.org ([2a00:23c5:6801:1801:40:2fca:953a:e6ba]) by smtp.gmail.com with ESMTPSA id p15sm7622355wrt.15.2021.01.28.09.09.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Jan 2021 09:09:53 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, mathieu.poirier@linaro.org, linux-doc@vger.kernel.org, suzuki.poulose@arm.com Subject: [PATCH v4 09/10] coresight: syscfg: Add initial configfs support Date: Thu, 28 Jan 2021 17:09:35 +0000 Message-Id: <20210128170936.9222-10-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210128170936.9222-1-mike.leach@linaro.org> References: <20210128170936.9222-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210128_120956_549535_BE298666 X-CRM114-Status: GOOD ( 23.16 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: gregkh@linuxfoundation.org, alexander.shishkin@linux.intel.com, yabinc@google.com, corbet@lwn.net, linux-kernel@vger.kernel.org, tingwei@codeaurora.org, leo.yan@linaro.org, Mike Leach MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Adds configfs subsystem and attributes to the configuration manager to enable the listing of loaded configurations and features. The default values of feature parameters can be accessed and altered from these attributes to affect all installed devices using the feature. Signed-off-by: Mike Leach --- drivers/hwtracing/coresight/Makefile | 3 +- .../hwtracing/coresight/coresight-config.c | 1 + .../coresight/coresight-syscfg-configfs.c | 399 ++++++++++++++++++ .../coresight/coresight-syscfg-configfs.h | 45 ++ .../hwtracing/coresight/coresight-syscfg.c | 77 ++++ .../hwtracing/coresight/coresight-syscfg.h | 7 + 6 files changed, 531 insertions(+), 1 deletion(-) create mode 100644 drivers/hwtracing/coresight/coresight-syscfg-configfs.c create mode 100644 drivers/hwtracing/coresight/coresight-syscfg-configfs.h diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile index 2707bfef1b76..391c93a08902 100644 --- a/drivers/hwtracing/coresight/Makefile +++ b/drivers/hwtracing/coresight/Makefile @@ -5,7 +5,8 @@ obj-$(CONFIG_CORESIGHT) += coresight.o coresight-y := coresight-core.o coresight-etm-perf.o coresight-platform.o \ coresight-sysfs.o coresight-syscfg.o coresight-config.o \ - coresight-cfg-preload.o coresight-cfg-afdo.o + coresight-cfg-preload.o coresight-cfg-afdo.o \ + coresight-syscfg-configfs.o obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \ coresight-tmc-etr.o diff --git a/drivers/hwtracing/coresight/coresight-config.c b/drivers/hwtracing/coresight/coresight-config.c index 6cc4b213d9b6..225ceca1428c 100644 --- a/drivers/hwtracing/coresight/coresight-config.c +++ b/drivers/hwtracing/coresight/coresight-config.c @@ -243,3 +243,4 @@ void cscfg_csdev_disable_config(struct cscfg_config_csdev *cfg) cfg->enabled = false; } } + diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c new file mode 100644 index 000000000000..79a11ebd6782 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c @@ -0,0 +1,399 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#include + +#include "coresight-syscfg-configfs.h" + +/* create a default ci_type. */ +static inline struct config_item_type *cscfg_create_ci_type(void) +{ + struct config_item_type *ci_type; + + ci_type = devm_kzalloc(to_device_cscfg(), sizeof(*ci_type), GFP_KERNEL); + if (ci_type) + ci_type->ct_owner = THIS_MODULE; + + return ci_type; +} + +/* configurations sub-group */ + +/* attributes for the config view group */ +static ssize_t cscfg_cfg_description_show(struct config_item *item, char *page) +{ + struct cscfg_fs_config *fs_config = container_of(to_config_group(item), + struct cscfg_fs_config, group); + + return scnprintf(page, PAGE_SIZE, "%s\n", fs_config->desc->brief); +} +CONFIGFS_ATTR_RO(cscfg_cfg_, description); + +static ssize_t cscfg_cfg_feature_refs_show(struct config_item *item, char *page) +{ + struct cscfg_fs_config *fs_config = container_of(to_config_group(item), + struct cscfg_fs_config, group); + const struct cscfg_config_desc *desc = fs_config->desc; + ssize_t ch_used = 0; + int i; + + if (desc->nr_refs) { + for (i = 0; i < desc->nr_refs; i++) { + ch_used += scnprintf(page + ch_used, PAGE_SIZE - ch_used, + "%s\n", desc->refs[i].name); + } + } + return ch_used; +} +CONFIGFS_ATTR_RO(cscfg_cfg_, feature_refs); + +/* list preset values in order of features and params */ +static ssize_t cscfg_cfg_values_show(struct config_item *item, char *page) +{ + const struct cscfg_feature_desc *feat; + const struct cscfg_config_desc *cfg; + struct cscfg_fs_preset *fs_preset; + int i, j, val_idx, preset_idx; + ssize_t used = 0; + + fs_preset = container_of(to_config_group(item), struct cscfg_fs_preset, group); + cfg = fs_preset->desc; + + if (!cfg->nr_presets) + return 0; + + preset_idx = fs_preset->preset_num - 1; + + /* start index on the correct array line */ + val_idx = cfg->nr_total_params * preset_idx; + + /* + * A set of presets is the sum of all params in used features, + * in order of declaration of features and params in the features + */ + for (i = 0; i < cfg->nr_refs; i++) { + feat = cscfg_get_named_feat_desc(cfg->refs[i].name); + for (j = 0; j < feat->nr_params; j++) { + used += scnprintf(page + used, PAGE_SIZE - used, + "%s.%s = 0x%llx ", + feat->name, feat->params[j].name, + cfg->presets[val_idx++]); + } + } + used += scnprintf(page + used, PAGE_SIZE - used, "\n"); + + return used; +} +CONFIGFS_ATTR_RO(cscfg_cfg_, values); + +static struct configfs_attribute *cscfg_config_view_attrs[] = { + &cscfg_cfg_attr_description, + &cscfg_cfg_attr_feature_refs, + NULL, +}; + +static struct config_item_type cscfg_config_view_type = { + .ct_owner = THIS_MODULE, + .ct_attrs = cscfg_config_view_attrs, +}; + +static struct configfs_attribute *cscfg_config_preset_attrs[] = { + &cscfg_cfg_attr_values, + NULL, +}; + +static struct config_item_type cscfg_config_preset_type = { + .ct_owner = THIS_MODULE, + .ct_attrs = cscfg_config_preset_attrs, +}; + + +static int cscfg_add_preset_groups(struct cscfg_fs_config *cfg_view) +{ + int preset_num; + struct cscfg_fs_preset *cfg_preset; + struct cscfg_config_desc *cfg_desc = cfg_view->desc; + char name[CONFIGFS_ITEM_NAME_LEN]; + + if (!cfg_desc->nr_presets) + return 0; + + for (preset_num = 1; preset_num <= cfg_desc->nr_presets; preset_num++) { + cfg_preset = devm_kzalloc(to_device_cscfg(), + sizeof(struct cscfg_fs_config), GFP_KERNEL); + + if (!cfg_preset) + return -ENOMEM; + + snprintf(name, CONFIGFS_ITEM_NAME_LEN, "preset%d", preset_num); + cfg_preset->preset_num = preset_num; + cfg_preset->desc = cfg_view->desc; + config_group_init_type_name(&cfg_preset->group, name, + &cscfg_config_preset_type); + configfs_add_default_group(&cfg_preset->group, &cfg_view->group); + } + return 0; +} + +static struct config_group *cscfg_create_config_group(struct cscfg_config_desc *cfg_desc) +{ + struct cscfg_fs_config *cfg_view; + struct device *dev = to_device_cscfg(); + int err; + + if (!dev) + return ERR_PTR(-EINVAL); + + cfg_view = devm_kzalloc(dev, sizeof(struct cscfg_fs_config), GFP_KERNEL); + if (!cfg_view) + return ERR_PTR(-ENOMEM); + + cfg_view->desc = cfg_desc; + config_group_init_type_name(&cfg_view->group, cfg_desc->name, &cscfg_config_view_type); + + /* add in a preset dir for each preset */ + err = cscfg_add_preset_groups(cfg_view); + if (err) + return ERR_PTR(err); + + return &cfg_view->group; +} + +/* attributes for features view */ + +static ssize_t cscfg_feat_description_show(struct config_item *item, char *page) +{ + struct cscfg_fs_feature *fs_feat = container_of(to_config_group(item), + struct cscfg_fs_feature, group); + + return scnprintf(page, PAGE_SIZE, "%s\n", fs_feat->desc->brief); +} +CONFIGFS_ATTR_RO(cscfg_feat_, description); + +static ssize_t cscfg_feat_matches_show(struct config_item *item, char *page) +{ + struct cscfg_fs_feature *fs_feat = container_of(to_config_group(item), + struct cscfg_fs_feature, group); + u32 match_flags = fs_feat->desc->match_flags; + int used = 0; + + if (match_flags & CS_CFG_MATCH_CLASS_SRC_ALL) + used = scnprintf(page, PAGE_SIZE, "SRC_ALL "); + + if (match_flags & CS_CFG_MATCH_CLASS_SRC_ETM4) + used += scnprintf(page + used, PAGE_SIZE - used, "SRC_ETMV4 "); + + used += scnprintf(page + used, PAGE_SIZE - used, "\n"); + return used; +} +CONFIGFS_ATTR_RO(cscfg_feat_, matches); + +static ssize_t cscfg_feat_nr_params_show(struct config_item *item, char *page) +{ + struct cscfg_fs_feature *fs_feat = container_of(to_config_group(item), + struct cscfg_fs_feature, group); + + return scnprintf(page, PAGE_SIZE, "%d\n", fs_feat->desc->nr_params); +} +CONFIGFS_ATTR_RO(cscfg_feat_, nr_params); + +/* base feature desc attrib structures */ +static struct configfs_attribute *cscfg_feature_view_attrs[] = { + &cscfg_feat_attr_description, + &cscfg_feat_attr_matches, + &cscfg_feat_attr_nr_params, + NULL, +}; + +static struct config_item_type cscfg_feature_view_type = { + .ct_owner = THIS_MODULE, + .ct_attrs = cscfg_feature_view_attrs, +}; + +static ssize_t cscfg_param_value_show(struct config_item *item, char *page) +{ + struct cscfg_fs_param *param_item = container_of(to_config_group(item), + struct cscfg_fs_param, group); + int param_idx = param_item->param_idx; + struct cscfg_feature_desc *desc = param_item->desc; + + return scnprintf(page, PAGE_SIZE, "0x%llx\n", desc->params[param_idx].value); +} + +static ssize_t cscfg_param_value_store(struct config_item *item, + const char *page, size_t size) +{ + struct cscfg_fs_param *param_item = container_of(to_config_group(item), + struct cscfg_fs_param, group); + struct cscfg_feature_desc *desc = param_item->desc; + int param_idx = param_item->param_idx; + u64 val; + int err; + + err = kstrtoull(page, 0, &val); + if (!err) + err = cscfg_update_feat_param_val(desc, param_idx, val); + + return err ? err : size; +} +CONFIGFS_ATTR(cscfg_param_, value); + +static struct configfs_attribute *cscfg_param_view_attrs[] = { + &cscfg_param_attr_value, + NULL, +}; + +static struct config_item_type cscfg_param_view_type = { + .ct_owner = THIS_MODULE, + .ct_attrs = cscfg_param_view_attrs, +}; + +/* + * 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 + * be determined. Therefore we add each item as a group directory, with a value attribute. + */ +static int cscfg_create_params_group_items(struct cscfg_feature_desc *feat_desc, + struct config_group *params_group) +{ + struct device *dev = to_device_cscfg(); + 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) + return -ENOMEM; + param_item->desc = feat_desc; + param_item->param_idx = i; + config_group_init_type_name(¶m_item->group, feat_desc->params[i].name, + &cscfg_param_view_type); + configfs_add_default_group(¶m_item->group, params_group); + } + return 0; +} + +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 config_group *params_group = NULL; + struct device *dev = to_device_cscfg(); + int item_err; + + if (!dev) + return ERR_PTR(-EINVAL); + + feat_view = devm_kzalloc(dev, 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); + if (!params_group) + return ERR_PTR(-ENOMEM); + + params_group_type = cscfg_create_ci_type(); + if (!params_group_type) + return ERR_PTR(-ENOMEM); + } + + feat_view->desc = feat_desc; + config_group_init_type_name(&feat_view->group, + feat_desc->name, + &cscfg_feature_view_type); + 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); + } + return &feat_view->group; +} + +static struct config_item_type cscfg_configs_type = { + .ct_owner = THIS_MODULE, +}; + +static struct config_group cscfg_configs_grp = { + .cg_item = { + .ci_namebuf = "configurations", + .ci_type = &cscfg_configs_type, + }, +}; + +/* add configuration to configurations group */ +int cscfg_configfs_add_config(struct cscfg_config_desc *cfg_desc) +{ + struct config_group *new_group; + int err; + + new_group = cscfg_create_config_group(cfg_desc); + if (IS_ERR(new_group)) + return PTR_ERR(new_group); + err = configfs_register_group(&cscfg_configs_grp, new_group); + return err; +} + +static struct config_item_type cscfg_features_type = { + .ct_owner = THIS_MODULE, +}; + +static struct config_group cscfg_features_grp = { + .cg_item = { + .ci_namebuf = "features", + .ci_type = &cscfg_features_type, + }, +}; + +/* add feature to features group */ +int cscfg_configfs_add_feature(struct cscfg_feature_desc *feat_desc) +{ + struct config_group *new_group; + int err; + + 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); + return err; +} + +int cscfg_configfs_init(struct cscfg_manager *cscfg_mgr) +{ + struct configfs_subsystem *subsys; + struct config_item_type *ci_type; + + if (!cscfg_mgr) + return -EINVAL; + + ci_type = cscfg_create_ci_type(); + if (!ci_type) + return -ENOMEM; + + subsys = &cscfg_mgr->cfgfs_subsys; + config_item_set_name(&subsys->su_group.cg_item, CSCFG_FS_SUBSYS_NAME); + subsys->su_group.cg_item.ci_type = ci_type; + + config_group_init(&subsys->su_group); + mutex_init(&subsys->su_mutex); + + /* Add default groups to subsystem */ + config_group_init(&cscfg_configs_grp); + configfs_add_default_group(&cscfg_configs_grp, &subsys->su_group); + + config_group_init(&cscfg_features_grp); + configfs_add_default_group(&cscfg_features_grp, &subsys->su_group); + + return configfs_register_subsystem(subsys); +} + +void cscfg_configfs_release(struct cscfg_manager *cscfg_mgr) +{ + configfs_unregister_subsystem(&cscfg_mgr->cfgfs_subsys); +} diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.h b/drivers/hwtracing/coresight/coresight-syscfg-configfs.h new file mode 100644 index 000000000000..5e49819b80fc --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Coresight system configuration driver - support for configfs. + */ + +#ifndef CORESIGHT_SYSCFG_CONFIGFS_H +#define CORESIGHT_SYSCFG_CONFIGFS_H + +#include +#include "coresight-syscfg.h" + +#define CSCFG_FS_SUBSYS_NAME "coresight-syscfg" + +/* container for configuration view */ +struct cscfg_fs_config { + struct cscfg_config_desc *desc; + struct config_group group; +}; + +/* container for feature view */ +struct cscfg_fs_feature { + struct cscfg_feature_desc *desc; + struct config_group group; +}; + +/* container for parameter view */ +struct cscfg_fs_param { + int param_idx; + struct cscfg_feature_desc *desc; + struct config_group group; +}; + +/* container for preset view */ +struct cscfg_fs_preset { + int preset_num; + struct cscfg_config_desc *desc; + struct config_group group; +}; + +int cscfg_configfs_init(struct cscfg_manager *cscfg_mgr); +void cscfg_configfs_release(struct cscfg_manager *cscfg_mgr); +int cscfg_configfs_add_config(struct cscfg_config_desc *cfg_desc); +int cscfg_configfs_add_feature(struct cscfg_feature_desc *feat_desc); + +#endif /* CORESIGHT_SYSCFG_CONFIGFS_H */ diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index d79cf5b36758..c0707c31fc31 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -9,6 +9,7 @@ #include "coresight-config.h" #include "coresight-etm-perf.h" #include "coresight-syscfg.h" +#include "coresight-syscfg-configfs.h" /* * cscfg_ API manages configurations and features for the entire coresight @@ -302,6 +303,70 @@ static int cscfg_load_config(struct cscfg_config_desc *cfg_desc) return 0; } +/* get a feature descriptor by name */ +const struct cscfg_feature_desc *cscfg_get_named_feat_desc(const char *name) +{ + const struct cscfg_feature_desc *feat = NULL, *feat_item; + + mutex_lock(&cscfg_mutex); + + list_for_each_entry(feat_item, &cscfg_mgr->data.feat_desc_list, item) { + if (strcmp(feat_item->name, name) == 0) { + feat = feat_item; + break; + } + } + + mutex_unlock(&cscfg_mutex); + return feat; +} + +static struct cscfg_feature_csdev * +cscfg_csdev_get_feat_from_desc(struct coresight_device *csdev, + struct cscfg_feature_desc *feat_desc) +{ + struct cscfg_feature_csdev *feat_csdev = NULL, *item; + + list_for_each_entry(item, &csdev->feature_csdev_list, node) { + if (item->desc == feat_desc) { + feat_csdev = item; + break; + } + } + return feat_csdev; +} + +int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc, + int param_idx, u64 value) +{ + int err = 0; + struct cscfg_feature_csdev *feat_csdev; + struct cscfg_csdev_register *item; + + mutex_lock(&cscfg_mutex); + + /* check if any config active & return busy */ + if (atomic_read(&cscfg_mgr->data.sys_active_cnt)) { + err = -EBUSY; + goto unlock_exit; + } + + /* set the value */ + feat_desc->params[param_idx].value = value; + + /* update loaded instances.*/ + list_for_each_entry(item, &cscfg_mgr->data.csdev_desc_list, item) { + feat_csdev = cscfg_csdev_get_feat_from_desc(item->csdev, feat_desc); + if (feat_csdev) + feat_csdev->params[param_idx].current_value = value; + } + +unlock_exit: + mutex_unlock(&cscfg_mutex); + return err; +} + + /* * External API function to load feature and config sets. * Take a 0 terminated array of feature descriptors and/or configuration @@ -324,6 +389,7 @@ int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs, feat_descs[i]->name); goto do_unlock; } + cscfg_configfs_add_feature(feat_descs[i]); i++; } } @@ -338,6 +404,7 @@ int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs, cfg_descs[i]->name); goto do_unlock; } + cscfg_configfs_add_config(cfg_descs[i]); i++; } } @@ -613,6 +680,7 @@ struct device *to_device_cscfg(void) /* Must have a release function or the kernel will complain on module unload */ void cscfg_dev_release(struct device *dev) { + cscfg_configfs_release(cscfg_mgr); kfree(cscfg_mgr); cscfg_mgr = NULL; } @@ -639,6 +707,7 @@ int cscfg_create_device(void) dev->init_name = "system_cfg"; err = device_register(dev); + if (err) cscfg_dev_release(dev); @@ -668,6 +737,10 @@ int __init cscfg_init(void) if (err) return err; + err = cscfg_configfs_init(cscfg_mgr); + if (err) + goto exit_dev_clear; + INIT_LIST_HEAD(&cscfg_mgr->data.csdev_desc_list); INIT_LIST_HEAD(&cscfg_mgr->data.feat_desc_list); INIT_LIST_HEAD(&cscfg_mgr->data.config_desc_list); @@ -676,6 +749,10 @@ int __init cscfg_init(void) dev_info(to_device_cscfg(), "CoreSight Configuration manager initialised"); return 0; + +exit_dev_clear: + cscfg_clear_device(); + return err; } void __exit cscfg_exit(void) diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h index a8a6b21315d8..62700e4e9e05 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.h +++ b/drivers/hwtracing/coresight/coresight-syscfg.h @@ -6,6 +6,7 @@ #ifndef CORESIGHT_SYSCFG_H #define CORESIGHT_SYSCFG_H +#include #include #include @@ -48,6 +49,10 @@ struct cscfg_csdev_register { int __init cscfg_init(void); void __exit cscfg_exit(void); int cscfg_preload(void); +const struct cscfg_feature_desc *cscfg_get_named_feat_desc(const char *name); +int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc, + int param_idx, u64 value); + /* syscfg manager external API */ int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs, @@ -71,10 +76,12 @@ void cscfg_csdev_disable_active_config(struct coresight_device *csdev); * * @dev: The device. * @data: The API data. + * @cfgfs_subsys: configfs subsystem used to manage configurations. */ struct cscfg_manager { struct device dev; struct cscfg_api_data data; + struct configfs_subsystem cfgfs_subsys; }; /* get reference to dev in cscfg_manager */ From patchwork Thu Jan 28 17:09:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12054225 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-22.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,MENTIONS_GIT_HOSTING,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 943DCC433E0 for ; Thu, 28 Jan 2021 17:12:37 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 36C5A64E15 for ; Thu, 28 Jan 2021 17:12:37 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 36C5A64E15 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=mj39cDchYlHzx9uQ82rO4NnvPGL/95qH8FoFjFKNyG8=; b=g97jD7JoV+JVQVyq4fbvB/f6Yb XyGxYb9c+sMMnPNfMbmp725APxu2fq5lqd9GmIdl7audxvuRoCZ9EFneIeEgRmVdrYOf/0GU1S2k0 uwV/w1JCXkjZDK24J0AMbsOagMR2/biATEURhINbW9rnW06jVvYWEttFqvYAc2Qg3P/LsN2m2ej5A plW5mAfLzbZ49IV6neZVtePgEGiPwSrsGO1CoDyP/qIk35dmLp5kPHkJW5AiD2py9vboSBH2WhI8H wfd1G6Tf9p5N/KNXM1eOD0BOWSYCvEZBY71fEhBxpBapc6oqsdg9AeIFGdfzzD2O2v5Bbs0+5zUzJ isoVllSw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5Ap2-0000c5-8O; Thu, 28 Jan 2021 17:11:08 +0000 Received: from mail-wm1-x32a.google.com ([2a00:1450:4864:20::32a]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l5Anu-0000C8-D3 for linux-arm-kernel@lists.infradead.org; Thu, 28 Jan 2021 17:10:01 +0000 Received: by mail-wm1-x32a.google.com with SMTP id u14so5170469wmq.4 for ; Thu, 28 Jan 2021 09:09:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=5mcqqy82Ujzfkd4RAqTV/kkOcSpfwGBGe2qxfCGbTA4=; b=flloVmPQDMv0LgnKDG4sLs/YArJgIGsVCKrlvJC//nruF/Ql2UwQSA5TqJl9b1AxeN w5TqcDa1gDVWWl8NOVmlbEqmdmT7ztcBXVWMQAyYjHwljqISk5XrcFfDyOdnU6+vJ6tp Y1MuEW0uZM0hD+F9fuvxIyKhrsZARojl/S+Jk1VKhXflVDoUbTfq71E9THHtSXmR0knB KEcw+4th3+c55IQ7OTwENzkBWC3YRMNPCKlFEg6BzsVpyYE86bGDFJUcQCEM4bbKUVtE 0ZxJmAU1fEH2/WwdbLvGiImylcejw9Unwo60WHu4eaLzkdNc0jiUBMVhiIwrId061Xdn 4tfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=5mcqqy82Ujzfkd4RAqTV/kkOcSpfwGBGe2qxfCGbTA4=; b=jg3cXgGY8Sbai5Sek7Av1n3xrNxb/5qIteuhkE+m2RGq1xecix9HPXwOx2A3O9Av6t H7S5sLX1lxriX9aipvs+HUXVtXxTZHCyy3Y+ay19y4cSNyAvbgLvTUAnRbimYTtdZ3lW LKmokm1fojG4KUtLOOt6Rc6TC5H1SdbCZHEpsZcireUu4d0tBoRPbh43Xim7BEIe+o6V mDIV0KjoarmM8qac6i9a7w219sFBagPrODmHN4PELD85TxVVsDjcD1S7qb0jD5oKlHA6 VXZ8JOJ/Ltwy+XNaJmotnd55Qun0zcBuTlkFXmsQm9Ja3p/ONmSbimwsN7QHM9eQXjX8 8Z2g== X-Gm-Message-State: AOAM5305x1ldCWUpw32DPEFsL/2Esaf9a5nsOaJ8L57/yKMTyY1g9V0c /zMkQSUdLwVhwkn14E/eNnXBAN2KRK+VEA== X-Google-Smtp-Source: ABdhPJy+Q3uxGZqP/bMkphyvMCJUGbYc7+B7PgVJsGd4/jil4y76CZHkpAIP+IA47Mq24SWi3k2XOA== X-Received: by 2002:a1c:7906:: with SMTP id l6mr260809wme.22.1611853796099; Thu, 28 Jan 2021 09:09:56 -0800 (PST) Received: from linaro.org ([2a00:23c5:6801:1801:40:2fca:953a:e6ba]) by smtp.gmail.com with ESMTPSA id p15sm7622355wrt.15.2021.01.28.09.09.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Jan 2021 09:09:55 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, mathieu.poirier@linaro.org, linux-doc@vger.kernel.org, suzuki.poulose@arm.com Subject: [PATCH v4 10/10] coresight: docs: Add documentation for CoreSight config Date: Thu, 28 Jan 2021 17:09:36 +0000 Message-Id: <20210128170936.9222-11-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210128170936.9222-1-mike.leach@linaro.org> References: <20210128170936.9222-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210128_120958_556801_FAA19913 X-CRM114-Status: GOOD ( 28.45 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: gregkh@linuxfoundation.org, alexander.shishkin@linux.intel.com, yabinc@google.com, corbet@lwn.net, linux-kernel@vger.kernel.org, tingwei@codeaurora.org, leo.yan@linaro.org, Mike Leach MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Adds documentation for the CoreSight System configuration manager. Signed-off-by: Mike Leach Reviewed-by: Mathieu Poirier --- .../trace/coresight/coresight-config.rst | 244 ++++++++++++++++++ Documentation/trace/coresight/coresight.rst | 16 ++ 2 files changed, 260 insertions(+) create mode 100644 Documentation/trace/coresight/coresight-config.rst diff --git a/Documentation/trace/coresight/coresight-config.rst b/Documentation/trace/coresight/coresight-config.rst new file mode 100644 index 000000000000..3a4aa7bfa131 --- /dev/null +++ b/Documentation/trace/coresight/coresight-config.rst @@ -0,0 +1,244 @@ +.. SPDX-License-Identifier: GPL-2.0 + +====================================== +CoreSight System Configuration Manager +====================================== + + :Author: Mike Leach + :Date: October 2020 + +Introduction +============ + +The CoreSight System Configuration manager is an API that allows the +programming of the CoreSight system with pre-defined configurations that +can then be easily enabled from sysfs or perf. + +Many CoreSight components can be programmed in complex ways - especially ETMs. +In addition, components can interact across the CoreSight system, often via +the cross trigger components such as CTI and CTM. These system settings can +be defined and enabled as named configurations. + + +Basic Concepts +============== + +This section introduces the basic concepts of a CoreSight system configuration. + + +Features +-------- + +A feature is a named set of programming for a CoreSight device. The programming +is device dependent, and can be defined in terms of absolute register values, +resource usage and parameter values. + +The feature is defined using a descriptor. This descriptor is used to load onto +a matching device, either when the feature is loaded into the system, or when the +CoreSight device is registered with the configuration manager. + +The load process involves interpreting the descriptor into a set of register +accesses in the driver - the resource usage and parameter descriptions +translated into appropriate register accesses. This interpretation makes it easy +and efficient for the feature to be programmed onto the device when required. + +The feature will not be active on the device until the feature is enabled, and +the device itself is enabled. When the device is enabled then enabled features +will be programmed into the device hardware. + +A feature is enabled as part of a configuration being enabled on the system. + + +Parameter Value +~~~~~~~~~~~~~~~ + +A parameter value is a named value that may be set by the user prior to the +feature being enabled that can adjust the behaviour of the operation programmed +by the feature. + +For example, this could be a count value in a programmed operation that repeats +at a given rate. When the feature is enabled then the current value of the +parameter is used in programming the device. + +The feature descriptor defines a default value for a parameter, which is used +if the user does not supply a new value. + +Users can update parameter values using the configfs API for the CoreSight +system - which is described below. + +The current value of the parameter is loaded into the device when the feature +is enabled on that device. + + +Configurations +-------------- + +A configuration defines a set of features that are to be used in a trace +session where the configuration is selected. For any trace session only one +configuration may be selected. + +The features defined may be on any type of device that is registered +to support system configuration. A configuration may select features to be +enabled on a class of devices - i.e. any ETMv4, or specific devices, e.g. a +specific CTI on the system. + +As with the feature, a descriptor is used to define the configuration. +This will define the features that must be enabled as part of the configuration +as well as any preset values that can be used to override default parameter +values. + + +Preset Values +~~~~~~~~~~~~~ + +Preset values are easily selectable sets of parameter values for the features +that the configuration uses. The number of values in a single preset set, equals +the sum of parameter values in the features used by the configuration. + +e.g. a configuration consists of 3 features, one has 2 parameters, one has +a single parameter, and another has no parameters. A single preset set will +therefore have 3 values. + +Presets are optionally defined by the configuration, up to 15 can be defined. +If no preset is selected, then the parameter values defined in the feature +are used as normal. + + +Operation +~~~~~~~~~ + +The following steps take place in the operation of a configuration. + +1) In this example, the configuration is 'autofdo', which has an + associated feature 'strobing' that works on ETMv4 CoreSight Devices. + +2) The configuration is enabled. For example 'perf' may select the + configuration as part of its command line:: + + perf record -e cs_etm/autofdo/ myapp + + which will enable the 'autofdo' configuration. + +3) perf starts tracing on the system. As each ETMv4 that perf uses for + trace is enabled, the configuration manager will check if the ETMv4 + has a feature that relates to the currently active configuration. + In this case 'strobing' is enabled & programmed into the ETMv4. + +4) When the ETMv4 is disabled, any registers marked as needing to be + saved will be read back. + +5) At the end of the perf session, the configuration will be disabled. + + +Viewing Configurations and Features +=================================== + +The set of configurations and features that are currently loaded into the +system can be viewed using the configfs API. + +Mount configfs as normal and the 'coresight-syscfg' subsystem will appear:: + + $ ls /config + coresight-syscfg stp-policy + +This has two sub-directories:: + + $ cd coresight-syscfg/ + $ ls + configurations features + +The system has the configuration 'autofdo' built in. It may be examined as +follows:: + + $ cd configurations/ + $ ls + autofdo + $ cd autofdo/ + $ ls + description preset1 preset3 preset5 preset7 preset9 + feature_refs preset2 preset4 preset6 preset8 + $ cat description + Setup ETMs with strobing for autofdo + $ cat feature_refs + strobing + +Each preset declared has a preset subdirectory declared. The values for +the preset can be examined:: + + $ cat preset1/values + strobing.window = 0x1388 strobing.period = 0x2 + $ cat preset2/values + strobing.window = 0x1388 strobing.period = 0x4 + +The features referenced by the configuration can be examined in the features +directory:: + + $ cd ../../features/strobing/ + $ ls + description matches nr_params params + $ cat description + Generate periodic trace capture windows. + parameter 'window': a number of CPU cycles (W) + parameter 'period': trace enabled for W cycles every period x W cycles + $ cat matches + SRC_ETMV4 + $ cat nr_params + 2 + +Move to the params directory to examine and adjust parameters:: + + cd params + $ ls + period window + $ cd period + $ ls + value + $ cat value + 0x2710 + # echo 15000 > value + # cat value + 0x3a98 + +Parameters adjusted in this way are reflected in all device instances that have +loaded the feature. + + +Using Configurations in perf +============================ + +The configurations loaded into the CoreSight configuration management are +also declared in the perf 'cs_etm' event infrastructure so that they can +be selected when running trace under perf:: + + $ ls /sys/devices/cs_etm + configurations format perf_event_mux_interval_ms sinks type + events nr_addr_filters power + +Key directories here are 'configurations' - which lists the loaded +configurations, and 'events' - a generic perf directory which allows +selection on the perf command line.:: + + $ ls configurations/ + autofdo + $ cat configurations/autofdo + 0xa7c3dddd + +As with the sinks entries, this provides a hash of the configuration name. +The entry in the 'events' directory uses perfs built in syntax generator +to substitute the syntax for the name when evaluating the command:: + + $ ls events/ + autofdo + $ cat events/autofdo + configid=0xa7c3dddd + +The 'autofdo' configuration may be selected on the perf command line:: + + $ perf record -e cs_etm/autofdo/u --per-thread + +A preset to override the current parameter values can also be selected:: + + $ perf record -e cs_etm/autofdo,preset=1/u --per-thread + +When configurations are selected in this way, then the trace sink used is +automatically selected. diff --git a/Documentation/trace/coresight/coresight.rst b/Documentation/trace/coresight/coresight.rst index 0b73acb44efa..0122d9bebf35 100644 --- a/Documentation/trace/coresight/coresight.rst +++ b/Documentation/trace/coresight/coresight.rst @@ -587,6 +587,20 @@ A separate documentation file is provided to explain the use of these devices. (:doc:`coresight-ect`) [#fourth]_. +CoreSight System Configuration +------------------------------ + +CoreSight components can be complex devices with many programming options. +Furthermore, components can be programmed to interact with each other across the +complete system. + +A CoreSight System Configuration manager is provided to allow these complex programming +configurations to be selected and used easily from perf and sysfs. + +See the separate document for further information. +(:doc:`coresight-config`) [#fifth]_. + + .. [#first] Documentation/ABI/testing/sysfs-bus-coresight-devices-stm .. [#second] Documentation/trace/stm.rst @@ -594,3 +608,5 @@ A separate documentation file is provided to explain the use of these devices. .. [#third] https://github.com/Linaro/perf-opencsd .. [#fourth] Documentation/trace/coresight/coresight-ect.rst + +.. [#fifth] Documentation/trace/coresight/coresight-config.rst