CoreSight ETMv4.4 obsoletes memory mapped access to ETM and
mandates the system instructions for registers.
This also implies that they may not be on the amba bus.
Right now all the CoreSight components are accessed via memory
map. Also, we have some common routines in coresight generic
code driver (e.g, CS_LOCK, claim/disclaim), which assume the
mmio. In order to preserve the generic algorithms at a single
place and to allow dynamic switch for ETMs, this series introduces
an abstraction layer for accessing a coresight device. It is
designed such that the mmio access are fast tracked (i.e, without
an indirect function call).
This will also help us to get rid of the driver+attribute specific
sysfs show/store routines and replace them with a single routine
to access a given register offset (which can be embedded in the
dev_ext_attribute). This is not currently implemented in the series,
but can be achieved.
Further we switch the generic routines to work with the abstraction.
With this in place, we refactor the etm4x code a bit to allow for
supporting the system instructions with very little new code.
We use TRCDEVARCH for the detection of the ETM component, which
is a standard register as per CoreSight architecture, rather than
the etm specific id register TRCIDR1. This is for making sure
that we are able to detect the ETM via system instructions accurately,
when the the trace unit could be anything (etm or a custom trace unit).
To keep the backward compatibility for any existing broken
impelementation which may not implement TRCDEVARCH, we fall back to TRCIDR1.
Also this covers us for the changes in the future architecture [0].
Also, v8.4 self-hosted tracing extensions (coupled with ETMv4.4) adds
new filtering registers for trace by exception level. So on a v8.4
system, with Trace Filtering support, without the appropriate
programming of the Trace filter registers (TRFCR_ELx), tracing
will not be enabled. This series also includes the TraceFiltering
support to cover the ETM-v4.4 support.
The series has been mildly tested on a model for system instructions.
I would really appreciate any testing on real hardware.
Applies on coresight/next. A tree is available here [1].
[0] https://developer.arm.com/docs/ddi0601/g/aarch64-system-registers/trcidr1
[1] https://gitlab.arm.com/linux-arm/linux-skp coresight/etm/sysreg-v7
Changes since v6:
- New patch: Patch9 : Prepare the sysfs attributes for
filtering by offset of the register
- New patch: Patch12: Hide ETM registers unaccessible
on the ETM (for system instructions based ETMs)
- Split the list of ETM registers to memory mapped only
and common registers (Patch 11)
- Fixed the alignment issues pointed by Mathieu
(Patch 3, 14, 24)
Changes since v5:
- Rebased on to coresight/next.
- Moved trcdevarch to mgmt/ in sysfs and updated the sysfs ABI
document (Mike Leach)
- New patch : Moved the etm4_check_arch_features to run on the CPU, since
the PID of the ETM has to be read on the CPU and is unavailable
otherwise.
Changes since v4:
- Fix typo in commit description for the patches 02 & 15
- Refactor the AMBA device "remove" call back for use with
paltform_driver. (patch 21). Thus remove Review tag by Mathieu,
even though the changes are minimal.
- Added "remove" callback for platform_driver in patch 22, removed
Review tag by Mathieu
- Add 'U' suffix for constants in Patch 24 (Catalin)
- Fixed field extraction in Patch 25
Changes since v3:
- Device tree compatible changed to etm4x
- Use etm4x_** instead of generalizing etm_ in etm4x driver.
- Added v8.4 self hosted trace support patches, reworked
from Jonathan's series.
- Dropped queued patches.
- Expose TRCDEVARCH via trcidr, as this will be needed for
the userspace tools to determine the trace major/minor
arch versions.
- Remove csa argument to read()/write() (Mathieu)
- Fix secure exception mask calculation (Mathieu)
- Fix various coding style comments (Mathieu)
(See individual patches for change log)
Changes since V2:
- Several fixes to the ETM register accesses. Access a register
when it is present.
- Add support for TRCIDR3.NUMPROCS for v4.2+
- Drop OS lock detection. Use software lock only in case of mmio.
- Fix issues with the Exception level masks (Mike Leach)
- Fall back to using TRCIDR1 when TRCDEVARCH is not "present"
- Use a generic notion of ETM architecture (rather than using
the encoding as in registers)
- Fixed some checkpatch issues.
- Changed the dts compatible string to "arm,coresight-etm-sysreg"
(Mike Leach)
Changes since V1:
- Flip the switch for iomem from no_iomem to io_mem in csdev_access.
- Split patches for claim/disclaim and CS_LOCK/UNLOCK conversions.
- Move device access initialisation for etm4x to the target CPU
- Cleanup secure exception level mask handling.
- Switch to use TRCDEVARCH for ETM component discovery. This
is for making
- Check the availability of OS/Software Locks before using them.
Known issues:
Checkpatch failure for "coresight: etm4x: Add sysreg access helpers" :
ERROR: Macros with complex values should be enclosed in parentheses
#121: FILE: drivers/hwtracing/coresight/coresight-etm4x.h:153:
+#define CASE_READ(res, x) \
+ case (x): { (res) = read_etm4x_sysreg_const_offset((x)); break; }
I don't know a way to fix the warning without loosing the code
readability, which I believe is crucial for such a construct.
Jonathan Zhou (2):
arm64: Add TRFCR_ELx definitions
coresight: Add support for v8.4 SelfHosted tracing
Suzuki K Poulose (26):
coresight: etm4x: Handle access to TRCSSPCICRn
coresight: etm4x: Skip accessing TRCPDCR in save/restore
coresight: Introduce device access abstraction
coresight: tpiu: Prepare for using coresight device access abstraction
coresight: Convert coresight_timeout to use access abstraction
coresight: Convert claim/disclaim operations to use access wrappers
coresight: etm4x: Always read the registers on the host CPU
coresight: etm4x: Convert all register accesses
coresight: etm4x: Make offset available for sysfs attributes
coresight: etm4x: Add commentary on the registers
coresight: etm4x: Add sysreg access helpers
coresight: etm4x: Hide sysfs attributes for unavailable registers
coresight: etm4x: Define DEVARCH register fields
coresight: etm4x: Check for Software Lock
coresight: etm4x: Cleanup secure exception level masks
coresight: etm4x: Clean up exception level masks
coresight: etm4x: Handle ETM architecture version
coresight: etm4x: Detect access early on the target CPU
coresight: etm4x: Use TRCDEVARCH for component discovery
coresight: etm4x: Expose trcdevarch via sysfs
coresight: etm4x: Add necessary synchronization for sysreg access
coresight: etm4x: Detect system instructions support
coresight: etm4x: Refactor probing routine
coresight: etm4x: Run arch feature detection on the CPU
coresight: etm4x: Add support for sysreg only devices
dts: bindings: coresight: ETM system register access only units
.../testing/sysfs-bus-coresight-devices-etm4x | 8 +
.../devicetree/bindings/arm/coresight.txt | 5 +-
arch/arm64/include/asm/sysreg.h | 11 +
drivers/hwtracing/coresight/coresight-catu.c | 12 +-
drivers/hwtracing/coresight/coresight-core.c | 122 ++-
.../hwtracing/coresight/coresight-cti-core.c | 18 +-
drivers/hwtracing/coresight/coresight-etb10.c | 10 +-
.../coresight/coresight-etm3x-core.c | 9 +-
.../coresight/coresight-etm4x-core.c | 805 ++++++++++++------
.../coresight/coresight-etm4x-sysfs.c | 187 ++--
drivers/hwtracing/coresight/coresight-etm4x.h | 505 ++++++++++-
.../hwtracing/coresight/coresight-funnel.c | 7 +-
.../coresight/coresight-replicator.c | 13 +-
drivers/hwtracing/coresight/coresight-stm.c | 4 +-
.../hwtracing/coresight/coresight-tmc-core.c | 16 +-
.../hwtracing/coresight/coresight-tmc-etf.c | 10 +-
.../hwtracing/coresight/coresight-tmc-etr.c | 4 +-
drivers/hwtracing/coresight/coresight-tpiu.c | 31 +-
include/linux/coresight.h | 220 ++++-
19 files changed, 1520 insertions(+), 477 deletions(-)
--
2.24.1
Add ETM PID for Cortex-A78 to the list of supported ETMs.
Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan(a)codeaurora.org>
---
Changes in v2:
* Rebased on top of coresight/next from kernel.org coresight repo.
---
drivers/hwtracing/coresight/coresight-etm4x-core.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 15016f757828..a5b13a7779c3 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -1951,6 +1951,7 @@ static const struct amba_id etm4_ids[] = {
CS_AMBA_UCI_ID(0x000bbd05, uci_id_etm4),/* Cortex-A55 */
CS_AMBA_UCI_ID(0x000bbd0a, uci_id_etm4),/* Cortex-A75 */
CS_AMBA_UCI_ID(0x000bbd0c, uci_id_etm4),/* Neoverse N1 */
+ CS_AMBA_UCI_ID(0x000bbd41, uci_id_etm4),/* Cortex-A78 */
CS_AMBA_UCI_ID(0x000f0205, uci_id_etm4),/* Qualcomm Kryo */
CS_AMBA_UCI_ID(0x000f0211, uci_id_etm4),/* Qualcomm Kryo */
CS_AMBA_UCI_ID(0x000bb802, uci_id_etm4),/* Qualcomm Kryo 385 Cortex-A55 */
base-commit: 06c18e28c402ecfb842df8e22a19a097c35ffca9
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
This patch set is to follow up the patch series "coresight: etm-perf:
Fix pid tracing with VHE" [1].
Since the kernel and documentation patches have been picked up by
Mathieu Poirier and will go through the char-misc-next branch [2] to the
mainline kernel; the rest patches are for the perf tool, so combine
these patches into this patch set.
The patch set can be cleanly applied on perf/core branch with:
commit 6db59d357e8e ("perf arm64/s390: Fix printf conversion specifier for IP addresses")
And this patch set has been verified on Arm Juno-r2 board.
Changes from v3:
* Added Reviewed-by tags (Mathieu/Mike/Suzuki);
* Changed to use the existed macros for option bits in patch 02/05
(Mathieu).
[1] https://lore.kernel.org/patchwork/cover/1376776/
[2] https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git/log/?h…
Leo Yan (2):
tools headers UAPI: Update tools' copy of linux/coresight-pmu.h
perf cs-etm: Add helper cs_etm__get_pid_fmt()
Suzuki K Poulose (3):
perf cs-etm: Fix bitmap for option
perf cs-etm: Support PID tracing in config
perf cs-etm: Detect pid in VMID for kernel running at EL2
tools/include/linux/coresight-pmu.h | 20 ++++--
tools/perf/arch/arm/util/cs-etm.c | 69 ++++++++++++++-----
.../perf/util/cs-etm-decoder/cs-etm-decoder.c | 38 ++++++++--
tools/perf/util/cs-etm.c | 42 +++++++++++
tools/perf/util/cs-etm.h | 1 +
5 files changed, 145 insertions(+), 25 deletions(-)
--
2.25.1
The following patches fix opening perf.data files that have timestamps
(ordered data), aren't recorded with --per-thread, and that have
discontinuous data in a single aux trace buffer.
I have some open questions:
* Can cs_etm__update_queues() be removed from cs_etm__flush_events()?
* Why does the second commit start making some files process correctly?
* Is it ok to wait for the flush to start processing? Previously
processing happened when the first aux record was delivered to
cs_etm__process_event().
* Do the aux records need to be saved into a new buffer or can they
be pulled from elsewhere?
I also have some further changes to make to make per-thread mode work
where the cpu field of the sample is set to -1. And when there are
no timestamps cs_etm__process_timeless_queues() is used, which is a
completely different code path.
Thanks
James
James Clark (5):
perf cs-etm: Split up etm queue setup function
perf cs-etm: Only search timestamp in current sample's queue.
perf cs-etm: Save aux records in each etm queue
perf cs-etm: don't process queues until cs_etm__flush_events
perf cs-etm: split decode by aux records.
tools/perf/util/cs-etm.c | 200 +++++++++++++++++++++++----------------
1 file changed, 121 insertions(+), 79 deletions(-)
--
2.28.0
This patch series is to support PID tracing with Virtualization Host
Extensions (VHE).
Since the patch series v1 was sent out for reviewing, we had some
discussion and finalized the solution which is implemented in this
version. Simply to say, to be backward compatibility, and can both
support PID tracing for the kernel is running at either EL1 or EL2,
the two new PMU formats "contextid1" and "contextid2" are introduced,
which works as a switch to trace PID for EL1 kernel and EL2 kernel
respectively.
The existed PMU format "contextid" needs to be backward compatible for
users, it's changed to an alias for "contextid1" on EL1 kernel and for
"contextid2" on EL2 kernel. Therefore, even without setting "contextid"
config, the perf tool can dynamically pick up the config for PID
tracing, so the user doesn't have to set the "contexid" config manually.
As results, we now have three PMU formats, for easier understanding the
implementation, just copy and paste the descriptions for these three PMU
formats from the patch 07/07:
"contextid1": Available on both EL1 kernel and EL2 kernel. When the
kernel is running at EL1, "contextid1" enables the PID
tracing; when the kernel is running at EL2, this enables
tracing the PID of guest applications.
"contextid2": Only usable when the kernel is running at EL2. When
selected, enables PID tracing on EL2 kernel.
"contextid": Will be an alias for the option that enables PID
tracing. I.e,
contextid == contextid1, on EL1 kernel.
contextid == contextid2, on EL2 kernel.
This patch series can be cleanly applied on perf/core branch:
commit cd07e536b020 ("Merge remote-tracking branch 'torvalds/master' into perf/core")
... and applied on the mainline kernel:
commit 88bb507a74ea ("Merge tag 'media/v5.11-3' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media")
The patch series has been tested on Arm Juno-r2 board. Verified the
kernel with EL1 and didn't find issue; though absenting the platform for
kernel with EL2, after some hacking in kernel driver and tool to emulate
the code paths for kernel on EL2, can see the code path is hit without
failure.
Changes from v1:
* Refactored PMU formats, added formats "contextid1"/"contextid2", and
reworked format "contextid" (Suzuki/Mathieu);
* Refined the comments for perf configs (Leo/Mike);
* Added patch 07/07 for description PID tracing in docs;
* Found the issue for bitmap for option, extracted patch 03/07 for the
fixing.
Changes from RFC:
* Added comments to clarify cases requested (Leo);
* Explain the change to generic flags for cs_etm_set_option() in the
commit description;
* Stored PID format in metadata and passed it to decoder (Leo);
* Enhanced cs-etm for backward compatibility (Denis Nikitin).
Leo Yan (3):
coresight: etm-perf: Clarify comment on perf options
perf cs-etm: Add helper cs_etm__get_pid_fmt()
Documentation: coresight: Add PID tracing description
Suzuki K Poulose (4):
coresight: etm-perf: Support PID tracing for kernel at EL2
perf cs-etm: Fix bitmap for option
perf cs-etm: Support PID tracing in config
perf cs-etm: Detect pid in VMID for kernel running at EL2
Documentation/trace/coresight/coresight.rst | 37 ++++++++++
.../hwtracing/coresight/coresight-etm-perf.c | 32 +++++++-
.../coresight/coresight-etm4x-core.c | 13 ++++
include/linux/coresight-pmu.h | 20 +++--
tools/include/linux/coresight-pmu.h | 20 +++--
tools/perf/arch/arm/util/cs-etm.c | 73 +++++++++++++++----
.../perf/util/cs-etm-decoder/cs-etm-decoder.c | 32 +++++++-
tools/perf/util/cs-etm.c | 43 +++++++++++
tools/perf/util/cs-etm.h | 1 +
9 files changed, 239 insertions(+), 32 deletions(-)
--
2.25.1
Bonjour,
Les entreprises scandinaves à la recherche de spécialistes en informatique utilisent ce que l'on appelle le nearshoring, valorisant fortement les compétences des développeurs polonais, l'un des meilleurs développeurs au monde.
La Pologne est devenue un Tech-Hub pour l'Europe. La Scandinavie a investi plus de 11 milliards d'euros en Pologne au cours de la dernière décennie, où de plus en plus d'entreprises à capitaux scandinaves recherchent des spécialistes de l'industrie informatique.
Notre équipe de 400 professionnels du logiciel comprend des analystes commerciaux, des développeurs front-end, des développeurs back-end, des concepteurs UX, des chefs de projet, des ingénieurs Full-Stack, des ingénieurs DevOps et des testeurs.
Nous livrons des projets agiles utilisant PHP, C #, Java, .Net, Python, Q&A pour des clients mondiaux comme ING Group, Santander, Discovery, Asseco, Volvo et Generali. Jusqu'à présent, nous avons acquis une expertise de l'industrie dans les services financiers, la fabrication, le commerce électronique, les médias et sommes prêts à utiliser ces connaissances pour développer nos activités.
Pouvons-nous explorer ensemble vos besoins actuels en matière de développement logiciel?
Cordialement,
Pierre Musso
The current fixed metadata version format (version 0), means that adding
metadata parameter items renders files from a previous version of perf
unreadable. Per CPU parameters appear in a fixed order, but there is no
field to indicate the number of ETM parameters per CPU.
This patch updates the per CPU parameter blocks to include a NR_PARAMs
value which indicates the number of parameters in the block.
The header version is incremented to 1. Fixed ordering is retained,
new ETM parameters are added to the end of the list.
The reader code is updated to be able to read current version 0 files,
For version 1, the reader will read the number of parameters in the
per CPU block. This allows the reader to process older or newer files
that may have different numbers of parameters than in use at the
time perf was built.
Changes since v3
1. Fixed index bug (Leo)
Changes since v2
1. Add error path print to improve --dump logging
2. Replace some hardcoded values with enum consts (Mathieu).
Changes since v1 (from Review by Leo):
1. Split printing routine into sub functions per version
2. Renamed NR_PARAMs to NR_TRC_PARAMs to emphasise use as count of trace
related parameters, not total block parameter.
3. Misc other fixes.
Signed-off-by: Mike Leach <mike.leach(a)linaro.org>
---
tools/perf/arch/arm/util/cs-etm.c | 7 +-
tools/perf/util/cs-etm.c | 235 ++++++++++++++++++++++++------
tools/perf/util/cs-etm.h | 30 +++-
3 files changed, 223 insertions(+), 49 deletions(-)
diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
index bd446aba64f7..b0470f2a955a 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -572,7 +572,7 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
struct auxtrace_record *itr,
struct perf_record_auxtrace_info *info)
{
- u32 increment;
+ u32 increment, nr_trc_params;
u64 magic;
struct cs_etm_recording *ptr =
container_of(itr, struct cs_etm_recording, itr);
@@ -607,6 +607,7 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
/* How much space was used */
increment = CS_ETMV4_PRIV_MAX;
+ nr_trc_params = CS_ETMV4_PRIV_MAX - CS_ETMV4_TRCCONFIGR;
} else {
magic = __perf_cs_etmv3_magic;
/* Get configuration register */
@@ -624,11 +625,13 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
/* How much space was used */
increment = CS_ETM_PRIV_MAX;
+ nr_trc_params = CS_ETM_PRIV_MAX - CS_ETM_ETMCR;
}
/* Build generic header portion */
info->priv[*offset + CS_ETM_MAGIC] = magic;
info->priv[*offset + CS_ETM_CPU] = cpu;
+ info->priv[*offset + CS_ETM_NR_TRC_PARAMS] = nr_trc_params;
/* Where the next CPU entry should start from */
*offset += increment;
}
@@ -674,7 +677,7 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
/* First fill out the session header */
info->type = PERF_AUXTRACE_CS_ETM;
- info->priv[CS_HEADER_VERSION_0] = 0;
+ info->priv[CS_HEADER_VERSION] = CS_HEADER_CURRENT_VERSION;
info->priv[CS_PMU_TYPE_CPUS] = type << 32;
info->priv[CS_PMU_TYPE_CPUS] |= nr_cpu;
info->priv[CS_ETM_SNAPSHOT] = ptr->snapshot_mode;
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index a2a369e2fbb6..f9af3fe0ed83 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -2435,7 +2435,7 @@ static bool cs_etm__is_timeless_decoding(struct cs_etm_auxtrace *etm)
}
static const char * const cs_etm_global_header_fmts[] = {
- [CS_HEADER_VERSION_0] = " Header version %llx\n",
+ [CS_HEADER_VERSION] = " Header version %llx\n",
[CS_PMU_TYPE_CPUS] = " PMU type/num cpus %llx\n",
[CS_ETM_SNAPSHOT] = " Snapshot %llx\n",
};
@@ -2443,6 +2443,7 @@ static const char * const cs_etm_global_header_fmts[] = {
static const char * const cs_etm_priv_fmts[] = {
[CS_ETM_MAGIC] = " Magic number %llx\n",
[CS_ETM_CPU] = " CPU %lld\n",
+ [CS_ETM_NR_TRC_PARAMS] = " NR_TRC_PARAMS %llx\n",
[CS_ETM_ETMCR] = " ETMCR %llx\n",
[CS_ETM_ETMTRACEIDR] = " ETMTRACEIDR %llx\n",
[CS_ETM_ETMCCER] = " ETMCCER %llx\n",
@@ -2452,6 +2453,7 @@ static const char * const cs_etm_priv_fmts[] = {
static const char * const cs_etmv4_priv_fmts[] = {
[CS_ETM_MAGIC] = " Magic number %llx\n",
[CS_ETM_CPU] = " CPU %lld\n",
+ [CS_ETM_NR_TRC_PARAMS] = " NR_TRC_PARAMS %llx\n",
[CS_ETMV4_TRCCONFIGR] = " TRCCONFIGR %llx\n",
[CS_ETMV4_TRCTRACEIDR] = " TRCTRACEIDR %llx\n",
[CS_ETMV4_TRCIDR0] = " TRCIDR0 %llx\n",
@@ -2461,26 +2463,167 @@ static const char * const cs_etmv4_priv_fmts[] = {
[CS_ETMV4_TRCAUTHSTATUS] = " TRCAUTHSTATUS %llx\n",
};
-static void cs_etm__print_auxtrace_info(__u64 *val, int num)
+static const char * const param_unk_fmt =
+ " Unknown parameter [%d] %llx\n";
+static const char * const magic_unk_fmt =
+ " Magic number Unknown %llx\n";
+
+static int cs_etm__print_cpu_metadata_v0(__u64 *val, int *offset)
{
- int i, j, cpu = 0;
+ int i = *offset, j, nr_params = 0, fmt_offset;
+ __u64 magic;
- for (i = 0; i < CS_HEADER_VERSION_0_MAX; i++)
- fprintf(stdout, cs_etm_global_header_fmts[i], val[i]);
+ /* check magic value */
+ magic = val[i + CS_ETM_MAGIC];
+ if ((magic != __perf_cs_etmv3_magic) &&
+ (magic != __perf_cs_etmv4_magic)) {
+ /* failure - note bad magic value */
+ fprintf(stdout, magic_unk_fmt, magic);
+ return -EINVAL;
+ }
+
+ /* print common header block */
+ fprintf(stdout, cs_etm_priv_fmts[CS_ETM_MAGIC], val[i++]);
+ fprintf(stdout, cs_etm_priv_fmts[CS_ETM_CPU], val[i++]);
+
+ if (magic == __perf_cs_etmv3_magic) {
+ nr_params = CS_ETM_NR_TRC_PARAMS_V0;
+ fmt_offset = CS_ETM_ETMCR;
+ /* after common block, offset format index past NR_PARAMS */
+ for (j = fmt_offset; j < nr_params + fmt_offset; j++, i++)
+ fprintf(stdout, cs_etm_priv_fmts[j], val[i]);
+ } else if (magic == __perf_cs_etmv4_magic) {
+ nr_params = CS_ETMV4_NR_TRC_PARAMS_V0;
+ fmt_offset = CS_ETMV4_TRCCONFIGR;
+ /* after common block, offset format index past NR_PARAMS */
+ for (j = fmt_offset; j < nr_params + fmt_offset; j++, i++)
+ fprintf(stdout, cs_etmv4_priv_fmts[j], val[i]);
+ }
+ *offset = i;
+ return 0;
+}
+
+static int cs_etm__print_cpu_metadata_v1(__u64 *val, int *offset)
+{
+ int i = *offset, j, total_params = 0;
+ __u64 magic;
+
+ magic = val[i + CS_ETM_MAGIC];
+ /* total params to print is NR_PARAMS + common block size for v1 */
+ total_params = val[i + CS_ETM_NR_TRC_PARAMS] + CS_ETM_COMMON_BLK_MAX_V1;
- for (i = CS_HEADER_VERSION_0_MAX; cpu < num; cpu++) {
- if (val[i] == __perf_cs_etmv3_magic)
- for (j = 0; j < CS_ETM_PRIV_MAX; j++, i++)
+ if (magic == __perf_cs_etmv3_magic) {
+ for (j = 0; j < total_params; j++, i++) {
+ /* if newer record - could be excess params */
+ if (j >= CS_ETM_PRIV_MAX)
+ fprintf(stdout, param_unk_fmt, j, val[i]);
+ else
fprintf(stdout, cs_etm_priv_fmts[j], val[i]);
- else if (val[i] == __perf_cs_etmv4_magic)
- for (j = 0; j < CS_ETMV4_PRIV_MAX; j++, i++)
+ }
+ } else if (magic == __perf_cs_etmv4_magic) {
+ for (j = 0; j < total_params; j++, i++) {
+ /* if newer record - could be excess params */
+ if (j >= CS_ETMV4_PRIV_MAX)
+ fprintf(stdout, param_unk_fmt, j, val[i]);
+ else
fprintf(stdout, cs_etmv4_priv_fmts[j], val[i]);
- else
- /* failure.. return */
+ }
+ } else {
+ /* failure - note bad magic value and error out */
+ fprintf(stdout, magic_unk_fmt, magic);
+ return -EINVAL;
+ }
+ *offset = i;
+ return 0;
+}
+
+static void cs_etm__print_auxtrace_info(__u64 *val, int num)
+{
+ int i, cpu = 0, version, err;
+
+ /* bail out early on bad header version */
+ version = val[0];
+ if (version > CS_HEADER_CURRENT_VERSION) {
+ /* failure.. return */
+ fprintf(stdout, " Unknown Header Version = %x, ", version);
+ fprintf(stdout, "Version supported <= %x\n", CS_HEADER_CURRENT_VERSION);
+ return;
+ }
+
+ for (i = 0; i < CS_HEADER_VERSION_MAX; i++)
+ fprintf(stdout, cs_etm_global_header_fmts[i], val[i]);
+
+ for (i = CS_HEADER_VERSION_MAX; cpu < num; cpu++) {
+ if (version == 0)
+ err = cs_etm__print_cpu_metadata_v0(val, &i);
+ else if (version == 1)
+ err = cs_etm__print_cpu_metadata_v1(val, &i);
+ if (err)
return;
}
}
+/*
+ * Read a single cpu parameter block from the auxtrace_info priv block.
+ *
+ * For version 1 there is a per cpu nr_params entry. If we are handling
+ * version 1 file, then there may be less, the same, or more params
+ * indicated by this value than the compile time number we understand.
+ *
+ * For a version 0 info block, there are a fixed number, and we need to
+ * fill out the nr_param value in the metadata we create.
+ */
+static u64 *cs_etm__create_meta_blk(u64 *buff_in, int *buff_in_offset,
+ int out_blk_size, int nr_params_v0)
+{
+ u64 *metadata = NULL;
+ int hdr_version;
+ int nr_in_params, nr_out_params, nr_cmn_params;
+ int i, k;
+
+ metadata = zalloc(sizeof(*metadata) * out_blk_size);
+ if (!metadata)
+ return NULL;
+
+ /* read block current index & version */
+ i = *buff_in_offset;
+ hdr_version = buff_in[CS_HEADER_VERSION];
+
+ if (!hdr_version) {
+ /* read version 0 info block into a version 1 metadata block */
+ nr_in_params = nr_params_v0;
+ metadata[CS_ETM_MAGIC] = buff_in[i + CS_ETM_MAGIC];
+ metadata[CS_ETM_CPU] = buff_in[i + CS_ETM_CPU];
+ metadata[CS_ETM_NR_TRC_PARAMS] = nr_in_params;
+ /* remaining block params at offset +1 from source */
+ for (k = CS_ETM_ETMCR - 1; k < nr_in_params; k++)
+ metadata[k+1] = buff_in[i + k];
+ /* version 0 has 2 common params */
+ nr_cmn_params = 2;
+ } else {
+ /* read version 1 info block - input and output nr_params may differ */
+ /* version 1 has 3 common params */
+ nr_cmn_params = 3;
+ nr_in_params = buff_in[i + CS_ETM_NR_TRC_PARAMS];
+
+ /* if input has more params than output - skip excess */
+ nr_out_params = nr_in_params + nr_cmn_params;
+ if (nr_out_params > out_blk_size)
+ nr_out_params = out_blk_size;
+
+ for (k = CS_ETM_MAGIC; k < nr_out_params; k++)
+ metadata[k] = buff_in[i + k];
+
+ /* record the actual nr params we copied */
+ metadata[CS_ETM_NR_TRC_PARAMS] = nr_out_params - nr_cmn_params;
+ }
+
+ /* adjust in offset by number of in params used */
+ i += nr_in_params + nr_cmn_params;
+ *buff_in_offset = i;
+ return metadata;
+}
+
int cs_etm__process_auxtrace_info(union perf_event *event,
struct perf_session *session)
{
@@ -2492,11 +2635,12 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
int info_header_size;
int total_size = auxtrace_info->header.size;
int priv_size = 0;
- int num_cpu;
- int err = 0, idx = -1;
- int i, j, k;
+ int num_cpu, trcidr_idx;
+ int err = 0;
+ int i, j;
u64 *ptr, *hdr = NULL;
u64 **metadata = NULL;
+ u64 hdr_version;
/*
* sizeof(auxtrace_info_event::type) +
@@ -2512,16 +2656,21 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
/* First the global part */
ptr = (u64 *) auxtrace_info->priv;
- /* Look for version '0' of the header */
- if (ptr[0] != 0)
+ /* Look for version of the header */
+ hdr_version = ptr[0];
+ if (hdr_version > CS_HEADER_CURRENT_VERSION) {
+ /* print routine will print an error on bad version */
+ if (dump_trace)
+ cs_etm__print_auxtrace_info(auxtrace_info->priv, 0);
return -EINVAL;
+ }
- hdr = zalloc(sizeof(*hdr) * CS_HEADER_VERSION_0_MAX);
+ hdr = zalloc(sizeof(*hdr) * CS_HEADER_VERSION_MAX);
if (!hdr)
return -ENOMEM;
/* Extract header information - see cs-etm.h for format */
- for (i = 0; i < CS_HEADER_VERSION_0_MAX; i++)
+ for (i = 0; i < CS_HEADER_VERSION_MAX; i++)
hdr[i] = ptr[i];
num_cpu = hdr[CS_PMU_TYPE_CPUS] & 0xffffffff;
pmu_type = (unsigned int) ((hdr[CS_PMU_TYPE_CPUS] >> 32) &
@@ -2552,35 +2701,31 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
*/
for (j = 0; j < num_cpu; j++) {
if (ptr[i] == __perf_cs_etmv3_magic) {
- metadata[j] = zalloc(sizeof(*metadata[j]) *
- CS_ETM_PRIV_MAX);
- if (!metadata[j]) {
- err = -ENOMEM;
- goto err_free_metadata;
- }
- for (k = 0; k < CS_ETM_PRIV_MAX; k++)
- metadata[j][k] = ptr[i + k];
+ metadata[j] =
+ cs_etm__create_meta_blk(ptr, &i,
+ CS_ETM_PRIV_MAX,
+ CS_ETM_NR_TRC_PARAMS_V0);
/* The traceID is our handle */
- idx = metadata[j][CS_ETM_ETMTRACEIDR];
- i += CS_ETM_PRIV_MAX;
+ trcidr_idx = CS_ETM_ETMTRACEIDR;
+
} else if (ptr[i] == __perf_cs_etmv4_magic) {
- metadata[j] = zalloc(sizeof(*metadata[j]) *
- CS_ETMV4_PRIV_MAX);
- if (!metadata[j]) {
- err = -ENOMEM;
- goto err_free_metadata;
- }
- for (k = 0; k < CS_ETMV4_PRIV_MAX; k++)
- metadata[j][k] = ptr[i + k];
+ metadata[j] =
+ cs_etm__create_meta_blk(ptr, &i,
+ CS_ETMV4_PRIV_MAX,
+ CS_ETMV4_NR_TRC_PARAMS_V0);
/* The traceID is our handle */
- idx = metadata[j][CS_ETMV4_TRCTRACEIDR];
- i += CS_ETMV4_PRIV_MAX;
+ trcidr_idx = CS_ETMV4_TRCTRACEIDR;
+ }
+
+ if (!metadata[j]) {
+ err = -ENOMEM;
+ goto err_free_metadata;
}
/* Get an RB node for this CPU */
- inode = intlist__findnew(traceid_list, idx);
+ inode = intlist__findnew(traceid_list, metadata[j][trcidr_idx]);
/* Something went wrong, no need to continue */
if (!inode) {
@@ -2601,7 +2746,7 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
}
/*
- * Each of CS_HEADER_VERSION_0_MAX, CS_ETM_PRIV_MAX and
+ * Each of CS_HEADER_VERSION_MAX, CS_ETM_PRIV_MAX and
* CS_ETMV4_PRIV_MAX mark how many double words are in the
* global metadata, and each cpu's metadata respectively.
* The following tests if the correct number of double words was
@@ -2703,6 +2848,12 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
intlist__delete(traceid_list);
err_free_hdr:
zfree(&hdr);
-
+ /*
+ * At this point, as a minimum we have valid header. Dump the rest of
+ * the info section - the print routines will error out on structural
+ * issues.
+ */
+ if (dump_trace)
+ cs_etm__print_auxtrace_info(auxtrace_info->priv, num_cpu);
return err;
}
diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h
index 4ad925d6d799..e153d02df0de 100644
--- a/tools/perf/util/cs-etm.h
+++ b/tools/perf/util/cs-etm.h
@@ -17,23 +17,37 @@ struct perf_session;
*/
enum {
/* Starting with 0x0 */
- CS_HEADER_VERSION_0,
+ CS_HEADER_VERSION,
/* PMU->type (32 bit), total # of CPUs (32 bit) */
CS_PMU_TYPE_CPUS,
CS_ETM_SNAPSHOT,
- CS_HEADER_VERSION_0_MAX,
+ CS_HEADER_VERSION_MAX,
};
+/*
+ * Update the version for new format.
+ *
+ * New version 1 format adds a param count to the per cpu metadata.
+ * This allows easy adding of new metadata parameters.
+ * Requires that new params always added after current ones.
+ * Also allows client reader to handle file versions that are different by
+ * checking the number of params in the file vs the number expected.
+ */
+#define CS_HEADER_CURRENT_VERSION 1
+
/* Beginning of header common to both ETMv3 and V4 */
enum {
CS_ETM_MAGIC,
CS_ETM_CPU,
+ /* Number of trace config params in following ETM specific block */
+ CS_ETM_NR_TRC_PARAMS,
+ CS_ETM_COMMON_BLK_MAX_V1,
};
/* ETMv3/PTM metadata */
enum {
/* Dynamic, configurable parameters */
- CS_ETM_ETMCR = CS_ETM_CPU + 1,
+ CS_ETM_ETMCR = CS_ETM_COMMON_BLK_MAX_V1,
CS_ETM_ETMTRACEIDR,
/* RO, taken from sysFS */
CS_ETM_ETMCCER,
@@ -41,10 +55,13 @@ enum {
CS_ETM_PRIV_MAX,
};
+/* define fixed version 0 length - allow new format reader to read old files. */
+#define CS_ETM_NR_TRC_PARAMS_V0 (CS_ETM_ETMIDR - CS_ETM_ETMCR + 1)
+
/* ETMv4 metadata */
enum {
/* Dynamic, configurable parameters */
- CS_ETMV4_TRCCONFIGR = CS_ETM_CPU + 1,
+ CS_ETMV4_TRCCONFIGR = CS_ETM_COMMON_BLK_MAX_V1,
CS_ETMV4_TRCTRACEIDR,
/* RO, taken from sysFS */
CS_ETMV4_TRCIDR0,
@@ -55,6 +72,9 @@ enum {
CS_ETMV4_PRIV_MAX,
};
+/* define fixed version 0 length - allow new format reader to read old files. */
+#define CS_ETMV4_NR_TRC_PARAMS_V0 (CS_ETMV4_TRCAUTHSTATUS - CS_ETMV4_TRCCONFIGR + 1)
+
/*
* ETMv3 exception encoding number:
* See Embedded Trace Macrocell spcification (ARM IHI 0014Q)
@@ -162,7 +182,7 @@ struct cs_etm_packet_queue {
#define BMVAL(val, lsb, msb) ((val & GENMASK(msb, lsb)) >> lsb)
-#define CS_ETM_HEADER_SIZE (CS_HEADER_VERSION_0_MAX * sizeof(u64))
+#define CS_ETM_HEADER_SIZE (CS_HEADER_VERSION_MAX * sizeof(u64))
#define __perf_cs_etmv3_magic 0x3030303030303030ULL
#define __perf_cs_etmv4_magic 0x4040404040404040ULL
--
2.17.1