From patchwork Tue Nov 30 22:00:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12694226 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id F22A9C433F5 for ; Tue, 30 Nov 2021 22:03:59 +0000 (UTC) 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=QD4W128ZtOAUc4 1FOnNXJ/qQ1Xtizn5wl2tPmJQDtvIVjp8Tggk8fTvLvF+BcVhzJwWVvAUUBCXGT/CD9DkU1yJABTB 1+EleWmFwd2/P6PV3lR8tNv6PY5Y0RszY0v7Tipyxrstkb7AMtj++knZwyEXL9avc4CLFN/MuLb5b 2H4YHrOg8e9u6zuv4TPzltZSXsryc61D0Heq3JfEDC49HdQ044jN531K1QaqnmJ8cKMyJpMK1fG8k PtXC1vy+s6KH82HYLZ+B179QlEdCYBGZ4xP5Ju+JanHvpPA9zHolq/lxmgZIF/KZyc8G8w2C/sN6x vP1snJsi/sOtct3Bp2wg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1msBCW-006sF0-3q; Tue, 30 Nov 2021 22:02:12 +0000 Received: from mail-wm1-x332.google.com ([2a00:1450:4864:20::332]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1msBBV-006rxD-JW for linux-arm-kernel@lists.infradead.org; Tue, 30 Nov 2021 22:01:14 +0000 Received: by mail-wm1-x332.google.com with SMTP id o19-20020a1c7513000000b0033a93202467so15839555wmc.2 for ; Tue, 30 Nov 2021 14:01:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Y5h9pIf4O35Nf8PvDSWgpzyfLGkiD3rIZ7lZAMc3i+o=; b=C2wtZVlN0P2s8ymHGVAwQGcKnyj9p1MMNtSgJDYHlWYe8wD90WSC0PSWHHb452kmfD 9ZpkB3opj1AOb/vnl3xw0dzO+26PgDlx3YAXmdj0OL3gMzKqRC3IXZoBTS9RCEsw9vGL Yye69YyJwkTOlsTJt7aVsAmQIuUqUIeQJxS2xSdIOfeq5RERfY0xg8zkx4SSMm3ixRDt F+IkCP5nid++KObL3Q6orswwEo/TstTDuzPiZ0qorUQlRhZ3/wV+hy9nBQlltjZieCJe F6G4bWq14XStpLIYTpZ28C32buxO2jwH+8cfBc4HTjyFT5X2rE7oubKFI49BrWVxHbfb A+mQ== 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=XCoPH1Y6oazMsVeMQmZPVyE7HYPsQEppqatVT8JRcL+/PUQ1cNXYTroppGdTr06ofG ZC4aXkkkewELNr+D/ZcCY5rOXVexCvMik5E0NQ80PBLKK+h0oBzi/1daTP4VAKtTo8jg u8CeY3L/qGf6IrzjV7LkcVoE3quehs/jgR3mB6l4Qy++8shE2vGI+tsGif7xNnFthxgW k5bAV/4a5jgwtiCwP7N3xiLxX1fqH1MjZgeOKiZdkHAzpiOvPM32lz9OdUD76ZoLPk7h N4q/ltqJvtl1a5kYLmWqjt8ufVX6elQgoEsVEos4n20QvLgOjzvCuKCwsl2a1RfLV9W8 p0TA== X-Gm-Message-State: AOAM530v4fmabNBKt7JjpRaBP+Wj5z1l5bbOSZSR6UX+v3UVaiuCvS/k hV9xX+TSvrlEHt8sZ+RQb78pq+Omogjh1Q== X-Google-Smtp-Source: ABdhPJx4ffygsTaW5Gowd0isviXkVccQfXj2LH3yIrWa8t9rl2k5gVuwyYN9U1mazYXzbtZnlDkIrQ== X-Received: by 2002:a05:600c:202:: with SMTP id 2mr1677754wmi.167.1638309667463; Tue, 30 Nov 2021 14:01:07 -0800 (PST) Received: from linaro.org ([2a00:23c5:6809:2201:546d:7d59:1703:bf96]) by smtp.gmail.com with ESMTPSA id y142sm3755280wmc.40.2021.11.30.14.01.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Nov 2021 14:01:07 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org Cc: mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [PATCH v2 1/6] coresight: configfs: Add in functionality for load via configfs Date: Tue, 30 Nov 2021 22:00:55 +0000 Message-Id: <20211130220100.25888-2-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211130220100.25888-1-mike.leach@linaro.org> References: <20211130220100.25888-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211130_140109_683880_0662F1A5 X-CRM114-Status: GOOD ( 32.38 ) 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 Tue Nov 30 22:00:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12694223 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id B7395C433F5 for ; Tue, 30 Nov 2021 22:02:54 +0000 (UTC) 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=HbzYYd0XxqIbBVwq5RA9lP/sj4YmXWPRbC5hb3v9ndI=; b=jfiqs73AIjBjvn VPZpONAGhFO1ylcrhbM2ARdrp8+FEyizQ5qIaDBRvegOLJZMtKN4JOLU0DxbeqY+kIH8Veb2msx56 WzBHXw2v15rnv9rS+wxckxWXKYrXBpueE3kT38h2zFgyRJ0jkVJACycyRHjFkspE/0EeFX0AvRELZ ncgHaXILwp0UOTU5+v2tjAEbwqLC77IKtsXchNgV52PwW4HWHG8pQA+4rpi0cbJ78ieG3Dd+tecNz rNaalKWaIIhHl+oOckq4npRlfreJothJiXpEDeYRrpeB16W7nWEkDt182wAN/T8hCZBFPe3fibQJV U0ZfZ0NlkwTTIzdVZATA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1msBBm-006s2j-U2; Tue, 30 Nov 2021 22:01:27 +0000 Received: from mail-wr1-x430.google.com ([2a00:1450:4864:20::430]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1msBBV-006rxE-82 for linux-arm-kernel@lists.infradead.org; Tue, 30 Nov 2021 22:01:11 +0000 Received: by mail-wr1-x430.google.com with SMTP id c4so47547233wrd.9 for ; Tue, 30 Nov 2021 14:01:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=GY+FDPiasaC8qdBr5wxiNWpcZqX7PLh07XwtaUHV8jQ=; b=cb1V1l6xGNt4TozaDVBokqcM+ImwHZyicNRwjIbwboMzjFLUjkQ6cqoxvfNseaRbCd L3jJz7GkCSOqy6yU4AKFAVILZ/nrx2mDAmRI3v8Az4swWZ+NLAFyWaUop2x+EdDy+3QQ JjY65iSjylAwo9bw1FfO6b8Zx3Fnk4QtcfxHW0TmlsvG3gnVKTpilOhugQ9hiq5dWdOK U3y5nhCBb5XMCsWhZCpQbiRtsWxvyvnI1EM3z2WGlWUfjC/Y4kkEUupTv896Og6DGDIN Z2iZek0/ld8ICN9yLa+cUWzFKBi/GBgR5RBs8WoFgbfUc9FaLXUxua8xJp4Bsw3ZJdmw 8TrA== 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=GY+FDPiasaC8qdBr5wxiNWpcZqX7PLh07XwtaUHV8jQ=; b=qAQKivGebNPCBJCjTZXXqFDXxmgJGnY0AO6as14Dkllx61bSpOYO6naBc+lvMEQ11r k1MnmTlek89Q9OUqhmPBnL3yN3ZEZdvObsu2f2Db4BClXB23H1tjEoSQnMgACn0JEZMa ltsaUfNSc3Vyv6FUK0mAYhUZ0NhPco/IIVWfkLlQ4pent6qr0oN/bGfCXctjkQD47Nyd 6z7prelDkG08wc5d/4bV/xOG2IKIHvbPtp5UrXoRjIXMRFVB+/+/jik+ZXXQNY3bouQO 9S6iw/Ie1h2BzrFWAVM+/CyhwlmFUWWUrTdb1RNwJVlar3OVaUOFj3NV8hN600t5e58L yveA== X-Gm-Message-State: AOAM530/wZr42rOvArG8md9x68i4tIHtUe14Ydz+9o3NkyI2C4wsDkFm F695l4PQWjDvOyqqd0Sa0jpe0PiZRvIEmA== X-Google-Smtp-Source: ABdhPJwVziS6K5gv55KVh1/cRTnlJhXTgb6hvOqWFwQH6PGregvvIGAR21pq3PtqECrxz1fIIKyESA== X-Received: by 2002:a05:6000:1289:: with SMTP id f9mr1741682wrx.329.1638309668036; Tue, 30 Nov 2021 14:01:08 -0800 (PST) Received: from linaro.org ([2a00:23c5:6809:2201:546d:7d59:1703:bf96]) by smtp.gmail.com with ESMTPSA id y142sm3755280wmc.40.2021.11.30.14.01.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Nov 2021 14:01:07 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org Cc: mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [PATCH v2 2/6] coresight: configfs: Add in binary attributes to load files Date: Tue, 30 Nov 2021 22:00:56 +0000 Message-Id: <20211130220100.25888-3-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211130220100.25888-1-mike.leach@linaro.org> References: <20211130220100.25888-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211130_140109_321430_F867BAAA X-CRM114-Status: GOOD ( 28.78 ) 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 433ede94dd63..50abdb5aa6b6 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 098fc34c4829..b5804cc2af9c 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -587,6 +587,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 Tue Nov 30 22:00:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12694224 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 8847BC433F5 for ; Tue, 30 Nov 2021 22:03:10 +0000 (UTC) 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=vvTT6jP0StzDBH msWFrHPj1TbsB38BbyZH7pKLT1OP9DoMNetrLVbfSKdel0rD1IfgzVpzfuz/HJV8wOKZHWorLotGc ipGme5GA5z8mMK2q+eCOSoU9I+KW2RX25+EjGenxaQ9daMBK11ps9RMKReZp/ZvP97dcoAQ0OzgXs map+wh2vBO8WA+1ZgzQmPlJ9TxUY3mM5q39fryNUXwnAqiDwr3LdMcHHFlBbALgLhFnie6fjEJSEv Y/Rh2i2h6hdcKiaFe3eMarZ60qfYaFsZLDQRPUhiA3UhwX4OuVBiewvZ152Fzvbr0VEvS2L02StLB WD2B4ZOO8lYYcIT8JVHg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1msBC0-006s5k-Mm; Tue, 30 Nov 2021 22:01:40 +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 1msBBW-006rxF-3z for linux-arm-kernel@lists.infradead.org; Tue, 30 Nov 2021 22:01:13 +0000 Received: by mail-wr1-x42b.google.com with SMTP id v11so47574898wrw.10 for ; Tue, 30 Nov 2021 14:01:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ZnJC6HDO4hKLnjoDe3yF52L4cyf5HBXuoo8iYrPGqxk=; b=Heu6V1n+5hsrCrrtyLwk4Kli9tWieQW1OMFM6prdyZVoURjs0jBJpQ1V4iiT6gX6zd gzueqrWHYTWiMIZsmlRdEaVYJU2yv7InP9rWAUiWS5W3jYRbwtTPhaNTxj6Bz13k880S Hy35Xw/l1Arr1KeRw3JQXEmT/jLmhDJdbawBHn7YBGMEqDlWUHlF1dn0lbCDYzS07/8n bULQRECk6XFvchyVQ/NroCFVx8nX6MWJfxUO409uK75i46VL+fpz1b28nicNmhmxfrhc Zw1BtNgi2fNDDDmLj/sJilLCQWSntAicWyOCyY5LXTOXrcuEDZ6Vgr1sUKoCllWQQoih iQmg== 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=3zmsQk9xzHt7upkriu4gwFsSz4BXoiOf8fxgc1bBL+IV6Y8uk5VHgHpxbDS/OCcwaR NMZPenE1lBVHnnRE7zZnuFUpvZiO40fPLvq/FtJo9iFAtzKpZwnIuKeFD0i3KMBBDZoC JYmQ0mTQ9SPmqr+zdxvE6daEX4dcct2sqMI9ULuDAvyPcd6vt3FQWZMRAPsnb25PHotH AKD1ftqEX6VCSPmBUihiMYXZdrdKd4/mEunGsXxGvL8t3jZnVx1laUL0UKjiAGBVSvnY el0Le3crrHQxinnXusFT5clQ/A7/s8iZaUC9iQhkeYjp0e4O/mV+KrLvg8RElJRf9USU Zdgg== X-Gm-Message-State: AOAM531b8JWLwC55Z4tTOVnSGGTWJK9l2JpQpumJotcps9ZixZBNfjmI AGngPM17Mhy6jWwCJtGh9Gprdg8Cd0FFtA== X-Google-Smtp-Source: ABdhPJxPMYhp4AfGEtg85n892LoyLHU6dIizxhtctX5t4qFbY7Ui+pFxD7MKdVbP7VNXTAyMFjfKbg== X-Received: by 2002:adf:f04d:: with SMTP id t13mr1925934wro.324.1638309668574; Tue, 30 Nov 2021 14:01:08 -0800 (PST) Received: from linaro.org ([2a00:23c5:6809:2201:546d:7d59:1703:bf96]) by smtp.gmail.com with ESMTPSA id y142sm3755280wmc.40.2021.11.30.14.01.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Nov 2021 14:01:08 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org Cc: mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [PATCH v2 3/6] coresight: configfs: Modify config files to allow userspace use Date: Tue, 30 Nov 2021 22:00:57 +0000 Message-Id: <20211130220100.25888-4-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211130220100.25888-1-mike.leach@linaro.org> References: <20211130220100.25888-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211130_140110_191038_2C638C20 X-CRM114-Status: GOOD ( 28.47 ) 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 Tue Nov 30 22:00:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12694227 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 23E04C433F5 for ; Tue, 30 Nov 2021 22:04:26 +0000 (UTC) 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=sjvTr2dxXVVXNu TjLK6xJkxjYORtHndIhjWDn7sJ4GZksvN1cIBxpTJOV7AEZ9q1sAREM6igzpTWmQ4cIYZ+PnunlOa UkqbYd7cy584elFC+aKboWF2H62taYLS3PHWzA/Ao81DYYviW/VN6+OwzcLmvNm51BshQM7KHdELW 1t2WuL00cXmRlUs19SMyx9cGWcPkDvadXJYiQOExbzRX8Ds/ri1dfCxzn/gd6wQ7eFMWHB6mk90kJ 0TwknCAy31bE+eckDKtNcihE44VCJXUMq0vtiNINUbeUC6v1CdVvnAUb+IzyU3EptQdOHFlusYUIn qxi0wzXdhhueFXY/1IdA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1msBCr-006sOb-Ur; Tue, 30 Nov 2021 22:02:34 +0000 Received: from mail-wr1-x432.google.com ([2a00:1450:4864:20::432]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1msBBW-006rxx-QZ for linux-arm-kernel@lists.infradead.org; Tue, 30 Nov 2021 22:01:14 +0000 Received: by mail-wr1-x432.google.com with SMTP id d24so47646900wra.0 for ; Tue, 30 Nov 2021 14:01:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Ky2DtWLrDHXeN3dfZEi54AGY8N6qWbQzEs2U9otpzmo=; b=rqa9Tk3Et7pBc16rS1wY79T9XjDuys2xBOFHp0G3J7x6EiYq80lWG7+5tfBg8bImOf p+d5l+yKa4HAC+Pm+vhK2ZRJbpx9g7cBT5KSuBmQPOUgmVzXD/skUsiue/fTRdL5sWzv BlHLLTRrn+6nN1lZLrzdgKqEcRsBj53wH1q1QOPpellrVqBiQHqBP8yUtHAODJOdLB13 Ge+axHH34UuImqp6NgSyZhgXWVtR+1I0Cr4AcDijXqhYRLeejPWEsiSJtrX8qlMEaQFu k3//o/sBNa6x/6fx10Ha+tGfGD/k/q5Y7lU6tP7UmTvWmaUjsrBVPgqgy0cpBxxhuzKE 4iXw== 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=6pJfWqi2jjjkgFnGfcCVKo26LQL4gp8Rkkc1H3/jQo/VRbz4Lxh8rfVQuAo4iekx0w Th1v9GVL1NtF21QtS4COr34X5DKmjnW0ASCAacZ/AsmFxAyVCaA3z/Bd/QlW9X7Wi5E0 Ks3AgJBhvkJl4MWYUE97z/GUlNYg2EE2ErOsv+Mz18UVthWWfDLy2DWyqRe/Jt1ztlfk tBEbLZwa8yIrjoLAK+6OqZGrhy78py1zwK0UfR7E8A9Bolqo4h0IZLAgIemjfoIJBa6s LeKfVR9uUj9jr/uOGXzPpapBN6JjZN6/b9M15j88IpQpt8f9bIaFecWBOXlQqfyt4oHb erRQ== X-Gm-Message-State: AOAM530Od1uBhMkFekJ2h9yV3z6sy0qIcWNOCgfc2ypyXX4Y6JEdwXc+ l7wOVIr5xSHc50nOwk3C8xGbu/88keIDOg== X-Google-Smtp-Source: ABdhPJzChQPckL8KE/hfbNS1yl9WjpxThQzCWI4uMtS19D5bi7BNPJFamIZTKWEaqSBiyoqKilpyNg== X-Received: by 2002:a5d:6dab:: with SMTP id u11mr1884192wrs.46.1638309669230; Tue, 30 Nov 2021 14:01:09 -0800 (PST) Received: from linaro.org ([2a00:23c5:6809:2201:546d:7d59:1703:bf96]) by smtp.gmail.com with ESMTPSA id y142sm3755280wmc.40.2021.11.30.14.01.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Nov 2021 14:01:08 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org Cc: mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [PATCH v2 4/6] coresight: samples: Add an example config writer for configfs load Date: Tue, 30 Nov 2021 22:00:58 +0000 Message-Id: <20211130220100.25888-5-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211130220100.25888-1-mike.leach@linaro.org> References: <20211130220100.25888-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211130_140110_904148_2C73CD4A X-CRM114-Status: GOOD ( 32.25 ) 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 Tue Nov 30 22:00:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12694225 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id A1244C433EF for ; Tue, 30 Nov 2021 22:03:27 +0000 (UTC) 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=2shdUsipFoNt4osFAgTNk0RNkzSqPt9P3wsQmSk8fFo=; b=WQySujpSllDs1z XPW3Af258yfs/Kleen7LPdjlMh40jk0rWtLKB20TCBs6uyvUhC4jTYNGN2Uj9RcXAs0WyO4I/6G+L ANVAZzl9+kAwHXaHwOY0TDkcbx4k7094eF2y5TmUFBpewQ74/Y3drofoNk4B8U6RsgQzGScxm5H1K lUtyxYPOQMby+Eb0aSC9mHFuMV+KWA4gSiy22FTvgcMQ++vVeRpC2KBBVArVYMdtPiov9o0NaPH36 JL3IX7SsGOxSrPi/T83xs3Jzk8PXiqOZZZ0hWtjpUigaM19b8a7VEkVhNeYVwcJEDZTKuC693L5OP OrBDDxGtOIlVA6+gM/gQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1msBCH-006s9d-Hm; Tue, 30 Nov 2021 22:01:57 +0000 Received: from mail-wr1-x429.google.com ([2a00:1450:4864:20::429]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1msBBX-006ryD-6a for linux-arm-kernel@lists.infradead.org; Tue, 30 Nov 2021 22:01:14 +0000 Received: by mail-wr1-x429.google.com with SMTP id d9so26706311wrw.4 for ; Tue, 30 Nov 2021 14:01:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Nj27ByMCOq05Ai/Gqjxxta7U7cPsZTGIc/1CiRF7cLg=; b=mlHcHAdofwpfAkJ+zd7JRE21fOngYj9anA100JVZDCsN8grkV6m/Z8xDptCDSvn/D6 UG/c3+vZEKXt7Ry/qwTEKTWl6LdFv2tgjf0ewe8TYVet0FyegBlZV+4tgh3G/TtOZqmg PqMlyW0NMezIeK8o+U4sH9WALKbtC7Smi9atWnaFfnNRuNgacAy2LEvaI0g/mNbkLC+x rHYMM5PQL7n7idJB8phh0qJnF9vsy9jVBOJxiJg4Kvy/R/4TS++1E6vlJX3Xx/Emog7L 9iYYD7f7mxP7GIEupsF4AIW6+pl6ESmM2mQAkv+k3nQ1J9aK6VwcUgVjF5mQuPUC4JTC ng2Q== 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=Nj27ByMCOq05Ai/Gqjxxta7U7cPsZTGIc/1CiRF7cLg=; b=OZxfa6hDb6Xq5vNIOrTbfUbi/8glUsA6X2IYJGjQmD8wtjH4AYF5cG616SBeXTbKNL Y+nXGj5/9wfLABBRhBJZmR1Rpx7XmYgspaR+yc9prJRqPZMfD+Uv6fdUS2MS0YcNlVD5 UuC+cEYVTLQ2X0PAOioKYNqx2YSrFm12NYuA4u6IZn8rNozxrT+cTQY5VO0+H31l6qAK 02leyaScRyrjXZ3+PiQWtXQ7NWlu6bNa5ILaITbVfj6uXm0VZTlW3xE7k7K76DCpqXKI HZRB0zy8ibbyVybMDnlDAf/ecvEdzT48VeCmU5+rWCAyyiFK/OZKxbn9qLqA18o3BVTY l/nw== X-Gm-Message-State: AOAM533SZQxQYfcpLoC0CUOCFMSrnUU15S8DDCDqZTQku0rSdpbYpsbt 8oLbm9bIl7hpf8WgoWx5LN+zN9KMBkDkxA== X-Google-Smtp-Source: ABdhPJy/6TUAheGi+srDn/bbfEtD8oFBONS1zBbkqQNyuQqTE/6YyZEZ8rwV3COQdHiD03JqEXigsA== X-Received: by 2002:a5d:4e52:: with SMTP id r18mr1872616wrt.224.1638309669831; Tue, 30 Nov 2021 14:01:09 -0800 (PST) Received: from linaro.org ([2a00:23c5:6809:2201:546d:7d59:1703:bf96]) by smtp.gmail.com with ESMTPSA id y142sm3755280wmc.40.2021.11.30.14.01.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Nov 2021 14:01:09 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org Cc: mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [PATCH v2 5/6] coresight: samples: Add coresight file reader sample program Date: Tue, 30 Nov 2021 22:00:59 +0000 Message-Id: <20211130220100.25888-6-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211130220100.25888-1-mike.leach@linaro.org> References: <20211130220100.25888-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211130_140111_301325_3486FFB2 X-CRM114-Status: GOOD ( 28.04 ) 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 | 47 +++++ samples/coresight/coresight-cfg-file-read.c | 191 ++++++++++++++++++++ 3 files changed, 256 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..fc01f33bc1ff --- /dev/null +++ b/samples/coresight/Makefile.host @@ -0,0 +1,47 @@ +# 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)/../../.)) + +# ensure we use all as the default - skip anything in included Makefile +.DEFAULT_GOAL = all +# MAKECMDGOALS isn't set if there's no explicit goal in the +# command line, so set the default. +MAKECMDGOALS ?= $(.DEFAULT_GOAL) + +# include the main Makefile to use some of the vars from it +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 + +.PHONY: all +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 Tue Nov 30 22:01:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12694228 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 3186BC433F5 for ; Tue, 30 Nov 2021 22:04:36 +0000 (UTC) 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=9JlDyHwXWj7ElJ5uinuNrR+u1km2Gf6pWQhkzS5YrVU=; b=MW9qPqE0SfyUqE eXVngJ3xEHxlapgeF8r1D1BkNrVbCLqlbSH7bH1pHbLNXhgpXjEwvfdCWCHSE4vkWlkM9fls+qsP/ TxfGnH+VE8zO3q4gG5fFsZ6SQasxbTWBlJ/hTZRrqMSibRAT5ofYEiiddXzLBp5nRw0qxu3JtLP+C KOv0DKnCEdSU2Bqi918xLEnRRO4l6WaFQ6B+57qn5fgyPJlGB3cQY2Hv8nVIO3voUJUj9pH050Myf odejxJq3/AV00jwhebd7LagKuPAF45WokyxButXETrdBzpfi/WfVRbLHDKtVeqs9P3+76cfc55uYd LQJb9/mjNzz4z2xSqu0A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1msBDD-006sYh-NT; Tue, 30 Nov 2021 22:02:56 +0000 Received: from mail-wr1-x436.google.com ([2a00:1450:4864:20::436]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1msBBX-006ryO-VR for linux-arm-kernel@lists.infradead.org; Tue, 30 Nov 2021 22:01:15 +0000 Received: by mail-wr1-x436.google.com with SMTP id d24so47647002wra.0 for ; Tue, 30 Nov 2021 14:01:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=qLR7XsaQsCwnfEm1WLtzUI8vZjVqNoJXPGzhwKhjbOo=; b=YgvkW8aZqAYGclcIHg/X97tK5ZecClJsThA5O8tLbU4xa0Ghx8AKifgJpSi9fpGfcm xH1h5lxpkuu22qtomMTTtvn5+UTJIEkQmG4V0/+0fgUxVtZChP54xXTQHBSA+/bEZlZI mIs/LHzQdi7bpTwt94umbnhXwWk4bRStj0jZ7jQh1uEVqCleX9+IsLvLMgoOxP1vJZ4C vnJaR8An69RUO2kEFgZsJUBiu6jC2xc3spPrunBr7vuCZ8REryj3Y/wnZsSwhd5KQWg/ cRqCiVJqmr1KYAyDEHX5d/5rmJVvMIF8NChhCAv9iNN68H9G/+67NCVwRiiNtcbd1JrF /YgQ== 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=qLR7XsaQsCwnfEm1WLtzUI8vZjVqNoJXPGzhwKhjbOo=; b=uCx0ES5X2TcbGpGBmJsbYXTkqN3sQ+BQnLgxndsHlIHriZ4eIQlBMG2t+MftgoLfHm eUg+IY02twCmU/Q1Qmiom4Tr51gvVimOn4keBCo8A2I9crs65SGK01cQHjmPX0+nx5CQ B4zw0gmGR0IUoaMeDADxWuEicmaS4wq0+uuos9/mvCCHlumnlcOg6r0S/Fw/I/5V/QCB 98KzrBARd2iEI/CeiQcSfVKyt9PcIT0z/jbmyhofJEc3AIBHl+6rIFSNgdLf/riirLaX W0HO40IMU1umOKzxkuZbNASSE9024EYTbGJ346wwW2APxvrrqpJle4Knhb60uQXoSka0 13fg== X-Gm-Message-State: AOAM533B6R2kvZzK4768RUN86M91c12Zrh/bpeBtVTCS/OU4K5zeTS8x lDNQAhPLoI2+9G1GdSiQBiZJRhM65Noz4w== X-Google-Smtp-Source: ABdhPJw0nkfR+fGsDgBkr3SObJEt/qH4o8Redb1b0ifohIRBnKfx/IcSmSDNkiGbVYkRXUpjb7Rx7w== X-Received: by 2002:a5d:452c:: with SMTP id j12mr1819757wra.430.1638309670420; Tue, 30 Nov 2021 14:01:10 -0800 (PST) Received: from linaro.org ([2a00:23c5:6809:2201:546d:7d59:1703:bf96]) by smtp.gmail.com with ESMTPSA id y142sm3755280wmc.40.2021.11.30.14.01.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Nov 2021 14:01:10 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org Cc: mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [PATCH v2 6/6] Documentation: coresight: docs for config load via configfs Date: Tue, 30 Nov 2021 22:01:00 +0000 Message-Id: <20211130220100.25888-7-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211130220100.25888-1-mike.leach@linaro.org> References: <20211130220100.25888-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211130_140112_088402_F0E539B0 X-CRM114-Status: GOOD ( 27.26 ) 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 via configfs, along with the demonstration programs in samples. Signed-off-by: Mike Leach --- .../trace/coresight/coresight-config.rst | 151 +++++++++++++++++- 1 file changed, 145 insertions(+), 6 deletions(-) diff --git a/Documentation/trace/coresight/coresight-config.rst b/Documentation/trace/coresight/coresight-config.rst index 6d5ffa6f7347..f11def230fab 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 feature_refs preset1 preset3 preset5 preset7 preset9 @@ -278,9 +278,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. @@ -289,6 +299,135 @@ 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 native binaries +to be created on the host machine rather than cross compiled version for the +target. + + +Binary Configuration File Format +-------------------------------- + +The file format is defined in the source file **coresight-config-file.h** + +The source reader and generator examples produce a binary of this format. + +This arrangement is reproduced below:- + +Overall File structure +~~~~~~~~~~~~~~~~~~~~~~ + +:: + + [cscfg_file_header] // Mandatory + [CONFIG_ELEM] // Optional - one per file, if present, first element in file. + [FEATURE_ELEM]* // Optional - multiple, defined by cscfg_file_header.nr_features + +File is invalid if both [CONFIG_ELEM] and [FEATURE_ELEM] are omitted. + +A file that contains only [FEATURE_ELEM] may be loaded, and the features used +by subsequently loaded files with [CONFIG_ELEM] elements. + +Where [CONFIG_ELEM] is present, then **cscfg_file_header.nr_features** and +**CONFIG_ELEM.nr_feat_refs** must have the same value. + +CONFIG_ELEM element +~~~~~~~~~~~~~~~~~~~ + +:: + + [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) // number of defined presets. + [u32 value](nr_total_params) // total parameters defined by all used features. + [u16 value](nr_feat_refs) // number of features referenced by the configuration + [u64 values] * (nr_presets * nr_total_params) // the preset values. + [cscfg_file_elem_str] * (nr_feat_refs) // the features used in the configurations. + +FEATURE_ELEM element +~~~~~~~~~~~~~~~~~~~~ + +:: + + [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) // flags to associate the feature with a device. + [u16 value](nr_regs) // number of registers. + [u16 value](nr_params) // number of parameters. + [cscfg_regval_desc struct] * (nr_regs) // register definitions + [PARAM_ELEM] * (nr_params) // parameters definitions + +PARAM_ELEM element +~~~~~~~~~~~~~~~~~~ + +:: + + [cscfg_file_elem_str] // parameter name. + [u64 value](param_value] // initial value. + +Additional definitions. +~~~~~~~~~~~~~~~~~~~~~~~ + +The following structures are defined in **coresight-config-file.h** + + * **struct cscfg_file_header** : This structure contains an initial magic number, the total + length of the file, and the number of features in the file. + * **struct cscfg_file_elem_header**: This defines the total length and type of a CONFIG_ELEM + or a FEATURE_ELEM. + * **struct cscfg_file_elem_str**: This defines a string and its length. + +The magic number in cscfg_file_header is defined as two bitfields:: + + [31:8] Fixed magic number to identify file type. + [7:0] Current file format version. + +The following defines determine the maximum overall file size and maximum individual +string size:: + + CSCFG_FILE_MAXSIZE // maximum overall file size. + CSCFG_FILE_STR_MAXSIZE // maximum individual string size.