1 /*
2  * Copyright 2019 The Hafnium Authors.
3  *
4  * Use of this source code is governed by a BSD-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/BSD-3-Clause.
7  */
8 
9 #include "../../src/arch/aarch64/hypervisor/perfmon.h"
10 
11 #include "../../src/arch/aarch64/sysregs.h"
12 #include "primary_with_secondary.h"
13 #include "sysregs.h"
14 #include "test/vmapi/ffa.h"
15 
TEAR_DOWN(perfmon)16 TEAR_DOWN(perfmon)
17 {
18 	EXPECT_FFA_ERROR(ffa_rx_release(), FFA_DENIED);
19 }
20 
TEST(perfmon,secondary_basic)21 TEST(perfmon, secondary_basic)
22 {
23 	struct ffa_value run_res;
24 	struct mailbox_buffers mb = set_up_mailbox();
25 
26 	SERVICE_SELECT(SERVICE_VM1, "perfmon_secondary_basic", mb.send);
27 
28 	run_res = ffa_run(SERVICE_VM1, 0);
29 	EXPECT_EQ(run_res.func, FFA_YIELD_32);
30 }
31 
32 /**
33  * Attempts to access performance monitor registers for read, without validating
34  * their value.
35  */
TEST(perfmon,primary_basic)36 TEST(perfmon, primary_basic)
37 {
38 	EXPECT_EQ(hf_vm_get_id(), HF_PRIMARY_VM_ID);
39 
40 	TRY_READ(PMCEID0_EL0);
41 	TRY_READ(PMCEID1_EL0);
42 	TRY_READ(PMCCFILTR_EL0);
43 	TRY_READ(PMCR_EL0);
44 }
45 
46 /**
47  * Tests a few performance counter registers for read and write, and checks that
48  * the expected value is written/read.
49  */
TEST(perfmon,primary_read_write)50 TEST(perfmon, primary_read_write)
51 {
52 	uintreg_t pmcr_el0 = read_msr(PMCR_EL0);
53 	uintreg_t perf_mon_count = GET_PMCR_EL0_N(pmcr_el0);
54 
55 	EXPECT_EQ(hf_vm_get_id(), HF_PRIMARY_VM_ID);
56 
57 	/*
58 	 * Ensure that there are enough performance counters in the underlying
59 	 * uArch for this test to pass.
60 	 */
61 	EXPECT_GE(perf_mon_count, 4);
62 
63 	CHECK_UPDATE(PMCCNTR_EL0, 0x5555, 0xaaaa);
64 
65 	write_msr(PMINTENCLR_EL1, 0xffff);
66 	CHECK_READ(PMINTENSET_EL1, 0);
67 
68 	/*
69 	 * Enable the first and second performance counters.
70 	 * Bits set in PMINTENSET_EL1 can be read in PMINTENCLR_EL1.
71 	 */
72 	write_msr(PMINTENSET_EL1, 0x3);
73 	CHECK_READ(PMINTENCLR_EL1, 0x3);
74 
75 	/*
76 	 * Enable the third and fourth performance counters.
77 	 * Writes to PMINTENSET_EL1 do not clear already set bits.
78 	 */
79 	write_msr(PMINTENSET_EL1, 0xc);
80 	CHECK_READ(PMINTENCLR_EL1, 0xf);
81 }
82 
83 /**
84  * Attempts to read all performance counters supported by the current CPU
85  * configuration.
86  */
87 /* NOLINTNEXTLINE(readability-function-size) */
TEST(perfmon,primary_counters)88 TEST(perfmon, primary_counters)
89 {
90 	uintreg_t pmcr_el0 = read_msr(PMCR_EL0);
91 	uintreg_t perf_mon_count = GET_PMCR_EL0_N(pmcr_el0);
92 
93 	EXPECT_EQ(hf_vm_get_id(), HF_PRIMARY_VM_ID);
94 
95 	if (perf_mon_count == 0) {
96 		return;
97 	}
98 
99 	switch (perf_mon_count - 1) {
100 	default:
101 		FAIL("More performance monitor registers than supported.");
102 	case 30:
103 		TRY_READ(PMEVCNTR30_EL0);
104 		CHECK_UPDATE(PMEVTYPER30_EL0, 0x0, 0x1);
105 		/* fallthrough */
106 	case 29:
107 		TRY_READ(PMEVCNTR29_EL0);
108 		CHECK_UPDATE(PMEVTYPER29_EL0, 0x0, 0x1);
109 		/* fallthrough */
110 	case 28:
111 		TRY_READ(PMEVCNTR28_EL0);
112 		CHECK_UPDATE(PMEVTYPER28_EL0, 0x0, 0x1);
113 		/* fallthrough */
114 	case 27:
115 		TRY_READ(PMEVCNTR27_EL0);
116 		CHECK_UPDATE(PMEVTYPER27_EL0, 0x0, 0x1);
117 		/* fallthrough */
118 	case 26:
119 		TRY_READ(PMEVCNTR26_EL0);
120 		CHECK_UPDATE(PMEVTYPER26_EL0, 0x0, 0x1);
121 		/* fallthrough */
122 	case 25:
123 		TRY_READ(PMEVCNTR25_EL0);
124 		CHECK_UPDATE(PMEVTYPER25_EL0, 0x0, 0x1);
125 		/* fallthrough */
126 	case 24:
127 		TRY_READ(PMEVCNTR24_EL0);
128 		CHECK_UPDATE(PMEVTYPER24_EL0, 0x0, 0x1);
129 		/* fallthrough */
130 	case 23:
131 		TRY_READ(PMEVCNTR23_EL0);
132 		CHECK_UPDATE(PMEVTYPER23_EL0, 0x0, 0x1);
133 		/* fallthrough */
134 	case 22:
135 		TRY_READ(PMEVCNTR22_EL0);
136 		CHECK_UPDATE(PMEVTYPER22_EL0, 0x0, 0x1);
137 		/* fallthrough */
138 	case 21:
139 		TRY_READ(PMEVCNTR21_EL0);
140 		CHECK_UPDATE(PMEVTYPER21_EL0, 0x0, 0x1);
141 		/* fallthrough */
142 	case 20:
143 		TRY_READ(PMEVCNTR20_EL0);
144 		CHECK_UPDATE(PMEVTYPER20_EL0, 0x0, 0x1);
145 		/* fallthrough */
146 	case 19:
147 		TRY_READ(PMEVCNTR19_EL0);
148 		CHECK_UPDATE(PMEVTYPER19_EL0, 0x0, 0x1);
149 		/* fallthrough */
150 	case 18:
151 		TRY_READ(PMEVCNTR18_EL0);
152 		CHECK_UPDATE(PMEVTYPER18_EL0, 0x0, 0x1);
153 		/* fallthrough */
154 	case 17:
155 		TRY_READ(PMEVCNTR17_EL0);
156 		CHECK_UPDATE(PMEVTYPER17_EL0, 0x0, 0x1);
157 		/* fallthrough */
158 	case 16:
159 		TRY_READ(PMEVCNTR16_EL0);
160 		CHECK_UPDATE(PMEVTYPER16_EL0, 0x0, 0x1);
161 		/* fallthrough */
162 	case 15:
163 		TRY_READ(PMEVCNTR15_EL0);
164 		CHECK_UPDATE(PMEVTYPER15_EL0, 0x0, 0x1);
165 		/* fallthrough */
166 	case 14:
167 		TRY_READ(PMEVCNTR14_EL0);
168 		CHECK_UPDATE(PMEVTYPER14_EL0, 0x0, 0x1);
169 		/* fallthrough */
170 	case 13:
171 		TRY_READ(PMEVCNTR13_EL0);
172 		CHECK_UPDATE(PMEVTYPER13_EL0, 0x0, 0x1);
173 		/* fallthrough */
174 	case 12:
175 		TRY_READ(PMEVCNTR12_EL0);
176 		CHECK_UPDATE(PMEVTYPER12_EL0, 0x0, 0x1);
177 		/* fallthrough */
178 	case 11:
179 		TRY_READ(PMEVCNTR11_EL0);
180 		CHECK_UPDATE(PMEVTYPER11_EL0, 0x0, 0x1);
181 		/* fallthrough */
182 	case 10:
183 		TRY_READ(PMEVCNTR10_EL0);
184 		CHECK_UPDATE(PMEVTYPER10_EL0, 0x0, 0x1);
185 		/* fallthrough */
186 	case 9:
187 		TRY_READ(PMEVCNTR9_EL0);
188 		CHECK_UPDATE(PMEVTYPER9_EL0, 0x0, 0x1);
189 		/* fallthrough */
190 	case 8:
191 		TRY_READ(PMEVCNTR8_EL0);
192 		CHECK_UPDATE(PMEVTYPER8_EL0, 0x0, 0x1);
193 		/* fallthrough */
194 	case 7:
195 		TRY_READ(PMEVCNTR7_EL0);
196 		CHECK_UPDATE(PMEVTYPER7_EL0, 0x0, 0x1);
197 		/* fallthrough */
198 	case 6:
199 		TRY_READ(PMEVCNTR6_EL0);
200 		CHECK_UPDATE(PMEVTYPER6_EL0, 0x0, 0x1);
201 		/* fallthrough */
202 	case 5:
203 		TRY_READ(PMEVCNTR5_EL0);
204 		CHECK_UPDATE(PMEVTYPER5_EL0, 0x0, 0x1);
205 		/* fallthrough */
206 	case 4:
207 		TRY_READ(PMEVCNTR4_EL0);
208 		CHECK_UPDATE(PMEVTYPER4_EL0, 0x0, 0x1);
209 		/* fallthrough */
210 	case 3:
211 		TRY_READ(PMEVCNTR3_EL0);
212 		CHECK_UPDATE(PMEVTYPER3_EL0, 0x0, 0x1);
213 		/* fallthrough */
214 	case 2:
215 		TRY_READ(PMEVCNTR2_EL0);
216 		CHECK_UPDATE(PMEVTYPER2_EL0, 0x0, 0x1);
217 		/* fallthrough */
218 	case 1:
219 		TRY_READ(PMEVCNTR1_EL0);
220 		CHECK_UPDATE(PMEVTYPER1_EL0, 0x0, 0x1);
221 		/* fallthrough */
222 	case 0:
223 		TRY_READ(PMEVCNTR0_EL0);
224 		CHECK_UPDATE(PMEVTYPER0_EL0, 0x0, 0x1);
225 		break;
226 	}
227 }
228