/*
 * Copyright (c) 2014-2020, Arm Limited and Contributors. All rights reserved.
 * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <inttypes.h>
#include <stdint.h>

#include <arch_helpers.h>
#include <common/debug.h>
#include <plat_startup.h>


/*
 * TFAHandoffParams
 * Parameter		bitfield	encoding
 * -----------------------------------------------------------------------------
 * Exec State		0		0 -> Aarch64, 1-> Aarch32
 * endianness		1		0 -> LE, 1 -> BE
 * secure (TZ)		2		0 -> Non secure, 1 -> secure
 * EL			3:4		00 -> EL0, 01 -> EL1, 10 -> EL2, 11 -> EL3
 * CPU#			5:6		00 -> A53_0, 01 -> A53_1, 10 -> A53_2, 11 -> A53_3
 */

#define FSBL_FLAGS_ESTATE_SHIFT		0U
#define FSBL_FLAGS_ESTATE_MASK		(1U << FSBL_FLAGS_ESTATE_SHIFT)
#define FSBL_FLAGS_ESTATE_A64		0U
#define FSBL_FLAGS_ESTATE_A32		1U

#define FSBL_FLAGS_ENDIAN_SHIFT		1U
#define FSBL_FLAGS_ENDIAN_MASK		(1U << FSBL_FLAGS_ENDIAN_SHIFT)
#define FSBL_FLAGS_ENDIAN_LE		0U
#define FSBL_FLAGS_ENDIAN_BE		1U

#define FSBL_FLAGS_TZ_SHIFT		2U
#define FSBL_FLAGS_TZ_MASK		(1U << FSBL_FLAGS_TZ_SHIFT)
#define FSBL_FLAGS_NON_SECURE		0U
#define FSBL_FLAGS_SECURE		1U

#define FSBL_FLAGS_EL_SHIFT		3U
#define FSBL_FLAGS_EL_MASK		(3U << FSBL_FLAGS_EL_SHIFT)
#define FSBL_FLAGS_EL0			0U
#define FSBL_FLAGS_EL1			1U
#define FSBL_FLAGS_EL2			2U
#define FSBL_FLAGS_EL3			3U

#define FSBL_FLAGS_CPU_SHIFT		5U
#define FSBL_FLAGS_CPU_MASK		(3U << FSBL_FLAGS_CPU_SHIFT)
#define FSBL_FLAGS_A53_0		0U
#define FSBL_FLAGS_A53_1		1U
#define FSBL_FLAGS_A53_2		2U
#define FSBL_FLAGS_A53_3		3U

/**
 * get_fsbl_cpu() - Get the target CPU for partition.
 * @partition: Pointer to partition struct.
 *
 * Return: FSBL_FLAGS_A53_0, FSBL_FLAGS_A53_1, FSBL_FLAGS_A53_2 or
 *         FSBL_FLAGS_A53_3.
 *
 */
static int32_t get_fsbl_cpu(const struct xfsbl_partition *partition)
{
	uint64_t flags = partition->flags & FSBL_FLAGS_CPU_MASK;

	return flags >> FSBL_FLAGS_CPU_SHIFT;
}

/**
 * get_fsbl_el() - Get the target exception level for partition.
 * @partition: Pointer to partition struct.
 *
 * Return: FSBL_FLAGS_EL0, FSBL_FLAGS_EL1, FSBL_FLAGS_EL2 or FSBL_FLAGS_EL3.
 *
 */
static int32_t get_fsbl_el(const struct xfsbl_partition *partition)
{
	uint64_t flags = partition->flags & FSBL_FLAGS_EL_MASK;

	return flags >> FSBL_FLAGS_EL_SHIFT;
}

/**
 * get_fsbl_ss() - Get the target security state for partition.
 * @partition: Pointer to partition struct.
 *
 * Return: FSBL_FLAGS_NON_SECURE or FSBL_FLAGS_SECURE.
 *
 */
static int32_t get_fsbl_ss(const struct xfsbl_partition *partition)
{
	uint64_t flags = partition->flags & FSBL_FLAGS_TZ_MASK;

	return flags >> FSBL_FLAGS_TZ_SHIFT;
}

/**
 * get_fsbl_endian() - Get the target endianness for partition.
 * @partition: Pointer to partition struct.
 *
 * Return: SPSR_E_LITTLE or SPSR_E_BIG.
 *
 */
static int32_t get_fsbl_endian(const struct xfsbl_partition *partition)
{
	uint64_t flags = partition->flags & FSBL_FLAGS_ENDIAN_MASK;

	flags >>= FSBL_FLAGS_ENDIAN_SHIFT;

	if (flags == FSBL_FLAGS_ENDIAN_BE) {
		return SPSR_E_BIG;
	} else {
		return SPSR_E_LITTLE;
	}
}

/**
 * get_fsbl_estate() - Get the target execution state for partition.
 * @partition: Pointer to partition struct.
 *
 * Return: FSBL_FLAGS_ESTATE_A32 or FSBL_FLAGS_ESTATE_A64.
 *
 */
static int32_t get_fsbl_estate(const struct xfsbl_partition *partition)
{
	uint64_t flags = partition->flags & FSBL_FLAGS_ESTATE_MASK;

	return flags >> FSBL_FLAGS_ESTATE_SHIFT;
}

/**
 * fsbl_tfa_handover() - Populates the bl32 and bl33 image info structures.
 * @bl32: BL32 image info structure.
 * @bl33: BL33 image info structure.
 * @tfa_handoff_addr: TF-A handoff address.
 *
 * Process the handoff parameters from the FSBL and populate the BL32 and BL33
 * image info structures accordingly.
 *
 * Return: Return the status of the handoff. The value will be from the
 *         fsbl_handoff enum.
 *
 */
enum fsbl_handoff fsbl_tfa_handover(entry_point_info_t *bl32,
					entry_point_info_t *bl33,
					uint64_t tfa_handoff_addr)
{
	const struct xfsbl_tfa_handoff_params *TFAHandoffParams;
	if (!tfa_handoff_addr) {
		WARN("BL31: No TFA handoff structure passed\n");
		return FSBL_HANDOFF_NO_STRUCT;
	}

	TFAHandoffParams = (struct xfsbl_tfa_handoff_params *)tfa_handoff_addr;
	if ((TFAHandoffParams->magic[0] != 'X') ||
	    (TFAHandoffParams->magic[1] != 'L') ||
	    (TFAHandoffParams->magic[2] != 'N') ||
	    (TFAHandoffParams->magic[3] != 'X')) {
		ERROR("BL31: invalid TF-A handoff structure at %" PRIx64 "\n",
		      tfa_handoff_addr);
		return FSBL_HANDOFF_INVAL_STRUCT;
	}

	VERBOSE("BL31: TF-A handoff params at:0x%" PRIx64 ", entries:%u\n",
		tfa_handoff_addr, TFAHandoffParams->num_entries);
	if (TFAHandoffParams->num_entries > FSBL_MAX_PARTITIONS) {
		ERROR("BL31: TF-A handoff params: too many partitions (%u/%u)\n",
		      TFAHandoffParams->num_entries, FSBL_MAX_PARTITIONS);
		return FSBL_HANDOFF_TOO_MANY_PARTS;
	}

	/*
	 * we loop over all passed entries but only populate two image structs
	 * (bl32, bl33). I.e. the last applicable images in the handoff
	 * structure will be used for the hand off
	 */
	for (size_t i = 0; i < TFAHandoffParams->num_entries; i++) {
		entry_point_info_t *image;
		int32_t target_estate, target_secure, target_cpu;
		uint32_t target_endianness, target_el;

		VERBOSE("BL31: %zd: entry:0x%" PRIx64 ", flags:0x%" PRIx64 "\n", i,
			TFAHandoffParams->partition[i].entry_point,
			TFAHandoffParams->partition[i].flags);

		target_cpu = get_fsbl_cpu(&TFAHandoffParams->partition[i]);
		if (target_cpu != FSBL_FLAGS_A53_0) {
			WARN("BL31: invalid target CPU (%i)\n", target_cpu);
			continue;
		}

		target_el = get_fsbl_el(&TFAHandoffParams->partition[i]);
		if ((target_el == FSBL_FLAGS_EL3) ||
		    (target_el == FSBL_FLAGS_EL0)) {
			WARN("BL31: invalid exception level (%i)\n", target_el);
			continue;
		}

		target_secure = get_fsbl_ss(&TFAHandoffParams->partition[i]);
		if (target_secure == FSBL_FLAGS_SECURE &&
		    target_el == FSBL_FLAGS_EL2) {
			WARN("BL31: invalid security state (%i) for exception level (%i)\n",
			     target_secure, target_el);
			continue;
		}

		target_estate = get_fsbl_estate(&TFAHandoffParams->partition[i]);
		target_endianness = get_fsbl_endian(&TFAHandoffParams->partition[i]);

		if (target_secure == FSBL_FLAGS_SECURE) {
			image = bl32;

			if (target_estate == FSBL_FLAGS_ESTATE_A32) {
				bl32->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
							 target_endianness,
							 DISABLE_ALL_EXCEPTIONS);
			} else {
				bl32->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
						     DISABLE_ALL_EXCEPTIONS);
			}
		} else {
			image = bl33;

			if (target_estate == FSBL_FLAGS_ESTATE_A32) {
				if (target_el == FSBL_FLAGS_EL2) {
					target_el = MODE32_hyp;
				} else {
					target_el = MODE32_sys;
				}

				bl33->spsr = SPSR_MODE32(target_el, SPSR_T_ARM,
							 target_endianness,
							 DISABLE_ALL_EXCEPTIONS);
			} else {
				if (target_el == FSBL_FLAGS_EL2) {
					target_el = MODE_EL2;
				} else {
					target_el = MODE_EL1;
				}

				bl33->spsr = SPSR_64(target_el, MODE_SP_ELX,
						     DISABLE_ALL_EXCEPTIONS);
			}
		}

		VERBOSE("Setting up %s entry point to:%" PRIx64 ", el:%x\n",
			target_secure == FSBL_FLAGS_SECURE ? "BL32" : "BL33",
			TFAHandoffParams->partition[i].entry_point,
			target_el);
		image->pc = TFAHandoffParams->partition[i].entry_point;

		if (target_endianness == SPSR_E_BIG) {
			EP_SET_EE(image->h.attr, EP_EE_BIG);
		} else {
			EP_SET_EE(image->h.attr, EP_EE_LITTLE);
		}
	}

	return FSBL_HANDOFF_SUCCESS;
}
