1 /*
2 * Copyright (c) 2023 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
3 * Licensed under the Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 * PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 */
12 #include <common/types.h>
13
14 /* PMCR_EL0 Performance Monitors Control Register */
15 #define PMCR_EL0_MASK (0x3f)
16 #define PMCR_EL0_E (1 << 0) /* Enable all counters */
17 #define PMCR_EL0_P (1 << 1) /* Event counter reset */
18 #define PMCR_EL0_C (1 << 2) /* Cycle counter reset */
19 #define PMCR_EL0_D (1 << 3) /* Clock divider */
20 #define PMCR_EL0_X \
21 (1 << 4) /* Enable export of events in an IMPLEMENTATION DEFINED event stream */
22 #define PMCR_EL0_DP \
23 (1 << 5) /* Disable cycle counter when event counting is prohibited */
24 #define PMCR_EL0_LC (1 << 6) /* Long cycle counter enable */
25 #define PMCR_EL0_N_SHIFT \
26 (11) /* An RO field that indicates the number of event counters implemented */
27 #define PMCR_EL0_N_MASK (0x1f)
28
29 /* PMUSERENR_EL0 Performance Monitors User Enable Register */
30 #define PMUSERENR_EL0_EN \
31 (1 \
32 << 0) /* Traps EL0 accesses to the Performance Monitors registers to EL1 */
33 #define PMUSERENR_EL0_SW (1 << 1) /* Software Increment write trap control */
34 #define PMUSERENR_EL0_CR (1 << 2) /* Cycle counter read trap control */
35 #define PMUSERENR_EL0_ER (1 << 3) /* Event counter read trap control */
36
37 /* PMCNTENSET_EL0 Performance Monitors Count Enable Set register */
38 #define PMCNTENSET_EL0_C \
39 (1 << 31) /* PMCCNTR_EL0 enable bit. Enables the cycle counter register. */
40
enable_cpu_cnt(void)41 void enable_cpu_cnt(void)
42 {
43 asm volatile(
44 "msr pmuserenr_el0, %0" ::"r"(PMUSERENR_EL0_EN | PMUSERENR_EL0_SW
45 | PMUSERENR_EL0_CR | PMUSERENR_EL0_ER));
46 asm volatile("msr pmcr_el0, %0" ::"r"(PMCR_EL0_LC | PMCR_EL0_E));
47 asm volatile("msr pmcntenset_el0, %0" ::"r"(PMCNTENSET_EL0_C));
48 }
49
disable_cpu_cnt(void)50 void disable_cpu_cnt(void)
51 {
52 asm volatile("msr pmcr_el0, %0" ::"r"(~PMCR_EL0_E));
53 asm volatile("msr pmcntenset_el0, %0" ::"r"(0));
54 }
55
pmu_init(void)56 void pmu_init(void)
57 {
58 enable_cpu_cnt();
59 }
60