/*
 * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef __TFTF_LIB_H__
#define __TFTF_LIB_H__

#ifndef __ASSEMBLY__

#include <arch.h>
#include <arch_helpers.h>
#include <stdbool.h>
#include <stdint.h>

/*
 * Possible error codes for signaling the result of a test
 * TEST_RESULT_MIN and TEST_RESULT_MAX are only used as bounds in the enum.
 */
typedef enum {
	/*
	 * NA = Not applicable.
	 * Initial value for a test result.
	 * Used for CPUs that don't participate in the test.
	 */
	TEST_RESULT_NA		= -1,

	TEST_RESULT_MIN		= 0,
	TEST_RESULT_SKIPPED	= TEST_RESULT_MIN,
	TEST_RESULT_SUCCESS,
	TEST_RESULT_FAIL,
	TEST_RESULT_CRASHED,

	TEST_RESULT_MAX
} test_result_t;

#define TEST_RESULT_IS_VALID(result) \
	((result >= TEST_RESULT_MIN) && (result < TEST_RESULT_MAX))

/*
 * PSCI Function Wrappers
 *
 * SMC calls to PSCI functions
 */
int32_t tftf_psci_cpu_on(u_register_t target_cpu,
			 uintptr_t entry_point_address,
			 u_register_t context_id);
int32_t tftf_psci_cpu_off(void);
int32_t tftf_psci_affinity_info(u_register_t target_affinity,
				uint32_t lowest_affinity_level);
int32_t tftf_psci_node_hw_state(u_register_t target_cpu, uint32_t power_level);
int32_t tftf_get_psci_feature_info(uint32_t psci_func_id);
u_register_t tftf_psci_stat_count(u_register_t target_cpu,
		uint32_t power_state);
u_register_t tftf_psci_stat_residency(u_register_t target_cpu,
		uint32_t power_state);

/*
 * PSCI Helper functions
 */

/*
 * Gets the context ID used when calling tftf_psci_cpu_on().
 */
u_register_t tftf_get_cpu_on_ctx_id(unsigned int core_pos);

/*
 * Sets the context ID used when calling tftf_psci_cpu_on().
 */
void tftf_set_cpu_on_ctx_id(unsigned int core_pos, u_register_t context_id);

/*
 * Gets the PSCI version of Trusted Firmware-A. The version number returned
 * is a 32-bit unsigned integer, with the upper 16 bits denoting the major
 * revision, and the lower 16 bits denoting the minor revision.
 */
unsigned int tftf_get_psci_version(void);

/*
 * Returns 0 if version is not a valid PSCI version supported by TFTF.
 * Otherwise it returns a value different of 0.
 */
int tftf_is_valid_psci_version(unsigned int version);


/*
 * The function constructs a composite state_id up-to the specified
 * affinity level querying the relevant state property from the platform.
 * It chooses the first matching state property from the array returned
 * by platform. In case the requested affinity level is not supported by
 * the platform, then this function uses DUMMY_STATE_ID as the local state
 * for that level. This allows the tests to construct composite state-id
 * for invalid affinity levels as well. It returns the expected return
 * value from CPU SUSPEND call.
 */
int tftf_psci_make_composite_state_id(uint32_t affinity_level,
		uint32_t state_type, uint32_t *state_id);

/*
 * This function composes the power state parameter in the right format
 * needed by PSCI. The detection of the power state format is done during
 * cold boot by tftf_detect_psci_pstate_format() function.
 */
uint32_t tftf_make_psci_pstate(uint32_t affinity_level,
					uint32_t state_type,
					uint32_t state_id);

/*
 * Returns 1, if the EL3 software supports PSCI's original format state ID as
 * NULL else returns zero
 */
unsigned int tftf_is_psci_state_id_null(void);

/*
 * Returns 1, if the EL3 software supports PSCI's original state format else
 * returns zero
 */
unsigned int tftf_is_psci_pstate_format_original(void);

/* Functions to wait for a specified number of ms or us */
void waitms(uint64_t ms);
void waitus(uint64_t us);

/*
 * SMC calls take a function identifier and up to 7 arguments.
 * Additionally, few SMC calls that originate from EL2 leverage the seventh
 * argument explicitly. Given that TFTF runs in EL2, we need to be able to
 * specify it.
 */
typedef struct {
	/* Function identifier. Identifies which function is being invoked. */
	uint32_t	fid;

	u_register_t	arg1;
	u_register_t	arg2;
	u_register_t	arg3;
	u_register_t	arg4;
	u_register_t	arg5;
	u_register_t	arg6;
	u_register_t	arg7;
} smc_args;

/* SMC calls can return up to 8 register values */
typedef struct {
	u_register_t	ret0;
	u_register_t	ret1;
	u_register_t	ret2;
	u_register_t	ret3;
	u_register_t	ret4;
	u_register_t	ret5;
	u_register_t	ret6;
	u_register_t	ret7;
} smc_ret_values;

/*
 * Trigger an SMC call.
 */
smc_ret_values tftf_smc(const smc_args *args);

/*
 * Trigger an HVC call.
 */
typedef smc_args hvc_args;

typedef smc_ret_values hvc_ret_values;

hvc_ret_values tftf_hvc(const hvc_args *args);

/*
 * Write a formatted string in the test output buffer.
 * Just like the standard libc's printf() function, the string produced is under
 * the control of a format string that specifies how subsequent arguments are
 * converted.
 *
 * The string will appear in the test report.
 * Use mp_printf() instead for volatile debug messages that are not meant to be
 * stored into the test report.
 * Note: The test output buffer referred here is a temporary buffer stored in
 * RAM. This function doesn't write anything into NVM.
 *
 * Upon successful return, return the number of characters printed (not
 * including the final '\0' character). If an output error is encountered,
 * a negative value is returned. If the function is not able to print any
 * character at all, this is considered as an output error. Note that a partial
 * write (i.e. when the string is truncated) is not considered as an output
 * error.
 */
__attribute__((format(printf, 1, 2)))
int tftf_testcase_printf(const char *format, ...);

/*
 * This function is meant to be used by tests.
 * It tells the framework that the test is going to reset the platform.
 *
 * It the test omits to call this function before resetting, the framework will
 * consider the test has crashed upon resumption.
 */
void tftf_notify_reboot(void);

/*
 * Returns 0 if the test function is executed for the first time,
 *      or 1 if the test rebooted the platform and the test function is being
 *         executed again.
 * This function is used for tests that reboot the platform, so that they can
 * execute different code paths on 1st execution and subsequent executions.
 */
unsigned int tftf_is_rebooted(void);

static inline unsigned int make_mpid(unsigned int clusterid,
#if FVP_MAX_PE_PER_CPU > 1
				     unsigned int coreid,
				     unsigned int threadid)
#else
				     unsigned int coreid)
#endif
{
	/*
	 * If MT bit is set then need to shift the affinities and also set the
	 * MT bit.
	 */
	if ((read_mpidr_el1() & MPIDR_MT_MASK) != 0)
		return MPIDR_MT_MASK |
#if FVP_MAX_PE_PER_CPU > 1
			((threadid & MPIDR_AFFLVL_MASK) << MPIDR_AFF0_SHIFT) |
#endif
			((coreid & MPIDR_AFFLVL_MASK) << MPIDR_AFF1_SHIFT)   |
			((clusterid & MPIDR_AFFLVL_MASK) << MPIDR_AFF2_SHIFT);
	else
		return ((coreid & MPIDR_AFFLVL_MASK) << MPIDR_AFF0_SHIFT) |
		       ((clusterid & MPIDR_AFFLVL_MASK) << MPIDR_AFF1_SHIFT);

}

#endif /* __ASSEMBLY__ */
#endif /* __TFTF_LIB_H__ */
