aboutsummaryrefslogtreecommitdiffstats
path: root/lib/cpus/aarch64/cpuamu.c
diff options
context:
space:
mode:
authordavidcunado-arm <david.cunado@arm.com>2018-02-27 21:58:42 +0000
committerGitHub <noreply@github.com>2018-02-27 21:58:42 +0000
commitba91a001f8e2ad2f92a7c20270894fcb51365781 (patch)
tree5dac30abcb7df910bb13de6597d67d2d2179c5dc /lib/cpus/aarch64/cpuamu.c
parentf461da2a3e413cc9091696633f495908664e9375 (diff)
parent714b21ffc71170bba343589fc010001645f1db57 (diff)
downloadplatform_external_arm-trusted-firmware-ba91a001f8e2ad2f92a7c20270894fcb51365781.tar.gz
platform_external_arm-trusted-firmware-ba91a001f8e2ad2f92a7c20270894fcb51365781.tar.bz2
platform_external_arm-trusted-firmware-ba91a001f8e2ad2f92a7c20270894fcb51365781.zip
Merge pull request #1274 from dp-arm/dp/a75
AMU fixes for Cortex-A75
Diffstat (limited to 'lib/cpus/aarch64/cpuamu.c')
-rw-r--r--lib/cpus/aarch64/cpuamu.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/lib/cpus/aarch64/cpuamu.c b/lib/cpus/aarch64/cpuamu.c
new file mode 100644
index 000000000..b9bad8604
--- /dev/null
+++ b/lib/cpus/aarch64/cpuamu.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cpuamu.h>
+#include <platform.h>
+#include <pubsub_events.h>
+
+#define CPUAMU_NR_COUNTERS 5U
+
+struct amu_ctx {
+ uint64_t cnts[CPUAMU_NR_COUNTERS];
+ unsigned int mask;
+};
+
+static struct amu_ctx amu_ctxs[PLATFORM_CORE_COUNT];
+
+int midr_match(unsigned int cpu_midr)
+{
+ unsigned int midr, midr_mask;
+
+ midr = (unsigned int)read_midr();
+ midr_mask = (MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) |
+ (MIDR_PN_MASK << MIDR_PN_SHIFT);
+ return ((midr & midr_mask) == (cpu_midr & midr_mask));
+}
+
+void cpuamu_context_save(unsigned int nr_counters)
+{
+ struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()];
+ unsigned int i;
+
+ assert(nr_counters <= CPUAMU_NR_COUNTERS);
+
+ /* Save counter configuration */
+ ctx->mask = cpuamu_read_cpuamcntenset_el0();
+
+ /* Disable counters */
+ cpuamu_write_cpuamcntenclr_el0(ctx->mask);
+ isb();
+
+ /* Save counters */
+ for (i = 0; i < nr_counters; i++)
+ ctx->cnts[i] = cpuamu_cnt_read(i);
+}
+
+void cpuamu_context_restore(unsigned int nr_counters)
+{
+ struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()];
+ unsigned int i;
+
+ assert(nr_counters <= CPUAMU_NR_COUNTERS);
+
+ /*
+ * Disable counters. They were enabled early in the
+ * CPU reset function.
+ */
+ cpuamu_write_cpuamcntenclr_el0(ctx->mask);
+ isb();
+
+ /* Restore counters */
+ for (i = 0; i < nr_counters; i++)
+ cpuamu_cnt_write(i, ctx->cnts[i]);
+ isb();
+
+ /* Restore counter configuration */
+ cpuamu_write_cpuamcntenset_el0(ctx->mask);
+}