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

#include <assert.h>
#include <errno.h>
#include <string.h>
#include <libfdt.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 SPCI %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 SPCI %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%llx\n", attr->load_address);
	VERBOSE("  entrypoint: 0x%llx\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);
	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);
	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,spci-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;
}
