// SPDX-License-Identifier: GPL-2.0-only
/*
 * SBI verification
 *
 * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
 */
#include <libcflat.h>
#include <stdlib.h>
#include <limits.h>
#include <asm/barrier.h>
#include <asm/csr.h>
#include <asm/delay.h>
#include <asm/isa.h>
#include <asm/processor.h>
#include <asm/sbi.h>
#include <asm/smp.h>
#include <asm/timer.h>

static void help(void)
{
	puts("Test SBI\n");
	puts("An environ must be provided where expected values are given.\n");
}

static struct sbiret __base_sbi_ecall(int fid, unsigned long arg0)
{
	return sbi_ecall(SBI_EXT_BASE, fid, arg0, 0, 0, 0, 0, 0);
}

static struct sbiret __time_sbi_ecall(unsigned long stime_value)
{
	return sbi_ecall(SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, stime_value, 0, 0, 0, 0, 0);
}

static bool env_or_skip(const char *env)
{
	if (!getenv(env)) {
		report_skip("missing %s environment variable", env);
		return false;
	}

	return true;
}

static void gen_report(struct sbiret *ret,
		       long expected_error, long expected_value)
{
	bool check_error = ret->error == expected_error;
	bool check_value = ret->value == expected_value;

	if (!check_error || !check_value)
		report_info("expected (error: %ld, value: %ld), received: (error: %ld, value %ld)",
			    expected_error, expected_value, ret->error, ret->value);

	report(check_error, "expected sbi.error");
	report(check_value, "expected sbi.value");
}

static void check_base(void)
{
	struct sbiret ret;
	long expected;

	report_prefix_push("base");

	ret = __base_sbi_ecall(SBI_EXT_BASE_GET_SPEC_VERSION, 0);
	if (ret.error || ret.value < 2) {
		report_skip("SBI spec version 0.2 or higher required");
		return;
	}

	report_prefix_push("spec_version");
	if (env_or_skip("SPEC_VERSION")) {
		expected = strtol(getenv("SPEC_VERSION"), NULL, 0);
		gen_report(&ret, 0, expected);
	}
	report_prefix_pop();

	report_prefix_push("impl_id");
	if (env_or_skip("IMPL_ID")) {
		expected = strtol(getenv("IMPL_ID"), NULL, 0);
		ret = __base_sbi_ecall(SBI_EXT_BASE_GET_IMP_ID, 0);
		gen_report(&ret, 0, expected);
	}
	report_prefix_pop();

	report_prefix_push("impl_version");
	if (env_or_skip("IMPL_VERSION")) {
		expected = strtol(getenv("IMPL_VERSION"), NULL, 0);
		ret = __base_sbi_ecall(SBI_EXT_BASE_GET_IMP_VERSION, 0);
		gen_report(&ret, 0, expected);
	}
	report_prefix_pop();

	report_prefix_push("probe_ext");
	expected = getenv("PROBE_EXT") ? strtol(getenv("PROBE_EXT"), NULL, 0) : 1;
	ret = __base_sbi_ecall(SBI_EXT_BASE_PROBE_EXT, SBI_EXT_BASE);
	gen_report(&ret, 0, expected);
	report_prefix_push("unavailable");
	ret = __base_sbi_ecall(SBI_EXT_BASE_PROBE_EXT, 0xb000000);
	gen_report(&ret, 0, 0);
	report_prefix_pop();
	report_prefix_pop();

	report_prefix_push("mvendorid");
	if (env_or_skip("MVENDORID")) {
		expected = strtol(getenv("MVENDORID"), NULL, 0);
		ret = __base_sbi_ecall(SBI_EXT_BASE_GET_MVENDORID, 0);
		gen_report(&ret, 0, expected);
	}
	report_prefix_pop();

	report_prefix_push("marchid");
	if (env_or_skip("MARCHID")) {
		expected = strtol(getenv("MARCHID"), NULL, 0);
		ret = __base_sbi_ecall(SBI_EXT_BASE_GET_MARCHID, 0);
		gen_report(&ret, 0, expected);
	}
	report_prefix_pop();

	report_prefix_push("mimpid");
	if (env_or_skip("MIMPID")) {
		expected = strtol(getenv("MIMPID"), NULL, 0);
		ret = __base_sbi_ecall(SBI_EXT_BASE_GET_MIMPID, 0);
		gen_report(&ret, 0, expected);
	}
	report_prefix_pop();

	report_prefix_pop();
}

struct timer_info {
	bool timer_works;
	bool mask_timer_irq;
	bool timer_irq_set;
	bool timer_irq_cleared;
	unsigned long timer_irq_count;
};

static struct timer_info timer_info;

static bool timer_irq_pending(void)
{
	return csr_read(CSR_SIP) & IP_TIP;
}

static void timer_irq_handler(struct pt_regs *regs)
{
	timer_info.timer_works = true;

	if (timer_info.timer_irq_count < ULONG_MAX)
		++timer_info.timer_irq_count;

	if (timer_irq_pending())
		timer_info.timer_irq_set = true;

	if (timer_info.mask_timer_irq)
		timer_irq_disable();
	else
		__time_sbi_ecall(ULONG_MAX);

	if (!timer_irq_pending())
		timer_info.timer_irq_cleared = true;
}

static void timer_check_set_timer(bool mask_timer_irq)
{
	struct sbiret ret;
	unsigned long begin, end, duration;
	const char *mask_test_str = mask_timer_irq ? " for mask irq test" : "";
	unsigned long d = getenv("TIMER_DELAY") ? strtol(getenv("TIMER_DELAY"), NULL, 0) : 200000;
	unsigned long margin = getenv("TIMER_MARGIN") ? strtol(getenv("TIMER_MARGIN"), NULL, 0) : 200000;

	d = usec_to_cycles(d);
	margin = usec_to_cycles(margin);

	timer_info = (struct timer_info){ .mask_timer_irq = mask_timer_irq };
	begin = timer_get_cycles();
	ret = __time_sbi_ecall(begin + d);

	report(!ret.error, "set timer%s", mask_test_str);
	if (ret.error)
		report_info("set timer%s failed with %ld\n", mask_test_str, ret.error);

	while ((end = timer_get_cycles()) <= (begin + d + margin) && !timer_info.timer_works)
		cpu_relax();

	report(timer_info.timer_works, "timer interrupt received%s", mask_test_str);
	report(timer_info.timer_irq_set, "pending timer interrupt bit set in irq handler%s", mask_test_str);

	if (!mask_timer_irq) {
		report(timer_info.timer_irq_set && timer_info.timer_irq_cleared,
		       "pending timer interrupt bit cleared by setting timer to -1");
	}

	if (timer_info.timer_works) {
		duration = end - begin;
		report(duration >= d && duration <= (d + margin), "timer delay honored%s", mask_test_str);
	}

	report(timer_info.timer_irq_count == 1, "timer interrupt received exactly once%s", mask_test_str);
}

static void check_time(void)
{
	bool pending;

	report_prefix_push("time");

	if (!sbi_probe(SBI_EXT_TIME)) {
		report_skip("time extension not available");
		report_prefix_pop();
		return;
	}

	report_prefix_push("set_timer");

	install_irq_handler(IRQ_S_TIMER, timer_irq_handler);
	local_irq_enable();
	if (cpu_has_extension(smp_processor_id(), ISA_SSTC)) {
		csr_write(CSR_STIMECMP, ULONG_MAX);
		if (__riscv_xlen == 32)
			csr_write(CSR_STIMECMPH, ULONG_MAX);
	}
	timer_irq_enable();

	timer_check_set_timer(false);

	if (csr_read(CSR_SIE) & IE_TIE)
		timer_check_set_timer(true);
	else
		report_skip("timer irq enable bit is not writable, skipping mask irq test");

	timer_irq_disable();
	__time_sbi_ecall(0);
	pending = timer_irq_pending();
	report(pending, "timer immediately pending by setting timer to 0");
	__time_sbi_ecall(ULONG_MAX);
	if (pending)
		report(!timer_irq_pending(), "pending timer cleared while masked");
	else
		report_skip("timer is not pending, skipping timer cleared while masked test");

	local_irq_disable();
	install_irq_handler(IRQ_S_TIMER, NULL);

	report_prefix_pop();
	report_prefix_pop();
}

int main(int argc, char **argv)
{

	if (argc > 1 && !strcmp(argv[1], "-h")) {
		help();
		exit(0);
	}

	report_prefix_push("sbi");
	check_base();
	check_time();

	return report_summary();
}
