From 367d0ffb14a4ed75cf34ec8f6699fbec853d36d8 Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Thu, 5 May 2016 13:59:07 +0100 Subject: AArch32: Enable GIC and TZC support This patch modifies GICv3 and TZC drivers to add AArch32 support. No modifications are required for the GICv2 driver for AArch32 support. The TZC driver assumes that the secure world is running in Little-Endian mode to do 64 bit manipulations. Assertions are present to validate the assumption. Note: The legacy GICv3 driver is not supported for AArch32. Change-Id: Id1bc75a9f5dafb9715c9500ca77b4606eb1e2458 --- drivers/arm/tzc/tzc400.c | 2 +- drivers/arm/tzc/tzc_common_private.c | 33 +++++++++++++++++++++++++++++++++ drivers/arm/tzc/tzc_dmc500.c | 2 +- 3 files changed, 35 insertions(+), 2 deletions(-) (limited to 'drivers/arm/tzc') diff --git a/drivers/arm/tzc/tzc400.c b/drivers/arm/tzc/tzc400.c index e5335872..ca088c32 100644 --- a/drivers/arm/tzc/tzc400.c +++ b/drivers/arm/tzc/tzc400.c @@ -206,7 +206,7 @@ void tzc400_configure_region(unsigned int filters, * Do address range check based on TZC configuration. A 64bit address is * the max and expected case. */ - assert(((region_top <= (UINT64_MAX >> (64 - tzc400.addr_width))) && + assert(((region_top <= _tzc_get_max_top_addr(tzc400.addr_width)) && (region_base < region_top))); /* region_base and (region_top + 1) must be 4KB aligned */ diff --git a/drivers/arm/tzc/tzc_common_private.c b/drivers/arm/tzc/tzc_common_private.c index dae6c3ac..8b1ddf49 100644 --- a/drivers/arm/tzc/tzc_common_private.c +++ b/drivers/arm/tzc/tzc_common_private.c @@ -28,6 +28,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include +#include #include #include @@ -199,4 +201,35 @@ static unsigned int _tzc_read_peripheral_id(uintptr_t base) return id; } + +#ifdef AARCH32 +static unsigned long long _tzc_get_max_top_addr(int addr_width) +{ + /* + * Assume at least 32 bit wide address and initialize the max. + * This function doesn't use 64-bit integer arithmetic to avoid + * having to implement additional compiler library functions. + */ + unsigned long long addr_mask = 0xFFFFFFFF; + uint32_t *addr_ptr = (uint32_t *)&addr_mask; + + assert(addr_width >= 32); + + /* This logic works only on little - endian platforms */ + assert((read_sctlr() & SCTLR_EE_BIT) == 0); + + /* + * If required address width is greater than 32, populate the higher + * 32 bits of the 64 bit field with the max address. + */ + if (addr_width > 32) + *(addr_ptr + 1) = ((1 << (addr_width - 32)) - 1); + + return addr_mask; +} +#else +#define _tzc_get_max_top_addr(addr_width)\ + (UINT64_MAX >> (64 - (addr_width))) +#endif /* AARCH32 */ + #endif diff --git a/drivers/arm/tzc/tzc_dmc500.c b/drivers/arm/tzc/tzc_dmc500.c index b2f0bf67..24e587c1 100644 --- a/drivers/arm/tzc/tzc_dmc500.c +++ b/drivers/arm/tzc/tzc_dmc500.c @@ -211,7 +211,7 @@ void tzc_dmc500_configure_region(int region_no, * Do address range check based on DMC-TZ configuration. A 43bit address * is the max and expected case. */ - assert(((region_top <= (UINT64_MAX >> (64 - 43))) && + assert(((region_top <= _tzc_get_max_top_addr(43)) && (region_base < region_top))); /* region_base and (region_top + 1) must be 4KB aligned */ -- cgit