mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-08 05:43:53 +00:00

Enforce full include path for includes. Deprecate old paths. The following folders inside include/lib have been left unchanged: - include/lib/cpus/${ARCH} - include/lib/el3_runtime/${ARCH} The reason for this change is that having a global namespace for includes isn't a good idea. It defeats one of the advantages of having folders and it introduces problems that are sometimes subtle (because you may not know the header you are actually including if there are two of them). For example, this patch had to be created because two headers were called the same way:e0ea0928d5
("Fix gpio includes of mt8173 platform to avoid collision."). More recently, this patch has had similar problems:46f9b2c3a2
("drivers: add tzc380 support"). This problem was introduced in commit4ecca33988
("Move include and source files to logical locations"). At that time, there weren't too many headers so it wasn't a real issue. However, time has shown that this creates problems. Platforms that want to preserve the way they include headers may add the removed paths to PLAT_INCLUDES, but this is discouraged. Change-Id: I39dc53ed98f9e297a5966e723d1936d6ccf2fc8f Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
176 lines
5.4 KiB
C
176 lines
5.4 KiB
C
/*
|
|
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <assert.h>
|
|
|
|
#include <common/debug.h>
|
|
#include <drivers/arm/tzc_dmc620.h>
|
|
#include <lib/mmio.h>
|
|
|
|
/* Mask to extract bit 31 to 16 */
|
|
#define MASK_31_16 UINT64_C(0x0000ffff0000)
|
|
/* Mask to extract bit 47 to 32 */
|
|
#define MASK_47_32 UINT64_C(0xffff00000000)
|
|
|
|
/* Helper macro for getting dmc_base addr of a dmc_inst */
|
|
#define DMC_BASE(plat_data, dmc_inst) \
|
|
((uintptr_t)(plat_data->dmc_base[dmc_inst]))
|
|
|
|
/* Pointer to the tzc_dmc620_config_data structure populated by the platform */
|
|
static const tzc_dmc620_config_data_t *g_plat_config_data;
|
|
|
|
#if ENABLE_ASSERTIONS
|
|
/*
|
|
* Helper function to check if the DMC-620 instance is present at the
|
|
* base address provided by the platform and also check if at least
|
|
* one dmc instance is present.
|
|
*/
|
|
static void tzc_dmc620_validate_plat_driver_data(
|
|
const tzc_dmc620_driver_data_t *plat_driver_data)
|
|
{
|
|
uint8_t dmc_inst, dmc_count;
|
|
unsigned int dmc_id;
|
|
uintptr_t base;
|
|
|
|
assert(plat_driver_data != NULL);
|
|
|
|
dmc_count = plat_driver_data->dmc_count;
|
|
assert(dmc_count > 0U);
|
|
|
|
for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) {
|
|
base = DMC_BASE(plat_driver_data, dmc_inst);
|
|
dmc_id = mmio_read_32(base + DMC620_PERIPHERAL_ID_0);
|
|
assert(dmc_id == DMC620_PERIPHERAL_ID_0_VALUE);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* Program a region with region base and region top addresses of all
|
|
* DMC-620 instances.
|
|
*/
|
|
static void tzc_dmc620_configure_region(int region_no,
|
|
unsigned long long region_base,
|
|
unsigned long long region_top,
|
|
unsigned int sec_attr)
|
|
{
|
|
uint32_t min_31_00, min_47_32;
|
|
uint32_t max_31_00, max_47_32;
|
|
uint8_t dmc_inst, dmc_count;
|
|
uintptr_t base;
|
|
const tzc_dmc620_driver_data_t *plat_driver_data;
|
|
|
|
plat_driver_data = g_plat_config_data->plat_drv_data;
|
|
assert(plat_driver_data != NULL);
|
|
|
|
/* Do range checks on regions. */
|
|
assert((region_no >= 0U) && (region_no <= DMC620_ACC_ADDR_COUNT));
|
|
|
|
/* region_base and (region_top + 1) must be 4KB aligned */
|
|
assert(((region_base | (region_top + 1U)) & (4096U - 1U)) == 0U);
|
|
|
|
dmc_count = plat_driver_data->dmc_count;
|
|
for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) {
|
|
min_31_00 = (region_base & MASK_31_16) | sec_attr;
|
|
min_47_32 = (region_base & MASK_47_32)
|
|
>> DMC620_ACC_ADDR_WIDTH;
|
|
max_31_00 = (region_top & MASK_31_16);
|
|
max_47_32 = (region_top & MASK_47_32)
|
|
>> DMC620_ACC_ADDR_WIDTH;
|
|
|
|
/* Extract the base address of the DMC-620 instance */
|
|
base = DMC_BASE(plat_driver_data, dmc_inst);
|
|
/* Configure access address region registers */
|
|
mmio_write_32(base + DMC620_ACC_ADDR_MIN_31_00_NEXT(region_no),
|
|
min_31_00);
|
|
mmio_write_32(base + DMC620_ACC_ADDR_MIN_47_32_NEXT(region_no),
|
|
min_47_32);
|
|
mmio_write_32(base + DMC620_ACC_ADDR_MAX_31_00_NEXT(region_no),
|
|
max_31_00);
|
|
mmio_write_32(base + DMC620_ACC_ADDR_MAX_47_32_NEXT(region_no),
|
|
max_47_32);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Set the action value for all the DMC-620 instances.
|
|
*/
|
|
static void tzc_dmc620_set_action(void)
|
|
{
|
|
uint8_t dmc_inst, dmc_count;
|
|
uintptr_t base;
|
|
const tzc_dmc620_driver_data_t *plat_driver_data;
|
|
|
|
plat_driver_data = g_plat_config_data->plat_drv_data;
|
|
dmc_count = plat_driver_data->dmc_count;
|
|
for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) {
|
|
/* Extract the base address of the DMC-620 instance */
|
|
base = DMC_BASE(plat_driver_data, dmc_inst);
|
|
/* Switch to READY */
|
|
mmio_write_32(base + DMC620_MEMC_CMD, DMC620_MEMC_CMD_GO);
|
|
mmio_write_32(base + DMC620_MEMC_CMD, DMC620_MEMC_CMD_EXECUTE);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Verify whether the DMC-620 configuration is complete by reading back
|
|
* configuration registers and comparing it with the configured value. If
|
|
* configuration is incomplete, loop till the configured value is reflected in
|
|
* the register.
|
|
*/
|
|
static void tzc_dmc620_verify_complete(void)
|
|
{
|
|
uint8_t dmc_inst, dmc_count;
|
|
uintptr_t base;
|
|
const tzc_dmc620_driver_data_t *plat_driver_data;
|
|
|
|
plat_driver_data = g_plat_config_data->plat_drv_data;
|
|
dmc_count = plat_driver_data->dmc_count;
|
|
for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) {
|
|
/* Extract the base address of the DMC-620 instance */
|
|
base = DMC_BASE(plat_driver_data, dmc_inst);
|
|
while ((mmio_read_32(base + DMC620_MEMC_STATUS) &
|
|
DMC620_MEMC_CMD_MASK) != DMC620_MEMC_CMD_GO)
|
|
continue;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Initialize the DMC-620 TrustZone Controller using the region configuration
|
|
* supplied by the platform. The DMC620 controller should be enabled elsewhere
|
|
* before invoking this function.
|
|
*/
|
|
void arm_tzc_dmc620_setup(const tzc_dmc620_config_data_t *plat_config_data)
|
|
{
|
|
int i;
|
|
|
|
/* Check if valid pointer is passed */
|
|
assert(plat_config_data != NULL);
|
|
|
|
/*
|
|
* Check if access address count passed by the platform is less than or
|
|
* equal to DMC620's access address count
|
|
*/
|
|
assert(plat_config_data->acc_addr_count <= DMC620_ACC_ADDR_COUNT);
|
|
|
|
#if ENABLE_ASSERTIONS
|
|
/* Validates the information passed by platform */
|
|
tzc_dmc620_validate_plat_driver_data(plat_config_data->plat_drv_data);
|
|
#endif
|
|
|
|
g_plat_config_data = plat_config_data;
|
|
|
|
INFO("Configuring DMC-620 TZC settings\n");
|
|
for (i = 0U; i < g_plat_config_data->acc_addr_count; i++)
|
|
tzc_dmc620_configure_region(i,
|
|
g_plat_config_data->plat_acc_addr_data[i].region_base,
|
|
g_plat_config_data->plat_acc_addr_data[i].region_top,
|
|
g_plat_config_data->plat_acc_addr_data[i].sec_attr);
|
|
|
|
tzc_dmc620_set_action();
|
|
tzc_dmc620_verify_complete();
|
|
INFO("DMC-620 TZC setup completed\n");
|
|
}
|