/*
 * Copyright 2018 The Hafnium Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdalign.h>

#include "hf/arch/vm/power_mgmt.h"

#include "hf/spinlock.h"

#include "vmapi/hf/call.h"

#include "hftest.h"

/*
 * TODO: Some of these tests are duplicated between 'primary_only' and
 * 'primary_with_secondaries'. Move them to a common place consider running
 * them inside secondary VMs too.
 */

/**
 * Confirms the primary VM has the primary ID.
 */
TEST(hf_vm_get_id, primary_has_primary_id)
{
	EXPECT_EQ(hf_vm_get_id(), HF_PRIMARY_VM_ID);
}

/**
 * Confirm there is only the primary VM.
 */
TEST(hf_vm_get_count, no_secondary_vms)
{
	EXPECT_EQ(hf_vm_get_count(), 1);
}

/**
 * Confirm the primary has at least one vcpu.
 */
TEST(hf_vcpu_get_count, primary_has_at_least_one)
{
	EXPECT_GE(hf_vcpu_get_count(HF_PRIMARY_VM_ID), 0);
}

/**
 * Confirm an error is returned when getting the vcpu count of a non-existant
 * VM.
 */
TEST(hf_vcpu_get_count, no_secondary_vms)
{
	EXPECT_EQ(hf_vcpu_get_count(HF_VM_ID_OFFSET + 1), 0);
}

/**
 * Confirm an error is returned when getting the vcpu count for a reserved ID.
 */
TEST(hf_vcpu_get_count, reserved_vm_id)
{
	spci_vm_id_t id;

	for (id = 0; id < HF_VM_ID_OFFSET; ++id) {
		EXPECT_EQ(hf_vcpu_get_count(id), 0);
	}
}

/**
 * Confirm an error is returned when getting the vcpu count of a VM with an ID
 * that is likely to be far outside the resource limit.
 */
TEST(hf_vcpu_get_count, large_invalid_vm_id)
{
	EXPECT_EQ(hf_vcpu_get_count(0xffff), 0);
}

/**
 * Confirm it is a no-op with a valid return code when running a vcpu from the
 * primary VM.
 */
TEST(hf_vcpu_run, cannot_run_primary)
{
	struct hf_vcpu_run_return res = hf_vcpu_run(HF_PRIMARY_VM_ID, 0);
	EXPECT_EQ(res.code, HF_VCPU_RUN_WAIT_FOR_INTERRUPT);
	EXPECT_EQ(res.sleep.ns, HF_SLEEP_INDEFINITE);
}

/**
 * Confirm it is a no-op with a valid return code when running a vcpu from a
 * non-existant secondary VM.
 */
TEST(hf_vcpu_run, cannot_run_absent_secondary)
{
	struct hf_vcpu_run_return res = hf_vcpu_run(1, 0);
	EXPECT_EQ(res.code, HF_VCPU_RUN_WAIT_FOR_INTERRUPT);
	EXPECT_EQ(res.sleep.ns, HF_SLEEP_INDEFINITE);
}

/**
 * Yielding from the primary is a noop.
 */
TEST(spci_yield, yield_is_noop_for_primary)
{
	EXPECT_EQ(spci_yield().func, SPCI_SUCCESS_32);
}

/**
 * Releases the lock passed in.
 */
static void vm_cpu_entry(uintptr_t arg)
{
	struct spinlock *lock = (struct spinlock *)arg;

	dlog("Second CPU started.\n");
	sl_unlock(lock);
}

/**
 * Confirm a new cpu can be started to execute in parallel.
 */
TEST(cpus, start)
{
	struct spinlock lock = SPINLOCK_INIT;
	alignas(4096) static uint8_t other_stack[4096];

	/* Start secondary while holding lock. */
	sl_lock(&lock);
	EXPECT_EQ(hftest_cpu_start(hftest_get_cpu_id(1), other_stack,
				   sizeof(other_stack), vm_cpu_entry,
				   (uintptr_t)&lock),
		  true);

	/* Wait for CPU to release the lock. */
	sl_lock(&lock);
}

/** Ensures that the Hafnium SPCI version is reported as expected. */
TEST(spci, spci_version)
{
	const int32_t major_revision = 0;
	const int32_t major_revision_offset = 16;
	const int32_t minor_revision = 9;
	const int32_t current_version =
		(major_revision << major_revision_offset) | minor_revision;

	struct spci_value ret = spci_version();
	EXPECT_EQ(ret.func, SPCI_SUCCESS_32);
	EXPECT_EQ(ret.arg2, current_version);
}

/** Ensures that SPCI_FEATURES is reporting the expected interfaces. */
TEST(spci, spci_features)
{
	struct spci_value ret;

	ret = spci_features(SPCI_ERROR_32);
	EXPECT_EQ(ret.func, SPCI_SUCCESS_32);

	ret = spci_features(SPCI_SUCCESS_32);
	EXPECT_EQ(ret.func, SPCI_SUCCESS_32);

	ret = spci_features(SPCI_VERSION_32);
	EXPECT_EQ(ret.func, SPCI_SUCCESS_32);

	ret = spci_features(SPCI_FEATURES_32);
	EXPECT_EQ(ret.func, SPCI_SUCCESS_32);

	ret = spci_features(SPCI_ID_GET_32);
	EXPECT_EQ(ret.func, SPCI_SUCCESS_32);

	ret = spci_features(SPCI_YIELD_32);
	EXPECT_EQ(ret.func, SPCI_SUCCESS_32);

	ret = spci_features(SPCI_MSG_SEND_32);
	EXPECT_EQ(ret.func, SPCI_SUCCESS_32);

	ret = spci_features(SPCI_MSG_POLL_32);
	EXPECT_EQ(ret.func, SPCI_SUCCESS_32);

	ret = spci_features(SPCI_MSG_WAIT_32);
	EXPECT_EQ(ret.func, SPCI_SUCCESS_32);

	ret = spci_features(SPCI_YIELD_32);
	EXPECT_EQ(ret.func, SPCI_SUCCESS_32);
}

/**
 * Ensures that SPCI_FEATURES returns not supported for a bogus FID or
 * currently non-implemented interfaces.
 */
TEST(spci, spci_features_not_supported)
{
	struct spci_value ret;

	ret = spci_features(0);
	EXPECT_EQ(ret.func, SPCI_ERROR_32);
	EXPECT_EQ(ret.arg2, SPCI_NOT_SUPPORTED);

	ret = spci_features(0x84000000);
	EXPECT_EQ(ret.func, SPCI_ERROR_32);
	EXPECT_EQ(ret.arg2, SPCI_NOT_SUPPORTED);

	ret = spci_features(SPCI_INTERRUPT_32);
	EXPECT_EQ(ret.func, SPCI_ERROR_32);
	EXPECT_EQ(ret.arg2, SPCI_NOT_SUPPORTED);

	ret = spci_features(SPCI_RX_RELEASE_32);
	EXPECT_EQ(ret.func, SPCI_ERROR_32);
	EXPECT_EQ(ret.arg2, SPCI_NOT_SUPPORTED);

	ret = spci_features(SPCI_RXTX_MAP_32);
	EXPECT_EQ(ret.func, SPCI_ERROR_32);
	EXPECT_EQ(ret.arg2, SPCI_NOT_SUPPORTED);

	ret = spci_features(SPCI_RXTX_UNMAP_32);
	EXPECT_EQ(ret.func, SPCI_ERROR_32);
	EXPECT_EQ(ret.arg2, SPCI_NOT_SUPPORTED);

	ret = spci_features(SPCI_PARTITION_INFO_GET_32);
	EXPECT_EQ(ret.func, SPCI_ERROR_32);
	EXPECT_EQ(ret.arg2, SPCI_NOT_SUPPORTED);

	ret = spci_features(SPCI_RUN_32);
	EXPECT_EQ(ret.func, SPCI_ERROR_32);
	EXPECT_EQ(ret.arg2, SPCI_NOT_SUPPORTED);

	ret = spci_features(SPCI_MSG_SEND_DIRECT_RESP_32);
	EXPECT_EQ(ret.func, SPCI_ERROR_32);
	EXPECT_EQ(ret.arg2, SPCI_NOT_SUPPORTED);

	ret = spci_features(SPCI_MSG_SEND_DIRECT_REQ_32);
	EXPECT_EQ(ret.func, SPCI_ERROR_32);
	EXPECT_EQ(ret.arg2, SPCI_NOT_SUPPORTED);

	ret = spci_features(SPCI_MSG_SEND_DIRECT_REQ_32);
	EXPECT_EQ(ret.func, SPCI_ERROR_32);
	EXPECT_EQ(ret.arg2, SPCI_NOT_SUPPORTED);

	ret = spci_features(SPCI_MSG_SEND_DIRECT_RESP_32);
	EXPECT_EQ(ret.func, SPCI_ERROR_32);
	EXPECT_EQ(ret.arg2, SPCI_NOT_SUPPORTED);
}

/**
 * Test that floating-point operations work in the primary VM.
 */
TEST(fp, fp)
{
	/*
	 * Get some numbers that the compiler can't tell are constants, so it
	 * can't optimise them away.
	 */
	double a = hf_vm_get_count();
	double b = hf_vcpu_get_count(HF_PRIMARY_VM_ID);
	double result = a * b;
	dlog("VM count: %d\n", hf_vm_get_count());
	dlog("vCPU count: %d\n", hf_vcpu_get_count(HF_PRIMARY_VM_ID));
	dlog("result: %d\n", (int)result);
	EXPECT_TRUE(a == 1.0);
	EXPECT_TRUE(b == 8.0);
	EXPECT_TRUE(result == 8.0);
}
