// Copyright Microsoft and CHERIoT Contributors.
// SPDX-License-Identifier: MIT

#include "tests.hh"
#include <compartment.h>
#include <simulator.h>

using namespace CHERI;

namespace
{
	/**
	 * Read the cycle counter.
	 */
	int rdcycle()
	{
		int cycles;
#ifdef SAIL
		// On Sail, report the number of instructions, the cycle count is
		// meaningless.
		__asm__ volatile("csrr %0, minstret" : "=r"(cycles));
#elifdef IBEX
		__asm__ volatile("csrr %0, mcycle" : "=r"(cycles));
#else
		__asm__ volatile("rdcycle %0" : "=r"(cycles));
#endif
		return cycles;
	}
	/**
	 * Call `fn` and log a message informing the user how long it took.
	 */
	void run_timed(const char *msg, auto &&fn)
	{
		int startCycles = rdcycle();
		fn();
		int cycles = rdcycle();
		debug_log("{} finished in {} cycles", msg, cycles - startCycles);
	}
} // namespace

/// Have we detected a crash in any of the compartments?
volatile bool crashDetected = false;

extern "C" enum ErrorRecoveryBehaviour
compartment_error_handler(struct ErrorState *frame, size_t mcause, size_t mtval)
{
	if (mcause == 0x2)
	{
		debug_log("Test failure in test runner");
#ifdef SIMULATION
		simulation_exit(1);
#endif
		return ErrorRecoveryBehaviour::ForceUnwind;
	}
	debug_log("mcause: {}, pcc: {}", mcause, frame->pcc);
	auto [reg, cause] = CHERI::extract_cheri_mtval(mtval);
	debug_log("Error {} in register {}", reg, cause);
	debug_log("Current test crashed");
	crashDetected = true;
	return ErrorRecoveryBehaviour::InstallContext;
}

/**
 * Test suite entry point.  Runs all of the tests that we have defined.
 */
void __cheri_compartment("test_runner") run_tests()
{
	// magic_enum is a pretty powerful stress-test of various bits of linkage.
	// In generating `enum_values`, it generates constant strings and pointers
	// to them in COMDAT sections.  These require merging across compilation
	// units during our first link stage and then require cap relocs so that
	// they are all correctly bounded.  This works as a good smoke test of our
	// linker script.
	debug_log("Checking that rel-ro caprelocs work.  This will crash if they "
	          "don't.  CHERI Permissions are:");
	for (auto &permission : magic_enum::enum_values<CHERI::Permission>())
	{
		debug_log("{}", permission);
	}

	/*
	 * Add a test to check the PermissionSet Iterator. We swap the permissions
	 * order to match it to the order the Iterator implements: the Iterator
	 * returns then in value order, and not insertion order.
	 */
	static constexpr PermissionSet Permissions{
	  Permission::Load, Permission::Store, Permission::LoadStoreCapability};
	static Permission permissionArray[] = {
	  Permission::Store, Permission::Load, Permission::LoadStoreCapability};
	size_t index = 0;
	for (auto permission : Permissions)
	{
		TEST(permission == permissionArray[index++],
		     "Iterator of PermissionSet failed");
	}
	// These need to be checked visually
	debug_log("Trying to print 8-bit integer: {}", uint8_t(0x12));
	debug_log("Trying to print unsigned 8-bit integer: {}", int8_t(34));
	debug_log("Trying to print char: {}", 'c');
	debug_log("Trying to print 32-bit integer: {}", 12345);
	debug_log("Trying to print 64-bit integer: {}", 123456789012345LL);
	debug_log("Trying to print unsigned 32-bit integer: {}", 0x12345U);
	debug_log("Trying to print unsigned 64-bit integer: {}",
	          0x123456789012345ULL);
	const char *testString = "Hello, world! with some trailing characters";
	// Make sure that we don't print the trailing characters
	debug_log("Trying to print string: {}", std::string_view{testString, 13});

	run_timed("All tests", []() {
		run_timed("Debug helpers (C++)", test_debug_cxx);
		run_timed("Debug helpers (C)", test_debug_c);
		run_timed("MMIO", test_mmio);
		run_timed("stdio", test_stdio);
		run_timed("Static sealing", test_static_sealing);
		run_timed("Crash recovery", test_crash_recovery);
		run_timed("Compartment calls", test_compartment_call);
		run_timed("check_pointer", test_check_pointer);
		run_timed("Misc APIs", test_misc);
		run_timed("Stacks exhaustion in the switcher", test_stack);
		run_timed("Thread pool", test_thread_pool);
		run_timed("Global Constructors", test_global_constructors);
		run_timed("Queue", test_queue);
		run_timed("Futex", test_futex);
		run_timed("Locks", test_locks);
		run_timed("Event groups", test_eventgroup);
		run_timed("Multiwaiter", test_multiwaiter);
		run_timed("Allocator", test_allocator);
	});

	TEST(crashDetected == false, "One or more tests failed");

	// Exit the simulator if we are running in simulation.
#ifdef SIMULATION
	simulation_exit();
#endif
	// Infinite loop if we're not in simulation.
	while (true)
	{
		yield();
	}
}
