From: Eric Auger <eric.auger@redhat.com>
To: eric.auger.pro@gmail.com, eric.auger@redhat.com,
kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu,
qemu-devel@nongnu.org, drjones@redhat.com, andrew.murray@arm.com,
sudeep.holla@arm.com, maz@kernel.org, will@kernel.org,
haibo.xu@linaro.org
Subject: [kvm-unit-tests RFC 2/4] spe: Probing and Introspection Test
Date: Mon, 31 Aug 2020 21:34:12 +0200 [thread overview]
Message-ID: <20200831193414.6951-3-eric.auger@redhat.com> (raw)
In-Reply-To: <20200831193414.6951-1-eric.auger@redhat.com>
Test whether Statistical Profiling Extensions (SPE) are
supported and in the positive collect dimensioning data from
the IDR registers. The First test only validates those.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
arm/Makefile.common | 1 +
arm/spe.c | 163 ++++++++++++++++++++++++++++++++++++++++++++
arm/unittests.cfg | 8 +++
3 files changed, 172 insertions(+)
create mode 100644 arm/spe.c
diff --git a/arm/Makefile.common b/arm/Makefile.common
index a123e85..4e7e4eb 100644
--- a/arm/Makefile.common
+++ b/arm/Makefile.common
@@ -8,6 +8,7 @@ tests-common = $(TEST_DIR)/selftest.flat
tests-common += $(TEST_DIR)/spinlock-test.flat
tests-common += $(TEST_DIR)/pci-test.flat
tests-common += $(TEST_DIR)/pmu.flat
+tests-common += $(TEST_DIR)/spe.flat
tests-common += $(TEST_DIR)/gic.flat
tests-common += $(TEST_DIR)/psci.flat
tests-common += $(TEST_DIR)/sieve.flat
diff --git a/arm/spe.c b/arm/spe.c
new file mode 100644
index 0000000..153c182
--- /dev/null
+++ b/arm/spe.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2020, Red Hat Inc, Eric Auger <eric.auger@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1 and
+ * only version 2.1 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ */
+#include "libcflat.h"
+#include "errata.h"
+#include "asm/barrier.h"
+#include "asm/sysreg.h"
+#include "asm/processor.h"
+#include "alloc_page.h"
+#include <bitops.h>
+
+struct spe {
+ int min_interval;
+ int maxsize;
+ int countsize;
+ bool fl_cap;
+ bool ft_cap;
+ bool fe_cap;
+ int align;
+ void *buffer;
+ bool unique_record_size;
+};
+
+static struct spe spe;
+
+#ifdef __arm__
+
+static bool spe_probe(void) { return false; }
+static void test_spe_introspection(void) { }
+
+#else
+
+#define ID_DFR0_PMSVER_SHIFT 32
+#define ID_DFR0_PMSVER_MASK 0xF
+
+#define PMBIDR_EL1_ALIGN_MASK 0xF
+#define PMBIDR_EL1_P 0x10
+#define PMBIDR_EL1_F 0x20
+
+#define PMSIDR_EL1_FE 0x1
+#define PMSIDR_EL1_FT 0x2
+#define PMSIDR_EL1_FL 0x4
+#define PMSIDR_EL1_ARCHINST 0x8
+#define PMSIDR_EL1_LDS 0x10
+#define PMSIDR_EL1_ERND 0x20
+#define PMSIDR_EL1_INTERVAL_SHIFT 8
+#define PMSIDR_EL1_INTERVAL_MASK 0xFUL
+#define PMSIDR_EL1_MAXSIZE_SHIFT 12
+#define PMSIDR_EL1_MAXSIZE_MASK 0xFUL
+#define PMSIDR_EL1_COUNTSIZE_SHIFT 16
+#define PMSIDR_EL1_COUNTSIZE_MASK 0xFUL
+
+#define PMSIDR_EL1 sys_reg(3, 0, 9, 9, 7)
+
+#define PMBIDR_EL1 sys_reg(3, 0, 9, 10, 7)
+
+static int min_interval(uint8_t idr_bits)
+{
+ switch (idr_bits) {
+ case 0x0:
+ return 256;
+ case 0x2:
+ return 512;
+ case 0x3:
+ return 768;
+ case 0x4:
+ return 1024;
+ case 0x5:
+ return 1536;
+ case 0x6:
+ return 2048;
+ case 0x7:
+ return 3072;
+ case 0x8:
+ return 4096;
+ default:
+ return -1;
+ }
+}
+
+static bool spe_probe(void)
+{
+ uint64_t pmbidr_el1, pmsidr_el1;
+ uint8_t pmsver;
+
+ pmsver = (get_id_aa64dfr0() >> ID_DFR0_PMSVER_SHIFT) & ID_DFR0_PMSVER_MASK;
+
+ report_info("PMSVer = %d", pmsver);
+ if (!pmsver || pmsver > 2)
+ return false;
+
+ pmbidr_el1 = read_sysreg_s(PMBIDR_EL1);
+ if (pmbidr_el1 & PMBIDR_EL1_P) {
+ report_info("MBIDR_EL1: Profiling buffer owned by this exception level");
+ return false;
+ }
+
+ spe.align = 1 << (pmbidr_el1 & PMBIDR_EL1_ALIGN_MASK);
+
+ pmsidr_el1 = read_sysreg_s(PMSIDR_EL1);
+
+ spe.min_interval = min_interval((pmsidr_el1 >> PMSIDR_EL1_INTERVAL_SHIFT) & PMSIDR_EL1_INTERVAL_MASK);
+ spe.maxsize = 1 << ((pmsidr_el1 >> PMSIDR_EL1_MAXSIZE_SHIFT) & PMSIDR_EL1_MAXSIZE_MASK);
+ spe.countsize = (pmsidr_el1 >> PMSIDR_EL1_COUNTSIZE_SHIFT) & PMSIDR_EL1_COUNTSIZE_MASK;
+
+ spe.fl_cap = pmsidr_el1 & PMSIDR_EL1_FL;
+ spe.ft_cap = pmsidr_el1 & PMSIDR_EL1_FT;
+ spe.fe_cap = pmsidr_el1 & PMSIDR_EL1_FE;
+
+ report_info("Align= %d bytes, Min Interval=%d Single record Max Size = %d bytes",
+ spe.align, spe.min_interval, spe.maxsize);
+ report_info("Filtering Caps: Lat=%d Type=%d Events=%d", spe.fl_cap, spe.ft_cap, spe.fe_cap);
+ if (spe.align == spe.maxsize) {
+ report_info("Each record is exactly %d bytes", spe.maxsize);
+ spe.unique_record_size = true;
+ }
+
+ spe.buffer = alloc_pages(0);
+
+ return true;
+}
+
+static void test_spe_introspection(void)
+{
+ report(spe.countsize == 0x2, "PMSIDR_EL1: CountSize = 0b0010");
+ report(spe.maxsize >= 16 && spe.maxsize <= 2048,
+ "PMSIDR_EL1: Single record max size = %d bytes", spe.maxsize);
+ report(spe.min_interval >= 256 && spe.min_interval <= 4096,
+ "PMSIDR_EL1: Minimal sampling interval = %d", spe.min_interval);
+}
+
+#endif
+
+int main(int argc, char *argv[])
+{
+ if (!spe_probe()) {
+ printf("SPE not supported, test skipped...\n");
+ return report_summary();
+ }
+
+ if (argc < 2)
+ report_abort("no test specified");
+
+ report_prefix_push("spe");
+
+ if (strcmp(argv[1], "spe-introspection") == 0) {
+ report_prefix_push(argv[1]);
+ test_spe_introspection();
+ report_prefix_pop();
+ } else {
+ report_abort("Unknown sub-test '%s'", argv[1]);
+ }
+ return report_summary();
+}
diff --git a/arm/unittests.cfg b/arm/unittests.cfg
index f776b66..c070939 100644
--- a/arm/unittests.cfg
+++ b/arm/unittests.cfg
@@ -134,6 +134,14 @@ extra_params = -append 'pmu-overflow-interrupt'
#groups = pmu
#accel = tcg
+[spe-introspection]
+file = spe.flat
+groups = spe
+arch = arm64
+extra_params = -append 'spe-introspection'
+accel = kvm
+arch = arm64
+
# Test GIC emulation
[gicv2-ipi]
file = gic.flat
--
2.21.3
next prev parent reply other threads:[~2020-08-31 19:35 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-31 19:34 [kvm-unit-tests RFC 0/4] KVM: arm64: Statistical Profiling Extension Tests Eric Auger
2020-08-31 19:34 ` [kvm-unit-tests RFC 1/4] arm64: Move get_id_aa64dfr0() in processor.h Eric Auger
2020-08-31 19:34 ` Eric Auger [this message]
2020-08-31 19:34 ` [kvm-unit-tests RFC 3/4] spe: Add profiling buffer test Eric Auger
2020-08-31 19:34 ` [kvm-unit-tests RFC 4/4] spe: Test Profiling Buffer Events Eric Auger
2020-09-01 7:34 ` Auger Eric
2020-09-01 9:24 ` [kvm-unit-tests RFC 0/4] KVM: arm64: Statistical Profiling Extension Tests Alexandru Elisei
2020-09-01 10:49 ` Auger Eric
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200831193414.6951-3-eric.auger@redhat.com \
--to=eric.auger@redhat.com \
--cc=andrew.murray@arm.com \
--cc=drjones@redhat.com \
--cc=eric.auger.pro@gmail.com \
--cc=haibo.xu@linaro.org \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=maz@kernel.org \
--cc=qemu-devel@nongnu.org \
--cc=sudeep.holla@arm.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).