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

#include <assert.h>
#include <string.h>
#include <libfdt.h>

#include <platform_def.h>

#include <common/debug.h>
#include <common/desc_image_load.h>
#include <common/tbbr/tbbr_img_def.h>
#if TRUSTED_BOARD_BOOT
#include <drivers/auth/mbedtls/mbedtls_config.h>
#endif
#include <lib/fconf/fconf.h>
#include <lib/fconf/fconf_dyn_cfg_getter.h>
#include <lib/fconf/fconf_tbbr_getter.h>
#include <plat/arm/common/arm_dyn_cfg_helpers.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>

#if TRUSTED_BOARD_BOOT

static void *mbedtls_heap_addr;
static size_t mbedtls_heap_size;

/*
 * This function is the implementation of the shared Mbed TLS heap between
 * BL1 and BL2 for Arm platforms. The shared heap address is passed from BL1
 * to BL2 with a pointer. This pointer resides inside the TB_FW_CONFIG file
 * which is a DTB.
 *
 * This function is placed inside an #if directive for the below reasons:
 *   - To allocate space for the Mbed TLS heap --only if-- Trusted Board Boot
 *     is enabled.
 *   - This implementation requires the DTB to be present so that BL1 has a
 *     mechanism to pass the pointer to BL2.
 */
int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
{
	assert(heap_addr != NULL);
	assert(heap_size != NULL);

#if defined(IMAGE_BL1) || BL2_AT_EL3

	/* If in BL1 or BL2_AT_EL3 define a heap */
	static unsigned char heap[TF_MBEDTLS_HEAP_SIZE];

	*heap_addr = heap;
	*heap_size = sizeof(heap);
	mbedtls_heap_addr = heap;
	mbedtls_heap_size = sizeof(heap);

#elif defined(IMAGE_BL2)

	/* If in BL2, retrieve the already allocated heap's info from DTB */
	*heap_addr = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_addr);
	*heap_size = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_size);

#endif

	return 0;
}

/*
 * Puts the shared Mbed TLS heap information to the DTB.
 * Executed only from BL1.
 */
void arm_bl1_set_mbedtls_heap(void)
{
	int err;
	uintptr_t tb_fw_cfg_dtb;

	/*
	 * If tb_fw_cfg_dtb==NULL then DTB is not present for the current
	 * platform. As such, we don't attempt to write to the DTB at all.
	 *
	 * If mbedtls_heap_addr==NULL, then it means we are using the default
	 * heap implementation. As such, BL2 will have its own heap for sure
	 * and hence there is no need to pass any information to the DTB.
	 *
	 * In the latter case, if we still wanted to write in the DTB the heap
	 * information, we would need to call plat_get_mbedtls_heap to retrieve
	 * the default heap's address and size.
	 */

	/* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB*/
	tb_fw_cfg_dtb = FCONF_GET_PROPERTY(fconf, dtb, base_addr);

	if ((tb_fw_cfg_dtb != 0UL) && (mbedtls_heap_addr != NULL)) {
		/* As libfdt use void *, we can't avoid this cast */
		void *dtb = (void *)tb_fw_cfg_dtb;

		err = arm_set_dtb_mbedtls_heap_info(dtb,
			mbedtls_heap_addr, mbedtls_heap_size);
		if (err < 0) {
			ERROR("BL1: unable to write shared Mbed TLS heap information to DTB\n");
			panic();
		}
		/*
		 * Ensure that the info written to the DTB is visible to other
		 * images. It's critical because BL2 won't be able to proceed
		 * without the heap info.
		 */
		flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize(dtb));
	}
}

#endif /* TRUSTED_BOARD_BOOT */

/*
 * BL2 utility function to initialize dynamic configuration specified by
 * TB_FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if
 * specified in TB_FW_CONFIG.
 */
void arm_bl2_dyn_cfg_init(void)
{
	unsigned int i;
	bl_mem_params_node_t *cfg_mem_params = NULL;
	uintptr_t image_base;
	size_t image_size;
	const unsigned int config_ids[] = {
			HW_CONFIG_ID,
			SOC_FW_CONFIG_ID,
			NT_FW_CONFIG_ID,
#ifdef SPD_tspd
			/* Currently tos_fw_config is only present for TSP */
			TOS_FW_CONFIG_ID
#endif
	};

	const struct dyn_cfg_dtb_info_t *dtb_info;

	/* Iterate through all the fw config IDs */
	for (i = 0; i < ARRAY_SIZE(config_ids); i++) {
		/* Get the config load address and size from TB_FW_CONFIG */
		cfg_mem_params = get_bl_mem_params_node(config_ids[i]);
		if (cfg_mem_params == NULL) {
			VERBOSE("Couldn't find HW_CONFIG in bl_mem_params_node\n");
			continue;
		}

		dtb_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, config_ids[i]);
		if (dtb_info == NULL) {
			VERBOSE("Couldn't find config_id %d load info in TB_FW_CONFIG\n",
					config_ids[i]);
			continue;
		}

		image_base = dtb_info->config_addr;
		image_size = dtb_info->config_max_size;

		/*
		 * Do some runtime checks on the load addresses of soc_fw_config,
		 * tos_fw_config, nt_fw_config. This is not a comprehensive check
		 * of all invalid addresses but to prevent trivial porting errors.
		 */
		if (config_ids[i] != HW_CONFIG_ID) {

			if (check_uptr_overflow(image_base, image_size))
				continue;

#ifdef	BL31_BASE
			/* Ensure the configs don't overlap with BL31 */
			if ((image_base >= BL31_BASE) &&
			    (image_base <= BL31_LIMIT))
				continue;
#endif
			/* Ensure the configs are loaded in a valid address */
			if (image_base < ARM_BL_RAM_BASE)
				continue;
#ifdef BL32_BASE
			/*
			 * If BL32 is present, ensure that the configs don't
			 * overlap with it.
			 */
			if ((image_base >= BL32_BASE) &&
			    (image_base <= BL32_LIMIT))
				continue;
#endif
		}


		cfg_mem_params->image_info.image_base = image_base;
		cfg_mem_params->image_info.image_max_size = (uint32_t)image_size;

		/*
		 * Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from
		 * HW_CONFIG or FW_CONFIG nodes
		 */
		cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
	}
}
