/*
 * Copyright (c) 2021-2022, 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/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)
{
#if STM32MP13
	clk_enable(TZC);
#endif
#if STM32MP15
	clk_enable(TZC1);
	clk_enable(TZC2);
#endif

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