/*
 * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include "cpu_errata_info.h"
#include <lib/cpus/cpu_ops.h>
#include <lib/cpus/errata.h>
#include <lib/smccc.h>
#include <lib/utils_def.h>
#include <services/errata_abi_svc.h>
#include <smccc_helpers.h>

/*
 * Global pointer that points to the specific
 * structure based on the MIDR part number
 */
struct em_cpu_list *cpu_ptr;

/* Structure array that holds CPU specific errata information */
struct em_cpu_list cpu_list[] = {
#if CORTEX_A78_H_INC
{
	.cpu_partnumber = CORTEX_A78_MIDR,
	.cpu_errata_list = {
		[0] = {2712571, 0x00, 0x12},
		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
	}
},
#endif /* CORTEX_A78_H_INC */

#if CORTEX_A78_AE_H_INC
{
	.cpu_partnumber = CORTEX_A78_AE_MIDR,
	.cpu_errata_list = {
		[0] = {2712574, 0x00, 0x02},
		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
	}
},
#endif /* CORTEX_A78_AE_H_INC */

#if CORTEX_A78C_H_INC
{
	.cpu_partnumber = CORTEX_A78C_MIDR,
	.cpu_errata_list = {
		[0] = {2712575, 0x01, 0x02},
		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
	}
},
#endif /* CORTEX_A78C_H_INC */

#if NEOVERSE_V1_H_INC
{
	.cpu_partnumber = NEOVERSE_V1_MIDR,
	.cpu_errata_list = {
		[0] = {2701953, 0x00, 0x11},
		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
	}
},
#endif /* NEOVERSE_V1_H_INC */

#if CORTEX_A710_H_INC
{
	.cpu_partnumber = CORTEX_A710_MIDR,
	.cpu_errata_list = {
		[0] = {2701952, 0x00, 0x21},
		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
	}
},
#endif /* CORTEX_A710_H_INC */

#if NEOVERSE_N2_H_INC
{
	.cpu_partnumber = NEOVERSE_N2_MIDR,
	.cpu_errata_list = {
		[0] = {2728475, 0x00, 0x02},
		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
	}
},
#endif /* NEOVERSE_N2_H_INC */

#if CORTEX_X2_H_INC
{
	.cpu_partnumber = CORTEX_X2_MIDR,
	.cpu_errata_list = {
		[0] = {2701952, 0x00, 0x21},
		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
	}
},
#endif /* CORTEX_X2_H_INC */

#if NEOVERSE_V2_H_INC
{
	.cpu_partnumber = NEOVERSE_V2_MIDR,
	.cpu_errata_list = {
		[0] = {2719103, 0x00, 0x01},
		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
	}
},
#endif /* NEOVERSE_V2_H_INC */

#if CORTEX_X3_H_INC
{
	.cpu_partnumber = CORTEX_X3_MIDR,
	.cpu_errata_list = {
		[0] = {2701951, 0x00, 0x11},
		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
	}
},
#endif /* CORTEX_X3_H_INC */

#if CORTEX_X4_H_INC
{
	.cpu_partnumber = CORTEX_X4_MIDR,
	.cpu_errata_list = {
		[0] = {2701112, 0x00, 0x00},
		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
	}
},
#endif /* CORTEX_X4_H_INC */

};

#if ERRATA_NON_ARM_INTERCONNECT

/* Check if the errata is enabled for non-arm interconnect */
static int32_t non_arm_interconnect_errata(uint32_t errata_id, long rev_var)
{
	int32_t ret_val = EM_UNKNOWN_ERRATUM;

	/* Determine the number of cpu listed in the cpu list */
	uint8_t size_cpulist = ARRAY_SIZE(cpu_list);

	/* Read the midr reg to extract cpu, revision and variant info */
	uint32_t midr_val = read_midr();

	for (uint8_t i = 0U; i < size_cpulist; i++) {
		cpu_ptr = &cpu_list[i];
		/*
		 * If the cpu partnumber in the cpu list, matches the midr
		 * part number, check to see if the errata ID matches
		 */
		if (EXTRACT_PARTNUM(midr_val) == EXTRACT_PARTNUM(cpu_ptr->cpu_partnumber)) {

			struct em_cpu *ptr = NULL;

			for (int j = 0; j < MAX_PLAT_CPU_ERRATA_ENTRIES; j++) {
				ptr = &cpu_ptr->cpu_errata_list[j];
				assert(ptr != NULL);
				if (errata_id == ptr->em_errata_id) {
					if (RXPX_RANGE(rev_var, ptr->em_rxpx_lo, ptr->em_rxpx_hi)) {
						ret_val = EM_AFFECTED;
						break;
					}
					ret_val = EM_NOT_AFFECTED;
					break;
				}
			}
			break;
		}
	}
	return ret_val;
}
#endif

/* Function to check if the errata exists for the specific CPU and rxpx */
int32_t verify_errata_implemented(uint32_t errata_id, uint32_t forward_flag)
{
	int32_t ret_val;
	struct cpu_ops *cpu_ops;
	struct erratum_entry *entry, *end;
	long rev_var;

	ret_val = EM_UNKNOWN_ERRATUM;
	rev_var = cpu_get_rev_var();

#if ERRATA_NON_ARM_INTERCONNECT
	ret_val = non_arm_interconnect_errata(errata_id, rev_var);
	if (ret_val != EM_UNKNOWN_ERRATUM) {
		return ret_val;
	}
#endif

	cpu_ops = get_cpu_ops_ptr();
	assert(cpu_ops != NULL);

	entry = cpu_ops->errata_list_start;
	assert(entry != NULL);

	end = cpu_ops->errata_list_end;
	assert(end != NULL);

	end--; /* point to the last erratum entry of the queried cpu */

	while ((entry <= end) && (ret_val == EM_UNKNOWN_ERRATUM)) {
		if (entry->id == errata_id) {
			if (entry->check_func(rev_var)) {
				if (entry->chosen)
					return EM_HIGHER_EL_MITIGATION;
				else
					return EM_AFFECTED;
			}
			return EM_NOT_AFFECTED;
		}
		entry += 1;
	}
	return ret_val;
}

/* Predicate indicating that a function id is part of EM_ABI */
bool is_errata_fid(uint32_t smc_fid)
{
	return ((smc_fid == ARM_EM_VERSION) ||
		(smc_fid == ARM_EM_FEATURES) ||
		(smc_fid == ARM_EM_CPU_ERRATUM_FEATURES));

}

bool validate_spsr_mode(void)
{
	/* In AArch64, if the caller is EL1, return true */

	#if __aarch64__
		if (GET_EL(read_spsr_el3()) == MODE_EL1) {
			return true;
		}
		return false;
	#else

	/* In AArch32, if in system/svc mode, return true */
		uint8_t read_el_state = GET_M32(read_spsr());

		if ((read_el_state == (MODE32_svc)) || (read_el_state == MODE32_sys)) {
			return true;
		}
		return false;
	#endif /* __aarch64__ */
}

uintptr_t errata_abi_smc_handler(uint32_t smc_fid, u_register_t x1,
				u_register_t x2, u_register_t x3, u_register_t x4,
				void *cookie, void *handle, u_register_t flags)
{
	int32_t ret_id = EM_UNKNOWN_ERRATUM;

	switch (smc_fid) {
	case ARM_EM_VERSION:
		SMC_RET1(handle, MAKE_SMCCC_VERSION(
			EM_VERSION_MAJOR, EM_VERSION_MINOR
		));
		break; /* unreachable */
	case ARM_EM_FEATURES:
		if (is_errata_fid((uint32_t)x1)) {
			SMC_RET1(handle, EM_SUCCESS);
		}

		SMC_RET1(handle, EM_NOT_SUPPORTED);
		break; /* unreachable */
	case ARM_EM_CPU_ERRATUM_FEATURES:

		/*
		 * If the forward flag is greater than zero and the calling EL
		 * is EL1 in AArch64 or in system mode or svc mode in case of AArch32,
		 * return Invalid Parameters.
		 */
		if (((uint32_t)x2 != 0) && (validate_spsr_mode())) {
			SMC_RET1(handle, EM_INVALID_PARAMETERS);
		}
		ret_id = verify_errata_implemented((uint32_t)x1, (uint32_t)x2);
		SMC_RET1(handle, ret_id);
		break; /* unreachable */
	default:
		{
		   WARN("Unimplemented Errata ABI Service Call: 0x%x\n", smc_fid);
		   SMC_RET1(handle, EM_UNKNOWN_ERRATUM);
		   break; /* unreachable */
		}
	}
}
