1 // SPDX-License-Identifier: GPL-2.0-only
3 * sbi_pmu_test.c - Tests the riscv64 SBI PMU functionality.
5 * Copyright (c) 2024, Rivos Inc.
12 #include <sys/types.h>
14 #include "test_util.h"
15 #include "processor.h"
17 #include "arch_timer.h"
18 #include "ucall_common.h"
20 /* Maximum counters(firmware + hardware) */
21 #define RISCV_MAX_PMU_COUNTERS 64
22 union sbi_pmu_ctr_info ctrinfo_arr
[RISCV_MAX_PMU_COUNTERS
];
24 /* Snapshot shared memory data */
25 #define PMU_SNAPSHOT_GPA_BASE BIT(30)
26 static void *snapshot_gva
;
27 static vm_paddr_t snapshot_gpa
;
29 static int vcpu_shared_irq_count
;
30 static int counter_in_use
;
32 /* Cache the available counters in a bitmask */
33 static unsigned long counter_mask_available
;
35 static bool illegal_handler_invoked
;
37 #define SBI_PMU_TEST_BASIC BIT(0)
38 #define SBI_PMU_TEST_EVENTS BIT(1)
39 #define SBI_PMU_TEST_SNAPSHOT BIT(2)
40 #define SBI_PMU_TEST_OVERFLOW BIT(3)
42 static int disabled_tests
;
44 unsigned long pmu_csr_read_num(int csr_num
)
46 #define switchcase_csr_read(__csr_num, __val) {\
48 __val = csr_read(__csr_num); \
50 #define switchcase_csr_read_2(__csr_num, __val) {\
51 switchcase_csr_read(__csr_num + 0, __val) \
52 switchcase_csr_read(__csr_num + 1, __val)}
53 #define switchcase_csr_read_4(__csr_num, __val) {\
54 switchcase_csr_read_2(__csr_num + 0, __val) \
55 switchcase_csr_read_2(__csr_num + 2, __val)}
56 #define switchcase_csr_read_8(__csr_num, __val) {\
57 switchcase_csr_read_4(__csr_num + 0, __val) \
58 switchcase_csr_read_4(__csr_num + 4, __val)}
59 #define switchcase_csr_read_16(__csr_num, __val) {\
60 switchcase_csr_read_8(__csr_num + 0, __val) \
61 switchcase_csr_read_8(__csr_num + 8, __val)}
62 #define switchcase_csr_read_32(__csr_num, __val) {\
63 switchcase_csr_read_16(__csr_num + 0, __val) \
64 switchcase_csr_read_16(__csr_num + 16, __val)}
66 unsigned long ret
= 0;
69 switchcase_csr_read_32(CSR_CYCLE
, ret
)
70 switchcase_csr_read_32(CSR_CYCLEH
, ret
)
76 #undef switchcase_csr_read_32
77 #undef switchcase_csr_read_16
78 #undef switchcase_csr_read_8
79 #undef switchcase_csr_read_4
80 #undef switchcase_csr_read_2
81 #undef switchcase_csr_read
84 static inline void dummy_func_loop(uint64_t iter
)
94 static void start_counter(unsigned long counter
, unsigned long start_flags
,
99 ret
= sbi_ecall(SBI_EXT_PMU
, SBI_EXT_PMU_COUNTER_START
, counter
, 1, start_flags
,
101 __GUEST_ASSERT(ret
.error
== 0, "Unable to start counter %ld\n", counter
);
104 /* This should be invoked only for reset counter use case */
105 static void stop_reset_counter(unsigned long counter
, unsigned long stop_flags
)
109 ret
= sbi_ecall(SBI_EXT_PMU
, SBI_EXT_PMU_COUNTER_STOP
, counter
, 1,
110 stop_flags
| SBI_PMU_STOP_FLAG_RESET
, 0, 0, 0);
111 __GUEST_ASSERT(ret
.error
== SBI_ERR_ALREADY_STOPPED
,
112 "Unable to stop counter %ld\n", counter
);
115 static void stop_counter(unsigned long counter
, unsigned long stop_flags
)
119 ret
= sbi_ecall(SBI_EXT_PMU
, SBI_EXT_PMU_COUNTER_STOP
, counter
, 1, stop_flags
,
121 __GUEST_ASSERT(ret
.error
== 0, "Unable to stop counter %ld error %ld\n",
125 static void guest_illegal_exception_handler(struct ex_regs
*regs
)
127 __GUEST_ASSERT(regs
->cause
== EXC_INST_ILLEGAL
,
128 "Unexpected exception handler %lx\n", regs
->cause
);
130 illegal_handler_invoked
= true;
131 /* skip the trapping instruction */
135 static void guest_irq_handler(struct ex_regs
*regs
)
137 unsigned int irq_num
= regs
->cause
& ~CAUSE_IRQ_FLAG
;
138 struct riscv_pmu_snapshot_data
*snapshot_data
= snapshot_gva
;
139 unsigned long overflown_mask
;
140 unsigned long counter_val
= 0;
142 /* Validate that we are in the correct irq handler */
143 GUEST_ASSERT_EQ(irq_num
, IRQ_PMU_OVF
);
145 /* Stop all counters first to avoid further interrupts */
146 stop_counter(counter_in_use
, SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT
);
148 csr_clear(CSR_SIP
, BIT(IRQ_PMU_OVF
));
150 overflown_mask
= READ_ONCE(snapshot_data
->ctr_overflow_mask
);
151 GUEST_ASSERT(overflown_mask
& 0x01);
153 WRITE_ONCE(vcpu_shared_irq_count
, vcpu_shared_irq_count
+1);
155 counter_val
= READ_ONCE(snapshot_data
->ctr_values
[0]);
156 /* Now start the counter to mimick the real driver behavior */
157 start_counter(counter_in_use
, SBI_PMU_START_FLAG_SET_INIT_VALUE
, counter_val
);
160 static unsigned long get_counter_index(unsigned long cbase
, unsigned long cmask
,
161 unsigned long cflags
,
166 ret
= sbi_ecall(SBI_EXT_PMU
, SBI_EXT_PMU_COUNTER_CFG_MATCH
, cbase
, cmask
,
167 cflags
, event
, 0, 0);
168 __GUEST_ASSERT(ret
.error
== 0, "config matching failed %ld\n", ret
.error
);
169 GUEST_ASSERT(ret
.value
< RISCV_MAX_PMU_COUNTERS
);
170 GUEST_ASSERT(BIT(ret
.value
) & counter_mask_available
);
175 static unsigned long get_num_counters(void)
179 ret
= sbi_ecall(SBI_EXT_PMU
, SBI_EXT_PMU_NUM_COUNTERS
, 0, 0, 0, 0, 0, 0);
181 __GUEST_ASSERT(ret
.error
== 0, "Unable to retrieve number of counters from SBI PMU");
182 __GUEST_ASSERT(ret
.value
< RISCV_MAX_PMU_COUNTERS
,
183 "Invalid number of counters %ld\n", ret
.value
);
188 static void update_counter_info(int num_counters
)
193 for (i
= 0; i
< num_counters
; i
++) {
194 ret
= sbi_ecall(SBI_EXT_PMU
, SBI_EXT_PMU_COUNTER_GET_INFO
, i
, 0, 0, 0, 0, 0);
196 /* There can be gaps in logical counter indicies*/
199 GUEST_ASSERT_NE(ret
.value
, 0);
201 ctrinfo_arr
[i
].value
= ret
.value
;
202 counter_mask_available
|= BIT(i
);
205 GUEST_ASSERT(counter_mask_available
> 0);
208 static unsigned long read_fw_counter(int idx
, union sbi_pmu_ctr_info ctrinfo
)
212 ret
= sbi_ecall(SBI_EXT_PMU
, SBI_EXT_PMU_COUNTER_FW_READ
, idx
, 0, 0, 0, 0, 0);
213 GUEST_ASSERT(ret
.error
== 0);
217 static unsigned long read_counter(int idx
, union sbi_pmu_ctr_info ctrinfo
)
219 unsigned long counter_val
= 0;
221 __GUEST_ASSERT(ctrinfo
.type
< 2, "Invalid counter type %d", ctrinfo
.type
);
223 if (ctrinfo
.type
== SBI_PMU_CTR_TYPE_HW
)
224 counter_val
= pmu_csr_read_num(ctrinfo
.csr
);
225 else if (ctrinfo
.type
== SBI_PMU_CTR_TYPE_FW
)
226 counter_val
= read_fw_counter(idx
, ctrinfo
);
231 static inline void verify_sbi_requirement_assert(void)
236 probe
= guest_sbi_probe_extension(SBI_EXT_PMU
, &out_val
);
237 GUEST_ASSERT(probe
&& out_val
== 1);
239 if (get_host_sbi_spec_version() < sbi_mk_version(2, 0))
240 __GUEST_ASSERT(0, "SBI implementation version doesn't support PMU Snapshot");
243 static void snapshot_set_shmem(vm_paddr_t gpa
, unsigned long flags
)
245 unsigned long lo
= (unsigned long)gpa
;
246 #if __riscv_xlen == 32
247 unsigned long hi
= (unsigned long)(gpa
>> 32);
249 unsigned long hi
= gpa
== -1 ? -1 : 0;
251 struct sbiret ret
= sbi_ecall(SBI_EXT_PMU
, SBI_EXT_PMU_SNAPSHOT_SET_SHMEM
,
252 lo
, hi
, flags
, 0, 0, 0);
254 GUEST_ASSERT(ret
.value
== 0 && ret
.error
== 0);
257 static void test_pmu_event(unsigned long event
)
259 unsigned long counter
;
260 unsigned long counter_value_pre
, counter_value_post
;
261 unsigned long counter_init_value
= 100;
263 counter
= get_counter_index(0, counter_mask_available
, 0, event
);
264 counter_value_pre
= read_counter(counter
, ctrinfo_arr
[counter
]);
266 /* Do not set the initial value */
267 start_counter(counter
, 0, 0);
268 dummy_func_loop(10000);
269 stop_counter(counter
, 0);
271 counter_value_post
= read_counter(counter
, ctrinfo_arr
[counter
]);
272 __GUEST_ASSERT(counter_value_post
> counter_value_pre
,
273 "Event update verification failed: post [%lx] pre [%lx]\n",
274 counter_value_post
, counter_value_pre
);
277 * We can't just update the counter without starting it.
278 * Do start/stop twice to simulate that by first initializing to a very
279 * high value and a low value after that.
281 start_counter(counter
, SBI_PMU_START_FLAG_SET_INIT_VALUE
, ULONG_MAX
/2);
282 stop_counter(counter
, 0);
283 counter_value_pre
= read_counter(counter
, ctrinfo_arr
[counter
]);
285 start_counter(counter
, SBI_PMU_START_FLAG_SET_INIT_VALUE
, counter_init_value
);
286 stop_counter(counter
, 0);
287 counter_value_post
= read_counter(counter
, ctrinfo_arr
[counter
]);
288 __GUEST_ASSERT(counter_value_pre
> counter_value_post
,
289 "Counter reinitialization verification failed : post [%lx] pre [%lx]\n",
290 counter_value_post
, counter_value_pre
);
292 /* Now set the initial value and compare */
293 start_counter(counter
, SBI_PMU_START_FLAG_SET_INIT_VALUE
, counter_init_value
);
294 dummy_func_loop(10000);
295 stop_counter(counter
, 0);
297 counter_value_post
= read_counter(counter
, ctrinfo_arr
[counter
]);
298 __GUEST_ASSERT(counter_value_post
> counter_init_value
,
299 "Event update verification failed: post [%lx] pre [%lx]\n",
300 counter_value_post
, counter_init_value
);
302 stop_reset_counter(counter
, 0);
305 static void test_pmu_event_snapshot(unsigned long event
)
307 unsigned long counter
;
308 unsigned long counter_value_pre
, counter_value_post
;
309 unsigned long counter_init_value
= 100;
310 struct riscv_pmu_snapshot_data
*snapshot_data
= snapshot_gva
;
312 counter
= get_counter_index(0, counter_mask_available
, 0, event
);
313 counter_value_pre
= read_counter(counter
, ctrinfo_arr
[counter
]);
315 /* Do not set the initial value */
316 start_counter(counter
, 0, 0);
317 dummy_func_loop(10000);
318 stop_counter(counter
, SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT
);
320 /* The counter value is updated w.r.t relative index of cbase */
321 counter_value_post
= READ_ONCE(snapshot_data
->ctr_values
[0]);
322 __GUEST_ASSERT(counter_value_post
> counter_value_pre
,
323 "Event update verification failed: post [%lx] pre [%lx]\n",
324 counter_value_post
, counter_value_pre
);
327 * We can't just update the counter without starting it.
328 * Do start/stop twice to simulate that by first initializing to a very
329 * high value and a low value after that.
331 WRITE_ONCE(snapshot_data
->ctr_values
[0], ULONG_MAX
/2);
332 start_counter(counter
, SBI_PMU_START_FLAG_INIT_SNAPSHOT
, 0);
333 stop_counter(counter
, SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT
);
334 counter_value_pre
= READ_ONCE(snapshot_data
->ctr_values
[0]);
336 WRITE_ONCE(snapshot_data
->ctr_values
[0], counter_init_value
);
337 start_counter(counter
, SBI_PMU_START_FLAG_INIT_SNAPSHOT
, 0);
338 stop_counter(counter
, SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT
);
339 counter_value_post
= READ_ONCE(snapshot_data
->ctr_values
[0]);
340 __GUEST_ASSERT(counter_value_pre
> counter_value_post
,
341 "Counter reinitialization verification failed : post [%lx] pre [%lx]\n",
342 counter_value_post
, counter_value_pre
);
344 /* Now set the initial value and compare */
345 WRITE_ONCE(snapshot_data
->ctr_values
[0], counter_init_value
);
346 start_counter(counter
, SBI_PMU_START_FLAG_INIT_SNAPSHOT
, 0);
347 dummy_func_loop(10000);
348 stop_counter(counter
, SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT
);
350 counter_value_post
= READ_ONCE(snapshot_data
->ctr_values
[0]);
351 __GUEST_ASSERT(counter_value_post
> counter_init_value
,
352 "Event update verification failed: post [%lx] pre [%lx]\n",
353 counter_value_post
, counter_init_value
);
355 stop_reset_counter(counter
, 0);
358 static void test_pmu_event_overflow(unsigned long event
)
360 unsigned long counter
;
361 unsigned long counter_value_post
;
362 unsigned long counter_init_value
= ULONG_MAX
- 10000;
363 struct riscv_pmu_snapshot_data
*snapshot_data
= snapshot_gva
;
365 counter
= get_counter_index(0, counter_mask_available
, 0, event
);
366 counter_in_use
= counter
;
368 /* The counter value is updated w.r.t relative index of cbase passed to start/stop */
369 WRITE_ONCE(snapshot_data
->ctr_values
[0], counter_init_value
);
370 start_counter(counter
, SBI_PMU_START_FLAG_INIT_SNAPSHOT
, 0);
371 dummy_func_loop(10000);
372 udelay(msecs_to_usecs(2000));
373 /* irq handler should have stopped the counter */
374 stop_counter(counter
, SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT
);
376 counter_value_post
= READ_ONCE(snapshot_data
->ctr_values
[0]);
377 /* The counter value after stopping should be less the init value due to overflow */
378 __GUEST_ASSERT(counter_value_post
< counter_init_value
,
379 "counter_value_post %lx counter_init_value %lx for counter\n",
380 counter_value_post
, counter_init_value
);
382 stop_reset_counter(counter
, 0);
385 static void test_invalid_event(void)
388 unsigned long event
= 0x1234; /* A random event */
390 ret
= sbi_ecall(SBI_EXT_PMU
, SBI_EXT_PMU_COUNTER_CFG_MATCH
, 0,
391 counter_mask_available
, 0, event
, 0, 0);
392 GUEST_ASSERT_EQ(ret
.error
, SBI_ERR_NOT_SUPPORTED
);
395 static void test_pmu_events(void)
397 int num_counters
= 0;
399 /* Get the counter details */
400 num_counters
= get_num_counters();
401 update_counter_info(num_counters
);
403 /* Sanity testing for any random invalid event */
404 test_invalid_event();
406 /* Only these two events are guaranteed to be present */
407 test_pmu_event(SBI_PMU_HW_CPU_CYCLES
);
408 test_pmu_event(SBI_PMU_HW_INSTRUCTIONS
);
413 static void test_pmu_basic_sanity(void)
418 int num_counters
= 0, i
;
419 union sbi_pmu_ctr_info ctrinfo
;
421 probe
= guest_sbi_probe_extension(SBI_EXT_PMU
, &out_val
);
422 GUEST_ASSERT(probe
&& out_val
== 1);
424 num_counters
= get_num_counters();
426 for (i
= 0; i
< num_counters
; i
++) {
427 ret
= sbi_ecall(SBI_EXT_PMU
, SBI_EXT_PMU_COUNTER_GET_INFO
, i
,
430 /* There can be gaps in logical counter indicies*/
433 GUEST_ASSERT_NE(ret
.value
, 0);
435 ctrinfo
.value
= ret
.value
;
438 * Accessibility check of hardware and read capability of firmware counters.
439 * The spec doesn't mandate any initial value. No need to check any value.
441 if (ctrinfo
.type
== SBI_PMU_CTR_TYPE_HW
) {
442 pmu_csr_read_num(ctrinfo
.csr
);
443 GUEST_ASSERT(illegal_handler_invoked
);
444 } else if (ctrinfo
.type
== SBI_PMU_CTR_TYPE_FW
) {
445 read_fw_counter(i
, ctrinfo
);
452 static void test_pmu_events_snaphost(void)
454 int num_counters
= 0;
455 struct riscv_pmu_snapshot_data
*snapshot_data
= snapshot_gva
;
458 /* Verify presence of SBI PMU and minimum requrired SBI version */
459 verify_sbi_requirement_assert();
461 snapshot_set_shmem(snapshot_gpa
, 0);
463 /* Get the counter details */
464 num_counters
= get_num_counters();
465 update_counter_info(num_counters
);
467 /* Validate shared memory access */
468 GUEST_ASSERT_EQ(READ_ONCE(snapshot_data
->ctr_overflow_mask
), 0);
469 for (i
= 0; i
< num_counters
; i
++) {
470 if (counter_mask_available
& (BIT(i
)))
471 GUEST_ASSERT_EQ(READ_ONCE(snapshot_data
->ctr_values
[i
]), 0);
473 /* Only these two events are guranteed to be present */
474 test_pmu_event_snapshot(SBI_PMU_HW_CPU_CYCLES
);
475 test_pmu_event_snapshot(SBI_PMU_HW_INSTRUCTIONS
);
480 static void test_pmu_events_overflow(void)
482 int num_counters
= 0;
484 /* Verify presence of SBI PMU and minimum requrired SBI version */
485 verify_sbi_requirement_assert();
487 snapshot_set_shmem(snapshot_gpa
, 0);
488 csr_set(CSR_IE
, BIT(IRQ_PMU_OVF
));
491 /* Get the counter details */
492 num_counters
= get_num_counters();
493 update_counter_info(num_counters
);
496 * Qemu supports overflow for cycle/instruction.
497 * This test may fail on any platform that do not support overflow for these two events.
499 test_pmu_event_overflow(SBI_PMU_HW_CPU_CYCLES
);
500 GUEST_ASSERT_EQ(vcpu_shared_irq_count
, 1);
502 test_pmu_event_overflow(SBI_PMU_HW_INSTRUCTIONS
);
503 GUEST_ASSERT_EQ(vcpu_shared_irq_count
, 2);
508 static void run_vcpu(struct kvm_vcpu
*vcpu
)
513 switch (get_ucall(vcpu
, &uc
)) {
515 REPORT_GUEST_ASSERT(uc
);
521 TEST_FAIL("Unknown ucall %lu", uc
.cmd
);
526 void test_vm_destroy(struct kvm_vm
*vm
)
528 memset(ctrinfo_arr
, 0, sizeof(union sbi_pmu_ctr_info
) * RISCV_MAX_PMU_COUNTERS
);
529 counter_mask_available
= 0;
533 static void test_vm_basic_test(void *guest_code
)
536 struct kvm_vcpu
*vcpu
;
538 vm
= vm_create_with_one_vcpu(&vcpu
, guest_code
);
539 __TEST_REQUIRE(__vcpu_has_sbi_ext(vcpu
, KVM_RISCV_SBI_EXT_PMU
),
540 "SBI PMU not available, skipping test");
541 vm_init_vector_tables(vm
);
542 /* Illegal instruction handler is required to verify read access without configuration */
543 vm_install_exception_handler(vm
, EXC_INST_ILLEGAL
, guest_illegal_exception_handler
);
545 vcpu_init_vector_tables(vcpu
);
551 static void test_vm_events_test(void *guest_code
)
553 struct kvm_vm
*vm
= NULL
;
554 struct kvm_vcpu
*vcpu
= NULL
;
556 vm
= vm_create_with_one_vcpu(&vcpu
, guest_code
);
557 __TEST_REQUIRE(__vcpu_has_sbi_ext(vcpu
, KVM_RISCV_SBI_EXT_PMU
),
558 "SBI PMU not available, skipping test");
564 static void test_vm_setup_snapshot_mem(struct kvm_vm
*vm
, struct kvm_vcpu
*vcpu
)
566 /* PMU Snapshot requires single page only */
567 vm_userspace_mem_region_add(vm
, VM_MEM_SRC_ANONYMOUS
, PMU_SNAPSHOT_GPA_BASE
, 1, 1, 0);
568 /* PMU_SNAPSHOT_GPA_BASE is identity mapped */
569 virt_map(vm
, PMU_SNAPSHOT_GPA_BASE
, PMU_SNAPSHOT_GPA_BASE
, 1);
571 snapshot_gva
= (void *)(PMU_SNAPSHOT_GPA_BASE
);
572 snapshot_gpa
= addr_gva2gpa(vcpu
->vm
, (vm_vaddr_t
)snapshot_gva
);
573 sync_global_to_guest(vcpu
->vm
, snapshot_gva
);
574 sync_global_to_guest(vcpu
->vm
, snapshot_gpa
);
577 static void test_vm_events_snapshot_test(void *guest_code
)
579 struct kvm_vm
*vm
= NULL
;
580 struct kvm_vcpu
*vcpu
;
582 vm
= vm_create_with_one_vcpu(&vcpu
, guest_code
);
583 __TEST_REQUIRE(__vcpu_has_sbi_ext(vcpu
, KVM_RISCV_SBI_EXT_PMU
),
584 "SBI PMU not available, skipping test");
586 test_vm_setup_snapshot_mem(vm
, vcpu
);
593 static void test_vm_events_overflow(void *guest_code
)
595 struct kvm_vm
*vm
= NULL
;
596 struct kvm_vcpu
*vcpu
;
598 vm
= vm_create_with_one_vcpu(&vcpu
, guest_code
);
599 __TEST_REQUIRE(__vcpu_has_sbi_ext(vcpu
, KVM_RISCV_SBI_EXT_PMU
),
600 "SBI PMU not available, skipping test");
602 __TEST_REQUIRE(__vcpu_has_isa_ext(vcpu
, KVM_RISCV_ISA_EXT_SSCOFPMF
),
603 "Sscofpmf is not available, skipping overflow test");
605 test_vm_setup_snapshot_mem(vm
, vcpu
);
606 vm_init_vector_tables(vm
);
607 vm_install_interrupt_handler(vm
, guest_irq_handler
);
609 vcpu_init_vector_tables(vcpu
);
610 /* Initialize guest timer frequency. */
611 vcpu_get_reg(vcpu
, RISCV_TIMER_REG(frequency
), &timer_freq
);
612 sync_global_to_guest(vm
, timer_freq
);
619 static void test_print_help(char *name
)
621 pr_info("Usage: %s [-h] [-d <test name>]\n", name
);
622 pr_info("\t-d: Test to disable. Available tests are 'basic', 'events', 'snapshot', 'overflow'\n");
623 pr_info("\t-h: print this help screen\n");
626 static bool parse_args(int argc
, char *argv
[])
630 while ((opt
= getopt(argc
, argv
, "hd:")) != -1) {
633 if (!strncmp("basic", optarg
, 5))
634 disabled_tests
|= SBI_PMU_TEST_BASIC
;
635 else if (!strncmp("events", optarg
, 6))
636 disabled_tests
|= SBI_PMU_TEST_EVENTS
;
637 else if (!strncmp("snapshot", optarg
, 8))
638 disabled_tests
|= SBI_PMU_TEST_SNAPSHOT
;
639 else if (!strncmp("overflow", optarg
, 8))
640 disabled_tests
|= SBI_PMU_TEST_OVERFLOW
;
652 test_print_help(argv
[0]);
656 int main(int argc
, char *argv
[])
658 if (!parse_args(argc
, argv
))
661 if (!(disabled_tests
& SBI_PMU_TEST_BASIC
)) {
662 test_vm_basic_test(test_pmu_basic_sanity
);
663 pr_info("SBI PMU basic test : PASS\n");
666 if (!(disabled_tests
& SBI_PMU_TEST_EVENTS
)) {
667 test_vm_events_test(test_pmu_events
);
668 pr_info("SBI PMU event verification test : PASS\n");
671 if (!(disabled_tests
& SBI_PMU_TEST_SNAPSHOT
)) {
672 test_vm_events_snapshot_test(test_pmu_events_snaphost
);
673 pr_info("SBI PMU event verification with snapshot test : PASS\n");
676 if (!(disabled_tests
& SBI_PMU_TEST_OVERFLOW
)) {
677 test_vm_events_overflow(test_pmu_events_overflow
);
678 pr_info("SBI PMU event verification with overflow test : PASS\n");