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

#include <stdint.h>

#include <common/tbbr/tbbr_img_def.h>
#include <drivers/measured_boot/event_log/event_log.h>
#if defined(ARM_COT_cca)
#include <tools_share/cca_oid.h>
#else
#include <tools_share/tbbr_oid.h>
#endif /* ARM_COT_cca */
#include <fvp_critical_data.h>

#include <plat/arm/common/plat_arm.h>
#include <plat/common/common_def.h>

#if defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd)
CASSERT(ARM_EVENT_LOG_DRAM1_SIZE >= PLAT_ARM_EVENT_LOG_MAX_SIZE, \
	assert_res_eventlog_mem_insufficient);
#endif /* defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd) */

/* Event Log data */
static uint64_t event_log_base;

/* FVP table with platform specific image IDs, names and PCRs */
const event_log_metadata_t fvp_event_log_metadata[] = {
	{ BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 },
	{ BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 },
	{ BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 },
	{ BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 },
	{ BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 },
	{ HW_CONFIG_ID, EVLOG_HW_CONFIG_STRING, PCR_0 },
	{ NT_FW_CONFIG_ID, EVLOG_NT_FW_CONFIG_STRING, PCR_0 },
	{ SCP_BL2_IMAGE_ID, EVLOG_SCP_BL2_STRING, PCR_0 },
	{ SOC_FW_CONFIG_ID, EVLOG_SOC_FW_CONFIG_STRING, PCR_0 },
	{ TOS_FW_CONFIG_ID, EVLOG_TOS_FW_CONFIG_STRING, PCR_0 },
	{ RMM_IMAGE_ID, EVLOG_RMM_STRING, PCR_0},

#if defined(SPD_spmd)
	{ SP_PKG1_ID, EVLOG_SP1_STRING, PCR_0 },
	{ SP_PKG2_ID, EVLOG_SP2_STRING, PCR_0 },
	{ SP_PKG3_ID, EVLOG_SP3_STRING, PCR_0 },
	{ SP_PKG4_ID, EVLOG_SP4_STRING, PCR_0 },
	{ SP_PKG5_ID, EVLOG_SP5_STRING, PCR_0 },
	{ SP_PKG6_ID, EVLOG_SP6_STRING, PCR_0 },
	{ SP_PKG7_ID, EVLOG_SP7_STRING, PCR_0 },
	{ SP_PKG8_ID, EVLOG_SP8_STRING, PCR_0 },
#endif

	{ CRITICAL_DATA_ID, EVLOG_CRITICAL_DATA_STRING, PCR_1 },

	{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) }	/* Terminator */
};

void bl2_plat_mboot_init(void)
{
	uint8_t *event_log_start;
	uint8_t *event_log_finish;
	size_t bl1_event_log_size;
	size_t event_log_max_size;
	int rc;

	rc = arm_get_tb_fw_info(&event_log_base, &bl1_event_log_size,
				&event_log_max_size);
	if (rc != 0) {
		ERROR("%s(): Unable to get Event Log info from TB_FW_CONFIG\n",
		      __func__);
		/*
		 * It is a fatal error because on FVP platform, BL2 software
		 * assumes that a valid Event Log buffer exist and it will use
		 * same Event Log buffer to append image measurements.
		 */
		panic();
	}

	/*
	 * BL1 and BL2 share the same Event Log buffer and that BL2 will
	 * append its measurements after BL1's
	 */
	event_log_start = (uint8_t *)((uintptr_t)event_log_base +
				      bl1_event_log_size);
	event_log_finish = (uint8_t *)((uintptr_t)event_log_base +
				       event_log_max_size);

	event_log_init((uint8_t *)event_log_start, event_log_finish);
}

int plat_mboot_measure_critical_data(unsigned int critical_data_id,
				     const void *base, size_t size)
{
	/*
	 * It is very unlikely that the critical data size would be
	 * bigger than 2^32 bytes
	 */
	assert(size < UINT32_MAX);
	assert(base != NULL);

	/* Calculate image hash and record data in Event Log */
	int err = event_log_measure_and_record((uintptr_t)base, (uint32_t)size,
					       critical_data_id,
					       fvp_event_log_metadata);
	if (err != 0) {
		ERROR("%s%s critical data (%i)\n",
		      "Failed to ", "record",  err);
		return err;
	}

	return 0;
}

#if TRUSTED_BOARD_BOOT
static int fvp_populate_critical_data(struct fvp_critical_data *critical_data)
{
	char *nv_ctr_oids[MAX_NV_CTR_IDS] = {
		[TRUSTED_NV_CTR_ID] = TRUSTED_FW_NVCOUNTER_OID,
		[NON_TRUSTED_NV_CTR_ID] = NON_TRUSTED_FW_NVCOUNTER_OID,
	};

	for (int i = 0; i < MAX_NV_CTR_IDS; i++) {
		int rc = plat_get_nv_ctr(nv_ctr_oids[i],
					 &critical_data->nv_ctr[i]);
		if (rc != 0) {
			return rc;
		}
	}

	return 0;
}
#endif /* TRUSTED_BOARD_BOOT */

static int fvp_populate_and_measure_critical_data(void)
{
	int rc = 0;

/*
 * FVP platform only measures 'platform NV-counter' and hence its
 * measurement makes sense during Trusted-Boot flow only.
 */
#if TRUSTED_BOARD_BOOT
	struct fvp_critical_data populate_critical_data;

	rc = fvp_populate_critical_data(&populate_critical_data);
	if (rc == 0) {
		rc = plat_mboot_measure_critical_data(CRITICAL_DATA_ID,
						&populate_critical_data,
						sizeof(populate_critical_data));
	}
#endif /* TRUSTED_BOARD_BOOT */

	return rc;
}

void bl2_plat_mboot_finish(void)
{
	int rc;

	/* Event Log address in Non-Secure memory */
	uintptr_t ns_log_addr;

	/* Event Log filled size */
	size_t event_log_cur_size;

	rc = fvp_populate_and_measure_critical_data();
	if (rc != 0) {
		panic();
	}

	event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base);

#if defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd)
	/* Copy Event Log to TZC secured DRAM memory */
	(void)memcpy((void *)ARM_EVENT_LOG_DRAM1_BASE,
		     (const void *)event_log_base,
		     event_log_cur_size);

	/* Ensure that the Event Log is visible in TZC secured DRAM memory */
	flush_dcache_range(ARM_EVENT_LOG_DRAM1_BASE, event_log_cur_size);
#endif /* defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd) */

	rc = arm_set_nt_fw_info(
#ifdef SPD_opteed
			    (uintptr_t)ARM_EVENT_LOG_DRAM1_BASE,
#endif
			    event_log_cur_size, &ns_log_addr);
	if (rc != 0) {
		ERROR("%s(): Unable to update %s_FW_CONFIG\n",
		      __func__, "NT");
		/*
		 * It is a fatal error because on FVP secure world software
		 * assumes that a valid event log exists and will use it to
		 * record the measurements into the fTPM.
		 * Note: In FVP platform, OP-TEE uses nt_fw_config to get the
		 * secure Event Log buffer address.
		 */
		panic();
	}

	/* Copy Event Log to Non-secure memory */
	(void)memcpy((void *)ns_log_addr, (const void *)event_log_base,
		     event_log_cur_size);

	/* Ensure that the Event Log is visible in Non-secure memory */
	flush_dcache_range(ns_log_addr, event_log_cur_size);

#if defined(SPD_tspd) || defined(SPD_spmd)
	/* Set Event Log data in TOS_FW_CONFIG */
	rc = arm_set_tos_fw_info((uintptr_t)ARM_EVENT_LOG_DRAM1_BASE,
				 event_log_cur_size);
	if (rc != 0) {
		ERROR("%s(): Unable to update %s_FW_CONFIG\n",
		      __func__, "TOS");
		panic();
	}
#endif /* defined(SPD_tspd) || defined(SPD_spmd) */

	dump_event_log((uint8_t *)event_log_base, event_log_cur_size);
}
