// SPDX-License-Identifier: GPL-2.0-only
/*
 * arch_timer.c - Tests the riscv64 sstc timer IRQ functionality
 *
 * The test validates the sstc timer IRQs using vstimecmp registers.
 * It's ported from the aarch64 arch_timer test.
 *
 * Copyright (c) 2024, Intel Corporation.
 */
#include "arch_timer.h"
#include "kvm_util.h"
#include "processor.h"
#include "timer_test.h"
#include "ucall_common.h"

static int timer_irq = IRQ_S_TIMER;

static void guest_irq_handler(struct pt_regs *regs)
{
	u64 xcnt, xcnt_diff_us, cmp;
	unsigned int intid = regs->cause & ~CAUSE_IRQ_FLAG;
	u32 cpu = guest_get_vcpuid();
	struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[cpu];

	timer_irq_disable();

	xcnt = timer_get_cycles();
	cmp = timer_get_cmp();
	xcnt_diff_us = cycles_to_usec(xcnt - shared_data->xcnt);

	/* Make sure we are dealing with the correct timer IRQ */
	GUEST_ASSERT_EQ(intid, timer_irq);

	__GUEST_ASSERT(xcnt >= cmp,
			"xcnt = 0x%"PRIx64", cmp = 0x%"PRIx64", xcnt_diff_us = 0x%" PRIx64,
			xcnt, cmp, xcnt_diff_us);

	WRITE_ONCE(shared_data->nr_iter, shared_data->nr_iter + 1);
}

static void guest_run(struct test_vcpu_shared_data *shared_data)
{
	u32 irq_iter, config_iter;

	shared_data->nr_iter = 0;
	shared_data->guest_stage = 0;

	for (config_iter = 0; config_iter < test_args.nr_iter; config_iter++) {
		/* Setup the next interrupt */
		timer_set_next_cmp_ms(test_args.timer_period_ms);
		shared_data->xcnt = timer_get_cycles();
		timer_irq_enable();

		/* Setup a timeout for the interrupt to arrive */
		udelay(msecs_to_usecs(test_args.timer_period_ms) +
			test_args.timer_err_margin_us);

		irq_iter = READ_ONCE(shared_data->nr_iter);
		__GUEST_ASSERT(config_iter + 1 == irq_iter,
				"config_iter + 1 = 0x%x, irq_iter = 0x%x.\n"
				"  Guest timer interrupt was not triggered within the specified\n"
				"  interval, try to increase the error margin by [-e] option.\n",
				config_iter + 1, irq_iter);
	}
}

static void guest_code(void)
{
	u32 cpu = guest_get_vcpuid();
	struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[cpu];

	timer_irq_disable();
	local_irq_enable();

	guest_run(shared_data);

	GUEST_DONE();
}

struct kvm_vm *test_vm_create(void)
{
	struct kvm_vm *vm;
	int nr_vcpus = test_args.nr_vcpus;

	vm = vm_create_with_vcpus(nr_vcpus, guest_code, vcpus);
	__TEST_REQUIRE(__vcpu_has_isa_ext(vcpus[0], KVM_RISCV_ISA_EXT_SSTC),
				   "SSTC not available, skipping test\n");

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

	for (int i = 0; i < nr_vcpus; i++)
		vcpu_init_vector_tables(vcpus[i]);

	/* Initialize guest timer frequency. */
	timer_freq = vcpu_get_reg(vcpus[0], RISCV_TIMER_REG(frequency));
	sync_global_to_guest(vm, timer_freq);
	pr_debug("timer_freq: %lu\n", timer_freq);

	/* Make all the test's cmdline args visible to the guest */
	sync_global_to_guest(vm, test_args);

	return vm;
}

void test_vm_cleanup(struct kvm_vm *vm)
{
	kvm_vm_free(vm);
}
