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

#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <libfdt.h>
#include <stdint.h>
#include <string.h>

#include <common/bl_common.h>
#include <common/debug.h>
#include <common/fdt_wrappers.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <platform_def.h>
#include <services/spm_core_manifest.h>

#define ATTRIBUTE_ROOT_NODE_STR "attribute"

/*******************************************************************************
 * SPMC attribute node parser
 ******************************************************************************/
static int manifest_parse_attribute(spmc_manifest_attribute_t *attr,
				    const void *fdt,
				    int node)
{
	uint32_t val32;
	int rc;

	assert((attr != NULL) && (fdt != NULL));

	rc = fdt_read_uint32(fdt, node, "maj_ver", &attr->major_version);
	if (rc != 0) {
		ERROR("Missing FFA %s version in SPM Core manifest.\n",
			"major");
		return rc;
	}

	rc = fdt_read_uint32(fdt, node, "min_ver", &attr->minor_version);
	if (rc != 0) {
		ERROR("Missing FFA %s version in SPM Core manifest.\n",
			"minor");
		return rc;
	}

	rc = fdt_read_uint32(fdt, node, "spmc_id", &val32);
	if (rc != 0) {
		ERROR("Missing SPMC ID in manifest.\n");
		return rc;
	}

	attr->spmc_id = val32 & 0xffff;

	rc = fdt_read_uint32(fdt, node, "exec_state", &attr->exec_state);
	if (rc != 0) {
		NOTICE("%s not specified in SPM Core manifest.\n",
			"Execution state");
	}

	rc = fdt_read_uint32(fdt, node, "binary_size", &attr->binary_size);
	if (rc != 0) {
		NOTICE("%s not specified in SPM Core manifest.\n",
			"Binary size");
	}

	rc = fdt_read_uint64(fdt, node, "load_address", &attr->load_address);
	if (rc != 0) {
		NOTICE("%s not specified in SPM Core manifest.\n",
			"Load address");
	}

	rc = fdt_read_uint64(fdt, node, "entrypoint", &attr->entrypoint);
	if (rc != 0) {
		NOTICE("%s not specified in SPM Core manifest.\n",
			"Entry point");
	}

	VERBOSE("SPM Core manifest attribute section:\n");
	VERBOSE("  version: %u.%u\n", attr->major_version, attr->minor_version);
	VERBOSE("  spmc_id: 0x%x\n", attr->spmc_id);
	VERBOSE("  binary_size: 0x%x\n", attr->binary_size);
	VERBOSE("  load_address: 0x%" PRIx64 "\n", attr->load_address);
	VERBOSE("  entrypoint: 0x%" PRIx64 "\n", attr->entrypoint);

	return 0;
}

/*******************************************************************************
 * Root node handler
 ******************************************************************************/
static int manifest_parse_root(spmc_manifest_attribute_t *manifest,
			       const void *fdt,
			       int root)
{
	int node;

	assert(manifest != NULL);

	node = fdt_subnode_offset_namelen(fdt, root, ATTRIBUTE_ROOT_NODE_STR,
		sizeof(ATTRIBUTE_ROOT_NODE_STR) - 1);
	if (node < 0) {
		ERROR("Root node doesn't contain subnode '%s'\n",
			ATTRIBUTE_ROOT_NODE_STR);
		return node;
	}

	return manifest_parse_attribute(manifest, fdt, node);
}

/*******************************************************************************
 * Platform handler to parse a SPM Core manifest.
 ******************************************************************************/
int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest,
				const void *pm_addr)
{
	int rc, unmap_ret;
	uintptr_t pm_base, pm_base_align;
	size_t mapped_size;

	assert(manifest != NULL);
	assert(pm_addr != NULL);

	/*
	 * Assume TOS_FW_CONFIG is not necessarily aligned to a page
	 * boundary, thus calculate the remaining space between SPMC
	 * manifest start address and upper page limit.
	 *
	 */
	pm_base = (uintptr_t)pm_addr;
	pm_base_align = page_align(pm_base, UP);

	if (pm_base == pm_base_align) {
		/* Page aligned */
		mapped_size = PAGE_SIZE;
	} else {
		mapped_size = pm_base_align - pm_base;
	}

	/* Check space within the page at least maps the FDT header */
	if (mapped_size < sizeof(struct fdt_header)) {
		ERROR("Error while mapping SPM Core manifest.\n");
		return -EINVAL;
	}

	/* Map first SPMC manifest page in the SPMD translation regime */
	pm_base_align = page_align(pm_base, DOWN);
	rc = mmap_add_dynamic_region((unsigned long long)pm_base_align,
				     pm_base_align,
				     PAGE_SIZE,
				     MT_RO_DATA | EL3_PAS);
	if (rc != 0) {
		ERROR("Error while mapping SPM Core manifest (%d).\n", rc);
		return rc;
	}

	rc = fdt_check_header(pm_addr);
	if (rc != 0) {
		ERROR("Wrong format for SPM Core manifest (%d).\n", rc);
		goto exit_unmap;
	}

	/* Check SPMC manifest fits within the upper mapped page boundary */
	if (mapped_size < fdt_totalsize(pm_addr)) {
		ERROR("SPM Core manifest too large.\n");
		rc = -EINVAL;
		goto exit_unmap;
	}

	VERBOSE("Reading SPM Core manifest at address %p\n", pm_addr);

	rc = fdt_node_offset_by_compatible(pm_addr, -1,
				"arm,ffa-core-manifest-1.0");
	if (rc < 0) {
		ERROR("Unrecognized SPM Core manifest\n");
		goto exit_unmap;
	}

	rc = manifest_parse_root(manifest, pm_addr, rc);

exit_unmap:
	unmap_ret = mmap_remove_dynamic_region(pm_base_align, PAGE_SIZE);
	if (unmap_ret != 0) {
		ERROR("Error while unmapping SPM Core manifest (%d).\n",
			unmap_ret);
		if (rc == 0) {
			rc = unmap_ret;
		}
	}

	return rc;
}
