From mboxrd@z Thu Jan 1 00:00:00 1970 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 12DB8C433EF for ; Thu, 26 May 2022 17:47: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:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=oeq3XLqU8+vreNTGs4be4Vgu6vqYqGIM/0IuXmH8OiM=; b=pkWF7jXqlKHV2n gHZabvcAw8tC3Hc0lDZ1t4/oLvyAzCa8gqE77ML1y4g/obA1vMtpHX9ftpzFugDv/lD9unxhIqMoF fZsaOf7hxOwXhQNE9uGqWOjJMSVBcfdMw/nBdiklvH++wH/YFnhcuUprjy1vhBFMsvnLMRsr8HvFt hRIKTqBHQYvpbTghMTib/vjKZCRb4bXvNfen+YjFqwZaF/Zmm2NAzBSVNDB07EObKicRQdkMZOJus WnAUxKxhG9nfYO6eNowOtVw9v64PA/IMTS/lNkA31dycbEOXtipSi8DFpFyjnXzsC9N5oizBRZh2o 2s6BvpVAUT8vrz06CLdg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nuHYy-00FWre-5H; Thu, 26 May 2022 17:46:20 +0000 Received: from mail-pg1-x536.google.com ([2607:f8b0:4864:20::536]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nuHYt-00FWqb-4r for linux-arm-kernel@lists.infradead.org; Thu, 26 May 2022 17:46:18 +0000 Received: by mail-pg1-x536.google.com with SMTP id 137so1885274pgb.5 for ; Thu, 26 May 2022 10:46:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=sPGMrO5DR5ss44cJ4buKsbxBGjZO4aVkRx9qTvgGnXY=; b=ou7jxrkqReDIcaO74bfdJarAPbP27/AFd/F3TKTzNkYPFAQOr5KgoU7nFnWd0fwgXJ dVbL21ZiY00PkIefI2SOZMSojNvNtGVix0Q1gzC2pgW4OvzHk6cKmprcKfsaqMp109Qk hZrSE2bvzS7VkKGtWdU+sq/Cakdmf+6FdrL9jUQodLbmHOAzWrP42oSDMdwIBbQNeG5d t3piTey2Ygun1e6FSZvsff5ZMMl26MvqTsETv8tKRXnxLVI7+KYTCScoZbjlV9WJ9rLC eZNrX8wYiyh+Ma5Lv1SZaYOG870DrlW2RHPXsuuw7A5oV+bM11JcLVczSKrHWytB90sV b7gA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=sPGMrO5DR5ss44cJ4buKsbxBGjZO4aVkRx9qTvgGnXY=; b=ix7cf294LU0mFHN/JvpoI+KD28JhrVorI+pRXhCvjrLhR11mV2pWOr9wtvDfIzrGr0 QOVbqU/Rg7R67XYlR7UM8YaOcLOR9dpMziIX7F7dd0KkU0SdkSJnrnVJ9aP4POs0hji0 9ddfDtFbkSdUje8o8Gs7UhA6ocjXz8X5SR9trlblG2iwnqElzYoEv2kREHAPVpGkiBYU VIUwZP7u4yrJlEaT84mX7B2Torh1kRQZ3vrGq4F/5AdU7KHz3uPV6jPFWxVgWBwuTiLt 11xqsiK3IaB12c5HrmOpeaq597UwbzvQV7hI8TMiHFD2k5WLITvkixBjVj/HaS68PyR3 W1tw== X-Gm-Message-State: AOAM531Jss4LIa5u0dYjz2mJvoU+2DBwzFea9uScQY7KZM+ijfVQYgQW S8+d6Z4UO/naCYd3ICjFNb/5XEYmpv2hZw== X-Google-Smtp-Source: ABdhPJwWAB28gwoDm5RHCU531tBeMlptSpnHCzhccOcXhcd5cjKrMi6ee1hj9Bqd8x1nGtKApH+l9g== X-Received: by 2002:aa7:95b9:0:b0:518:9c47:e6b2 with SMTP id a25-20020aa795b9000000b005189c47e6b2mr21677923pfk.66.1653587166293; Thu, 26 May 2022 10:46:06 -0700 (PDT) Received: from p14s (S0106889e681aac74.cg.shawcable.net. [68.147.0.187]) by smtp.gmail.com with ESMTPSA id ik8-20020a170902ab0800b0015e8d4eb2cdsm1798227plb.279.2022.05.26.10.46.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 May 2022 10:46:04 -0700 (PDT) Date: Thu, 26 May 2022 11:46:02 -0600 From: Mathieu Poirier To: Mike Leach Cc: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org Subject: Re: [PATCH v3 4/5] coresight: tools: Add config file write and reader tools Message-ID: <20220526174602.GA309576@p14s> References: <20220414064457.12052-1-mike.leach@linaro.org> <20220414064457.12052-5-mike.leach@linaro.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20220414064457.12052-5-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220526_104615_289201_FB8AEB57 X-CRM114-Status: GOOD ( 40.94 ) 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: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On Thu, Apr 14, 2022 at 07:44:56AM +0100, Mike Leach wrote: > 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; \ > + } > + Either use a single space between the code and the '\' character or align them all on the same column. > +/* 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; > +} > + > + Extra line. > +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; > +} Add an extra line. > +/* > + * 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 > + * > + * Two extra lines. > + */ > +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" There is no need to 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" Not sure there is any value in specifying a define... I'd just hard code it the same way it was done for "example1". > + > +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" Same here. > + > +/* 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; I would put this in coresight-cfg-filegen.c. That way people only have to change a single file rather than two. More comments to follow on this file. I am not sure there is a need to read .cscfg files. > + > +#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 */ > -- > 2.17.1 > _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel