/*
 * Copyright 2016 NXP Semiconductor, Inc.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <errno.h>
#include <linux/kernel.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/types.h>
#include <asm/macro.h>
#include <asm/armv8/sec_firmware.h>

DECLARE_GLOBAL_DATA_PTR;
extern void c_runtime_cpu_setup(void);

#define SEC_FIRMWARE_LOADED	0x1
#define SEC_FIRMWARE_RUNNING	0x2
#define SEC_FIRMWARE_ADDR_MASK	(~0x3)
/*
 * Secure firmware load addr
 * Flags used: 0x1 secure firmware has been loaded to secure memory
 *             0x2 secure firmware is running
 */
phys_addr_t sec_firmware_addr;

#ifndef SEC_FIRMWARE_FIT_IMAGE
#define SEC_FIRMWARE_FIT_IMAGE		"firmware"
#endif
#ifndef SEC_FIRMEWARE_FIT_CNF_NAME
#define SEC_FIRMEWARE_FIT_CNF_NAME	"config@1"
#endif
#ifndef SEC_FIRMWARE_TARGET_EL
#define SEC_FIRMWARE_TARGET_EL		2
#endif

static int sec_firmware_get_data(const void *sec_firmware_img,
				const void **data, size_t *size)
{
	int conf_node_off, fw_node_off;
	char *conf_node_name = NULL;
	char *desc;
	int ret;

	conf_node_name = SEC_FIRMEWARE_FIT_CNF_NAME;

	conf_node_off = fit_conf_get_node(sec_firmware_img, conf_node_name);
	if (conf_node_off < 0) {
		printf("SEC Firmware: %s: no such config\n", conf_node_name);
		return -ENOENT;
	}

	fw_node_off = fit_conf_get_prop_node(sec_firmware_img, conf_node_off,
			SEC_FIRMWARE_FIT_IMAGE);
	if (fw_node_off < 0) {
		printf("SEC Firmware: No '%s' in config\n",
		       SEC_FIRMWARE_FIT_IMAGE);
		return -ENOLINK;
	}

	/* Verify secure firmware image */
	if (!(fit_image_verify(sec_firmware_img, fw_node_off))) {
		printf("SEC Firmware: Bad firmware image (bad CRC)\n");
		return -EINVAL;
	}

	if (fit_image_get_data(sec_firmware_img, fw_node_off, data, size)) {
		printf("SEC Firmware: Can't get %s subimage data/size",
		       SEC_FIRMWARE_FIT_IMAGE);
		return -ENOENT;
	}

	ret = fit_get_desc(sec_firmware_img, fw_node_off, &desc);
	if (ret)
		printf("SEC Firmware: Can't get description\n");
	else
		printf("%s\n", desc);

	return ret;
}

/*
 * SEC Firmware FIT image parser checks if the image is in FIT
 * format, verifies integrity of the image and calculates raw
 * image address and size values.
 *
 * Returns 0 on success and a negative errno on error task fail.
 */
static int sec_firmware_parse_image(const void *sec_firmware_img,
					const void **raw_image_addr,
					size_t *raw_image_size)
{
	int ret;

	ret = sec_firmware_get_data(sec_firmware_img, raw_image_addr,
					raw_image_size);
	if (ret)
		return ret;

	debug("SEC Firmware: raw_image_addr = 0x%p, raw_image_size = 0x%lx\n",
	      *raw_image_addr, *raw_image_size);

	return 0;
}

static int sec_firmware_copy_image(const char *title,
			 u64 image_addr, u32 image_size, u64 sec_firmware)
{
	debug("%s copied to address 0x%p\n", title, (void *)sec_firmware);
	memcpy((void *)sec_firmware, (void *)image_addr, image_size);
	flush_dcache_range(sec_firmware, sec_firmware + image_size);

	return 0;
}

/*
 * This function will parse the SEC Firmware image, and then load it
 * to secure memory.
 */
static int sec_firmware_load_image(const void *sec_firmware_img)
{
	const void *raw_image_addr;
	size_t raw_image_size = 0;
	int ret;

	/*
	 * The Excetpion Level must be EL3 to load and initialize
	 * the SEC Firmware.
	 */
	if (current_el() != 3) {
		ret = -EACCES;
		goto out;
	}

#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
	/*
	 * The SEC Firmware must be stored in secure memory.
	 * Append SEC Firmware to secure mmu table.
	 */
	if (!(gd->arch.secure_ram & MEM_RESERVE_SECURE_MAINTAINED)) {
		ret = -ENXIO;
		goto out;
	}

	sec_firmware_addr = (gd->arch.secure_ram & MEM_RESERVE_SECURE_ADDR_MASK) +
			gd->arch.tlb_size;
#else
#error "The CONFIG_SYS_MEM_RESERVE_SECURE must be defined when enabled SEC Firmware support"
#endif

	/* Align SEC Firmware base address to 4K */
	sec_firmware_addr = (sec_firmware_addr + 0xfff) & ~0xfff;
	debug("SEC Firmware: Load address: 0x%llx\n",
	      sec_firmware_addr & SEC_FIRMWARE_ADDR_MASK);

	ret = sec_firmware_parse_image(sec_firmware_img, &raw_image_addr,
			&raw_image_size);
	if (ret)
		goto out;

	/* TODO:
	 * Check if the end addr of SEC Firmware has been extend the secure
	 * memory.
	 */

	/* Copy the secure firmware to secure memory */
	ret = sec_firmware_copy_image("SEC Firmware", (u64)raw_image_addr,
			raw_image_size, sec_firmware_addr &
			SEC_FIRMWARE_ADDR_MASK);
	if (ret)
		goto out;

	sec_firmware_addr |= SEC_FIRMWARE_LOADED;
	debug("SEC Firmware: Entry point: 0x%llx\n",
	      sec_firmware_addr & SEC_FIRMWARE_ADDR_MASK);

	return 0;

out:
	printf("SEC Firmware: error (%d)\n", ret);
	sec_firmware_addr = 0;

	return ret;
}

static int sec_firmware_entry(u32 *eret_hold_l, u32 *eret_hold_h)
{
	const void *entry = (void *)(sec_firmware_addr &
				SEC_FIRMWARE_ADDR_MASK);

	return _sec_firmware_entry(entry, eret_hold_l, eret_hold_h);
}

/* Check the secure firmware FIT image */
__weak bool sec_firmware_is_valid(const void *sec_firmware_img)
{
	if (fdt_check_header(sec_firmware_img)) {
		printf("SEC Firmware: Bad firmware image (not a FIT image)\n");
		return false;
	}

	if (!fit_check_format(sec_firmware_img)) {
		printf("SEC Firmware: Bad firmware image (bad FIT header)\n");
		return false;
	}

	return true;
}

#ifdef CONFIG_SEC_FIRMWARE_ARMV8_PSCI
/*
 * The PSCI_VERSION function is added from PSCI v0.2. When the PSCI
 * v0.1 received this function, the NOT_SUPPORTED (0xffff_ffff) error
 * number will be returned according to SMC Calling Conventions. But
 * when getting the NOT_SUPPORTED error number, we cannot ensure if
 * the PSCI version is v0.1 or other error occurred. So, PSCI v0.1
 * won't be supported by this framework.
 * And if the secure firmware isn't running, return NOT_SUPPORTED.
 *
 * The return value on success is PSCI version in format
 * major[31:16]:minor[15:0].
 */
unsigned int sec_firmware_support_psci_version(void)
{
	if (sec_firmware_addr & SEC_FIRMWARE_RUNNING)
		return _sec_firmware_support_psci_version();

	return 0xffffffff;
}
#endif

/*
 * sec_firmware_init - Initialize the SEC Firmware
 * @sec_firmware_img:	the SEC Firmware image address
 * @eret_hold_l:	the address to hold exception return address low
 * @eret_hold_h:	the address to hold exception return address high
 */
int sec_firmware_init(const void *sec_firmware_img,
			u32 *eret_hold_l,
			u32 *eret_hold_h)
{
	int ret;

	if (!sec_firmware_is_valid(sec_firmware_img))
		return -EINVAL;

	ret = sec_firmware_load_image(sec_firmware_img);
	if (ret) {
		printf("SEC Firmware: Failed to load image\n");
		return ret;
	} else if (sec_firmware_addr & SEC_FIRMWARE_LOADED) {
		ret = sec_firmware_entry(eret_hold_l, eret_hold_h);
		if (ret) {
			printf("SEC Firmware: Failed to initialize\n");
			return ret;
		}
	}

	debug("SEC Firmware: Return from SEC Firmware: current_el = %d\n",
	      current_el());

	/*
	 * The PE will be turned into target EL when returned from
	 * SEC Firmware.
	 */
	if (current_el() != SEC_FIRMWARE_TARGET_EL)
		return -EACCES;

	sec_firmware_addr |= SEC_FIRMWARE_RUNNING;

	/* Set exception table and enable caches if it isn't EL3 */
	if (current_el() != 3) {
		c_runtime_cpu_setup();
		enable_caches();
	}

	return 0;
}
