blob: 3a2fa819f8788d9fbfea8bbdc8e807e72e73697d [file] [log] [blame]
Dimitris Papastamos1be747f2018-02-14 10:28:36 +00001/*
2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <cpuamu.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00008#include <lib/el3_runtime/pubsub_events.h>
9#include <plat/common/platform.h>
Dimitris Papastamos1be747f2018-02-14 10:28:36 +000010
Dimitris Papastamos864364a2018-02-27 10:55:39 +000011#define CPUAMU_NR_COUNTERS 5U
Dimitris Papastamos1be747f2018-02-14 10:28:36 +000012
Daniel Boulby14f70052018-05-03 10:59:09 +010013struct cpuamu_ctx {
Dimitris Papastamos1be747f2018-02-14 10:28:36 +000014 uint64_t cnts[CPUAMU_NR_COUNTERS];
Dimitris Papastamos864364a2018-02-27 10:55:39 +000015 unsigned int mask;
Dimitris Papastamos1be747f2018-02-14 10:28:36 +000016};
17
Daniel Boulby14f70052018-05-03 10:59:09 +010018static struct cpuamu_ctx cpuamu_ctxs[PLATFORM_CORE_COUNT];
Dimitris Papastamos1be747f2018-02-14 10:28:36 +000019
20int midr_match(unsigned int cpu_midr)
21{
22 unsigned int midr, midr_mask;
23
Dimitris Papastamos864364a2018-02-27 10:55:39 +000024 midr = (unsigned int)read_midr();
Dimitris Papastamos1be747f2018-02-14 10:28:36 +000025 midr_mask = (MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) |
26 (MIDR_PN_MASK << MIDR_PN_SHIFT);
27 return ((midr & midr_mask) == (cpu_midr & midr_mask));
28}
29
30void cpuamu_context_save(unsigned int nr_counters)
31{
Daniel Boulby14f70052018-05-03 10:59:09 +010032 struct cpuamu_ctx *ctx = &cpuamu_ctxs[plat_my_core_pos()];
Dimitris Papastamos864364a2018-02-27 10:55:39 +000033 unsigned int i;
Dimitris Papastamos1be747f2018-02-14 10:28:36 +000034
35 assert(nr_counters <= CPUAMU_NR_COUNTERS);
36
37 /* Save counter configuration */
38 ctx->mask = cpuamu_read_cpuamcntenset_el0();
39
40 /* Disable counters */
41 cpuamu_write_cpuamcntenclr_el0(ctx->mask);
42 isb();
43
44 /* Save counters */
45 for (i = 0; i < nr_counters; i++)
46 ctx->cnts[i] = cpuamu_cnt_read(i);
47}
48
49void cpuamu_context_restore(unsigned int nr_counters)
50{
Daniel Boulby14f70052018-05-03 10:59:09 +010051 struct cpuamu_ctx *ctx = &cpuamu_ctxs[plat_my_core_pos()];
Dimitris Papastamos864364a2018-02-27 10:55:39 +000052 unsigned int i;
Dimitris Papastamos1be747f2018-02-14 10:28:36 +000053
54 assert(nr_counters <= CPUAMU_NR_COUNTERS);
55
56 /*
57 * Disable counters. They were enabled early in the
58 * CPU reset function.
59 */
60 cpuamu_write_cpuamcntenclr_el0(ctx->mask);
61 isb();
62
63 /* Restore counters */
64 for (i = 0; i < nr_counters; i++)
65 cpuamu_cnt_write(i, ctx->cnts[i]);
66 isb();
67
68 /* Restore counter configuration */
69 cpuamu_write_cpuamcntenset_el0(ctx->mask);
70}