From patchwork Mon Nov 1 22:47:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12597519 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F0AC1C433F5 for ; Mon, 1 Nov 2021 22:50:42 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 B7CDF60EDF for ; Mon, 1 Nov 2021 22:50:42 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org B7CDF60EDF Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=zikzOYjPrI8JQfYg059WhwfQSDtYU3s2hP/AKyuMKW4=; b=el3C2Va/Ee3u/B WVVg5y0VYGa3QjRc8EHwAtJFAqu/PUlLrRlwEloN7IZ8XPO4lgFk/AwqCQRt3MkBX/5yptqkM39zj q7hoUdb2AaQUnIWlNBRhTK1Vk5BjpsyduCcQeceC21TbBIcUEpIC7giXisw8TTSQz5MeS4KE5mb8o R4+g/mgwdKH59KznUJ1RHNcLxMgPXbkSP1huJanHMXmRIAgQE4eUYovphjpf+AR7QEkzJtLB03JbZ 6ykzBNVaARQqS9yuiD+NJWdMiVHRjbp0VmY35eA2j9c7kIQKntYAKCCOp/PhBqu3FaXT5iW4S3ghQ sGnTJmnvwTIPTemViYTA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhg70-00HS13-2G; Mon, 01 Nov 2021 22:49:06 +0000 Received: from mail-wr1-x42a.google.com ([2a00:1450:4864:20::42a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhg5Y-00HRVm-JB for linux-arm-kernel@lists.infradead.org; Mon, 01 Nov 2021 22:47:41 +0000 Received: by mail-wr1-x42a.google.com with SMTP id s13so23263380wrb.3 for ; Mon, 01 Nov 2021 15:47:35 -0700 (PDT) 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=Y5h9pIf4O35Nf8PvDSWgpzyfLGkiD3rIZ7lZAMc3i+o=; b=PYFfn+vCkGys5hghdvXZpoKHp+yzXBUjhTxycnPxB3gIPwqhlqQYv8HBF9+u0xRj38 WJ7he2AUhDcumoGVP2SkwTaUJ1sYJqEWMlZdVrdfv6fi5uVDY5csHS4Q/1EsZCtLRSug Rd3CZGtzOYrJ9SuYgewECCoDRGouCVeMnjnHBgXlA6uLBXb5bXjtmaHjWAzY5o006dw0 kpaD4c7HKkPBXwX+YJycR6zD5eXpCMlkRZORvBKIPW8F8pOrXXPjboDk+Lnzs69B826X Uz9igU8i/ie7Rtlu4cw93dnVH53VU66u2YEHMjDTUTJGemFxuY4b9CEAlrnpbNbSeLcV 8GMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Y5h9pIf4O35Nf8PvDSWgpzyfLGkiD3rIZ7lZAMc3i+o=; b=2kiTY9s0u/fe2ujPXrqwE51T4VgxPaRx3y5T2UsD7FCeDHtfFrevZ98ZvlcDr4RmW1 /7kpLihfP+cLydZspZCOykSmNET50sIRVN88FUfEzSV2ZDspg4wGzO5Msq87AkZVr/8F UtE7wiUvZL3E1GS9323ChBLelDKrjJi/IGoMOXwNqauCymAO4uLRwAhn8RkA3WpcHtcn SLgsvJsSzULHI37ezRHYj9B5/TzpL5GkKlXrAblkw0ERUS/1rt5YaIccdcXC1gogUHx3 CYSZ6pg/cnJznSe8ZTCNnu+BBOjYR4t1BRvznhsP+xv6i8hbL0+pJ7481K0QDTSfJaNn 39gA== X-Gm-Message-State: AOAM530fjMDxQlclhGOpnj3G1MQeKmBTX8ulJ+s7JqrC1XJ/vzshafJW px3V0FVarPWjIZO206HhOJkVjbIyIVb/OQ== X-Google-Smtp-Source: ABdhPJyBhdGpahxECsvk2jBBmn8MLOhZIuCLGDKram5uQNWDUUd0XcMS3NkiGAv4ukCLdRCUPhgy8w== X-Received: by 2002:a5d:4107:: with SMTP id l7mr23673727wrp.209.1635806854464; Mon, 01 Nov 2021 15:47:34 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:cd6d:75aa:3402:e4a]) by smtp.gmail.com with ESMTPSA id 10sm858647wme.27.2021.11.01.15.47.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 15:47:34 -0700 (PDT) From: Mike Leach To: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org, mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [PATCH 1/6] coresight: configfs: Add in functionality for load via configfs Date: Mon, 1 Nov 2021 22:47:26 +0000 Message-Id: <20211101224731.27870-2-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211101224731.27870-1-mike.leach@linaro.org> References: <20211101224731.27870-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211101_154736_677542_43E378DB X-CRM114-Status: GOOD ( 32.21 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add in functionality to allow load via configfs. define a binary file format and provide a reader for that format that will create and populate configuration and feature structures use by the driver infrastructure. Signed-off-by: Mike Leach --- drivers/hwtracing/coresight/Makefile | 2 +- .../coresight/coresight-config-file.c | 432 ++++++++++++++++++ .../coresight/coresight-config-file.h | 118 +++++ .../hwtracing/coresight/coresight-config.h | 17 + .../hwtracing/coresight/coresight-syscfg.h | 1 + 5 files changed, 569 insertions(+), 1 deletion(-) create mode 100644 drivers/hwtracing/coresight/coresight-config-file.c create mode 100644 drivers/hwtracing/coresight/coresight-config-file.h diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile index b6c4a48140ec..5de2bb79f4ac 100644 --- a/drivers/hwtracing/coresight/Makefile +++ b/drivers/hwtracing/coresight/Makefile @@ -6,7 +6,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-config.o \ coresight-cfg-preload.o coresight-cfg-afdo.o \ - coresight-syscfg-configfs.o + coresight-syscfg-configfs.o coresight-config-file.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-file.c b/drivers/hwtracing/coresight/coresight-config-file.c new file mode 100644 index 000000000000..3fd001938324 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-config-file.c @@ -0,0 +1,432 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#include "coresight-config.h" +#include "coresight-config-file.h" +#include "coresight-syscfg.h" + +#define cscfg_extract_u64(val64) { \ + val64 = *(u64 *)(buffer + used); \ + used += sizeof(u64); \ + } + +#define cscfg_extract_u32(val32) { \ + val32 = *(u32 *)(buffer + used); \ + used += sizeof(u32); \ + } + +#define cscfg_extract_u16(val16) { \ + val16 = *(u16 *)(buffer + used); \ + used += sizeof(u16); \ + } + +#define cscfg_extract_u8(val8) { \ + val8 = *(buffer + used); \ + used++; \ + } + +static int cscfg_file_read_hdr(const u8 *buffer, const int buflen, int *buf_used, + struct cscfg_file_header *hdr) +{ + /* file header always at the start of the buffer */ + int used = 0; + + if (buflen < sizeof(struct cscfg_file_header)) + return -EINVAL; + + cscfg_extract_u32(hdr->magic_version); + if (hdr->magic_version != CSCFG_FILE_MAGIC_VERSION) + return -EINVAL; + + cscfg_extract_u16(hdr->length); + if (hdr->length > buflen) + return -EINVAL; + + cscfg_extract_u16(hdr->nr_features); + + *buf_used = used; + return 0; +} + +static int cscfg_file_read_elem_hdr(const u8 *buffer, const int buflen, int *buf_used, + struct cscfg_file_elem_header *elem_hdr) +{ + int used = *buf_used; + + if ((buflen - used) < (sizeof(u16) + sizeof(u8))) + return -EINVAL; + + /* read length and check enough buffer remains for this element */ + elem_hdr->elem_length = *(u16 *)(buffer + used); + if ((buflen - used) < elem_hdr->elem_length) + return -EINVAL; + /* don't use extract fn as we update used _after_ the comparison */ + used += sizeof(u16); + + /* read type and validate */ + cscfg_extract_u8(elem_hdr->elem_type); + if ((elem_hdr->elem_type < CSCFG_FILE_ELEM_TYPE_FEAT) || + (elem_hdr->elem_type > CSCFG_FILE_ELEM_TYPE_CFG)) + return -EINVAL; + + *buf_used = used; + return 0; +} + +static int cscfg_file_read_elem_str(const u8 *buffer, const int buflen, int *buf_used, + struct cscfg_file_elem_str *elem_str) +{ + int used = *buf_used; + + if ((buflen - used) < sizeof(u16)) + return -EINVAL; + + cscfg_extract_u16(elem_str->str_len); + + if ((buflen - used) < elem_str->str_len) + return -EINVAL; + + /* check for 0 termination */ + if (buffer[elem_str->str_len - 1] != 0) + return -EINVAL; + + elem_str->str = devm_kstrdup(cscfg_device(), (char *)buffer, GFP_KERNEL); + used += elem_str->str_len; + + *buf_used = used; + return 0; +} + +static int cscfg_file_alloc_desc_arrays(struct cscfg_fs_load_descs *desc_arrays, + int nr_features) +{ + /* arrays are 0 terminated - max of 1 config & nr_features features */ + desc_arrays->config_descs = devm_kcalloc(cscfg_device(), 2, + sizeof(struct cscfg_config_desc *), + GFP_KERNEL); + if (!desc_arrays->config_descs) + return -ENOMEM; + desc_arrays->feat_descs = devm_kcalloc(cscfg_device(), nr_features + 1, + sizeof(struct cscfg_feature_desc *), + GFP_KERNEL); + if (!desc_arrays->feat_descs) + return -ENOMEM; + return 0; +} + +static int cscfg_file_read_elem_config(const u8 *buffer, const int buflen, int *buf_used, + struct cscfg_fs_load_descs *desc_arrays) +{ + struct cscfg_file_elem_header elem_hdr; + struct cscfg_file_elem_str elem_str; + struct cscfg_config_desc *config_desc; + int used = *buf_used, nr_preset_vals, nr_preset_bytes, i; + int err = 0; + u64 *presets; + + /* + * read the header - if not config, then don't update buf_used + * pointer on return + */ + err = cscfg_file_read_elem_hdr(buffer, buflen, &used, &elem_hdr); + if (err) + return err; + if (elem_hdr.elem_type != CSCFG_FILE_ELEM_TYPE_CFG) + return 0; + + /* we have a config - allocate the descriptor */ + config_desc = devm_kzalloc(cscfg_device(), sizeof(struct cscfg_config_desc), + GFP_KERNEL); + if (!config_desc) + return -ENOMEM; + + /* read the name string */ + err = cscfg_file_read_elem_str(buffer, buflen, &used, &elem_str); + if (err) + return err; + config_desc->name = elem_str.str; + + /* read the description string */ + err = cscfg_file_read_elem_str(buffer, buflen, &used, &elem_str); + if (err) + return err; + config_desc->description = elem_str.str; + + /* read in some values */ + if ((buflen - used) < sizeof(u64)) + return -EINVAL; + cscfg_extract_u16(config_desc->nr_presets); + cscfg_extract_u32(config_desc->nr_total_params); + cscfg_extract_u16(config_desc->nr_feat_refs); + + /* read the array of 64bit presets if present */ + nr_preset_vals = config_desc->nr_total_params * config_desc->nr_presets; + if (nr_preset_vals) { + presets = devm_kcalloc(cscfg_device(), nr_preset_vals, + sizeof(u64), GFP_KERNEL); + if (!presets) + return -ENOMEM; + + nr_preset_bytes = sizeof(u64) * nr_preset_vals; + if ((buflen - used) < nr_preset_bytes) + return -EINVAL; + + memcpy(presets, (buffer + used), nr_preset_bytes); + config_desc->presets = presets; + used += nr_preset_bytes; + } + + /* read the array of feature names referenced by the config */ + if (config_desc->nr_feat_refs) { + config_desc->feat_ref_names = devm_kcalloc(cscfg_device(), + config_desc->nr_feat_refs, + sizeof(char *), + GFP_KERNEL); + if (!config_desc->feat_ref_names) + return -ENOMEM; + + for (i = 0; i < config_desc->nr_feat_refs; i++) { + err = cscfg_file_read_elem_str(buffer, buflen, &used, &elem_str); + if (err) + return err; + config_desc->feat_ref_names[i] = elem_str.str; + } + } + + desc_arrays->config_descs[0] = config_desc; + *buf_used = used; + return 0; +} + +/* just read the config name - if there is a config at this position */ +static int cscfg_file_read_elem_config_name(const u8 *buffer, const int buflen, int *buf_used, + struct cscfg_file_elem_str *elem_str) +{ + struct cscfg_file_elem_header elem_hdr; + int used = *buf_used; + int err; + + elem_str->str_len = 0; + /* + * read the header - if not config, then don't update buf_used + * pointer on return + */ + err = cscfg_file_read_elem_hdr(buffer, buflen, &used, &elem_hdr); + if (err) + return err; + if (elem_hdr.elem_type != CSCFG_FILE_ELEM_TYPE_CFG) + return 0; + + /* read the name string */ + err = cscfg_file_read_elem_str(buffer, buflen, &used, elem_str); + if (err) + return err; + *buf_used = used; + + return 0; +} + +static int cscfg_file_read_elem_param(const u8 *buffer, const int buflen, int *buf_used, + struct cscfg_parameter_desc *param_desc) +{ + struct cscfg_file_elem_str elem_str; + int err = 0, used = *buf_used; + + /* parameter name */ + err = cscfg_file_read_elem_str(buffer, buflen, &used, &elem_str); + if (err) + return err; + param_desc->name = elem_str.str; + + /* parameter value */ + if ((buflen - used) < sizeof(u64)) + return -EINVAL; + cscfg_extract_u64(param_desc->value); + + *buf_used = used; + return err; +} + +static int cscfg_file_read_elem_feature(const u8 *buffer, const int buflen, int *buf_used, + struct cscfg_fs_load_descs *desc_arrays, + const int feat_idx) +{ + struct cscfg_file_elem_header elem_hdr; + struct cscfg_file_elem_str elem_str; + struct cscfg_feature_desc *feat_desc; + struct cscfg_regval_desc *p_reg_desc; + int used = *buf_used, err, i, nr_regs_bytes; + u32 val32; + + /* allocate the feature descriptor object */ + feat_desc = devm_kzalloc(cscfg_device(), sizeof(struct cscfg_feature_desc), + GFP_KERNEL); + if (!feat_desc) + return -ENOMEM; + + /* read and check the element header */ + err = cscfg_file_read_elem_hdr(buffer, buflen, &used, &elem_hdr); + if (err) + return err; + + if (elem_hdr.elem_type != CSCFG_FILE_ELEM_TYPE_FEAT) + return -EINVAL; + + /* read the feature name */ + err = cscfg_file_read_elem_str(buffer, buflen, &used, &elem_str); + if (err) + return err; + feat_desc->name = elem_str.str; + + /* read the description string */ + err = cscfg_file_read_elem_str(buffer, buflen, &used, &elem_str); + if (err) + return err; + feat_desc->description = elem_str.str; + + /* + * read in some values + * [u32 value: match_flags] + * [u16 value: nr_regs] - number of registers. + * [u16 value: nr_params] - number of parameters. + */ + cscfg_extract_u32(feat_desc->match_flags); + cscfg_extract_u16(feat_desc->nr_regs); + cscfg_extract_u16(feat_desc->nr_params); + + /* register descriptors - 32 bit + 64 bit value */ + if (feat_desc->nr_regs) { + nr_regs_bytes = ((sizeof(u32) + sizeof(u64)) * feat_desc->nr_regs); + if ((buflen - used) < nr_regs_bytes) + return -EINVAL; + feat_desc->regs_desc = devm_kcalloc(cscfg_device(), + feat_desc->nr_regs, + sizeof(struct cscfg_regval_desc), + GFP_KERNEL); + if (!feat_desc->regs_desc) + return -ENOMEM; + + for (i = 0; i < feat_desc->nr_regs; i++) { + cscfg_extract_u32(val32); + p_reg_desc = (struct cscfg_regval_desc *)&feat_desc->regs_desc[i]; + CSCFG_FILE_U32_TO_REG_DESC_INFO(val32, p_reg_desc); + cscfg_extract_u64(feat_desc->regs_desc[i].val64); + } + } + + /* parameter descriptors - string + 64 bit value */ + if (feat_desc->nr_params) { + feat_desc->params_desc = devm_kcalloc(cscfg_device(), + feat_desc->nr_params, + sizeof(struct cscfg_parameter_desc), + GFP_KERNEL); + if (!feat_desc->params_desc) + return -ENOMEM; + for (i = 0; i < feat_desc->nr_params; i++) { + err = cscfg_file_read_elem_param(buffer, buflen, &used, + &feat_desc->params_desc[i]); + if (err) + return err; + } + } + + desc_arrays->feat_descs[feat_idx] = feat_desc; + *buf_used = used; + return 0; +} + +/* just read the feature name - if there is a feature at this position */ +static int cscfg_file_read_elem_feat_name(const u8 *buffer, const int buflen, int *buf_used, + struct cscfg_file_elem_str *elem_str) +{ + struct cscfg_file_elem_header elem_hdr; + int used = *buf_used; + int err; + + elem_str->str_len = 0; + /* + * read the header - if not config, then don't update buf_used + * pointer on return + */ + err = cscfg_file_read_elem_hdr(buffer, buflen, &used, &elem_hdr); + if (err) + return err; + if (elem_hdr.elem_type != CSCFG_FILE_ELEM_TYPE_FEAT) + return -EINVAL; + + /* read the feature name */ + err = cscfg_file_read_elem_str(buffer, buflen, &used, elem_str); + if (err) + return err; + *buf_used = used; + + return 0; +} + +/* + * Read a buffer and create the configuration and feature + * descriptors to load into the cscfg system + */ +int cscfg_file_read_buffer(const u8 *buffer, const int buflen, + struct cscfg_fs_load_descs *desc_arrays) +{ + struct cscfg_file_header hdr; + int used = 0, err, i; + + /* read in the file header */ + err = cscfg_file_read_hdr(buffer, buflen, &used, &hdr); + if (err) + return err; + + /* allocate the memory for the descriptor pointer arrays */ + err = cscfg_file_alloc_desc_arrays(desc_arrays, hdr.nr_features); + if (err) + return err; + + /* read elements */ + + /* first element could be a config so check */ + err = cscfg_file_read_elem_config(buffer, buflen, &used, desc_arrays); + if (err) + return err; + + /* now read and populate all the feature descriptors */ + for (i = 0; i < hdr.nr_features; i++) { + err = cscfg_file_read_elem_feature(buffer, buflen, &used, desc_arrays, i); + if (err) + return err; + } + return used; +} + +int cscfg_file_read_buffer_first_name(const u8 *buffer, const int buflen, + const char **name) +{ + struct cscfg_file_header hdr; + struct cscfg_file_elem_str elem_str; + int used = 0, err = 0; + + *name = NULL; + + /* read in the file header */ + err = cscfg_file_read_hdr(buffer, buflen, &used, &hdr); + if (err) + return err; + + err = cscfg_file_read_elem_config_name(buffer, buflen, &used, &elem_str); + if (err) + return err; + + /* no config string - get first feature name */ + if (!elem_str.str_len) { + err = cscfg_file_read_elem_feat_name(buffer, buflen, &used, &elem_str); + if (err) + return err; + } + if (elem_str.str_len) + *name = elem_str.str; + return err; +} diff --git a/drivers/hwtracing/coresight/coresight-config-file.h b/drivers/hwtracing/coresight/coresight-config-file.h new file mode 100644 index 000000000000..6c8c5af0a614 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-config-file.h @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#ifndef _CORESIGHT_CORESIGHT_CONFIG_FILE_H +#define _CORESIGHT_CORESIGHT_CONFIG_FILE_H + +/* + * Structures to represent configuration descriptors in a memory buffer + * to serialise to and from files + * + * File structure - for loading a configuration + features + * from configfs. + * + * [cscfg_file_header] - mandatory + * [CONFIG_ELEM] - optional - only one permitted, + * [FEATURE_ELEM] * [cscfg_file_header.nr_features] + * - optional - file valid with config only. + * + * Invalid file if no config or features. + * + * + * File structure for [CONFIG_ELEM]: + * + * [cscfg_file_elem_header] - header length value to end of feature strings. + * [cscfg_file_elem_str] - name of the configuration + * [cscfg_file_elem_str] - description of configuration + * [u16 value - nr_presets] + * [u32 value - nr_total_params] + * [u16 value - nr_feat_refs] + * [u64 values] * (nr_presets * nr_total_params) + * [cscfg_file_elem_str] * nr_feat_refs + * + * Only one configuration per file. + * + * File structure for a [FEATURE_ELEM] + * + * [cscfg_file_elem_header] - header length is total bytes to end of param structures. + * [cscfg_file_elem_str] - feature name. + * [cscfg_file_elem_str] - feature description. + * [u32 value: match_flags] + * [u16 value: nr_regs] - number of registers. + * [u16 value: nr_params] - number of parameters. + * [cscfg_regval_desc struct] * nr_regs + * [PARAM_ELEM] * nr_params + * + * File structure for [PARAM_ELEM] + * + * [cscfg_file_elem_str] - parameter name. + * [u64 value: param_value] - initial value. + */ + +/* major element types - configurations and features */ + +#define CSCFG_FILE_ELEM_TYPE_FEAT 0x1 +#define CSCFG_FILE_ELEM_TYPE_CFG 0x2 + +#define CSCFG_FILE_MAGIC_VERSION 0xC5CF0001 + +#define CSCFG_FILE_U32_TO_REG_DESC_INFO(val32, p_desc) \ + { \ + p_desc->type = (val32 >> 24) & 0xFF; \ + p_desc->offset = (val32 >> 12) & 0xFFF; \ + p_desc->hw_info = val32 & 0xFFF; \ + } + +#define CSCFG_FILE_REG_DESC_INFO_TO_U32(val32, p_desc) \ + { \ + val32 = p_desc->hw_info & 0xFFF; \ + val32 |= ((p_desc->offset & 0xFFF) << 12); \ + val32 |= ((p_desc->type & 0xFF) << 24); \ + } + +/* binary attributes in configfs need a max size - declare a value for this. */ +#define CSCFG_FILE_MAXSIZE 16384 + +/* limit string sizes */ +#define CSCFG_FILE_STR_MAXSIZE 1024 + + +/** + * file header. + * + * @magic_version: magic number / version for file/buffer format. + * @length : total length of all data in the buffer. + * @nr_features : total number of features in the buffer. + */ +struct cscfg_file_header { + u32 magic_version; + u16 length; + u16 nr_features; +}; + +/** + * element header + * + * @elem_length: total length of this element + * @elem_type : type of this element - one of CSCFG_FILE_ELEM_TYPE.. defines. + */ +struct cscfg_file_elem_header { + u16 elem_length; + u8 elem_type; +}; + +/** + * string file element. + * + * @str_len: length of string buffer including 0 terminator + * @str : string buffer - 0 terminated. + */ +struct cscfg_file_elem_str { + u16 str_len; + char *str; +}; + +#endif /* _CORESIGHT_CORESIGHT_CONFIG_FILE_H */ diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h index 9bd44b940add..770986316bc2 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -150,6 +150,23 @@ struct cscfg_config_desc { struct config_group *fs_group; }; +/** + * Dynamically loaded descriptor arrays loaded via configfs. + * + * For builtin or module loaded configurations / features these are + * statically defined at compile time. For configfs we create the arrays + * dynamically so need a structure to handle this. + * + * @owner_info: associated owner info struct to add to load order list. + * @config_descs: array of config descriptor pointers. + * @feat_descs: array of feature descriptor pointers. + */ +struct cscfg_fs_load_descs { + void *owner_info; + struct cscfg_config_desc **config_descs; + struct cscfg_feature_desc **feat_descs; +}; + /** * config register instance - part of a loaded feature. * maps register values to csdev driver structures diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h index 9106ffab4833..6a6e33585be9 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.h +++ b/drivers/hwtracing/coresight/coresight-syscfg.h @@ -66,6 +66,7 @@ struct cscfg_registered_csdev { enum cscfg_load_owner_type { CSCFG_OWNER_PRELOAD, CSCFG_OWNER_MODULE, + CSCFG_OWNER_CONFIGFS, }; /** From patchwork Mon Nov 1 22:47: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: 12597509 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E6F04C433F5 for ; Mon, 1 Nov 2021 22:49:11 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 B599160EDF for ; Mon, 1 Nov 2021 22:49:11 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org B599160EDF Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=21i1qwcjrilVJOB2sZtOsqOegs5Y7R65W1pQDV0ji7s=; b=rx/d8Rtq8tRJuN xUUZOesouVE5BD8GfQcUmOavvMHcSIyYMCyZnQbU62M7rP+MZ3oRoZfW6kH2arh7xMHRpLvrMCBi6 mZcKffA4Vxa+Ptm4Vgim59030hTed0hkhYFvm98/rZ5L+PglmLTDLcfRfcNG1CNj6rzHniRgwlNyR KracXi6gwfkG6Zj75AY2svvHwXFZwI9OXtXYpG3JzxRgU/SJqRKGy53wDPWs8P4rF47G9lUyxu8cc 5Gyr+lPqs/mc7fjz29sVZEo/jOWnqhHqBsUHwLF6QCKGNWaGtVFM7WWUa0/3fRZfsD9dkg4W3p8x1 SA4JBfcYvXh3EqsDFNTQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhg5m-00HRZ2-H9; Mon, 01 Nov 2021 22:47:50 +0000 Received: from mail-wr1-x42b.google.com ([2a00:1450:4864:20::42b]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhg5Y-00HRVn-Ei for linux-arm-kernel@lists.infradead.org; Mon, 01 Nov 2021 22:47:38 +0000 Received: by mail-wr1-x42b.google.com with SMTP id s13so23263431wrb.3 for ; Mon, 01 Nov 2021 15:47:36 -0700 (PDT) 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=6KRbH9mLbGvcaPLCyVN9O1UOrtK0Cg+7Cez0byQAE4I=; b=ubAyyYf+eVDvC24+SYffiyUH3C5VgTSu2W3g7ghzX33GGa3+R7LgW4fMuhyFC4ngAk qQHp0IEJkBY1Hxj3OwWsXdX0uzTAAeKGfr+JWxmOutK+KZZ4+uic9gZ7bc4s2lj0l0cu lJ9RrJKgLHvTm5s1W7YBmgB3b3zmfKaZbsoK9e/9RPHCZOsxMKZSA5fXKS2UxXAjbB4Z XODZEtXMNy8OCwfr5OECBgKl4FdErpdrlv5VX7Z0xzhzrB6E7AfI20TyUwOkLoN+nNsJ o2GgystNpBkWxQvEJHFaYyAmbUUt1j9UznPI0vmjFRHOkZfAur/ha0EXme3JuPL6lzXX dnSw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=6KRbH9mLbGvcaPLCyVN9O1UOrtK0Cg+7Cez0byQAE4I=; b=cjKPJmXCl5mTYSK8jon3sucrWITBdauqiLuk+4X6q8hekJUP84i925FUCKrrwWq6Pf 6zl4B/T1InYRShc7wuzoIaI34qdiKibHMiIDXtrvg0ZSb1tPnc8xNEg4OMQjNPqI0v7J xaHgJkgCrtc93qs4u683tmZYYWKxgAU8BQa8Tt4OxXQ+QLY7Tgcy8Uj+rc5rhaEGiPzg Ez7xdq6vZc0yiq+Yajb4eT8EV3rfj+f4Y7FZwFKop8hMnlCICvL2gymOgSHS40GeBgx0 szt5+J7ae7NbN9L9BkX5+/fcskfub5ODzkhvD/OHI1hxbcg8NXWkJzk3EHzG1d3uV5XY y1hA== X-Gm-Message-State: AOAM533dTFJNnS8l83YV2uixJbMfPGL5OQtiMwwAKsZa0bw7dFZQDDPu C0VBxJkxcDCEhhp4TTKaJToEpUDkSf00Og== X-Google-Smtp-Source: ABdhPJzQM3Y+hgpdXhItO57YzWQUUMP5De5XK513XJwJcEAI7pcRHJsv/D0qJWIvA3JVBIIOC093dA== X-Received: by 2002:adf:fb04:: with SMTP id c4mr40906792wrr.39.1635806855003; Mon, 01 Nov 2021 15:47:35 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:cd6d:75aa:3402:e4a]) by smtp.gmail.com with ESMTPSA id 10sm858647wme.27.2021.11.01.15.47.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 15:47:34 -0700 (PDT) From: Mike Leach To: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org, mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [PATCH 2/6] coresight: configfs: Add in binary attributes to load files Date: Mon, 1 Nov 2021 22:47:27 +0000 Message-Id: <20211101224731.27870-3-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211101224731.27870-1-mike.leach@linaro.org> References: <20211101224731.27870-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211101_154736_526434_1DF0B10B X-CRM114-Status: GOOD ( 28.60 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add in functionality and binary attribute to load configurations as binary data. Reads the incoming attribute, which must be formatted correctly as defined in the file reader code - and will create a configuration and/or features and load them into the system. These will then appear in configfs ready for use. Unload functionality is also provided. Signed-off-by: Mike Leach --- .../coresight/coresight-config-file.h | 7 + .../coresight/coresight-syscfg-configfs.c | 148 +++++++++++++++++- .../coresight/coresight-syscfg-configfs.h | 8 + .../hwtracing/coresight/coresight-syscfg.c | 36 +++++ .../hwtracing/coresight/coresight-syscfg.h | 1 + 5 files changed, 193 insertions(+), 7 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-config-file.h b/drivers/hwtracing/coresight/coresight-config-file.h index 6c8c5af0a614..03899f7d94c9 100644 --- a/drivers/hwtracing/coresight/coresight-config-file.h +++ b/drivers/hwtracing/coresight/coresight-config-file.h @@ -115,4 +115,11 @@ struct cscfg_file_elem_str { char *str; }; +/* kernel configfs needs to read the incoming file buffers to load. */ +int cscfg_file_read_buffer(const u8 *buffer, const int buflen, + struct cscfg_fs_load_descs *desc_arrays); +/* to unload we just need the first name - config or first feature */ +int cscfg_file_read_buffer_first_name(const u8 *buffer, const int buflen, + const char **name); + #endif /* _CORESIGHT_CORESIGHT_CONFIG_FILE_H */ diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c index c388a77a2683..21a67aae4ea9 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c @@ -7,6 +7,7 @@ #include #include "coresight-config.h" +#include "coresight-config-file.h" #include "coresight-syscfg-configfs.h" /* create a default ci_type. */ @@ -380,14 +381,147 @@ static struct config_group *cscfg_create_feature_group(struct cscfg_feature_desc return &feat_view->group; } +/* Attributes in configfs that allow load and unload of configuration binary files */ + +/* load "buffer" as a configuration binary file */ +static ssize_t cscfg_cfg_load_write(struct config_item *item, const void *buffer, size_t size) +{ + struct cscfg_fs_configs_grp *configs_grp; + struct cscfg_fs_load_descs *load_descs = 0; + struct cscfg_load_owner_info *owner_info = 0; + int err = 0; + const char *name; + + configs_grp = container_of(to_config_group(item), struct cscfg_fs_configs_grp, group); + if (size > CSCFG_FILE_MAXSIZE) { + scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN, + "Load error: Input file too large.\n"); + return -EINVAL; + } + + load_descs = kzalloc(sizeof(struct cscfg_fs_load_descs), GFP_KERNEL); + owner_info = kzalloc(sizeof(struct cscfg_load_owner_info), GFP_KERNEL); + if (!load_descs || !owner_info) { + err = -ENOMEM; + goto exit_memfree; + } + + load_descs->owner_info = owner_info; + owner_info->owner_handle = load_descs; + owner_info->type = CSCFG_OWNER_CONFIGFS; + + err = cscfg_file_read_buffer(buffer, size, load_descs); + if (err) { + scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN, + "Load error: Failed to read input file.\n"); + goto exit_memfree; + } + + err = cscfg_load_config_sets(load_descs->config_descs, load_descs->feat_descs, owner_info); + if (err) { + scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN, + "Load error: Failed to load configuaration file.\n"); + goto exit_memfree; + } + + /* name of config if there is one, otherwise first feature */ + if (load_descs->config_descs[0]) + name = load_descs->config_descs[0]->name; + else + name = load_descs->feat_descs[0]->name; + scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN, + "OK: configuration file loaded (%s).\n", name); + + return size; + +exit_memfree: + kfree(load_descs); + kfree(owner_info); + return err; +} +CONFIGFS_BIN_ATTR_WO(cscfg_cfg_, load, NULL, CSCFG_FILE_MAXSIZE); + +/* read "buffer" and unload configuration */ +static ssize_t cscfg_cfg_unload_write(struct config_item *item, const void *buffer, size_t size) +{ + struct cscfg_fs_configs_grp *configs_grp; + struct cscfg_fs_load_descs *load_descs; + const char *name; + int err; + + configs_grp = container_of(to_config_group(item), struct cscfg_fs_configs_grp, group); + if (size > CSCFG_FILE_MAXSIZE) { + scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN, + "Unload error: Input file too large\n"); + return -EINVAL; + } + + err = cscfg_file_read_buffer_first_name(buffer, size, &name); + if (err) { + scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN, + "Unload error: Failed to read input file\n"); + return err; + } + + load_descs = cscfg_find_fs_owned_cfg_by_name(name); + if (!load_descs) { + scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN, + "Unload error: Failed to find configuration %s from input file\n", + name); + return err; + } + err = cscfg_unload_config_sets(load_descs->owner_info); + if (err) { + scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN, + "Unload error: Cannot unload configuration %s\n", + name); + return err; + } + + scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN, + "OK: configuration file unloaded (%s).\n", name); + + kfree((struct cscfg_load_owner_info *)load_descs->owner_info); + kfree(load_descs); + return size; +} +CONFIGFS_BIN_ATTR_WO(cscfg_cfg_, unload, NULL, CSCFG_FILE_MAXSIZE); + +/* show the status of the last load / unload operation */ +static ssize_t cscfg_cfg_last_load_status_show(struct config_item *item, char *page) +{ + struct cscfg_fs_configs_grp *configs_grp; + + configs_grp = container_of(to_config_group(item), struct cscfg_fs_configs_grp, group); + + return scnprintf(page, PAGE_SIZE, "%s\n", configs_grp->status); +} +CONFIGFS_ATTR_RO(cscfg_cfg_, last_load_status); + +static struct configfs_attribute *cscfg_config_configs_attrs[] = { + &cscfg_cfg_attr_last_load_status, + NULL, +}; + +static struct configfs_bin_attribute *cscfg_config_configfs_bin_attrs[] = { + &cscfg_cfg_attr_load, + &cscfg_cfg_attr_unload, + NULL, +}; + static struct config_item_type cscfg_configs_type = { .ct_owner = THIS_MODULE, + .ct_bin_attrs = cscfg_config_configfs_bin_attrs, + .ct_attrs = cscfg_config_configs_attrs, }; -static struct config_group cscfg_configs_grp = { - .cg_item = { - .ci_namebuf = "configurations", - .ci_type = &cscfg_configs_type, +/* group for configurations dir, with load, unload and status attribs */ +static struct cscfg_fs_configs_grp cscfg_configs_grp = { + .group = { + .cg_item = { + .ci_namebuf = "configurations", + .ci_type = &cscfg_configs_type, + }, }, }; @@ -400,7 +534,7 @@ int cscfg_configfs_add_config(struct cscfg_config_desc *config_desc) new_group = cscfg_create_config_group(config_desc); if (IS_ERR(new_group)) return PTR_ERR(new_group); - err = configfs_register_group(&cscfg_configs_grp, new_group); + err = configfs_register_group(&cscfg_configs_grp.group, new_group); if (!err) config_desc->fs_group = new_group; return err; @@ -468,8 +602,8 @@ int cscfg_configfs_init(struct cscfg_manager *cscfg_mgr) 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_configs_grp.group); + configfs_add_default_group(&cscfg_configs_grp.group, &subsys->su_group); config_group_init(&cscfg_features_grp); configfs_add_default_group(&cscfg_features_grp, &subsys->su_group); diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.h b/drivers/hwtracing/coresight/coresight-syscfg-configfs.h index 373d84d43268..8d6900e8c1ea 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.h +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.h @@ -11,6 +11,14 @@ #define CSCFG_FS_SUBSYS_NAME "cs-syscfg" +#define CSCFG_FS_STATUS_STRLEN 256 + +/* container for configs group */ +struct cscfg_fs_configs_grp { + struct config_group group; + char status[CSCFG_FS_STATUS_STRLEN]; +}; + /* container for configuration view */ struct cscfg_fs_config { struct cscfg_config_desc *config_desc; diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index 759c32889efd..ceab30eac9b9 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -586,6 +586,42 @@ int cscfg_unload_config_sets(struct cscfg_load_owner_info *owner_info) } EXPORT_SYMBOL_GPL(cscfg_unload_config_sets); +/* find a configuration owned by configfs by name of config / first feature */ +struct cscfg_fs_load_descs *cscfg_find_fs_owned_cfg_by_name(const char *name) +{ + struct cscfg_load_owner_info *owner_info; + struct cscfg_fs_load_descs *fs_load_cfg = NULL; + struct cscfg_config_desc *config_desc; + struct cscfg_feature_desc *feat_desc; + + mutex_lock(&cscfg_mutex); + + /* search the load_owner list for CONFIGFS loaded types */ + list_for_each_entry(owner_info, &cscfg_mgr->load_order_list, item) { + /* if this is a config fs owned item, then try to match */ + if (owner_info->type == CSCFG_OWNER_CONFIGFS) { + fs_load_cfg = owner_info->owner_handle; + /* first try to match the name against the config if it exists */ + if (fs_load_cfg->config_descs[0]) { + config_desc = fs_load_cfg->config_descs[0]; + if (!strcmp(config_desc->name, name)) + goto exit_unlock; + /* no config - match against first feature name */ + } else { + feat_desc = fs_load_cfg->feat_descs[0]; + if (!strcmp(feat_desc->name, name)) + goto exit_unlock; + } + /* no match - move on */ + fs_load_cfg = NULL; + } + } + +exit_unlock: + mutex_unlock(&cscfg_mutex); + return fs_load_cfg; +} + /* Handle coresight device registration and add configs and features to devices */ /* iterate through config lists and load matching configs to device */ diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h index 6a6e33585be9..6bc29abe0650 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.h +++ b/drivers/hwtracing/coresight/coresight-syscfg.h @@ -95,6 +95,7 @@ int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc, int param_idx, u64 value); int cscfg_config_sysfs_activate(struct cscfg_config_desc *cfg_desc, bool activate); void cscfg_config_sysfs_set_preset(int preset); +struct cscfg_fs_load_descs *cscfg_find_fs_owned_cfg_by_name(const char *name); /* syscfg manager external API */ int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs, From patchwork Mon Nov 1 22:47: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: 12597511 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2F81AC433EF for ; Mon, 1 Nov 2021 22:49:22 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 F047960EDF for ; Mon, 1 Nov 2021 22:49:21 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org F047960EDF Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=KDX4fb35enD/YVzG9JMMBLMly3ROXtlWyZdCP29L2qA=; b=bB9XALnLZsfjT/ F78oG83zR+9yYn6YLFaYZbho1D5Eh/zWWu4KteU/d4gQzsyMKYIdPup/axcPEK7k5RB1/EHDeQoNZ yZh3QLTHR0HECZlS8F5oSUNB1bIrq8GNFoOMABc5eLEgi5c4f9UIaWZAa8+iKZSol3c/W4rtMy9rf PNvYnQPRoKufhfbICYfZddTn5hn6wmNBgu84zcEdtL+RodrNQZUkwq61jCwW8eR+eMX8pIhkRMtmj 8x8XiK1L1lUtIRODUqe1ccmwqTplOaY+2JdEq/kb3YCUJOdcfMqLI/qM8mdls5O54t49+FFSNtSCD mlLJfBB93hSzOui0HqjA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhg5y-00HRaZ-BM; Mon, 01 Nov 2021 22:48:02 +0000 Received: from mail-wr1-x42c.google.com ([2a00:1450:4864:20::42c]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhg5Z-00HRVq-4d for linux-arm-kernel@lists.infradead.org; Mon, 01 Nov 2021 22:47:40 +0000 Received: by mail-wr1-x42c.google.com with SMTP id o14so30306742wra.12 for ; Mon, 01 Nov 2021 15:47:36 -0700 (PDT) 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=ZnJC6HDO4hKLnjoDe3yF52L4cyf5HBXuoo8iYrPGqxk=; b=g1JU4d0ZZgYReuLo1r1rs+vQSBa0naVHcblGIlO9p568/vtbAvwi99VvzORL0gZYrT SXwh2zhFmFmN+2ZR/DYaVYTdbkmylkl5WptBZqOJ1Y3GK7zxI0YsCTB2hJLC7rc3m4ja Bl5Brhs+rBrKH6FznpK17RkoVNzxauVWKVwhhFruU9ptQu2Vlglxq9bH9aoWXYJ+1JG1 mi1ZWji2pBiTU/PfUDTgOP414ysGELacucHpzJO2Xu8tilXzbr5SrwFN3f/f9YmMgZ03 bC+RaFNJ0KhfBNwAvMoEx3q2n0/CmvBe4dRRMm/BoKCky0Ngh1EbagJMb14cbe/0HtJo Q87Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ZnJC6HDO4hKLnjoDe3yF52L4cyf5HBXuoo8iYrPGqxk=; b=5cZtvBqaSCnXPX2s/GvE8DS72F6asrpowrmiW/FbZlTPTqvy3kfT1BkfU8xp/rcj+C 6Ilc+Rt5Yx2gRDxUAy66n0wLQGk0nhADzgRzIX4VshfgWASENfZ9ZFlOU1+50zjFKps6 UaiRLoTUI1vnQuxtdLchrNNm6Q9WT5zUQfOcAOAHef1ad+/76Qt99Dnwcr6KV+hDKOS/ 2ypwA7EZFgtIgY1+sCZshUrVJSkZRSc4nLYtA35gJsouLR33v31WVGJnDFdDj8d6bilE UIbcoqmNjSIX5MdRTO0ztLrWCmWxdPFsKZ6tPyZum27JFzIYPMQrDsBFTf8USzv+To6k nFWw== X-Gm-Message-State: AOAM5331GD7/3Y7XsGxNu1y6ht6Tg0DdK9S7DMPJkM0ME4nr4W5kMGXR v6ONq0on10MsE44DRQFSy7y+W369I2+mgA== X-Google-Smtp-Source: ABdhPJyC9R8v6NZJN6N3rZS79CuRZCvccTIstRdhkApOo3igdBxkyAhPXNNjA7SNOyR81XP8lQZ8Hg== X-Received: by 2002:adf:fa8f:: with SMTP id h15mr42245281wrr.323.1635806855660; Mon, 01 Nov 2021 15:47:35 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:cd6d:75aa:3402:e4a]) by smtp.gmail.com with ESMTPSA id 10sm858647wme.27.2021.11.01.15.47.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 15:47:35 -0700 (PDT) From: Mike Leach To: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org, mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [PATCH 3/6] coresight: configfs: Modify config files to allow userspace use Date: Mon, 1 Nov 2021 22:47:28 +0000 Message-Id: <20211101224731.27870-4-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211101224731.27870-1-mike.leach@linaro.org> References: <20211101224731.27870-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211101_154737_209683_F2344F7A X-CRM114-Status: GOOD ( 28.36 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Update coresight-config.h and the coresight-config-file.c & .h to allow use in userspace programs. Use __KERNEL__ defines to filter out driver only structures and elements so that user space programs can use the descriptor structures. Abstract memory allocation in coresight-config-file.c to allow read file functions to be run in userspace and kernel drivers. Signed-off-by: Mike Leach --- .../coresight/coresight-config-file.c | 96 +++++++++++++------ .../coresight/coresight-config-file.h | 33 +++++++ .../hwtracing/coresight/coresight-config.h | 21 ++++ 3 files changed, 122 insertions(+), 28 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-config-file.c b/drivers/hwtracing/coresight/coresight-config-file.c index 3fd001938324..77a64b54280d 100644 --- a/drivers/hwtracing/coresight/coresight-config-file.c +++ b/drivers/hwtracing/coresight/coresight-config-file.c @@ -4,10 +4,58 @@ * Author: Mike Leach */ -#include "coresight-config.h" #include "coresight-config-file.h" + +/* + * To allow reuse of this source in tools, define memory allocation fns according + * to build environment. + */ + +#ifdef __KERNEL__ #include "coresight-syscfg.h" +static void *cscfg_calloc(size_t num, size_t size) +{ + return devm_kcalloc(cscfg_device(), num, size, GFP_KERNEL); +} + +static char *cscfg_strdup(const char *str) +{ + return devm_kstrdup(cscfg_device(), str, GFP_KERNEL); +} + +static void *cscfg_zalloc(size_t size) +{ + return devm_kzalloc(cscfg_device(), size, GFP_KERNEL); +} + +#else + +#include +#include +#include + +static void *cscfg_calloc(size_t num, size_t size) +{ + return calloc(num, size); +} + +static char *cscfg_strdup(const char *str) +{ + return strdup(str); +} + +static void *cscfg_zalloc(size_t size) +{ + void *ptr = malloc(size); + + if (ptr) + memset(ptr, 0, size); + return ptr; +} + +#endif + #define cscfg_extract_u64(val64) { \ val64 = *(u64 *)(buffer + used); \ used += sizeof(u64); \ @@ -80,6 +128,7 @@ static int cscfg_file_read_elem_str(const u8 *buffer, const int buflen, int *buf struct cscfg_file_elem_str *elem_str) { int used = *buf_used; + const u8 *str; if ((buflen - used) < sizeof(u16)) return -EINVAL; @@ -89,11 +138,13 @@ static int cscfg_file_read_elem_str(const u8 *buffer, const int buflen, int *buf if ((buflen - used) < elem_str->str_len) return -EINVAL; + str = buffer + used; + /* check for 0 termination */ - if (buffer[elem_str->str_len - 1] != 0) + if (str[elem_str->str_len - 1] != 0) return -EINVAL; - elem_str->str = devm_kstrdup(cscfg_device(), (char *)buffer, GFP_KERNEL); + elem_str->str = cscfg_strdup((char *)str); used += elem_str->str_len; *buf_used = used; @@ -104,14 +155,12 @@ static int cscfg_file_alloc_desc_arrays(struct cscfg_fs_load_descs *desc_arrays, int nr_features) { /* arrays are 0 terminated - max of 1 config & nr_features features */ - desc_arrays->config_descs = devm_kcalloc(cscfg_device(), 2, - sizeof(struct cscfg_config_desc *), - GFP_KERNEL); + desc_arrays->config_descs = cscfg_calloc(2, sizeof(struct cscfg_config_desc *)); if (!desc_arrays->config_descs) return -ENOMEM; - desc_arrays->feat_descs = devm_kcalloc(cscfg_device(), nr_features + 1, - sizeof(struct cscfg_feature_desc *), - GFP_KERNEL); + + desc_arrays->feat_descs = cscfg_calloc(nr_features + 1, + sizeof(struct cscfg_feature_desc *)); if (!desc_arrays->feat_descs) return -ENOMEM; return 0; @@ -138,8 +187,7 @@ static int cscfg_file_read_elem_config(const u8 *buffer, const int buflen, int * return 0; /* we have a config - allocate the descriptor */ - config_desc = devm_kzalloc(cscfg_device(), sizeof(struct cscfg_config_desc), - GFP_KERNEL); + config_desc = cscfg_zalloc(sizeof(struct cscfg_config_desc)); if (!config_desc) return -ENOMEM; @@ -165,8 +213,7 @@ static int cscfg_file_read_elem_config(const u8 *buffer, const int buflen, int * /* read the array of 64bit presets if present */ nr_preset_vals = config_desc->nr_total_params * config_desc->nr_presets; if (nr_preset_vals) { - presets = devm_kcalloc(cscfg_device(), nr_preset_vals, - sizeof(u64), GFP_KERNEL); + presets = cscfg_calloc(nr_preset_vals, sizeof(u64)); if (!presets) return -ENOMEM; @@ -181,10 +228,8 @@ static int cscfg_file_read_elem_config(const u8 *buffer, const int buflen, int * /* read the array of feature names referenced by the config */ if (config_desc->nr_feat_refs) { - config_desc->feat_ref_names = devm_kcalloc(cscfg_device(), - config_desc->nr_feat_refs, - sizeof(char *), - GFP_KERNEL); + config_desc->feat_ref_names = cscfg_calloc(config_desc->nr_feat_refs, + sizeof(char *)); if (!config_desc->feat_ref_names) return -ENOMEM; @@ -262,8 +307,7 @@ static int cscfg_file_read_elem_feature(const u8 *buffer, const int buflen, int u32 val32; /* allocate the feature descriptor object */ - feat_desc = devm_kzalloc(cscfg_device(), sizeof(struct cscfg_feature_desc), - GFP_KERNEL); + feat_desc = cscfg_zalloc(sizeof(struct cscfg_feature_desc)); if (!feat_desc) return -ENOMEM; @@ -302,10 +346,8 @@ static int cscfg_file_read_elem_feature(const u8 *buffer, const int buflen, int nr_regs_bytes = ((sizeof(u32) + sizeof(u64)) * feat_desc->nr_regs); if ((buflen - used) < nr_regs_bytes) return -EINVAL; - feat_desc->regs_desc = devm_kcalloc(cscfg_device(), - feat_desc->nr_regs, - sizeof(struct cscfg_regval_desc), - GFP_KERNEL); + feat_desc->regs_desc = cscfg_calloc(feat_desc->nr_regs, + sizeof(struct cscfg_regval_desc)); if (!feat_desc->regs_desc) return -ENOMEM; @@ -319,10 +361,8 @@ static int cscfg_file_read_elem_feature(const u8 *buffer, const int buflen, int /* parameter descriptors - string + 64 bit value */ if (feat_desc->nr_params) { - feat_desc->params_desc = devm_kcalloc(cscfg_device(), - feat_desc->nr_params, - sizeof(struct cscfg_parameter_desc), - GFP_KERNEL); + feat_desc->params_desc = cscfg_calloc(feat_desc->nr_params, + sizeof(struct cscfg_parameter_desc)); if (!feat_desc->params_desc) return -ENOMEM; for (i = 0; i < feat_desc->nr_params; i++) { @@ -399,7 +439,7 @@ int cscfg_file_read_buffer(const u8 *buffer, const int buflen, if (err) return err; } - return used; + return 0; } int cscfg_file_read_buffer_first_name(const u8 *buffer, const int buflen, diff --git a/drivers/hwtracing/coresight/coresight-config-file.h b/drivers/hwtracing/coresight/coresight-config-file.h index 03899f7d94c9..04c365e5109b 100644 --- a/drivers/hwtracing/coresight/coresight-config-file.h +++ b/drivers/hwtracing/coresight/coresight-config-file.h @@ -7,6 +7,39 @@ #ifndef _CORESIGHT_CORESIGHT_CONFIG_FILE_H #define _CORESIGHT_CORESIGHT_CONFIG_FILE_H +#include + +#ifndef __KERNEL__ +/* + * allow the user space programs to include the coresight config headers + * to use the _desc structures, and reuse the read code + */ +#ifndef u8 +typedef __u8 u8; +typedef __u16 u16; +typedef __u32 u32; +typedef __u64 u64; +#endif + +/* ARRAY SIZE is useful too */ +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +/* define EINVAL for user space */ +#ifndef EINVAL +#define EINVAL 22 +#endif + +#ifndef ENOMEM +#define ENOMEM 12 +#endif + +#endif + +#include "coresight-config.h" + + /* * Structures to represent configuration descriptors in a memory buffer * to serialise to and from files diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h index 770986316bc2..2136393df710 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -7,7 +7,14 @@ #ifndef _CORESIGHT_CORESIGHT_CONFIG_H #define _CORESIGHT_CORESIGHT_CONFIG_H +/* + * Filter out kernel only portions of the file to allow user space programs + * to use the descriptor definitions. + */ +#ifdef __KERNEL__ #include +#endif + #include /* CoreSight Configuration Management - component and system wide configuration */ @@ -103,14 +110,18 @@ struct cscfg_regval_desc { struct cscfg_feature_desc { const char *name; const char *description; +#ifdef __KERNEL__ struct list_head item; +#endif u32 match_flags; int nr_params; struct cscfg_parameter_desc *params_desc; int nr_regs; struct cscfg_regval_desc *regs_desc; +#ifdef __KERNEL__ void *load_owner; struct config_group *fs_group; +#endif }; /** @@ -138,16 +149,20 @@ struct cscfg_feature_desc { struct cscfg_config_desc { const char *name; const char *description; +#ifdef __KERNEL__ struct list_head item; +#endif int nr_feat_refs; const char **feat_ref_names; int nr_presets; int nr_total_params; const u64 *presets; /* nr_presets * nr_total_params */ +#ifdef __KERNEL__ struct dev_ext_attribute *event_ea; atomic_t active_cnt; void *load_owner; struct config_group *fs_group; +#endif }; /** @@ -162,11 +177,16 @@ struct cscfg_config_desc { * @feat_descs: array of feature descriptor pointers. */ struct cscfg_fs_load_descs { +#ifdef __KERNEL__ void *owner_info; +#endif struct cscfg_config_desc **config_descs; struct cscfg_feature_desc **feat_descs; }; +/* remainder of header is used by the kernel drivers only */ +#ifdef __KERNEL__ + /** * config register instance - part of a loaded feature. * maps register values to csdev driver structures @@ -274,4 +294,5 @@ void cscfg_csdev_disable_config(struct cscfg_config_csdev *config_csdev); /* reset a feature to default values */ void cscfg_reset_feat(struct cscfg_feature_csdev *feat_csdev); +#endif /* __KERNEL__ */ #endif /* _CORESIGHT_CORESIGHT_CONFIG_H */ From patchwork Mon Nov 1 22:47: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: 12597517 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C0584C433EF for ; Mon, 1 Nov 2021 22:50:20 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 8C10160F0F for ; Mon, 1 Nov 2021 22:50:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 8C10160F0F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=na+rsbqUFRydmF/QVrOLa2iVQCQo8DoGE3x17z1VkYw=; b=VQLALkd/dUDDu1 2kRym0teXzGOqFaU++LaVat0H7r1OCjWog0EGIUK8NCKq9Z+f7d+LhISxHy87GRg0gxQnjn4oOYep DiLB5UMlCo2mGS6MdzxxsgNJ9V47aKlKqZy0P9MKBfs6ytOrUY7Vrg2crBwKyqYQ9CdHQrEXMvKdp 1Az/wGLNDZEtlD7jbzKZOD/gxb9akvQbqHBMGwMuIpJk8Iqkmc6GBoEbbZUTeNi4E0Gtit+5Zjs0G Iol/zYXxoh4uCC1depbVNSo2yZLU+GrJmMR8Zk6cWFSIbb08K9rs5QbNPkfGmsL4mAHNZTr7ug0+u R4XG5JrMQKCRKsvETtyw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhg6b-00HRp0-7S; Mon, 01 Nov 2021 22:48:41 +0000 Received: from mail-wm1-x331.google.com ([2a00:1450:4864:20::331]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhg5Z-00HRWa-W5 for linux-arm-kernel@lists.infradead.org; Mon, 01 Nov 2021 22:47:41 +0000 Received: by mail-wm1-x331.google.com with SMTP id o4-20020a1c7504000000b0032cab7473caso604036wmc.1 for ; Mon, 01 Nov 2021 15:47:37 -0700 (PDT) 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=Ky2DtWLrDHXeN3dfZEi54AGY8N6qWbQzEs2U9otpzmo=; b=SLAfoAZgZdLfT/Ok3mLdDCPAL9uUlIoa8zat/nGejcvBeAeutyt/oylM9vvrN3TE3c UjvhAcA0C4YWPzHn1M3NsLaLB37JV7j2pZs7Zs5O0ry8/acD9k5QHUpddLCedeETB/1U pHCtkDHrLMjt6HEAp4F4AXdKEjDlHilAVfDCUIqcdZofmZ8TxyWAaYEeGWgYSsWEwrFK /ww79aHpC1kv3iH9VV2Q0ykdRg1nc0/yP0Whjczw7dVdq0GkUu2wXL0UNfeK34Tqfueg GwSDMVGUiBqQQflsjWyDBUjoCnkh3wwNHpraVDevW58kEFdO/HR+j48mEyOXjFbHyaiD OKNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Ky2DtWLrDHXeN3dfZEi54AGY8N6qWbQzEs2U9otpzmo=; b=LhpiWP8CL/72oi2L2rUHET09HfEDhVQp7gMKsw1bhjmG45qbrsBHA6wekqFfxuAoYB DaYBs4n1ieT4PviXThcHlwZniMz6hsLXkvVDhUdNgxTym+mnVQx6yKof2CVaBEr395Ym CKeq59uTItY8edzZZWOpgPL+Iz+oq1KD4uILc/L5PDp5RxK861NiBHKDqolxM4861eyd XrWR8kWhqSNYy4p0AZEQWfza92JBAuv5oNj64nnIMhvK4Q4yCzYOj4i65VpqsLfIIMHP 1IjhKSNFaVGAgHIwB1+P3ZFuX6+MDdCrEELLXHU8uZ0NlmCoSkHBAf65MhAdr7K4AjNS yuDQ== X-Gm-Message-State: AOAM533Rq3Umt/mGP8KPaQQiqzI52T2uuB9GhmAReP1QQOIVPdZ/RqMQ 2j8u1rkirc5DAJD4VYVFUujl5A== X-Google-Smtp-Source: ABdhPJwb8FWIcbWRDxAH5Y/nVSx0eEFBMqCfqcnLXkTTbC4sZHKV59bKm//X97+XKt84SvAt4JVoMQ== X-Received: by 2002:a7b:c344:: with SMTP id l4mr2260228wmj.64.1635806856258; Mon, 01 Nov 2021 15:47:36 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:cd6d:75aa:3402:e4a]) by smtp.gmail.com with ESMTPSA id 10sm858647wme.27.2021.11.01.15.47.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 15:47:35 -0700 (PDT) From: Mike Leach To: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org, mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [PATCH 4/6] coresight: samples: Add an example config writer for configfs load Date: Mon, 1 Nov 2021 22:47:29 +0000 Message-Id: <20211101224731.27870-5-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211101224731.27870-1-mike.leach@linaro.org> References: <20211101224731.27870-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211101_154738_079730_DA882E83 X-CRM114-Status: GOOD ( 32.07 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add an example file generator to test loading configurations via a binary attribute in configfs. Provides a file buffer writer function that can be re-used in other userspace programs. Buffer write format matches that expected by the corresponding reader in the configfs driver code. Signed-off-by: Mike Leach --- samples/coresight/Makefile | 7 + samples/coresight/coresight-cfg-bufw.c | 302 ++++++++++++++++++++++ samples/coresight/coresight-cfg-bufw.h | 24 ++ samples/coresight/coresight-cfg-filegen.c | 89 +++++++ 4 files changed, 422 insertions(+) create mode 100644 samples/coresight/coresight-cfg-bufw.c create mode 100644 samples/coresight/coresight-cfg-bufw.h create mode 100644 samples/coresight/coresight-cfg-filegen.c diff --git a/samples/coresight/Makefile b/samples/coresight/Makefile index b3fce4af2347..07bfd99d7a68 100644 --- a/samples/coresight/Makefile +++ b/samples/coresight/Makefile @@ -1,4 +1,11 @@ # SPDX-License-Identifier: GPL-2.0-only +# coresight config - loadable module configuration. obj-$(CONFIG_SAMPLE_CORESIGHT_SYSCFG) += coresight-cfg-sample.o ccflags-y += -I$(srctree)/drivers/hwtracing/coresight + +# coresight config - configfs loadable binary config generator +userprogs-always-y += coresight-cfg-filegen + +coresight-cfg-filegen-objs := coresight-cfg-filegen.o coresight-cfg-bufw.o +userccflags += -I$(srctree)/drivers/hwtracing/coresight diff --git a/samples/coresight/coresight-cfg-bufw.c b/samples/coresight/coresight-cfg-bufw.c new file mode 100644 index 000000000000..8c32a8509eef --- /dev/null +++ b/samples/coresight/coresight-cfg-bufw.c @@ -0,0 +1,302 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#include + +#include "coresight-cfg-bufw.h" + +/* + * Set of macros to make writing the buffer code easier. + *. + * Uses naming convention as 'buffer' for the buffer pointer and + * 'used' as the current bytes used by the encosing function. + */ +#define cscfg_write_u64(val64) { \ + *(u64 *)(buffer + used) = val64; \ + used += sizeof(u64); \ + } + +#define cscfg_write_u32(val32) { \ + *(u32 *)(buffer + used) = val32; \ + used += sizeof(u32); \ + } + +#define cscfg_write_u16(val16) { \ + *(u16 *)(buffer + used) = val16; \ + used += sizeof(u16); \ + } + +#define cscfg_write_u8(val8) { \ + *(buffer + used) = val8; \ + used++; \ + } + +#define CHECK_WRET(rval) { \ + if (rval < 0) \ + return rval; \ + used += rval; \ + } + +/* write the header at the start of the buffer */ +static int cscfg_file_write_fhdr(u8 *buffer, const int buflen, + const struct cscfg_file_header *fhdr) +{ + int used = 0; + + cscfg_write_u32(fhdr->magic_version); + cscfg_write_u16(fhdr->length); + cscfg_write_u16(fhdr->nr_features); + return used; +} + +static int cscfg_file_write_string(u8 *buffer, const int buflen, const char *string) +{ + int len, used = 0; + + len = strlen(string); + if (len > CSCFG_FILE_STR_MAXSIZE) + return -EINVAL; + + if (buflen < (len + 1 + sizeof(u16))) + return -EINVAL; + + cscfg_write_u16((u16)(len + 1)); + strcpy((char *)(buffer + used), string); + used += (len + 1); + + return used; +} + +static int cscfg_file_write_elem_hdr(u8 *buffer, const int buflen, + struct cscfg_file_elem_header *ehdr) +{ + int used = 0; + + if (buflen < (sizeof(u16) + sizeof(u8))) + return -EINVAL; + + cscfg_write_u16(ehdr->elem_length); + cscfg_write_u8(ehdr->elem_type); + + return used; +} + + +static int cscfg_file_write_config(u8 *buffer, const int buflen, + struct cscfg_config_desc *config_desc) +{ + int used = 0, bytes_w, space_req, preset_bytes, i; + struct cscfg_file_elem_header ehdr; + + ehdr.elem_length = 0; + ehdr.elem_type = CSCFG_FILE_ELEM_TYPE_CFG; + + /* write element header at current buffer location */ + bytes_w = cscfg_file_write_elem_hdr(buffer, buflen, &ehdr); + CHECK_WRET(bytes_w); + + /* write out the configuration name */ + bytes_w = cscfg_file_write_string(buffer + used, buflen - used, + config_desc->name); + CHECK_WRET(bytes_w); + + /* write out the description string */ + bytes_w = cscfg_file_write_string(buffer + used, buflen - used, + config_desc->description); + CHECK_WRET(bytes_w); + + /* + * calculate the space needed for variables + presets + * [u16 value - nr_presets] + * [u32 value - nr_total_params] + * [u16 value - nr_feat_refs] + * [u64 values] * (nr_presets * nr_total_params) + */ + preset_bytes = sizeof(u64) * config_desc->nr_presets * config_desc->nr_total_params; + space_req = (sizeof(u16) * 2) + sizeof(u32) + preset_bytes; + + if ((buflen - used) < space_req) + return -EINVAL; + + cscfg_write_u16((u16)config_desc->nr_presets); + cscfg_write_u32((u32)config_desc->nr_total_params); + cscfg_write_u16((u16)config_desc->nr_feat_refs); + if (preset_bytes) { + memcpy(buffer + used, (u8 *)config_desc->presets, preset_bytes); + used += preset_bytes; + } + + /* now write the feature ref names */ + for (i = 0; i < config_desc->nr_feat_refs; i++) { + bytes_w = cscfg_file_write_string(buffer + used, buflen - used, + config_desc->feat_ref_names[i]); + CHECK_WRET(bytes_w); + } + + /* rewrite the element header with the correct length */ + ehdr.elem_length = used; + bytes_w = cscfg_file_write_elem_hdr(buffer, buflen, &ehdr); + /* no CHECK_WRET as used must not be updated */ + if (bytes_w < 0) + return bytes_w; + + return used; +} + +/* + * write a parameter structure into the buffer in following format: + * [cscfg_file_elem_str] - parameter name. + * [u64 value: param_value] - initial value. + */ +static int cscfg_file_write_param(u8 *buffer, const int buflen, + struct cscfg_parameter_desc *param_desc) +{ + int used = 0, bytes_w; + + bytes_w = cscfg_file_write_string(buffer + used, buflen - used, + param_desc->name); + CHECK_WRET(bytes_w); + + if ((buflen - used) < sizeof(u64)) + return -EINVAL; + + cscfg_write_u64(param_desc->value); + return used; +} +/* + * Write a feature element from cscfg_feature_desc in following format: + * + * [cscfg_file_elem_header] - header length is total bytes to end of param structures. + * [cscfg_file_elem_str] - feature name. + * [cscfg_file_elem_str] - feature description. + * [u32 value: match_flags] + * [u16 value: nr_regs] - number of registers. + * [u16 value: nr_params] - number of parameters. + * [cscfg_regval_desc struct] * nr_regs + * [PARAM_ELEM] * nr_params + * + * + */ +static int cscfg_file_write_feat(u8 *buffer, const int buflen, + struct cscfg_feature_desc *feat_desc) +{ + struct cscfg_file_elem_header ehdr; + struct cscfg_regval_desc *p_reg_desc; + int used = 0, bytes_w, i, space_req; + u32 val32; + + ehdr.elem_length = 0; + ehdr.elem_type = CSCFG_FILE_ELEM_TYPE_FEAT; + + /* write element header at current buffer location */ + bytes_w = cscfg_file_write_elem_hdr(buffer, buflen, &ehdr); + CHECK_WRET(bytes_w); + + /* write out the name string */ + bytes_w = cscfg_file_write_string(buffer + used, buflen - used, + feat_desc->name); + CHECK_WRET(bytes_w) + + /* write out the description string */ + bytes_w = cscfg_file_write_string(buffer + used, buflen - used, + feat_desc->description); + CHECK_WRET(bytes_w); + + /* check for space for variables and register structures */ + space_req = (sizeof(u16) * 2) + sizeof(u32) + + (sizeof(struct cscfg_regval_desc) * feat_desc->nr_regs); + if ((buflen - used) < space_req) + return -EINVAL; + + /* write the variables */ + cscfg_write_u32((u32)feat_desc->match_flags); + cscfg_write_u16((u16)feat_desc->nr_regs); + cscfg_write_u16((u16)feat_desc->nr_params); + + /*write the registers */ + for (i = 0; i < feat_desc->nr_regs; i++) { + p_reg_desc = (struct cscfg_regval_desc *)&feat_desc->regs_desc[i]; + CSCFG_FILE_REG_DESC_INFO_TO_U32(val32, p_reg_desc); + cscfg_write_u32(val32); + cscfg_write_u64(feat_desc->regs_desc[i].val64); + } + + /* write any parameters */ + for (i = 0; i < feat_desc->nr_params; i++) { + bytes_w = cscfg_file_write_param(buffer + used, buflen - used, + &feat_desc->params_desc[i]); + CHECK_WRET(bytes_w); + } + + /* + * rewrite the element header at the start of the buffer block + * with the correct length + */ + ehdr.elem_length = used; + bytes_w = cscfg_file_write_elem_hdr(buffer, buflen, &ehdr); + /* no CHECK_WRET as used must not be updated */ + if (bytes_w < 0) + return bytes_w; + + return used; +} + +/* + * write a buffer from the configuration and feature + * descriptors to write into a file for configfs. + * + * Will only write one config, and/or a number of features, + * per the file standard. + */ +int cscfg_file_write_buffer(u8 *buffer, const int buflen, + struct cscfg_config_desc *config_desc, + struct cscfg_feature_desc **feat_descs) +{ + struct cscfg_file_header fhdr; + int used = 0, bytes_w, i; + + /* init the file header */ + fhdr.magic_version = CSCFG_FILE_MAGIC_VERSION; + fhdr.length = 0; + fhdr.nr_features = 0; + + /* count the features */ + if (feat_descs) { + while (feat_descs[fhdr.nr_features]) + fhdr.nr_features++; + } + + /* need a buffer and at least one config or feature */ + if ((!config_desc && !fhdr.nr_features) || + !buffer || (buflen > CSCFG_FILE_MAXSIZE)) + return -EINVAL; + + /* write a header at the start to get the length of the header */ + bytes_w = cscfg_file_write_fhdr(buffer, buflen, &fhdr); + CHECK_WRET(bytes_w); + + /* write a single config */ + if (config_desc) { + bytes_w = cscfg_file_write_config(buffer + used, buflen - used, + config_desc); + CHECK_WRET(bytes_w); + } + + /* write any features */ + for (i = 0; i < fhdr.nr_features; i++) { + bytes_w = cscfg_file_write_feat(buffer + used, buflen - used, + feat_descs[i]); + CHECK_WRET(bytes_w); + } + + /* finally re-write the header at the buffer start with the correct length */ + fhdr.length = (u16)used; + bytes_w = cscfg_file_write_fhdr(buffer, buflen, &fhdr); + /* no CHECK_WRET as used must not be updated */ + if (bytes_w < 0) + return bytes_w; + return used; +} diff --git a/samples/coresight/coresight-cfg-bufw.h b/samples/coresight/coresight-cfg-bufw.h new file mode 100644 index 000000000000..00b16c583cad --- /dev/null +++ b/samples/coresight/coresight-cfg-bufw.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#ifndef _CORESIGHT_CFG_BUFW_H +#define _CORESIGHT_CFG_BUFW_H + +#include "coresight-config-file.h" + +/* + * Function to take coresight configurations and features and + * write them into a supplied memory buffer for serialisation + * into a file. + * + * Resulting file can then be loaded into the coresight + * infrastructure via configfs. + */ +int cscfg_file_write_buffer(u8 *buffer, const int buflen, + struct cscfg_config_desc *config_desc, + struct cscfg_feature_desc **feat_descs); + +#endif /* _CORESIGHT_CFG_BUFW_H */ diff --git a/samples/coresight/coresight-cfg-filegen.c b/samples/coresight/coresight-cfg-filegen.c new file mode 100644 index 000000000000..c8be18ee97b6 --- /dev/null +++ b/samples/coresight/coresight-cfg-filegen.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#include +#include +#include +#include + +#include "coresight-cfg-bufw.h" + +/* + * generate example binary coresight configuration files for loading + * into the coresight subsystem via configfs + */ + +/* create a similar configuration example as the coresight-cfg-sample.c file. */ + +/* we will provide 4 sets of preset parameter values */ +#define AFDO2_NR_PRESETS 4 +/* the total number of parameters in used features - strobing has 2 */ +#define AFDO2_NR_PARAM_SUM 2 + +static const char *afdo2_ref_names[] = { + "strobing", +}; + +/* + * set of presets leaves strobing window constant while varying period to allow + * experimentation with mark / space ratios for various workloads + */ +static u64 afdo2_presets[AFDO2_NR_PRESETS][AFDO2_NR_PARAM_SUM] = { + { 2000, 100 }, + { 2000, 1000 }, + { 2000, 5000 }, + { 2000, 10000 }, +}; + +struct cscfg_config_desc afdo3 = { + .name = "autofdo3", + .description = "Setup ETMs with strobing for autofdo\n" + "Supplied presets allow experimentation with mark-space ratio for various loads\n", + .nr_feat_refs = ARRAY_SIZE(afdo2_ref_names), + .feat_ref_names = afdo2_ref_names, + .nr_presets = AFDO2_NR_PRESETS, + .nr_total_params = AFDO2_NR_PARAM_SUM, + .presets = &afdo2_presets[0][0], +}; + +static struct cscfg_feature_desc *sample_feats[] = { + NULL +}; + +static struct cscfg_config_desc *sample_cfgs[] = { + &afdo3, + NULL +}; + + +#define CSCFG_BIN_FILENAME "example1.cscfg" + +int main(int argc, char **argv) +{ + u8 buffer[CSCFG_FILE_MAXSIZE]; + int used; + FILE *fp; + + printf("Coresight Configuration file Generator\n\n"); + + used = cscfg_file_write_buffer(buffer, CSCFG_FILE_MAXSIZE, + sample_cfgs[0], sample_feats); + + if (used < 0) { + printf("Error %d writing configuration %s into buffer\n", + used, sample_cfgs[0]->name); + return used; + } + + fp = fopen(CSCFG_BIN_FILENAME, "wb"); + if (fp == NULL) { + printf("Error opening file %s\n", CSCFG_BIN_FILENAME); + return -1; + } + fwrite(buffer, used, sizeof(u8), fp); + fclose(fp); + return 0; +} From patchwork Mon Nov 1 22:47: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: 12597515 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B070C433F5 for ; Mon, 1 Nov 2021 22:49:59 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 40D8A60EDF for ; Mon, 1 Nov 2021 22:49:59 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 40D8A60EDF Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=V1m5sJsCcSyIDv4vnGiXKYB93bO0wES3795JJ8qw8v4=; b=tvoo2rJ2IVFz2d RY2WyPfuL8dhNtdV51O9Bt6UuoVnK716THM5FtmgalJz3owTn3kx7VfiHi8rvig3jg4N2ROIyes97 EOeEYpmdedrGkKRoJOXbTv/F1NjevlV5R+tA1eNp+gShQhw7r3eKGqRIEPWlJX4mTiQzUoiB7JOwF 8fBicgiYFXj/XWwvSzsSRp0uYQEGWbxpI5AKOHKbLN0OPjVBMB5rFcjRwK7VcRFGQmv3GIGJJpgg7 mFJIw+i0g9gPGg9iVd2NjziVcb1zZjpr1oOUFEEkdmNM2IxJJM/ZjbP/vX3ExTIlqBuD7/N7twQcf 7h4bvovDmpPuelbS+d4Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhg6M-00HRif-Hx; Mon, 01 Nov 2021 22:48:26 +0000 Received: from mail-wm1-x330.google.com ([2a00:1450:4864:20::330]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhg5a-00HRWo-Cv for linux-arm-kernel@lists.infradead.org; Mon, 01 Nov 2021 22:47:41 +0000 Received: by mail-wm1-x330.google.com with SMTP id d72-20020a1c1d4b000000b00331140f3dc8so787564wmd.1 for ; Mon, 01 Nov 2021 15:47:38 -0700 (PDT) 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=ElgsHFIxGhWIeAwYTepUlvD78s3e2qkXFzFps0JCwKI=; b=i5/tMqJ9uRpGOm76jVfmJn4tLo82L1ZxjcimyftsPOmyKI6TMbtURraHcIW5kh1+gy 3E5Ec6vwZJ3PO+cKUmpS3ywXo1y7/Yp3PyvyKx8v6q13AavQF4ZhsBl8KUxr19qLrz11 PC2ozu0shpPo7v9ETiI38wDEDkCMDKCPyL/kBp3UG5cPYsIPwbZLclbjotBXLa6bqyB6 odz82iBVIoVBmVvuC3CVAPgZm9oofjcsycKXzKgie13k3r20SYXOY6GxRuRN2ALfewEl kX/dlt4IIt73/V7l/E7UvUQ7rd+yzuQBpRmPqmjihWiSAORFi5V+BNBt4YWR96yGUFQ8 Wrjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ElgsHFIxGhWIeAwYTepUlvD78s3e2qkXFzFps0JCwKI=; b=A5HrXrTDhX/PwVTi/ecOQUZMBZ5F2B1H7XwWb3dbthB+ZhwG+/CAvx7+HsqYAi9Z3/ KPdb6bzJA1bDelifETykjHyWccpiGZoDSqlwRhwRJKshQix5cBNRg67kG9x+e9SaApWs t1sRfOWruXRNc2tR5j6QIMsanzO8xaiu05GVlV/S/4/64kPIPxNzwJH3JzRRrLMpbIFG U8GRjf8KC2DNrkymQwIFEOIaUG5x4mwKbhuttIkKv76wMO/PJ1pHJkCKJcYGT18F/hQ8 8K8RO6hu1iewf1/rJKi6NwtZsMtuyhsICv9cxjokRHe/x4hUuui9BKBBkoznj9YgqHJt rS+w== X-Gm-Message-State: AOAM532iszzlVGkaTMl4oztZChw4T2i742qqM7h/ugAO96+axHCmlmwZ ylhCOFftGcoKnpzhLiz4M2+A6A== X-Google-Smtp-Source: ABdhPJwG+lFAwaQwnlRP8GWNHS7b79dB4Dl5QGDzyCYgIfLWNu7JwpOLFElyj1tXprKOV4bbBXRpaw== X-Received: by 2002:a05:600c:4ec8:: with SMTP id g8mr2129870wmq.153.1635806856966; Mon, 01 Nov 2021 15:47:36 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:cd6d:75aa:3402:e4a]) by smtp.gmail.com with ESMTPSA id 10sm858647wme.27.2021.11.01.15.47.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 15:47:36 -0700 (PDT) From: Mike Leach To: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org, mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [PATCH 5/6] coresight: samples: Add coresight file reader sample program Date: Mon, 1 Nov 2021 22:47:30 +0000 Message-Id: <20211101224731.27870-6-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211101224731.27870-1-mike.leach@linaro.org> References: <20211101224731.27870-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211101_154738_493454_E9D6CC4C X-CRM114-Status: GOOD ( 26.62 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add a userspace program to read and print a configuration generated for loading via the configfs attributes. Signed-off-by: Mike Leach --- samples/coresight/Makefile | 20 +- samples/coresight/Makefile.host | 39 ++++ samples/coresight/coresight-cfg-file-read.c | 191 ++++++++++++++++++++ 3 files changed, 248 insertions(+), 2 deletions(-) create mode 100644 samples/coresight/Makefile.host create mode 100644 samples/coresight/coresight-cfg-file-read.c diff --git a/samples/coresight/Makefile b/samples/coresight/Makefile index 07bfd99d7a68..ad8f29a77881 100644 --- a/samples/coresight/Makefile +++ b/samples/coresight/Makefile @@ -4,8 +4,24 @@ obj-$(CONFIG_SAMPLE_CORESIGHT_SYSCFG) += coresight-cfg-sample.o ccflags-y += -I$(srctree)/drivers/hwtracing/coresight -# coresight config - configfs loadable binary config generator -userprogs-always-y += coresight-cfg-filegen +# coresight config - configfs loadable binary config generator & reader +userprogs-always-y += coresight-cfg-filegen coresight-cfg-file-read coresight-cfg-filegen-objs := coresight-cfg-filegen.o coresight-cfg-bufw.o +coresight-cfg-file-read-objs := coresight-cfg-file-read.o coresight-config-file.o + +# pull in the coresight headers userccflags += -I$(srctree)/drivers/hwtracing/coresight + +# need to copy over the reader source from the driver tree - to build separately +CORESIGHT_SRC_PATH := $(abspath $(srctree)/$(src)) + +$(src)/coresight-config-file.c: copy_coresight_source + +.PHONY: copy_coresight_source + +copy_coresight_source: + @cp $(CORESIGHT_SRC_PATH)/../../drivers/hwtracing/coresight/coresight-config-file.c $(CORESIGHT_SRC_PATH)/. + +# clean up the copy after use. +clean-files += coresight-config-file.c diff --git a/samples/coresight/Makefile.host b/samples/coresight/Makefile.host new file mode 100644 index 000000000000..068cc2ca6ece --- /dev/null +++ b/samples/coresight/Makefile.host @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: GPL-2.0-only + +# Makefile to build just the example userspace programs on host m/c + +this-makefile := $(lastword $(MAKEFILE_LIST)) +sample-src := $(realpath $(dir $(this-makefile))) +srctree := $(realpath $(dir $(sample-src)/../../.)) + +include Makefile + +# compile flags +CFLAGS += $(CPPFLAGS) -c -Wall -DLINUX -Wno-switch -Wlogical-op -fPIC $(userccflags) + +# debug variant +ifdef DEBUG +CFLAGS += -g -O0 -DDEBUG +else +CFLAGS += -O2 -DNDEBUG +endif + +all: coresight-cfg-filegen coresight-cfg-file-read + +coresight-config-file.o: src_copy + $(CC) $(CFLAGS) coresight-config-file.c -o coresight-config-file.o + +.PHONY: src_copy +src_copy: + @cp $(srctree)/drivers/hwtracing/coresight/coresight-config-file.c $(sample-src)/. + +coresight-cfg-filegen: $(coresight-cfg-filegen-objs) + $(CC) $(LDFLAGS) $(coresight-cfg-filegen-objs) -o coresight-cfg-filegen + +coresight-cfg-file-read: $(coresight-cfg-file-read-objs) + $(CC) $(LDFLAGS) $(coresight-cfg-file-read-objs) -o coresight-cfg-file-read + +clean: + rm -f $(userprogs-always-y) + rm -f *.o + rm -f $(clean-files) diff --git a/samples/coresight/coresight-cfg-file-read.c b/samples/coresight/coresight-cfg-file-read.c new file mode 100644 index 000000000000..4e0fd840428f --- /dev/null +++ b/samples/coresight/coresight-cfg-file-read.c @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#include +#include +#include +#include +#include + +#include "coresight-config-file.h" + +/* + * tool to read and print a generated configuration + * re-uses the read code source from the driver. + */ + +static void print_configs(struct cscfg_fs_load_descs *load_descs) +{ + struct cscfg_config_desc *config_desc = load_descs->config_descs[0]; + int i, j, p; + + if (!config_desc) { + printf("File contains no configurations.\n\n"); + return; + } + + printf("Configuration name : %s\n", config_desc->name); + printf("Uses %d features:-\n", config_desc->nr_feat_refs); + for (i = 0; i < config_desc->nr_feat_refs; i++) + printf("Feature-%d: %s\n", i + 1, config_desc->feat_ref_names[i]); + + printf("\nProvides %d sets of preset values, %d presets per set\n", config_desc->nr_presets, + config_desc->nr_total_params); + if (config_desc->nr_presets) { + for (i = 0; i < config_desc->nr_presets; i++) { + printf("set[%d]: ", i); + for (j = 0; j < config_desc->nr_total_params; j++) { + p = (i * config_desc->nr_total_params) + j; + printf("0x%llx, ", config_desc->presets[p]); + } + printf("\n"); + } + } + printf("\n\n"); +} + +static void print_reg_type_info(u8 type) +{ + if (type & CS_CFG_REG_TYPE_STD) + printf("std_reg "); + if (type & CS_CFG_REG_TYPE_RESOURCE) + printf("resource "); + if (type & CS_CFG_REG_TYPE_VAL_PARAM) + printf("param_index "); + if (type & CS_CFG_REG_TYPE_VAL_64BIT) + printf("64_bit "); + else + printf("32_bit "); + if (type & CS_CFG_REG_TYPE_VAL_MASK) + printf("masked "); + if (type & CS_CFG_REG_TYPE_VAL_SAVE) + printf("save_on_disable "); + +} + +static void print_regs(int nr, struct cscfg_regval_desc *regs_desc_array) +{ + int i; + struct cscfg_regval_desc *reg_desc; + u8 type; + u16 offset; + u16 info; + + for (i = 0; i < nr; i++) { + reg_desc = ®s_desc_array[i]; + type = (u8)reg_desc->type; + offset = (u16)reg_desc->offset; + info = (u16)reg_desc->hw_info; + + printf("Reg(%d): Type 0x%x: ", i, type); + print_reg_type_info(type); + printf("\nOffset: 0x%03x; HW Info: 0x%03x\n", offset, info); + printf("Value: "); + if (type & CS_CFG_REG_TYPE_VAL_64BIT) + printf("0x%llx\n", reg_desc->val64); + else if (type & CS_CFG_REG_TYPE_VAL_PARAM) + printf("idx = %d\n", reg_desc->param_idx); + else { + printf("0x%x ", reg_desc->val32); + if (type & CS_CFG_REG_TYPE_VAL_MASK) + printf(" mask: 0x%x", reg_desc->mask32); + printf("\n"); + } + } +} + +static void print_params(int nr, struct cscfg_parameter_desc *params_desc) +{ + int i; + + for (i = 0; i < nr; i++) + printf("Param(%d) : %s; Init value 0x%llx\n", i, + params_desc[i].name, params_desc[i].value); +} + +static void print_features(struct cscfg_fs_load_descs *load_descs) +{ + struct cscfg_feature_desc *feat_desc = 0; + int idx = 0; + + feat_desc = load_descs->feat_descs[idx]; + if (!feat_desc) { + printf("File contains no features\n\n"); + return; + } + + while (feat_desc) { + printf("Feature %d name : %s\n", idx+1, feat_desc->name); + printf("Description: %s\n", feat_desc->description); + printf("Match flags: 0x%x\n", feat_desc->match_flags); + printf("Number of Paraneters: %d\n", feat_desc->nr_params); + if (feat_desc->nr_params) + print_params(feat_desc->nr_params, feat_desc->params_desc); + printf("Number of Registers: %d\n", feat_desc->nr_regs); + if (feat_desc->nr_regs) + print_regs(feat_desc->nr_regs, feat_desc->regs_desc); + printf("\n\n"); + + /* next feature */ + idx++; + feat_desc = load_descs->feat_descs[idx]; + } +} + +int main(int argc, char **argv) +{ + FILE *fp; + struct cscfg_fs_load_descs *load_descs; + int err, fsize; + u8 buffer[CSCFG_FILE_MAXSIZE]; + + printf("CoreSight Configuration file reader\n\n"); + + /* need a filename */ + if (argc <= 1) { + printf("Please provide filename on command line\n"); + return -EINVAL; + } + + /* open file and read into the buffer. */ + fp = fopen(argv[1], "rb"); + if (fp == NULL) { + printf("Error opening file %s\n", argv[1]); + return -EINVAL; + } + + fseek(fp, 0, SEEK_END); + fsize = ftell(fp); + rewind(fp); + if (fsize > CSCFG_FILE_MAXSIZE) { + printf("Error: Input file too large."); + fclose(fp); + return -EINVAL; + } + fread(buffer, sizeof(u8), fsize, fp); + fclose(fp); + + /* allocate the descriptor structures to be populated by read operation */ + load_descs = malloc(sizeof(struct cscfg_fs_load_descs)); + if (!load_descs) { + printf("Error allocating load descs structure.\n"); + return -ENOMEM; + } + + /* read the buffer and create the configuration and feature structures */ + err = cscfg_file_read_buffer(buffer, fsize, load_descs); + if (err) { + printf("Error reading configuration file\n"); + goto exit_free_mem; + } + /* print the contents of the structures */ + print_configs(load_descs); + print_features(load_descs); + +exit_free_mem: + free(load_descs); + return err; +} From patchwork Mon Nov 1 22:47: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: 12597513 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 80ABEC433F5 for ; Mon, 1 Nov 2021 22:49:50 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 4654B60F42 for ; Mon, 1 Nov 2021 22:49:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 4654B60F42 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=jnEmX4YgnVJoTzy4Olct3cfBmWBdp1wpdUcfYsPiGLM=; b=asU5+W1Bxeas0Q E18w9EYWIRsRDc3ErUfux9yHvw00uxXuu6uvMzedU5oRpzuaTDPOmC74UAjswUXf2slV4SsSr43d6 swQAZvyR3cfQPpXm/JPpN9hKyJ11f/M061yM0vzCmd5jBFgVFHfBTlPgyGD7a1FtY0H1vyJcx7Bwa 4ZIamxPpW/2diE+FqK8sAOMrmKFheT1vLaoeRDvg2mG6gDBmrdhLL8SP83VItdJOaUo61jC8CIgEm tJLhOBYUuTVv1h0tkGJ79+6hsecaQCz8p2hNd7250UCNdURAXRSXyuK4M/f25WyaS58H+K6gywQHg Knhb3ineK9PRZWB2IBQA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhg69-00HRdT-ON; Mon, 01 Nov 2021 22:48:13 +0000 Received: from mail-wr1-x42f.google.com ([2a00:1450:4864:20::42f]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhg5a-00HRWv-Ud for linux-arm-kernel@lists.infradead.org; Mon, 01 Nov 2021 22:47:41 +0000 Received: by mail-wr1-x42f.google.com with SMTP id d5so15104466wrc.1 for ; Mon, 01 Nov 2021 15:47:38 -0700 (PDT) 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=hF66nuqLbg4fzI1VN/ff4Po+KDRcRXpEL2qgfiYf73M=; b=A5yzZyYC/caTx2PWybydLqXSGO5fj4GoTpF/64ZPibNUy8fBRhBGWHOltSFOxvj1oD peB2Iasqeg7oixSBXgCLM680Miqt0sHzxEqIjIdwad2wqswvUTXjML3wuT9Xg0psNzra Nky7oak8hwG9uyMVQ0D1cptn7Ez5w6GilzdnMJrwPouHYVKH4z3jjxkoSpkY88/VpnkF 8a6Am2k7VOHhuH3amNjHa29QSRuGVFA7I/imfprSA84uNTNPDKfycQUQzhJefTW2/0Sq 8aEZaB7rXrRaI/UcTNvKEen7hwfNuxjPFXxoRmcWSXeMgA4E2PXut09h0RYF5OHy5Iho X96Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hF66nuqLbg4fzI1VN/ff4Po+KDRcRXpEL2qgfiYf73M=; b=Pi5NB7oyYSRwABQ91XdGQxRM/boQGEWSe+cEjUAEaaWVzjKz8VNSblj8jmP+ZKkXSi /8RiMaUhUGsJDt120+kKo2K6nYR53Vle8Mdt/pDgYg224OiW5nZF5pJSk/NWE8celh6N BppjIFqfWuxS8kxT4yb9qHzyQZl19L3nisJ9si9ycOltAnNfRT0tWgtX4Goyy8M105Uj YvloAH9rbDOMgzKaoj17uGTm5ZS/2+58mRLD42EwJ7/RhRTiYK2TUEblYY4EJUeN3Um/ dugTrGZcosDxYLb1I7VOZfe94qDomjui103xleUMuYjxoxJG2EuP6PkLdYsJyyjLe+eV yDfA== X-Gm-Message-State: AOAM530t6Y1sq4zht1wJwMaBvSfF+2qusuNvqMkpwhW8kbrFZEe1Ii6Q ZYJSbu1tvStFICV1PbZrwlgexQ== X-Google-Smtp-Source: ABdhPJweerr/yqRhIMjoDTirICHrA2quBW9wjOF5NhGYbPZkahXaERNh2FtBEEmyrIUOTWMI+p9qcw== X-Received: by 2002:a05:6000:1842:: with SMTP id c2mr15229824wri.301.1635806857474; Mon, 01 Nov 2021 15:47:37 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:cd6d:75aa:3402:e4a]) by smtp.gmail.com with ESMTPSA id 10sm858647wme.27.2021.11.01.15.47.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 15:47:37 -0700 (PDT) From: Mike Leach To: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org, mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [PATCH 6/6] Documentation: coresight: Update coresight configuration docs Date: Mon, 1 Nov 2021 22:47:31 +0000 Message-Id: <20211101224731.27870-7-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211101224731.27870-1-mike.leach@linaro.org> References: <20211101224731.27870-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211101_154739_031656_035AD886 X-CRM114-Status: GOOD ( 22.23 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add documentation covering the configfs updates that allow binary configuration files to be loaded and unloaded, along with the demonstration programs in samples. Signed-off-by: Mike Leach --- .../trace/coresight/coresight-config.rst | 65 +++++++++++++++++-- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/Documentation/trace/coresight/coresight-config.rst b/Documentation/trace/coresight/coresight-config.rst index 911db4da7f99..8ea640b3f6f9 100644 --- a/Documentation/trace/coresight/coresight-config.rst +++ b/Documentation/trace/coresight/coresight-config.rst @@ -152,7 +152,7 @@ follows:: $ cd configurations/ $ ls - autofdo + autofdo last_load_status load unload $ cd autofdo/ $ ls description preset1 preset3 preset5 preset7 preset9 @@ -247,9 +247,19 @@ Creating and Loading Custom Configurations ========================================== Custom configurations and / or features can be dynamically loaded into the -system by using a loadable module. +system by using a loadable module, or by loading a binary configuration +file in configfs. + +Loaded configurations can use previously loaded features. The system will +ensure that it is not possible to unload a feature that is currently in +use, by enforcing the unload order as the strict reverse of the load order. + +An example of a custom configuration module, and generators for binary +configuration files are found in './samples/coresight'. + -An example of a custom configuration is found in ./samples/coresight. +Using a Loadable Module +----------------------- This creates a new configuration that uses the existing built in strobing feature, but provides a different set of presets. @@ -258,6 +268,49 @@ When the module is loaded, then the configuration appears in the configfs file system and is selectable in the same way as the built in configuration described above. -Configurations can use previously loaded features. The system will ensure -that it is not possible to unload a feature that is currently in use, by -enforcing the unload order as the strict reverse of the load order. +The file 'coresight-cfg-sample.c' contains the configuration and module +initialisation code needed to create the loadable module. + +This will be built alongside the kernel modules if select in KConfig. + + +Using a Binary Configuration File +--------------------------------- + +Building the samples creates the 'coresight-cfg-filegen' program that will +generate a configuration binary 'example1.cscfg' that can be loaded into the +system using configfs. The configuration declared in the source file +'coresight-cfg-filegen.c' is named 'autofdo3' - the name that will be used +once loaded. + +The source files 'coresight-cfg-bufw.h' and 'coresight-cfg-bufw.c' provide a +standard function to convert a configuration declared in 'C' into the correct +binary buffer format. These files can be re-used to create new custom +configurations. + +The program 'coresight-cfg-file-read' can read back and print a configuration +binary. This is built using the reader from the driver code. + +There are additional attributes in the configurations directory - load, unload +and last_load_status that can be used to load and unload configuration +binary files. To load, 'cat' the binary config into the load attribute:: + + $ ls /config/cs-syscfg/configurations/ + autofdo last_load_status load unload + $ cat example1.cscfg > /config/cs-syscfg/configurations/load + $ ls /config/cs-syscfg/configurations/ + autofdo autofdo3 last_load_status load unload + $ cat /config/cs-syscfg/configurations/last_load_status + OK: configuration file loaded (autofdo3). + +To unload, use the same file in the unload attribute:: + + $ cat example1.cscfg > /config/cs-syscfg/configurations/unload + $ cat /config/cs-syscfg/configurations/last_load_status + OK: configuration file unloaded (autofdo3). + ls /config/cs-syscfg/configurations/ + autofdo last_load_status load unload + +The generator and reader programs can also be built directly, separately from +the kernel build by using the 'Makefile.host' file. This allows binaries to be +created on the host machine when cross compiling.