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

#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;
}

/*
 * SEC Firmware FIT image parser to check if any loadable is
 * present. If present, verify integrity of the loadable and
 * copy loadable to address provided in (loadable_h, loadable_l).
 *
 * Returns 0 on success and a negative errno on error task fail.
 */
static int sec_firmware_check_copy_loadable(const void *sec_firmware_img,
					    u32 *loadable_l, u32 *loadable_h)
{
	phys_addr_t sec_firmware_loadable_addr = 0;
	int conf_node_off, ld_node_off;
	char *conf_node_name = NULL;
	const void *data;
	size_t size;
	ulong load;

	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;
	}

	ld_node_off = fit_conf_get_prop_node(sec_firmware_img, conf_node_off,
					     FIT_LOADABLE_PROP);
	if (ld_node_off >= 0) {
		printf("SEC Firmware: '%s' present in config\n",
		       FIT_LOADABLE_PROP);

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

		if (fit_image_get_data(sec_firmware_img, ld_node_off,
				       &data, &size)) {
			printf("SEC Loadable: Can't get subimage data/size");
			return -ENOENT;
		}

		/* Get load address, treated as load offset to secure memory */
		if (fit_image_get_load(sec_firmware_img, ld_node_off, &load)) {
			printf("SEC Loadable: Can't get subimage load");
			return -ENOENT;
		}

		/* Compute load address for loadable in secure memory */
		sec_firmware_loadable_addr = (sec_firmware_addr -
						gd->arch.tlb_size) + load;

		/* Copy loadable to secure memory and flush dcache */
		debug("%s copied to address 0x%p\n",
		      FIT_LOADABLE_PROP, (void *)sec_firmware_loadable_addr);
		memcpy((void *)sec_firmware_loadable_addr, data, size);
		flush_dcache_range(sec_firmware_loadable_addr,
				   sec_firmware_loadable_addr + size);
	}

	/* Populate address ptrs for loadable image with loadbale addr */
	out_le32(loadable_l, (sec_firmware_loadable_addr & WORD_MASK));
	out_le32(loadable_h, (sec_firmware_loadable_addr >> WORD_SHIFT));

	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. Also load any loadable if present along with SEC
 * Firmware image.
 */
static int sec_firmware_load_image(const void *sec_firmware_img,
				   u32 *loadable_l, u32 *loadable_h)
{
	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;

	/*
	 * Check if any loadable are present along with firmware image, if
	 * present load them.
	 */
	ret = sec_firmware_check_copy_loadable(sec_firmware_img, loadable_l,
					       loadable_h);
	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 (current_el() == SEC_FIRMWARE_TARGET_EL)
		return _sec_firmware_support_psci_version();

	return PSCI_INVALID_VER;
}
#endif

/*
 * Check with sec_firmware if it supports random number generation
 * via HW RNG
 *
 * The return value will be true if it is supported
 */
bool sec_firmware_support_hwrng(void)
{
	uint8_t rand[8];
	if (sec_firmware_addr & SEC_FIRMWARE_RUNNING) {
		if (!sec_firmware_get_random(rand, 8))
			return true;
	}

	return false;
}

/*
 * sec_firmware_get_random - Get a random number from SEC Firmware
 * @rand:		random number buffer to be filled
 * @bytes:		Number of bytes of random number to be supported
 * @eret:		-1 in case of error, 0 for success
 */
int sec_firmware_get_random(uint8_t *rand, int bytes)
{
	unsigned long long num;
	struct pt_regs regs;
	int param1;

	if (!bytes || bytes > 8) {
		printf("Max Random bytes genration supported is 8\n");
		return -1;
	}
#define SIP_RNG_64 0xC200FF11
	regs.regs[0] = SIP_RNG_64;

	if (bytes <= 4)
		param1 = 0;
	else
		param1 = 1;
	regs.regs[1] = param1;

	smc_call(&regs);

	if (regs.regs[0])
		return -1;

	num = regs.regs[1];
	memcpy(rand, &num, bytes);

	return 0;
}

/*
 * 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
 * @loadable_l:		the address to hold loadable address low
 * @loadable_h:		the address to hold loadable address high
 */
int sec_firmware_init(const void *sec_firmware_img,
			u32 *eret_hold_l,
			u32 *eret_hold_h,
			u32 *loadable_l,
			u32 *loadable_h)
{
	int ret;

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

	ret = sec_firmware_load_image(sec_firmware_img, loadable_l,
				      loadable_h);
	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;
}

/*
 * fdt_fix_kaslr - Add kalsr-seed node in Device tree
 * @fdt:		Device tree
 * @eret:		0 in case of error, 1 for success
 */
int fdt_fixup_kaslr(void *fdt)
{
	int nodeoffset;
	int err, ret = 0;
	u8 rand[8];

#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT)
	/* Check if random seed generation is  supported */
	if (sec_firmware_support_hwrng() == false)
		return 0;

	ret = sec_firmware_get_random(rand, 8);
	if (ret < 0) {
		printf("WARNING: No random number to set kaslr-seed\n");
		return 0;
	}

	err = fdt_check_header(fdt);
	if (err < 0) {
		printf("fdt_chosen: %s\n", fdt_strerror(err));
		return 0;
	}

	/* find or create "/chosen" node. */
	nodeoffset = fdt_find_or_add_subnode(fdt, 0, "chosen");
	if (nodeoffset < 0)
		return 0;

	err = fdt_setprop(fdt, nodeoffset, "kaslr-seed", rand,
				  sizeof(rand));
	if (err < 0) {
		printf("WARNING: can't set kaslr-seed %s.\n",
		       fdt_strerror(err));
		return 0;
	}
	ret = 1;
#endif

	return ret;
}
