/*******************************************************************************
 * Initialize the TrustZone Controller.
 * Early initialization create only one region with full access to secure.
 * This setting is used before and during DDR initialization.
 ******************************************************************************/
static void early_init_tzc400(void)
{
	stm32mp_clk_enable(TZC1);
	stm32mp_clk_enable(TZC2);

	tzc400_init(STM32MP1_TZC_BASE);

	tzc400_disable_filters();

	/* Region 1 set to cover Non-Secure DRAM at 0xC000_0000 */
	tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 1,
				STM32MP_DDR_BASE,
				STM32MP_DDR_BASE +
				(STM32MP_DDR_MAX_SIZE - 1U),
				TZC_REGION_S_NONE,
				TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) |
				TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID));

	/* Raise an exception if a NS device tries to access secure memory */
	tzc400_set_action(TZC_ACTION_ERR);

	tzc400_enable_filters();
}
/*
 * For the moment we assume that all security programming is done by the
 * primary core.
 * TODO:
 * Might want to enable interrupt on violations when supported?
 */
void plat_security_setup(void)
{
	struct tzc_instance controller;

	/*
	 * The Base FVP has a TrustZone address space controller, the Foundation
	 * FVP does not. Trying to program the device on the foundation FVP will
	 * cause an abort.
	 *
	 * If the platform had additional peripheral specific security
	 * configurations, those would be configured here.
	 */

	if (!platform_get_cfgvar(CONFIG_HAS_TZC))
		return;

	/*
	 * The TrustZone controller controls access to main DRAM. Give
	 * full NS access for the moment to use with OS.
	 */
	INFO("Configuring TrustZone Controller\n");

	/*
	 * The driver does some error checking and will assert.
	 * - Provide base address of device on platform.
	 * - Provide width of ACE-Lite IDs on platform.
	 */
	controller.base = TZC400_BASE;
	controller.aid_width = FVP_AID_WIDTH;
	tzc_init(&controller);

	/*
	 * Currently only filters 0 and 2 are connected on Base FVP.
	 * Filter 0 : CPU clusters (no access to DRAM by default)
	 * Filter 1 : not connected
	 * Filter 2 : LCDs (access to VRAM allowed by default)
	 * Filter 3 : not connected
	 * Programming unconnected filters will have no effect at the
	 * moment. These filter could, however, be connected in future.
	 * So care should be taken not to configure the unused filters.
	 */

	/* Disable all filters before programming. */
	tzc_disable_filters(&controller);

	/*
	 * Allow full access to all DRAM to supported devices for the
	 * moment. Give access to the CPUs and Virtio. Some devices
	 * would normally use the default ID so allow that too. We use
	 * three different regions to cover the three separate blocks of
	 * memory in the FVPs. We allow secure access to DRAM to load NS
	 * software.
	 * FIXME: In current models Virtio uses a reserved ID. This is
	 * not correct and will be fixed.
	 */

	/* Set to cover 2GB block of DRAM */
	tzc_configure_region(&controller, FILTER_SHIFT(0), 1,
			DRAM_BASE, 0xFFFFFFFF, TZC_REGION_S_RDWR,
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_AP) |
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_DEFAULT) |
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_RES5));

	/* Set to cover the 30GB block */
	tzc_configure_region(&controller, FILTER_SHIFT(0), 2,
			0x880000000, 0xFFFFFFFFF, TZC_REGION_S_RDWR,
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_AP) |
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_DEFAULT) |
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_RES5));

	/* Set to cover 480GB block */
	tzc_configure_region(&controller, FILTER_SHIFT(0), 3,
			0x8800000000, 0xFFFFFFFFFF, TZC_REGION_S_RDWR,
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_AP) |
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_DEFAULT) |
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_RES5));

	/*
	 * TODO: Interrupts are not currently supported. The only
	 * options we have are for access errors to occur quietly or to
	 * cause an exception. We choose to cause an exception.
	 */
	tzc_set_action(&controller, TZC_ACTION_ERR);

	/* Enable filters. */
	tzc_enable_filters(&controller);
}
static void init_tzc400(void)
{
	/* Enable all filter units available */
	mmio_write_32(TZC400_BASE + GATE_KEEPER_OFF, 0x0000000f);

	/*
	 * Secure read and write are enabled for region 0, and the background
	 * region (region 0) is enabled for all four filter units
	 */
	mmio_write_32(TZC400_BASE + REGION_ATTRIBUTES_OFF, 0xc0000000);

	/*
	 * Enable Non-secure read/write accesses for the Soc Devices from the
	 * Non-Secure World
	 */
	mmio_write_32(TZC400_BASE + REGION_ID_ACCESS_OFF,
		TZC_REGION_ACCESS_RDWR(TZC400_NSAID_CCI400)	|
		TZC_REGION_ACCESS_RDWR(TZC400_NSAID_PCIE)	|
		TZC_REGION_ACCESS_RDWR(TZC400_NSAID_HDLCD0)	|
		TZC_REGION_ACCESS_RDWR(TZC400_NSAID_HDLCD1)	|
		TZC_REGION_ACCESS_RDWR(TZC400_NSAID_USB)	|
		TZC_REGION_ACCESS_RDWR(TZC400_NSAID_DMA330)	|
		TZC_REGION_ACCESS_RDWR(TZC400_NSAID_THINLINKS)	|
		TZC_REGION_ACCESS_RDWR(TZC400_NSAID_AP)		|
		TZC_REGION_ACCESS_RDWR(TZC400_NSAID_GPU)	|
		TZC_REGION_ACCESS_RDWR(TZC400_NSAID_SCP)	|
		TZC_REGION_ACCESS_RDWR(TZC400_NSAID_CORESIGHT)
		);
}
/*
 * For the moment we assume that all security programming is done by the
 * primary core.
 * TODO:
 * Might want to enable interrupt on violations when supported?
 */
void plat_security_setup(void)
{
	tzc_instance_t controller;

	/*
	 * The Base FVP has a TrustZone address space controller, the Foundation
	 * FVP does not. Trying to program the device on the foundation FVP will
	 * cause an abort.
	 *
	 * If the platform had additional peripheral specific security
	 * configurations, those would be configured here.
	 */

	if (!platform_get_cfgvar(CONFIG_HAS_TZC))
		return;

	/*
	 * The TrustZone controller controls access to main DRAM. Give
	 * full NS access for the moment to use with OS.
	 */
	INFO("Configuring TrustZone Controller\n");

	/*
	 * The driver does some error checking and will assert.
	 * - Provide base address of device on platform.
	 * - Provide width of ACE-Lite IDs on platform.
	 */
	controller.base = TZC400_BASE;
	controller.aid_width = FVP_AID_WIDTH;
	tzc_init(&controller);

	/*
	 * Currently only filters 0 and 2 are connected on Base FVP.
	 * Filter 0 : CPU clusters (no access to DRAM by default)
	 * Filter 1 : not connected
	 * Filter 2 : LCDs (access to VRAM allowed by default)
	 * Filter 3 : not connected
	 * Programming unconnected filters will have no effect at the
	 * moment. These filter could, however, be connected in future.
	 * So care should be taken not to configure the unused filters.
	 */

	/* Disable all filters before programming. */
	tzc_disable_filters(&controller);

	/*
	 * Allow only non-secure access to all DRAM to supported devices.
	 * Give access to the CPUs and Virtio. Some devices
	 * would normally use the default ID so allow that too. We use
	 * two regions to cover the blocks of physical memory in the FVPs.
	 *
	 * Software executing in the secure state, such as a secure
	 * boot-loader, can access the DRAM by using the NS attributes in
	 * the MMU translation tables and descriptors.
	 */

	/* Set to cover the first block of DRAM */
	tzc_configure_region(&controller, FILTER_SHIFT(0), 1,
			DRAM_BASE, 0xFFFFFFFF, TZC_REGION_S_NONE,
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_DEFAULT) |
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_PCI) |
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_AP) |
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_VIRTIO) |
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_VIRTIO_OLD));

	/* Set to cover the second block of DRAM */
	tzc_configure_region(&controller, FILTER_SHIFT(0), 2,
			0x880000000, 0xFFFFFFFFF, TZC_REGION_S_NONE,
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_DEFAULT) |
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_PCI) |
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_AP) |
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_VIRTIO) |
			TZC_REGION_ACCESS_RDWR(FVP_NSAID_VIRTIO_OLD));

	/*
	 * TODO: Interrupts are not currently supported. The only
	 * options we have are for access errors to occur quietly or to
	 * cause an exception. We choose to cause an exception.
	 */
	tzc_set_action(&controller, TZC_ACTION_ERR);

	/* Enable filters. */
	tzc_enable_filters(&controller);
}