// SPDX-License-Identifier: GPL-2.0-only
/*
 * sbi_pmu_test.c - Tests the riscv64 SBI PMU functionality.
 *
 * Copyright (c) 2024, Rivos Inc.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include "kvm_util.h"
#include "test_util.h"
#include "processor.h"
#include "sbi.h"
#include "arch_timer.h"
#include "ucall_common.h"

/* Maximum counters(firmware + hardware) */
#define RISCV_MAX_PMU_COUNTERS 64
union sbi_pmu_ctr_info ctrinfo_arr[RISCV_MAX_PMU_COUNTERS];

/* Snapshot shared memory data */
#define PMU_SNAPSHOT_GPA_BASE		BIT(30)
static void *snapshot_gva;
static vm_paddr_t snapshot_gpa;

static int vcpu_shared_irq_count;
static int counter_in_use;

/* Cache the available counters in a bitmask */
static unsigned long counter_mask_available;

static bool illegal_handler_invoked;

#define SBI_PMU_TEST_BASIC	BIT(0)
#define SBI_PMU_TEST_EVENTS	BIT(1)
#define SBI_PMU_TEST_SNAPSHOT	BIT(2)
#define SBI_PMU_TEST_OVERFLOW	BIT(3)

static int disabled_tests;

unsigned long pmu_csr_read_num(int csr_num)
{
#define switchcase_csr_read(__csr_num, __val)		{\
	case __csr_num:					\
		__val = csr_read(__csr_num);		\
		break; }
#define switchcase_csr_read_2(__csr_num, __val)		{\
	switchcase_csr_read(__csr_num + 0, __val)	 \
	switchcase_csr_read(__csr_num + 1, __val)}
#define switchcase_csr_read_4(__csr_num, __val)		{\
	switchcase_csr_read_2(__csr_num + 0, __val)	 \
	switchcase_csr_read_2(__csr_num + 2, __val)}
#define switchcase_csr_read_8(__csr_num, __val)		{\
	switchcase_csr_read_4(__csr_num + 0, __val)	 \
	switchcase_csr_read_4(__csr_num + 4, __val)}
#define switchcase_csr_read_16(__csr_num, __val)	{\
	switchcase_csr_read_8(__csr_num + 0, __val)	 \
	switchcase_csr_read_8(__csr_num + 8, __val)}
#define switchcase_csr_read_32(__csr_num, __val)	{\
	switchcase_csr_read_16(__csr_num + 0, __val)	 \
	switchcase_csr_read_16(__csr_num + 16, __val)}

	unsigned long ret = 0;

	switch (csr_num) {
	switchcase_csr_read_32(CSR_CYCLE, ret)
	switchcase_csr_read_32(CSR_CYCLEH, ret)
	default :
		break;
	}

	return ret;
#undef switchcase_csr_read_32
#undef switchcase_csr_read_16
#undef switchcase_csr_read_8
#undef switchcase_csr_read_4
#undef switchcase_csr_read_2
#undef switchcase_csr_read
}

static inline void dummy_func_loop(uint64_t iter)
{
	int i = 0;

	while (i < iter) {
		asm volatile("nop");
		i++;
	}
}

static void start_counter(unsigned long counter, unsigned long start_flags,
			  unsigned long ival)
{
	struct sbiret ret;

	ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, counter, 1, start_flags,
			ival, 0, 0);
	__GUEST_ASSERT(ret.error == 0, "Unable to start counter %ld\n", counter);
}

/* This should be invoked only for reset counter use case */
static void stop_reset_counter(unsigned long counter, unsigned long stop_flags)
{
	struct sbiret ret;

	ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP, counter, 1,
					stop_flags | SBI_PMU_STOP_FLAG_RESET, 0, 0, 0);
	__GUEST_ASSERT(ret.error == SBI_ERR_ALREADY_STOPPED,
			       "Unable to stop counter %ld\n", counter);
}

static void stop_counter(unsigned long counter, unsigned long stop_flags)
{
	struct sbiret ret;

	ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP, counter, 1, stop_flags,
			0, 0, 0);
	__GUEST_ASSERT(ret.error == 0, "Unable to stop counter %ld error %ld\n",
			       counter, ret.error);
}

static void guest_illegal_exception_handler(struct ex_regs *regs)
{
	__GUEST_ASSERT(regs->cause == EXC_INST_ILLEGAL,
		       "Unexpected exception handler %lx\n", regs->cause);

	illegal_handler_invoked = true;
	/* skip the trapping instruction */
	regs->epc += 4;
}

static void guest_irq_handler(struct ex_regs *regs)
{
	unsigned int irq_num = regs->cause & ~CAUSE_IRQ_FLAG;
	struct riscv_pmu_snapshot_data *snapshot_data = snapshot_gva;
	unsigned long overflown_mask;
	unsigned long counter_val = 0;

	/* Validate that we are in the correct irq handler */
	GUEST_ASSERT_EQ(irq_num, IRQ_PMU_OVF);

	/* Stop all counters first to avoid further interrupts */
	stop_counter(counter_in_use, SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT);

	csr_clear(CSR_SIP, BIT(IRQ_PMU_OVF));

	overflown_mask = READ_ONCE(snapshot_data->ctr_overflow_mask);
	GUEST_ASSERT(overflown_mask & 0x01);

	WRITE_ONCE(vcpu_shared_irq_count, vcpu_shared_irq_count+1);

	counter_val = READ_ONCE(snapshot_data->ctr_values[0]);
	/* Now start the counter to mimick the real driver behavior */
	start_counter(counter_in_use, SBI_PMU_START_FLAG_SET_INIT_VALUE, counter_val);
}

static unsigned long get_counter_index(unsigned long cbase, unsigned long cmask,
				       unsigned long cflags,
				       unsigned long event)
{
	struct sbiret ret;

	ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase, cmask,
			cflags, event, 0, 0);
	__GUEST_ASSERT(ret.error == 0, "config matching failed %ld\n", ret.error);
	GUEST_ASSERT(ret.value < RISCV_MAX_PMU_COUNTERS);
	GUEST_ASSERT(BIT(ret.value) & counter_mask_available);

	return ret.value;
}

static unsigned long get_num_counters(void)
{
	struct sbiret ret;

	ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_NUM_COUNTERS, 0, 0, 0, 0, 0, 0);

	__GUEST_ASSERT(ret.error == 0, "Unable to retrieve number of counters from SBI PMU");
	__GUEST_ASSERT(ret.value < RISCV_MAX_PMU_COUNTERS,
		       "Invalid number of counters %ld\n", ret.value);

	return ret.value;
}

static void update_counter_info(int num_counters)
{
	int i = 0;
	struct sbiret ret;

	for (i = 0; i < num_counters; i++) {
		ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_GET_INFO, i, 0, 0, 0, 0, 0);

		/* There can be gaps in logical counter indicies*/
		if (ret.error)
			continue;
		GUEST_ASSERT_NE(ret.value, 0);

		ctrinfo_arr[i].value = ret.value;
		counter_mask_available |= BIT(i);
	}

	GUEST_ASSERT(counter_mask_available > 0);
}

static unsigned long read_fw_counter(int idx, union sbi_pmu_ctr_info ctrinfo)
{
	struct sbiret ret;

	ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_FW_READ, idx, 0, 0, 0, 0, 0);
	GUEST_ASSERT(ret.error == 0);
	return ret.value;
}

static unsigned long read_counter(int idx, union sbi_pmu_ctr_info ctrinfo)
{
	unsigned long counter_val = 0;

	__GUEST_ASSERT(ctrinfo.type < 2, "Invalid counter type %d", ctrinfo.type);

	if (ctrinfo.type == SBI_PMU_CTR_TYPE_HW)
		counter_val = pmu_csr_read_num(ctrinfo.csr);
	else if (ctrinfo.type == SBI_PMU_CTR_TYPE_FW)
		counter_val = read_fw_counter(idx, ctrinfo);

	return counter_val;
}

static inline void verify_sbi_requirement_assert(void)
{
	long out_val = 0;
	bool probe;

	probe = guest_sbi_probe_extension(SBI_EXT_PMU, &out_val);
	GUEST_ASSERT(probe && out_val == 1);

	if (get_host_sbi_spec_version() < sbi_mk_version(2, 0))
		__GUEST_ASSERT(0, "SBI implementation version doesn't support PMU Snapshot");
}

static void snapshot_set_shmem(vm_paddr_t gpa, unsigned long flags)
{
	unsigned long lo = (unsigned long)gpa;
#if __riscv_xlen == 32
	unsigned long hi = (unsigned long)(gpa >> 32);
#else
	unsigned long hi = gpa == -1 ? -1 : 0;
#endif
	struct sbiret ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_SNAPSHOT_SET_SHMEM,
				      lo, hi, flags, 0, 0, 0);

	GUEST_ASSERT(ret.value == 0 && ret.error == 0);
}

static void test_pmu_event(unsigned long event)
{
	unsigned long counter;
	unsigned long counter_value_pre, counter_value_post;
	unsigned long counter_init_value = 100;

	counter = get_counter_index(0, counter_mask_available, 0, event);
	counter_value_pre = read_counter(counter, ctrinfo_arr[counter]);

	/* Do not set the initial value */
	start_counter(counter, 0, 0);
	dummy_func_loop(10000);
	stop_counter(counter, 0);

	counter_value_post = read_counter(counter, ctrinfo_arr[counter]);
	__GUEST_ASSERT(counter_value_post > counter_value_pre,
		       "Event update verification failed: post [%lx] pre [%lx]\n",
		       counter_value_post, counter_value_pre);

	/*
	 * We can't just update the counter without starting it.
	 * Do start/stop twice to simulate that by first initializing to a very
	 * high value and a low value after that.
	 */
	start_counter(counter, SBI_PMU_START_FLAG_SET_INIT_VALUE, ULONG_MAX/2);
	stop_counter(counter, 0);
	counter_value_pre = read_counter(counter, ctrinfo_arr[counter]);

	start_counter(counter, SBI_PMU_START_FLAG_SET_INIT_VALUE, counter_init_value);
	stop_counter(counter, 0);
	counter_value_post = read_counter(counter, ctrinfo_arr[counter]);
	__GUEST_ASSERT(counter_value_pre > counter_value_post,
		       "Counter reinitialization verification failed : post [%lx] pre [%lx]\n",
		       counter_value_post, counter_value_pre);

	/* Now set the initial value and compare */
	start_counter(counter, SBI_PMU_START_FLAG_SET_INIT_VALUE, counter_init_value);
	dummy_func_loop(10000);
	stop_counter(counter, 0);

	counter_value_post = read_counter(counter, ctrinfo_arr[counter]);
	__GUEST_ASSERT(counter_value_post > counter_init_value,
		       "Event update verification failed: post [%lx] pre [%lx]\n",
		       counter_value_post, counter_init_value);

	stop_reset_counter(counter, 0);
}

static void test_pmu_event_snapshot(unsigned long event)
{
	unsigned long counter;
	unsigned long counter_value_pre, counter_value_post;
	unsigned long counter_init_value = 100;
	struct riscv_pmu_snapshot_data *snapshot_data = snapshot_gva;

	counter = get_counter_index(0, counter_mask_available, 0, event);
	counter_value_pre = read_counter(counter, ctrinfo_arr[counter]);

	/* Do not set the initial value */
	start_counter(counter, 0, 0);
	dummy_func_loop(10000);
	stop_counter(counter, SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT);

	/* The counter value is updated w.r.t relative index of cbase */
	counter_value_post = READ_ONCE(snapshot_data->ctr_values[0]);
	__GUEST_ASSERT(counter_value_post > counter_value_pre,
		       "Event update verification failed: post [%lx] pre [%lx]\n",
		       counter_value_post, counter_value_pre);

	/*
	 * We can't just update the counter without starting it.
	 * Do start/stop twice to simulate that by first initializing to a very
	 * high value and a low value after that.
	 */
	WRITE_ONCE(snapshot_data->ctr_values[0], ULONG_MAX/2);
	start_counter(counter, SBI_PMU_START_FLAG_INIT_SNAPSHOT, 0);
	stop_counter(counter, SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT);
	counter_value_pre = READ_ONCE(snapshot_data->ctr_values[0]);

	WRITE_ONCE(snapshot_data->ctr_values[0], counter_init_value);
	start_counter(counter, SBI_PMU_START_FLAG_INIT_SNAPSHOT, 0);
	stop_counter(counter, SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT);
	counter_value_post = READ_ONCE(snapshot_data->ctr_values[0]);
	__GUEST_ASSERT(counter_value_pre > counter_value_post,
		       "Counter reinitialization verification failed : post [%lx] pre [%lx]\n",
		       counter_value_post, counter_value_pre);

	/* Now set the initial value and compare */
	WRITE_ONCE(snapshot_data->ctr_values[0], counter_init_value);
	start_counter(counter, SBI_PMU_START_FLAG_INIT_SNAPSHOT, 0);
	dummy_func_loop(10000);
	stop_counter(counter, SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT);

	counter_value_post = READ_ONCE(snapshot_data->ctr_values[0]);
	__GUEST_ASSERT(counter_value_post > counter_init_value,
		       "Event update verification failed: post [%lx] pre [%lx]\n",
		       counter_value_post, counter_init_value);

	stop_reset_counter(counter, 0);
}

static void test_pmu_event_overflow(unsigned long event)
{
	unsigned long counter;
	unsigned long counter_value_post;
	unsigned long counter_init_value = ULONG_MAX - 10000;
	struct riscv_pmu_snapshot_data *snapshot_data = snapshot_gva;

	counter = get_counter_index(0, counter_mask_available, 0, event);
	counter_in_use = counter;

	/* The counter value is updated w.r.t relative index of cbase passed to start/stop */
	WRITE_ONCE(snapshot_data->ctr_values[0], counter_init_value);
	start_counter(counter, SBI_PMU_START_FLAG_INIT_SNAPSHOT, 0);
	dummy_func_loop(10000);
	udelay(msecs_to_usecs(2000));
	/* irq handler should have stopped the counter */
	stop_counter(counter, SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT);

	counter_value_post = READ_ONCE(snapshot_data->ctr_values[0]);
	/* The counter value after stopping should be less the init value due to overflow */
	__GUEST_ASSERT(counter_value_post < counter_init_value,
		       "counter_value_post %lx counter_init_value %lx for counter\n",
		       counter_value_post, counter_init_value);

	stop_reset_counter(counter, 0);
}

static void test_invalid_event(void)
{
	struct sbiret ret;
	unsigned long event = 0x1234; /* A random event */

	ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, 0,
			counter_mask_available, 0, event, 0, 0);
	GUEST_ASSERT_EQ(ret.error, SBI_ERR_NOT_SUPPORTED);
}

static void test_pmu_events(void)
{
	int num_counters = 0;

	/* Get the counter details */
	num_counters = get_num_counters();
	update_counter_info(num_counters);

	/* Sanity testing for any random invalid event */
	test_invalid_event();

	/* Only these two events are guaranteed to be present */
	test_pmu_event(SBI_PMU_HW_CPU_CYCLES);
	test_pmu_event(SBI_PMU_HW_INSTRUCTIONS);

	GUEST_DONE();
}

static void test_pmu_basic_sanity(void)
{
	long out_val = 0;
	bool probe;
	struct sbiret ret;
	int num_counters = 0, i;
	union sbi_pmu_ctr_info ctrinfo;

	probe = guest_sbi_probe_extension(SBI_EXT_PMU, &out_val);
	GUEST_ASSERT(probe && out_val == 1);

	num_counters = get_num_counters();

	for (i = 0; i < num_counters; i++) {
		ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_GET_INFO, i,
				0, 0, 0, 0, 0);

		/* There can be gaps in logical counter indicies*/
		if (ret.error)
			continue;
		GUEST_ASSERT_NE(ret.value, 0);

		ctrinfo.value = ret.value;

		/**
		 * Accessibility check of hardware and read capability of firmware counters.
		 * The spec doesn't mandate any initial value. No need to check any value.
		 */
		if (ctrinfo.type == SBI_PMU_CTR_TYPE_HW) {
			pmu_csr_read_num(ctrinfo.csr);
			GUEST_ASSERT(illegal_handler_invoked);
		} else if (ctrinfo.type == SBI_PMU_CTR_TYPE_FW) {
			read_fw_counter(i, ctrinfo);
		}
	}

	GUEST_DONE();
}

static void test_pmu_events_snaphost(void)
{
	int num_counters = 0;
	struct riscv_pmu_snapshot_data *snapshot_data = snapshot_gva;
	int i;

	/* Verify presence of SBI PMU and minimum requrired SBI version */
	verify_sbi_requirement_assert();

	snapshot_set_shmem(snapshot_gpa, 0);

	/* Get the counter details */
	num_counters = get_num_counters();
	update_counter_info(num_counters);

	/* Validate shared memory access */
	GUEST_ASSERT_EQ(READ_ONCE(snapshot_data->ctr_overflow_mask), 0);
	for (i = 0; i < num_counters; i++) {
		if (counter_mask_available & (BIT(i)))
			GUEST_ASSERT_EQ(READ_ONCE(snapshot_data->ctr_values[i]), 0);
	}
	/* Only these two events are guranteed to be present */
	test_pmu_event_snapshot(SBI_PMU_HW_CPU_CYCLES);
	test_pmu_event_snapshot(SBI_PMU_HW_INSTRUCTIONS);

	GUEST_DONE();
}

static void test_pmu_events_overflow(void)
{
	int num_counters = 0;

	/* Verify presence of SBI PMU and minimum requrired SBI version */
	verify_sbi_requirement_assert();

	snapshot_set_shmem(snapshot_gpa, 0);
	csr_set(CSR_IE, BIT(IRQ_PMU_OVF));
	local_irq_enable();

	/* Get the counter details */
	num_counters = get_num_counters();
	update_counter_info(num_counters);

	/*
	 * Qemu supports overflow for cycle/instruction.
	 * This test may fail on any platform that do not support overflow for these two events.
	 */
	test_pmu_event_overflow(SBI_PMU_HW_CPU_CYCLES);
	GUEST_ASSERT_EQ(vcpu_shared_irq_count, 1);

	test_pmu_event_overflow(SBI_PMU_HW_INSTRUCTIONS);
	GUEST_ASSERT_EQ(vcpu_shared_irq_count, 2);

	GUEST_DONE();
}

static void run_vcpu(struct kvm_vcpu *vcpu)
{
	struct ucall uc;

	vcpu_run(vcpu);
	switch (get_ucall(vcpu, &uc)) {
	case UCALL_ABORT:
		REPORT_GUEST_ASSERT(uc);
		break;
	case UCALL_DONE:
	case UCALL_SYNC:
		break;
	default:
		TEST_FAIL("Unknown ucall %lu", uc.cmd);
		break;
	}
}

void test_vm_destroy(struct kvm_vm *vm)
{
	memset(ctrinfo_arr, 0, sizeof(union sbi_pmu_ctr_info) * RISCV_MAX_PMU_COUNTERS);
	counter_mask_available = 0;
	kvm_vm_free(vm);
}

static void test_vm_basic_test(void *guest_code)
{
	struct kvm_vm *vm;
	struct kvm_vcpu *vcpu;

	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
	__TEST_REQUIRE(__vcpu_has_sbi_ext(vcpu, KVM_RISCV_SBI_EXT_PMU),
				   "SBI PMU not available, skipping test");
	vm_init_vector_tables(vm);
	/* Illegal instruction handler is required to verify read access without configuration */
	vm_install_exception_handler(vm, EXC_INST_ILLEGAL, guest_illegal_exception_handler);

	vcpu_init_vector_tables(vcpu);
	run_vcpu(vcpu);

	test_vm_destroy(vm);
}

static void test_vm_events_test(void *guest_code)
{
	struct kvm_vm *vm = NULL;
	struct kvm_vcpu *vcpu = NULL;

	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
	__TEST_REQUIRE(__vcpu_has_sbi_ext(vcpu, KVM_RISCV_SBI_EXT_PMU),
				   "SBI PMU not available, skipping test");
	run_vcpu(vcpu);

	test_vm_destroy(vm);
}

static void test_vm_setup_snapshot_mem(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
{
	/* PMU Snapshot requires single page only */
	vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, PMU_SNAPSHOT_GPA_BASE, 1, 1, 0);
	/* PMU_SNAPSHOT_GPA_BASE is identity mapped */
	virt_map(vm, PMU_SNAPSHOT_GPA_BASE, PMU_SNAPSHOT_GPA_BASE, 1);

	snapshot_gva = (void *)(PMU_SNAPSHOT_GPA_BASE);
	snapshot_gpa = addr_gva2gpa(vcpu->vm, (vm_vaddr_t)snapshot_gva);
	sync_global_to_guest(vcpu->vm, snapshot_gva);
	sync_global_to_guest(vcpu->vm, snapshot_gpa);
}

static void test_vm_events_snapshot_test(void *guest_code)
{
	struct kvm_vm *vm = NULL;
	struct kvm_vcpu *vcpu;

	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
	__TEST_REQUIRE(__vcpu_has_sbi_ext(vcpu, KVM_RISCV_SBI_EXT_PMU),
				   "SBI PMU not available, skipping test");

	test_vm_setup_snapshot_mem(vm, vcpu);

	run_vcpu(vcpu);

	test_vm_destroy(vm);
}

static void test_vm_events_overflow(void *guest_code)
{
	struct kvm_vm *vm = NULL;
	struct kvm_vcpu *vcpu;

	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
	__TEST_REQUIRE(__vcpu_has_sbi_ext(vcpu, KVM_RISCV_SBI_EXT_PMU),
				   "SBI PMU not available, skipping test");

	__TEST_REQUIRE(__vcpu_has_isa_ext(vcpu, KVM_RISCV_ISA_EXT_SSCOFPMF),
				   "Sscofpmf is not available, skipping overflow test");

	test_vm_setup_snapshot_mem(vm, vcpu);
	vm_init_vector_tables(vm);
	vm_install_interrupt_handler(vm, guest_irq_handler);

	vcpu_init_vector_tables(vcpu);
	/* Initialize guest timer frequency. */
	vcpu_get_reg(vcpu, RISCV_TIMER_REG(frequency), &timer_freq);
	sync_global_to_guest(vm, timer_freq);

	run_vcpu(vcpu);

	test_vm_destroy(vm);
}

static void test_print_help(char *name)
{
	pr_info("Usage: %s [-h] [-d <test name>]\n", name);
	pr_info("\t-d: Test to disable. Available tests are 'basic', 'events', 'snapshot', 'overflow'\n");
	pr_info("\t-h: print this help screen\n");
}

static bool parse_args(int argc, char *argv[])
{
	int opt;

	while ((opt = getopt(argc, argv, "hd:")) != -1) {
		switch (opt) {
		case 'd':
			if (!strncmp("basic", optarg, 5))
				disabled_tests |= SBI_PMU_TEST_BASIC;
			else if (!strncmp("events", optarg, 6))
				disabled_tests |= SBI_PMU_TEST_EVENTS;
			else if (!strncmp("snapshot", optarg, 8))
				disabled_tests |= SBI_PMU_TEST_SNAPSHOT;
			else if (!strncmp("overflow", optarg, 8))
				disabled_tests |= SBI_PMU_TEST_OVERFLOW;
			else
				goto done;
			break;
		case 'h':
		default:
			goto done;
		}
	}

	return true;
done:
	test_print_help(argv[0]);
	return false;
}

int main(int argc, char *argv[])
{
	if (!parse_args(argc, argv))
		exit(KSFT_SKIP);

	if (!(disabled_tests & SBI_PMU_TEST_BASIC)) {
		test_vm_basic_test(test_pmu_basic_sanity);
		pr_info("SBI PMU basic test : PASS\n");
	}

	if (!(disabled_tests & SBI_PMU_TEST_EVENTS)) {
		test_vm_events_test(test_pmu_events);
		pr_info("SBI PMU event verification test : PASS\n");
	}

	if (!(disabled_tests & SBI_PMU_TEST_SNAPSHOT)) {
		test_vm_events_snapshot_test(test_pmu_events_snaphost);
		pr_info("SBI PMU event verification with snapshot test : PASS\n");
	}

	if (!(disabled_tests & SBI_PMU_TEST_OVERFLOW)) {
		test_vm_events_overflow(test_pmu_events_overflow);
		pr_info("SBI PMU event verification with overflow test : PASS\n");
	}

	return 0;
}
