From patchwork Thu Apr 14 06:44:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12812977 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 3FAEBC433EF for ; Thu, 14 Apr 2022 06:46:32 +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=qwCwQMU4tcyTTrAP7ENMzND9O+L87vOPdG/vxoeDzxk=; b=tfL9zhoZ0BopEv uKlNZaJ7ioH8IvFYBKgupRj96C7xF/NNT/ZliAMM45VC8BNdPFEwJ8PAoxKHA1pFtGRolEQGVxnPY xvgR7kTWG1auhjHRDiF9XERL1PUVcJd8Q6rrYV/HU4YeUb+gJPv3k1TfaS+qzjOxek/h7DpeDKK3X 4yGa5fmquoQoqnWrCckm0WdUIOr9PrQF3Z4Aq6D4u/HyHtkQ0SjLM+9nS8dxE5x99J/EAJgaNnnVT 3RU6vTZcIzd1Tt7PnX8laBhSyJjy/3aOqu1/BqrF0PlDIeoHlmoWPu5OqHtPnEh7bBCIFSTz+mmbP /L9a4ymMRMqWSFb1PxlQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1netEB-0049Vp-E7; Thu, 14 Apr 2022 06:45:15 +0000 Received: from mail-wm1-x331.google.com ([2a00:1450:4864:20::331]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1netDy-0049Rt-2W for linux-arm-kernel@lists.infradead.org; Thu, 14 Apr 2022 06:45:05 +0000 Received: by mail-wm1-x331.google.com with SMTP id n126-20020a1c2784000000b0038e8af3e788so2537312wmn.1 for ; Wed, 13 Apr 2022 23:45:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=9BKKPdNJmFz6p4Ev8YUXdlUqAPgjPLDrJOr5q/gT/4k=; b=GIsHw8pUrIO9Qa9KY0c4tDG/AO9Lnz+SnHNOVrCF6UQL/7S+G0NZNd53L3Gh1pCys7 d/pYuqTqH1S/7lRWYflpmHWwsd2JOTYV2b8NOXJPX3pwIO0b+l3rphXFSjlk/kMCuZOV utNh93o7kbf6Kiu3+pNy5GYuBwn/uVgfKG9SqV2C/6wpAg9w//5yIvYYe1X/xYLYYqzf q/nK9OivCb+R8+yQhliea3ozzXCfMGjze/XEXwzq/++NpimfP6lBzEWRvMh4BrEpLjSw 9t0qmgrAFnJQB90fhPvHgLQqTtjYrDB6G8WXrsoXxTelKwVdiI2mQGgA5xvOSCaaoOWV d49Q== 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=9BKKPdNJmFz6p4Ev8YUXdlUqAPgjPLDrJOr5q/gT/4k=; b=Clg/GjEUjrg8ZrOHNzmXzeUjnVkGJwsg+SskYOBXgnrBKe5cDbFj2UU2H7+ayJn5JL u8bKmQoEeXx1T5gdEt+5CqufuFNgnEiZYgLyONkX3mAfN8MzNyq5xAdNhliD0rqdQ07T 7LMbhBfI2VqHtctlxOg9t2z8vYiPaNFrkijUnSljy8sXVRsfsWkqIjL89f4CZS3ZwKSE /H0AS0OrG+PyeSx2dWNH7XWz8YJ1HvEdRXBYVKrq7HsZO4CFO0svc4/av6bSCQozMmCd /qJR/KGOHKLy7UORYWC+rQKOexjsIV8dURhI51kRjaDYcClN6PgYzik4f1e+D72ZJ4g4 pVVA== X-Gm-Message-State: AOAM530EWAiFmMEedM9B8JWwKAgoWmsArEY/5kpdprkjDTSzyILmyH1w 1RBvkATu2d0HkpqR2rZQ1Qp0KH6K/SKNYw== X-Google-Smtp-Source: ABdhPJzkQ2mkcKrafyAPtudHjJR640UCvS9nz8hx2pDxvD1g1FYVeNGrrT3tKasUopkuiQxLxrALgg== X-Received: by 2002:a05:600c:3492:b0:38e:d3ea:9ae3 with SMTP id a18-20020a05600c349200b0038ed3ea9ae3mr2163290wmq.174.1649918700158; Wed, 13 Apr 2022 23:45:00 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:e4bb:355f:cdcf:ea80]) by smtp.gmail.com with ESMTPSA id c18-20020a7bc852000000b0038ebf5f191esm5395954wml.45.2022.04.13.23.44.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Apr 2022 23:44:59 -0700 (PDT) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, mathieu.poirier@linaro.org Cc: suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [PATCH v3 1/5] coresight: configfs: Add in functionality for load via configfs Date: Thu, 14 Apr 2022 07:44:53 +0100 Message-Id: <20220414064457.12052-2-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220414064457.12052-1-mike.leach@linaro.org> References: <20220414064457.12052-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220413_234502_174643_212B31B0 X-CRM114-Status: GOOD ( 31.75 ) 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 | 117 +++++ .../hwtracing/coresight/coresight-config.h | 15 + .../hwtracing/coresight/coresight-syscfg.h | 1 + 5 files changed, 566 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..591f4c2c4be9 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-config-file.h @@ -0,0 +1,117 @@ +/* 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 2e1670523461..9cd3c26ce023 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -85,6 +85,21 @@ struct cscfg_regval_desc { }; }; +/** + * 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. + * + * @config_descs: array of config descriptor pointers. + * @feat_descs: array of feature descriptor pointers. + */ +struct cscfg_fs_load_descs { + struct cscfg_config_desc **config_descs; + struct cscfg_feature_desc **feat_descs; +}; + /** * Device feature descriptor - combination of registers and parameters to * program a device to implement a specific complex function. 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 Thu Apr 14 06:44:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12812978 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 73B02C433F5 for ; Thu, 14 Apr 2022 06:46:41 +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=hKmia0IWiVIjfuunl7wGnp1Zsi+add2x3E82PZ+01DY=; b=4cSmlbpaMpF+CF xRz3BK1D4jS3gOq27e323ENNGsbtHVY2hCWktVjdG8h7oEnzLpj4rJmrLCoeJlqp3ShUYq1cYRJGr I1N+Y3zxKKkXJn23/VLSpofidUOTNF4Us9aUfjh8nK4UX/eBGrqvo6Jx4hsfIZJv1y13sWe3Uvkt4 pVQyE4/L9/Jy9gn5fB0+2WtDfFky3qZYwsrVcy0oemB1XlaV1GkSYOPEYp7+3KxX+N3w7zuaUsOgd 2Xc0/EQmR3OnDYlw0Wusw6mKdbRUe5tM3Dvzcih0PZVGNUNsEhyFMRGVbGl1Vjqibg2NnoxS/lgGi inY5aNDeimlYFiWaEc4A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1netEK-0049Xg-6l; Thu, 14 Apr 2022 06:45:24 +0000 Received: from mail-wm1-x32a.google.com ([2a00:1450:4864:20::32a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1netDz-0049S3-0l for linux-arm-kernel@lists.infradead.org; Thu, 14 Apr 2022 06:45:06 +0000 Received: by mail-wm1-x32a.google.com with SMTP id l62-20020a1c2541000000b0038e4570af2fso2520848wml.5 for ; Wed, 13 Apr 2022 23:45:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=20kSwrvFes3d9AaLZ9Dsa6NcYkb3CXOirJC6L4XWTcM=; b=jEiS0wh/Ug0p+JdlQcW6M/+fscpuaZrp5VUSlmWuvarL35lY9kxSHTx5RcfBPErzlB IVbvN766FYdWwqUpKCD+JEvEcYPtvgmyaBUBJLGHZ554qb6nqBwQ+0ZNNQbU/sxZ40xN JpW0HFHsk+bIW/58H4XktbDwE212jKOA9qrz0tsPSO/DSIvzDA3tjdoSB6KTA/lMRvR4 fAOxTbtfquIjqwVN+C5PwsWAK+CXd4bGC/uAXSjXDLd9pbWqkKs9khKo11et49r8r0AM Kpzsspcjb7xQHg4MT7ZR9i1V7Xvgk2YTRSNMC+t8Civ53DCM9wFxW+1nCMHupru/RMF4 0QHw== 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=20kSwrvFes3d9AaLZ9Dsa6NcYkb3CXOirJC6L4XWTcM=; b=kqSNjL1LDunKosPbIntsT95JvnizHOXmgYB93xz+YjKfjeNeL6dSBBhCZkT/7HTIDw bqVc5Z7Lv14IUHVqHUP531zA/JFhQlrX/teDzMkbu6KDdL4hwJ8cJUOOqPaD2z/hLcNc 6j+6OMQh2Xrgq9T+Ko0UYklliF525HluPy/df2gxGAuGEnqoFnJBFMU3sHYWjavDzhPK Wbypjj8+xVSHKDQn37vf2o2R3SbO2xw6WXmbJcJ9sAhIsBtTVxqO5vsjAR7Sc88vM8CB 2dvgyJeyjuHPZLPE7w8TwdKCWkcrzTR24r6JVmyk0WGEPsBqNUOPC9fwxtcpEO8qSolt z3zA== X-Gm-Message-State: AOAM532JIaM/UWmLCRd5uf1iCFIFakrBfThTXZydMLIqpdGhzr1uMeYo bxIGvvRV7N5l6c6MZAc+32tNzeAHE2Hc/w== X-Google-Smtp-Source: ABdhPJyzBJHbclXN29uw7e8ofcEHBNIEuZieWcubgt30CuMi6nezIdsuJoGtjfeZVVDxb95ZMtTJlg== X-Received: by 2002:a05:600c:5025:b0:38f:f782:253c with SMTP id n37-20020a05600c502500b0038ff782253cmr1182447wmr.42.1649918700806; Wed, 13 Apr 2022 23:45:00 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:e4bb:355f:cdcf:ea80]) by smtp.gmail.com with ESMTPSA id c18-20020a7bc852000000b0038ebf5f191esm5395954wml.45.2022.04.13.23.45.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Apr 2022 23:45:00 -0700 (PDT) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, mathieu.poirier@linaro.org Cc: suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [PATCH v3 2/5] coresight: configfs: Add in binary attributes to load files Date: Thu, 14 Apr 2022 07:44:54 +0100 Message-Id: <20220414064457.12052-3-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220414064457.12052-1-mike.leach@linaro.org> References: <20220414064457.12052-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220413_234503_106837_1EEBEC0E X-CRM114-Status: GOOD ( 24.03 ) 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 | 9 ++ .../coresight/coresight-syscfg-configfs.c | 91 +++++++++++++++++++ .../hwtracing/coresight/coresight-syscfg.c | 37 ++++++++ .../hwtracing/coresight/coresight-syscfg.h | 1 + 4 files changed, 138 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-config-file.h b/drivers/hwtracing/coresight/coresight-config-file.h index 591f4c2c4be9..f85cf1aabf56 100644 --- a/drivers/hwtracing/coresight/coresight-config-file.h +++ b/drivers/hwtracing/coresight/coresight-config-file.h @@ -7,6 +7,8 @@ #ifndef _CORESIGHT_CORESIGHT_CONFIG_FILE_H #define _CORESIGHT_CORESIGHT_CONFIG_FILE_H +#include "coresight-config.h" + /* * Structures to represent configuration descriptors in a memory buffer * to serialise to and from files @@ -114,4 +116,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..d1ddcba10ad8 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,10 +381,100 @@ 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_load_descs *load_descs = 0; + struct cscfg_load_owner_info *owner_info = 0; + int err = 0; + + if (size > CSCFG_FILE_MAXSIZE) { + pr_err("cscfg: 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; + } + + owner_info->owner_handle = load_descs; + owner_info->type = CSCFG_OWNER_CONFIGFS; + + err = cscfg_file_read_buffer(buffer, size, load_descs); + if (err) { + pr_err("cscfg: 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) { + pr_err("cscfg: Load error - Failed to load configuaration file.\n"); + goto exit_memfree; + } + + 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_load_owner_info *owner_info = 0; + const char *name; + int err; + + if (size > CSCFG_FILE_MAXSIZE) { + pr_err("cscfg: Unload error - Input file too large\n"); + return -EINVAL; + } + + err = cscfg_file_read_buffer_first_name(buffer, size, &name); + if (err) { + pr_err("cscfg: Unload error - Failed to read input file\n"); + return err; + } + + owner_info = cscfg_find_fs_owned_cfg_by_name(name); + if (!owner_info) { + pr_err("cscfg: Unload error: Failed to find configuration %s from input file\n", + name); + return err; + } + err = cscfg_unload_config_sets(owner_info); + if (err) { + pr_err("cscfg: Unload error: Cannot unload configuration %s\n", + name); + return err; + } + + kfree(owner_info); + kfree((struct cscfg_fs_load_descs *)(owner_info->owner_handle)); + return size; +} +CONFIGFS_BIN_ATTR_WO(cscfg_cfg_, unload, NULL, CSCFG_FILE_MAXSIZE); + +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, }; +/* group for configurations dir, with load and unload attribs */ static struct config_group cscfg_configs_grp = { .cg_item = { .ci_namebuf = "configurations", diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index 11850fd8c3b5..2e478b3e8c8d 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -587,6 +587,43 @@ 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_load_owner_info *cscfg_find_fs_owned_cfg_by_name(const char *name) +{ + struct cscfg_load_owner_info *owner_info = NULL; + struct cscfg_fs_load_descs *fs_load_cfg; + 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; + } + } + } + + /* not found */ + owner_info = NULL; + +exit_unlock: + mutex_unlock(&cscfg_mutex); + return owner_info; +} + /* 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..487d872d931a 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_load_owner_info *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 Thu Apr 14 06:44:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12812979 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 EDDFEC433F5 for ; Thu, 14 Apr 2022 06:46:53 +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=vQ76Q9lyHEPxPXUojJf+5iT7vwzLXEfX+SofP582QIg=; b=rPDh7kHGku+IVC ah8Ixj3a3Uj1dQi10lRSeS7v4WpZyalWbCm3Oip1RZ/0nllhgys79c6Ox3UrCctWTgCQP/+AfF+ch P3b7k9EykyXEeLSZWea9UxYB9S/uZa98Xkuqq7BjGC3S4SBPatkOO0Lnua/2E2h6tIKMz65VR8EMk 3XWHwPcNgdlw0+LXvZHA2ocNNUMtNVup3pvibB3QXx1cVMLT6yyFAXto40MI3T1KZeSmYtSd63m5V oTr3cB6nYR+LVsm8CfVazRS/veIR3BleC7CyX0cW03H0V6m+KmlMpc+QpaWZmYt81wGk8uMg0N72w UydiKRF441v6wpqOIIJA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1netEV-0049Zp-14; Thu, 14 Apr 2022 06:45:35 +0000 Received: from mail-wm1-x329.google.com ([2a00:1450:4864:20::329]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1netDz-0049SJ-LY for linux-arm-kernel@lists.infradead.org; Thu, 14 Apr 2022 06:45:06 +0000 Received: by mail-wm1-x329.google.com with SMTP id ay11-20020a05600c1e0b00b0038eb92fa965so5338303wmb.4 for ; Wed, 13 Apr 2022 23:45:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+nBEW0jm0yLeT5vwXFjCiio0kk5nWsE2+oQuJTfnj4Y=; b=cn92g6F0+ystIBpgu05t9FFS9Bn1wdKSiGDbxMb8bnfpGDTZTHcz3xi21GaMJa/1sf kKPxzcy7B3wZNNZW/TX9oHv+6OGuVOAQQZiwYKbcNbtgO4mXlq/YQBJDsmFYIkPGhDwd YrW+afFAXn5lh0jz5EFsYMTDsQJWrCDLQgOQCMxdAuaNEGxJsD+lj7/6Wc8nP9Q2zJ3j 0jN5KDK/PrleJTaAI6fRNPt8xfjNzS+h+lqLrpkrF1gfDR5P7FY1k+/JKFy6jOq6qAXt E4Nz1hJnYTROOuGJuHeKoMBPBFz1tevAgDWthN7+XKrVZQ0GlV38z4PKVH1gjoRpnTTP FtnA== 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=+nBEW0jm0yLeT5vwXFjCiio0kk5nWsE2+oQuJTfnj4Y=; b=gsW8mDm1YS08I7gvHrTtOW5IYVuNgUDwHp/XGSaXYVHKwKFGMEFlX/LK57XWAq6IFf vKMI07H80GI9+LRo82DhG37x3Oi7czO+MDtNxvB9tLp5BAkdIf8kYXzcPZTB8/y7nZ8V NhO397r7XklyIwqb3auGIq73Fah3HWqr5ao9tEOU7ihsiSWkRZM2so3pl8fu+zMQ8svE Ig+47YDu6MB2b2d5oMn8HXOi5olM7ng+HgZUTP8H6h5utUDYasQr8gKC4EKr4R9KBbc/ lbQcaj9CNCxUfYuETFiBS7aGSeNY03//3CD9HGa/W5WjMfit1nA6DclecB/HdxHNpEL/ smzQ== X-Gm-Message-State: AOAM531+RmeJUAj2SjehdesLB6PANHEj2sUVqNh0pB0yaFND4TG4gFMJ 3o/bz2xGy90RqiIUuFzxF+3gfIwqDyesCA== X-Google-Smtp-Source: ABdhPJztG5PYwqWC4ApFpJsUbJrHV29La307G72obov/B82LPG0te6IF5AxvT2MW3AxycE9N/FGlvA== X-Received: by 2002:a05:600c:3586:b0:38c:a92f:1744 with SMTP id p6-20020a05600c358600b0038ca92f1744mr2174259wmq.126.1649918701410; Wed, 13 Apr 2022 23:45:01 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:e4bb:355f:cdcf:ea80]) by smtp.gmail.com with ESMTPSA id c18-20020a7bc852000000b0038ebf5f191esm5395954wml.45.2022.04.13.23.45.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Apr 2022 23:45:01 -0700 (PDT) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, mathieu.poirier@linaro.org Cc: suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [PATCH v3 3/5] coresight: configfs: Modify config files to allow userspace use Date: Thu, 14 Apr 2022 07:44:55 +0100 Message-Id: <20220414064457.12052-4-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220414064457.12052-1-mike.leach@linaro.org> References: <20220414064457.12052-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220413_234503_793322_0A70456A X-CRM114-Status: GOOD ( 26.00 ) 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 | 95 +++++++++++++------ .../hwtracing/coresight/coresight-config.h | 12 +++ 2 files changed, 80 insertions(+), 27 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-config-file.c b/drivers/hwtracing/coresight/coresight-config-file.c index 3fd001938324..5b8f635ac50e 100644 --- a/drivers/hwtracing/coresight/coresight-config-file.c +++ b/drivers/hwtracing/coresight/coresight-config-file.c @@ -6,8 +6,57 @@ #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 +129,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 +139,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 +156,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 +188,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 +214,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 +229,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 +308,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 +347,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 +362,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 +440,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.h b/drivers/hwtracing/coresight/coresight-config.h index 9cd3c26ce023..fce74e2fbd0c 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 */ @@ -100,6 +107,10 @@ struct cscfg_fs_load_descs { struct cscfg_feature_desc **feat_descs; }; + +/* remainder of header is used by the kernel drivers only */ +#ifdef __KERNEL__ + /** * Device feature descriptor - combination of registers and parameters to * program a device to implement a specific complex function. @@ -272,4 +283,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 Thu Apr 14 06:44:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12812981 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 9C262C433F5 for ; Thu, 14 Apr 2022 06:47:21 +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=dAdGSdDx47Ly9GOFtlY+kS2HWSlwK5KqN7VEfbO2lfc=; b=QbN0y50pOPbQuk rGKiDfuB/dZPwc90LJFbLnVLQfFUjhBL/23Xf+hDgye7GUYOEHPBGtnQagFvwvkFuNOoexhwW0Wpz qNcmchz/y6zhcFVfRMNNuETjyjpovzayuuBJx72/XAYrqM1DTJ/RX6UOWUefiPzQlkfcFoa9geVBC PMc4TcNdPODYe3tVRpI90+yEji6Wt+LE9n+kuJe9xWvI8KvXZkps/giMgXsYw2wh0D1QnfNyPa8Ba K3oOtq3sqcjt8RTInm2ztt9qBLk/0SjPG4kdfs6UIUjrdlKbLoHT13rq9UC36+KMif5NJjmPw8G/B L/TJVmMYjsA4JDPehoVg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1netEt-0049jI-Du; Thu, 14 Apr 2022 06:45:59 +0000 Received: from mail-wm1-x330.google.com ([2a00:1450:4864:20::330]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1netE0-0049Sk-FB for linux-arm-kernel@lists.infradead.org; Thu, 14 Apr 2022 06:45:09 +0000 Received: by mail-wm1-x330.google.com with SMTP id r64so2417151wmr.4 for ; Wed, 13 Apr 2022 23:45:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=UOP6LaDToeaphpFVCfkRT9HOkk10ABgpjEiuRyi2ZOg=; b=n0CO11wj+PqSApt15SojlphsvIJM3VFiNE2sQRFlIMKsAdzR+FbBKZIx5dhYtaqw8O uiX/F5SrQVilniR5QX3tbYXuulZ7U68I9i/WonRMwgLa9iusNPLJo/SZ7zTiiXNHhlay Xlru8bnCO3dEGcLk5IBhFG/vzIEM2KvxX/RMe/8SBokecMc4VYObhmF446eDOXgB0J+c FpvHC5WLf0Ct2Le4Gwm+Atd7QcyhvGTZcTnXjPQBfPa+SN0LpdHEh0l6Y0R8Xrxl7iHv +BtmedxaRzQWaYTksUZ5qyTQrYm5kbtLOHyQ9V69hhaEZmxu2bCA9BStOSFZD90V1K+s vA3Q== 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=UOP6LaDToeaphpFVCfkRT9HOkk10ABgpjEiuRyi2ZOg=; b=Ka95UZ4khw42NYgvwxpFmPLoKzeOSRZ9CAg8Q8xe1GxRwJX3446yEcouubJ1Q6yIoe aQQ9QBcH9PXfvHwxTGsjrdISwQ8xBuLWKt2a7WlsM4wJ7hW2O3k0grXFH7ZuMNhTfXbQ 89xSkew/6lMtV6Zc187F0wSdQXSHJ4A0Lwk3Jujh2BH3d9SR7bOrL9uYw5+VDfew8EBB 8HQS2zc4K/eARGNrN1xdDTadqTdYGYrkD/8hlB1Ux5g9xkRm1swgoExI7ifi4XZ86Dv+ BoBjId6hIswNnGwiJdIwoaqgIdwFgnlQX41jYibd1AHU5xGvfNcIyExvE+omy4v7cJxu 7zew== X-Gm-Message-State: AOAM530o1vraMZZijvIAyra+fyLlfkNs9Z1AyQchoqEHB7XeiZzwNpWx 4G2cgkVDmeSp0gWQYtEXiENm0USAv6QYfw== X-Google-Smtp-Source: ABdhPJwmC1BBJpF01AUO9kbqejR4JCmzvTuJZNWlwVtdWLSJ2Iq7z9T2ZJG+6eBuuqD8FnrU9krIdg== X-Received: by 2002:a05:600c:4f87:b0:38c:adde:1d99 with SMTP id n7-20020a05600c4f8700b0038cadde1d99mr2122227wmq.16.1649918702079; Wed, 13 Apr 2022 23:45:02 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:e4bb:355f:cdcf:ea80]) by smtp.gmail.com with ESMTPSA id c18-20020a7bc852000000b0038ebf5f191esm5395954wml.45.2022.04.13.23.45.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Apr 2022 23:45:01 -0700 (PDT) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, mathieu.poirier@linaro.org Cc: suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [PATCH v3 4/5] coresight: tools: Add config file write and reader tools Date: Thu, 14 Apr 2022 07:44:56 +0100 Message-Id: <20220414064457.12052-5-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220414064457.12052-1-mike.leach@linaro.org> References: <20220414064457.12052-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220413_234504_593319_45039B56 X-CRM114-Status: GOOD ( 31.29 ) 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. Add a config file reader and printer. Takes in config files and prints the contents. Uses file reader source from kernel driver. Signed-off-by: Mike Leach --- MAINTAINERS | 2 + .../coresight/coresight-config-file.c | 2 + tools/coresight/Makefile | 51 +++ tools/coresight/coresight-cfg-bufw.c | 303 ++++++++++++++++++ tools/coresight/coresight-cfg-bufw.h | 26 ++ tools/coresight/coresight-cfg-example1.c | 65 ++++ tools/coresight/coresight-cfg-examples.h | 27 ++ tools/coresight/coresight-cfg-file-read.c | 197 ++++++++++++ tools/coresight/coresight-cfg-filegen.c | 58 ++++ tools/include/uapi/coresight-config-uapi.h | 76 +++++ 10 files changed, 807 insertions(+) create mode 100644 tools/coresight/Makefile create mode 100644 tools/coresight/coresight-cfg-bufw.c create mode 100644 tools/coresight/coresight-cfg-bufw.h create mode 100644 tools/coresight/coresight-cfg-example1.c create mode 100644 tools/coresight/coresight-cfg-examples.h create mode 100644 tools/coresight/coresight-cfg-file-read.c create mode 100644 tools/coresight/coresight-cfg-filegen.c create mode 100644 tools/include/uapi/coresight-config-uapi.h diff --git a/MAINTAINERS b/MAINTAINERS index 61d9f114c37f..4e59486e75b5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1985,6 +1985,8 @@ F: drivers/hwtracing/coresight/* F: include/dt-bindings/arm/coresight-cti-dt.h F: include/linux/coresight* F: samples/coresight/* +F: tools/coresight/* +F: tools/include/uapi/coresight-config-uapi.h F: tools/perf/arch/arm/util/auxtrace.c F: tools/perf/arch/arm/util/cs-etm.c F: tools/perf/arch/arm/util/cs-etm.h diff --git a/drivers/hwtracing/coresight/coresight-config-file.c b/drivers/hwtracing/coresight/coresight-config-file.c index 5b8f635ac50e..4a8b64405d84 100644 --- a/drivers/hwtracing/coresight/coresight-config-file.c +++ b/drivers/hwtracing/coresight/coresight-config-file.c @@ -36,6 +36,8 @@ static void *cscfg_zalloc(size_t size) #include #include +#include "uapi/coresight-config-uapi.h" + static void *cscfg_calloc(size_t num, size_t size) { return calloc(num, size); diff --git a/tools/coresight/Makefile b/tools/coresight/Makefile new file mode 100644 index 000000000000..4004c315d65c --- /dev/null +++ b/tools/coresight/Makefile @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: GPL-2.0-only +include ../scripts/Makefile.include +include ../scripts/Makefile.arch + +# Makefile to build the coresight configuration file reader and generator tools + +this-makefile := $(lastword $(MAKEFILE_LIST)) +tools-src := $(realpath $(dir $(this-makefile))) +srctree := $(realpath $(dir $(tools-src)/../../.)) + +# ensure we use all as the default - skip anything in included Makefile +.DEFAULT_GOAL = all +# MAKECMDGOALS isn't set if there's no explicit goal in the +# command line, so set the default. +MAKECMDGOALS ?= $(.DEFAULT_GOAL) + +# compile flags +CFLAGS += $(CPPFLAGS) -c -Wall -DLINUX -Wno-switch -Wlogical-op -fPIC -I$(srctree)/drivers/hwtracing/coresight -I$(srctree)/tools/include/ -I$(srctree)/tools/include/uapi + +# object files +coresight-cfg-file-gen-objs := coresight-cfg-filegen.o coresight-cfg-bufw.o coresight-cfg-example1.o +coresight-cfg-file-read-objs := coresight-cfg-file-read.o coresight-config-file.o + +# debug variant +ifdef DEBUG +CFLAGS += -g -O0 -DDEBUG +else +CFLAGS += -O2 -DNDEBUG +endif + +.PHONY: all +all: coresight-cfg-file-gen coresight-cfg-file-read + +coresight-config-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 $(srctree)/tools/coresight/. + +coresight-cfg-file-gen: $(coresight-cfg-file-gen-objs) + $(CC) $(LDFLAGS) $(coresight-cfg-file-gen-objs) -o coresight-cfg-file-gen + +coresight-cfg-file-read: $(coresight-cfg-file-read-objs) + $(CC) $(LDFLAGS) $(coresight-cfg-file-read-objs) -o coresight-cfg-file-read + +clean: + rm -f coresight-cfg-file-gen coresight-cfg-file-read + rm -f *.o + rm -f coresight-config-file.c + rm -f *.cscfg diff --git a/tools/coresight/coresight-cfg-bufw.c b/tools/coresight/coresight-cfg-bufw.c new file mode 100644 index 000000000000..73223de2b7e0 --- /dev/null +++ b/tools/coresight/coresight-cfg-bufw.c @@ -0,0 +1,303 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#include + +#include "coresight-cfg-bufw.h" +#include "uapi/coresight-config-uapi.h" + +/* + * Set of macros to make writing the buffer code easier. + *. + * Uses naming convention as 'buffer' for the buffer pointer and + * 'used' as the current bytes used by the encosing function. + */ +#define cscfg_write_u64(val64) { \ + *(u64 *)(buffer + used) = val64; \ + used += sizeof(u64); \ + } + +#define cscfg_write_u32(val32) { \ + *(u32 *)(buffer + used) = val32; \ + used += sizeof(u32); \ + } + +#define cscfg_write_u16(val16) { \ + *(u16 *)(buffer + used) = val16; \ + used += sizeof(u16); \ + } + +#define cscfg_write_u8(val8) { \ + *(buffer + used) = val8; \ + used++; \ + } + +#define CHECK_WRET(rval) { \ + if (rval < 0) \ + return rval; \ + used += rval; \ + } + +/* write the header at the start of the buffer */ +static int cscfg_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/tools/coresight/coresight-cfg-bufw.h b/tools/coresight/coresight-cfg-bufw.h new file mode 100644 index 000000000000..562df97599fc --- /dev/null +++ b/tools/coresight/coresight-cfg-bufw.h @@ -0,0 +1,26 @@ +/* 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 + +#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/tools/coresight/coresight-cfg-example1.c b/tools/coresight/coresight-cfg-example1.c new file mode 100644 index 000000000000..a71a6e43d7b3 --- /dev/null +++ b/tools/coresight/coresight-cfg-example1.c @@ -0,0 +1,65 @@ +// 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" +#include "coresight-cfg-examples.h" + +/* + * create a configuration only example using the strobing feature + */ + +/* we will provide 4 sets of preset parameter values */ +#define AFDO3_NR_PRESETS 4 +/* the total number of parameters in used features - strobing has 2 */ +#define AFDO3_NR_PARAM_SUM 2 + +static const char *afdo3_ref_names[] = { + "strobing", +}; + +/* + * set of presets leaves strobing window constant while varying period to allow + * experimentation with mark / space ratios for various workloads + */ +static u64 afdo3_presets[AFDO3_NR_PRESETS][AFDO3_NR_PARAM_SUM] = { + { 2000, 100 }, + { 2000, 1000 }, + { 2000, 5000 }, + { 2000, 10000 }, +}; + +struct cscfg_config_desc afdo3 = { + .name = "autofdo3", + .description = "Setup ETMs with strobing for autofdo\n" + "Supplied presets allow experimentation with mark-space ratio for various loads\n", + .nr_feat_refs = ARRAY_SIZE(afdo3_ref_names), + .feat_ref_names = afdo3_ref_names, + .nr_presets = AFDO3_NR_PRESETS, + .nr_total_params = AFDO3_NR_PARAM_SUM, + .presets = &afdo3_presets[0][0], +}; + +static struct cscfg_feature_desc *sample_feats[] = { + NULL +}; + +static struct cscfg_config_desc *sample_cfgs[] = { + &afdo3, + NULL +}; + +#define CSCFG_EG1_FILENAME "example1.cscfg" + +struct cscfg_file_eg_info buff_info_eg1 = { + .example_name = "example1", + .filename = CSCFG_EG1_FILENAME, + .config_descs = sample_cfgs, + .feat_descs = sample_feats, +}; diff --git a/tools/coresight/coresight-cfg-examples.h b/tools/coresight/coresight-cfg-examples.h new file mode 100644 index 000000000000..5c6908745201 --- /dev/null +++ b/tools/coresight/coresight-cfg-examples.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#ifndef _CORESIGHT_CFG_EXAMPLES_H +#define _CORESIGHT_CFG_EXAMPLES_H + +#include + +#include "uapi/coresight-config-uapi.h" +#include "coresight-cfg-bufw.h" + +/* structure to pass configuraiton information to generator program */ +struct cscfg_file_eg_info { + const char *example_name; + const char *filename; + struct cscfg_config_desc **config_descs; + struct cscfg_feature_desc **feat_descs; +}; + + +/* references to the configuration and feature example structures */ +extern struct cscfg_file_eg_info buff_info_eg1; + +#endif /* _CORESIGHT_CFG_EXAMPLES_H */ diff --git a/tools/coresight/coresight-cfg-file-read.c b/tools/coresight/coresight-cfg-file-read.c new file mode 100644 index 000000000000..da7b831eb2df --- /dev/null +++ b/tools/coresight/coresight-cfg-file-read.c @@ -0,0 +1,197 @@ +// 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" +#include "uapi/coresight-config-uapi.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%lx, ", 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%lx\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%lx\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; + } + err = fread(buffer, sizeof(u8), fsize, fp); + fclose(fp); + + if (err < fsize) { + printf("Error reading file %s\n", argv[1]); + return -EINVAL; + } + + /* allocate the descriptor structures to be populated by read operation */ + load_descs = malloc(sizeof(struct cscfg_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; +} diff --git a/tools/coresight/coresight-cfg-filegen.c b/tools/coresight/coresight-cfg-filegen.c new file mode 100644 index 000000000000..cd0589661d92 --- /dev/null +++ b/tools/coresight/coresight-cfg-filegen.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#include +#include +#include +#include + +#include "uapi/coresight-config-uapi.h" +#include "coresight-cfg-bufw.h" +#include "coresight-cfg-examples.h" + + +/* array of example files to generate */ +struct cscfg_file_eg_info *info_ptrs[] = { + &buff_info_eg1, + NULL, +}; + +int main(int argc, char **argv) +{ + struct cscfg_config_desc *config_desc; + struct cscfg_feature_desc **feat_descs; + u8 buffer[CSCFG_FILE_MAXSIZE]; + int used, idx = 0; + FILE *fp; + const char *filename; + + printf("Coresight Configuration file Generator\n\n"); + + while (info_ptrs[idx]) { + printf("Generating %s example\n", info_ptrs[idx]->example_name); + config_desc = info_ptrs[idx]->config_descs[0]; + feat_descs = info_ptrs[idx]->feat_descs; + filename = info_ptrs[idx]->filename; + used = cscfg_file_write_buffer(buffer, CSCFG_FILE_MAXSIZE, + config_desc, feat_descs); + + if (used < 0) { + printf("Error %d writing configuration %s into buffer\n", + used, info_ptrs[idx]->example_name); + return used; + } + + fp = fopen(filename, "wb"); + if (fp == NULL) { + printf("Error opening file %s\n", filename); + return -1; + } + fwrite(buffer, used, sizeof(u8), fp); + fclose(fp); + idx++; + } + return 0; +} diff --git a/tools/include/uapi/coresight-config-uapi.h b/tools/include/uapi/coresight-config-uapi.h new file mode 100644 index 000000000000..d051c01ea982 --- /dev/null +++ b/tools/include/uapi/coresight-config-uapi.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#ifndef _CORESIGHT_CORESIGHT_CONFIG_UAPI_H +#define _CORESIGHT_CORESIGHT_CONFIG_UAPI_H + +#include +#include + +#include "coresight-config.h" + +/* + * Userspace versions of the configuration and feature descriptors. + * Used in the tools/coresight programs. + * + * Compatible with structures in coresight-config.h for use in + * coresight-config-file.c common reader source file. + */ + +/** + * Device feature descriptor - combination of registers and parameters to + * program a device to implement a specific complex function. + * + * UAPI version - removed kernel constructs. + * + * @name: feature name. + * @description: brief description of the feature. + * @match_flags: matching information if loading into a device + * @nr_params: number of parameters used. + * @params_desc: array of parameters used. + * @nr_regs: number of registers used. + * @regs_desc: array of registers used. + */ +struct cscfg_feature_desc { + const char *name; + const char *description; + u32 match_flags; + int nr_params; + struct cscfg_parameter_desc *params_desc; + int nr_regs; + struct cscfg_regval_desc *regs_desc; +}; + +/** + * Configuration descriptor - describes selectable system configuration. + * + * A configuration describes device features in use, and may provide preset + * values for the parameters in those features. + * + * A single set of presets is the sum of the parameters declared by + * all the features in use - this value is @nr_total_params. + * + * UAPI version - removed kernel constructs. + * + * @name: name of the configuration - used for selection. + * @description: description of the purpose of the configuration. + * @nr_feat_refs: Number of features used in this configuration. + * @feat_ref_names: references to features used in this configuration. + * @nr_presets: Number of sets of presets supplied by this configuration. + * @nr_total_params: Sum of all parameters declared by used features + * @presets: Array of preset values. + */ +struct cscfg_config_desc { + const char *name; + const char *description; + int nr_feat_refs; + const char **feat_ref_names; + int nr_presets; + int nr_total_params; + const u64 *presets; /* nr_presets * nr_total_params */ +}; + +#endif /* _CORESIGHT_CORESIGHT_CONFIG_UAPI_H */ From patchwork Thu Apr 14 06:44:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12812980 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 1CBD9C433EF for ; Thu, 14 Apr 2022 06:47:03 +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=kd23wzb41v3c8NiQvOZf4RMyytoH45jplOndJsU78Uc=; b=ou4izyq8uwI6c0 ZFArjLd4WbSYfdxyo8tiD5cSPHJWGhlH1yaQxnz5yiacTPzRQQhhLmKEKKu3xVd9eQMExLnKYvoRy Qb3IBGpGalDavql4pQaA4Jj5l+ILhcZOQvyeNeSHLRGbDBRujBQeyvUliyVOrcoZu7ZzMILhGBxVQ Iw/nSQuPva7LSl2H5/HxV0cnmFNgCfxRJZOKU5jTKvFDKGEIOTOK+XyJdy9P0wa4FIuKzzxEqbU8+ kcmhKf+Ir0753MRmtHRK6ht3QJIEytOgLZMn3HOXpVLeIPTdgbFTDxoqZPeAG/8w+AiHA0uYngshm m3B8i6j/VZCQUYj9xD6Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1netEi-0049eU-6W; Thu, 14 Apr 2022 06:45:48 +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 1netE1-0049T2-3m for linux-arm-kernel@lists.infradead.org; Thu, 14 Apr 2022 06:45:07 +0000 Received: by mail-wr1-x430.google.com with SMTP id p18so4722744wru.5 for ; Wed, 13 Apr 2022 23:45:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Ti/f/BSzJkD54FKihoNGgsSmebrhWgRtHSKToK1NrWs=; b=EojdrftC2vk/G9oQWqAfBANAR1lVyKfRpZDSnxAVD1OOlLf3VFsVgOQ0xnp2cOehe+ xIDXGdgVUd43hl8LCY9IE+4V0xxdvZ1jzL2C/sv8zaDp0E+KmS15bVjrPjkQM+A5XD1Z YhnvJZxyQ2ste4GlrKaAjIFmrW3WMN5ZLHi36hYpaMAXFgiP+Ko65ScynolzHlf9plkj jKGRG6Z50Et7zI5FLMggQ+sY1gl4wTLfafH1N0IEX2FoVwavML8NnY1k8JWjFbVW03Hm rksCNJl5Fsk3eIJqIUXaMvkzNFYGiPUJeMUHD2XepZNczAhNjF0niBdpIx4BVkSRlMC1 qAUw== 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=Ti/f/BSzJkD54FKihoNGgsSmebrhWgRtHSKToK1NrWs=; b=qlYoCt2jsAa6wZSueBNrFVH0SqiiLgF9tA2oKZ+7uc5YCqCrQjh353Y6zaDLUtRX5X PpIP51lb1YySXiAGXkhneNxVxAx1l9zdVnBRLpo2HDdDzMPawzTKn4b4xddper9SDNnS ADgICoxy9GPEZfHCuoRJYpX0LbJu/qp+Yj0tGgQ2A2qU+3APrGMEEppQyKZRV6s5gO5y tgVrQR7a24Dk9eM20wKGy/JYgH+WHXPBkYZa1CHC3h9V19uBcOWcMdW4qtxM/oDUiBRl OlMXkiAc0kCUIYfJsdG9dyKArrFkCA4RE6o49udbFF95+IP61/nI4oOMkM0mz1SDFKEX q7nQ== X-Gm-Message-State: AOAM530B7xnzakO8SUPyfqoVICeihBZSMbMTK3763D6cBRZjocR0UJrV L6fd3K8YNRsYaobjz/zsLu7dbWxfOS9rHw== X-Google-Smtp-Source: ABdhPJyMXFahEvPxR0Rm8mkIZGZrAsqlzdmoH3Ju3HEXjm92UR+dvikvg+tmtPfUHVwuL4A4epYABw== X-Received: by 2002:a05:6000:1841:b0:204:ebf:1181 with SMTP id c1-20020a056000184100b002040ebf1181mr886916wri.681.1649918702769; Wed, 13 Apr 2022 23:45:02 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:e4bb:355f:cdcf:ea80]) by smtp.gmail.com with ESMTPSA id c18-20020a7bc852000000b0038ebf5f191esm5395954wml.45.2022.04.13.23.45.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Apr 2022 23:45:02 -0700 (PDT) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, mathieu.poirier@linaro.org Cc: suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [PATCH v3 5/5] Documentation: coresight: docs for config load via configfs Date: Thu, 14 Apr 2022 07:44:57 +0100 Message-Id: <20220414064457.12052-6-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220414064457.12052-1-mike.leach@linaro.org> References: <20220414064457.12052-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220413_234505_196178_ED0F6E87 X-CRM114-Status: GOOD ( 26.22 ) 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 | 166 +++++++++++++++++- 1 file changed, 160 insertions(+), 6 deletions(-) diff --git a/Documentation/trace/coresight/coresight-config.rst b/Documentation/trace/coresight/coresight-config.rst index 6d5ffa6f7347..9354cfcc04e3 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,16 @@ 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 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 +296,153 @@ 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. + +An example of a custom configuration module is found in './samples/coresight'. + +Using a Binary Configuration File +--------------------------------- + +The './tools/coresight' directory contains example programs to generate and +read and print binary configuration files. + +Building the tools creates the 'coresight-cfg-file-gen' 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-example1.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. Alternatively, addition examples can be added to the +'coresight-cfg-file-gen' program:: + + $ ./coresight-cfg-file-gen + Coresight Configuration file Generator + Generating example1 example + +The program 'coresight-cfg-file-read' can read back and print a configuration +binary. This is built using the file reader from the driver code +(coresight-config-file.c), which is copied over into './tools/coresight' at +build time.:: + + ./coresight-cfg-file-read example1.cscfg + CoreSight Configuration file reader + + Configuration name : autofdo3 + Uses 1 features:- + Feature-1: strobing + + Provides 4 sets of preset values, 2 presets per set + set[0]: 0x7d0, 0x64, + set[1]: 0x7d0, 0x3e8, + set[2]: 0x7d0, 0x1388, + set[3]: 0x7d0, 0x2710, + + File contains no features + +There are additional attributes in the configurations directory - load and +unload 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 load unload + $ cat example1.cscfg > /config/cs-syscfg/configurations/load + $ ls /config/cs-syscfg/configurations/ + autofdo autofdo3 last_load_status load unload + +To unload, use the same file in the unload attribute:: + + $ cat example1.cscfg > /config/cs-syscfg/configurations/unload + ls /config/cs-syscfg/configurations/ + autofdo load unload + + + +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.