/*
 * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>

#include <common/debug.h>
#include <common/fdt_wrappers.h>
#include <drivers/arm/tzc400.h>
#include <drivers/st/stm32mp1_clk.h>
#include <dt-bindings/clock/stm32mp1-clks.h>
#include <lib/fconf/fconf.h>
#include <lib/object_pool.h>
#include <libfdt.h>
#include <tools_share/firmware_image_package.h>

#include <platform_def.h>
#include <stm32mp_fconf_getter.h>

#define STM32MP_REGION_PARAMS	4
#define STM32MP_MAX_REGIONS	8
#define FORCE_SEC_REGION	BIT(31)

static uint32_t nb_regions;

struct dt_id_attr {
	fdt32_t id_attr[STM32MP_MAX_REGIONS];
};

void stm32mp1_arch_security_setup(void)
{
	stm32mp_clk_enable(TZC1);
	stm32mp_clk_enable(TZC2);

	tzc400_init(STM32MP1_TZC_BASE);
	tzc400_disable_filters();

	/*
	 * Region 0 set to cover all DRAM at 0xC000_0000
	 * Only secure access is granted in read/write.
	 */
	tzc400_configure_region0(TZC_REGION_S_RDWR, 0);

	tzc400_set_action(TZC_ACTION_ERR);
	tzc400_enable_filters();
}

void stm32mp1_security_setup(void)
{
	uint8_t i;

	assert(nb_regions > 0U);

	tzc400_init(STM32MP1_TZC_BASE);
	tzc400_disable_filters();

	/*
	 * Region 0 set to cover all DRAM at 0xC000_0000
	 * No access is allowed.
	 */
	tzc400_configure_region0(TZC_REGION_S_NONE, 0);

	for (i = 1U; i <= nb_regions; i++) {
		tzc400_update_filters(i, STM32MP1_FILTER_BIT_ALL);
	}

	tzc400_set_action(TZC_ACTION_INT);
	tzc400_enable_filters();
}

static int fconf_populate_stm32mp1_firewall(uintptr_t config)
{
	int node, len;
	unsigned int i;
	const struct dt_id_attr *conf_list;
	const void *dtb = (const void *)config;

	/* Assert the node offset point to "st,mem-firewall" compatible property */
	const char *compatible_str = "st,mem-firewall";

	node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
	if (node < 0) {
		ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
		return node;
	}

	conf_list = (const struct dt_id_attr *)fdt_getprop(dtb, node, "memory-ranges", &len);
	if (conf_list == NULL) {
		WARN("FCONF: Read cell failed for %s\n", "memory-ranges");
		return -1;
	}

	/* Locate the memory cells and read all values */
	for (i = 0U; i < (unsigned int)(len / (sizeof(uint32_t) * STM32MP_REGION_PARAMS)); i++) {
		uint32_t base;
		uint32_t size;
		uint32_t sec_attr;
		uint32_t nsaid;

		base = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS]);
		size = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 1]);
		sec_attr = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 2]);
		nsaid = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 3]);

		VERBOSE("FCONF: stm32mp1-firewall cell found with value = 0x%x 0x%x 0x%x 0x%x\n",
			base, size, sec_attr, nsaid);

		nb_regions++;

		/* Configure region but keep disabled for secure access for BL2 load */
		tzc400_configure_region(0U, nb_regions, (unsigned long long)base,
					(unsigned long long)base + size - 1ULL, sec_attr, nsaid);
	}

	/* Force flush as the value will be used cache off */
	flush_dcache_range((uintptr_t)&nb_regions, sizeof(uint32_t));

	return 0;
}

FCONF_REGISTER_POPULATOR(FW_CONFIG, stm32mp1_firewall, fconf_populate_stm32mp1_firewall);
