Commit 367d0ffb authored by Soby Mathew's avatar Soby Mathew
Browse files

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
parent 3e3616ab
...@@ -75,8 +75,12 @@ void gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data) ...@@ -75,8 +75,12 @@ void gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data)
plat_driver_data->g1s_interrupt_num == 0); plat_driver_data->g1s_interrupt_num == 0);
/* Check for system register support */ /* Check for system register support */
#ifdef AARCH32
assert(read_id_pfr1() & (ID_PFR1_GIC_MASK << ID_PFR1_GIC_SHIFT));
#else
assert(read_id_aa64pfr0_el1() & assert(read_id_aa64pfr0_el1() &
(ID_AA64PFR0_GIC_MASK << ID_AA64PFR0_GIC_SHIFT)); (ID_AA64PFR0_GIC_MASK << ID_AA64PFR0_GIC_SHIFT));
#endif /* AARCH32 */
/* The GIC version should be 3.0 */ /* The GIC version should be 3.0 */
gic_version = gicd_read_pidr2(plat_driver_data->gicd_base); gic_version = gicd_read_pidr2(plat_driver_data->gicd_base);
......
...@@ -79,9 +79,13 @@ ...@@ -79,9 +79,13 @@
* Macro to convert a GICR_TYPER affinity value into a MPIDR value. Bits[31:24] * Macro to convert a GICR_TYPER affinity value into a MPIDR value. Bits[31:24]
* are zeroes. * are zeroes.
*/ */
#ifdef AARCH32
#define mpidr_from_gicr_typer(typer_val) (((typer_val) >> 32) & 0xffffff)
#else
#define mpidr_from_gicr_typer(typer_val) \ #define mpidr_from_gicr_typer(typer_val) \
((((typer_val >> 56) & MPIDR_AFFLVL_MASK) << MPIDR_AFF3_SHIFT) | \ (((((typer_val) >> 56) & MPIDR_AFFLVL_MASK) << MPIDR_AFF3_SHIFT) | \
((typer_val >> 32) & 0xffffff)) (((typer_val) >> 32) & 0xffffff))
#endif
/******************************************************************************* /*******************************************************************************
* Private GICv3 function prototypes for accessing entire registers. * Private GICv3 function prototypes for accessing entire registers.
......
...@@ -206,7 +206,7 @@ void tzc400_configure_region(unsigned int filters, ...@@ -206,7 +206,7 @@ void tzc400_configure_region(unsigned int filters,
* Do address range check based on TZC configuration. A 64bit address is * Do address range check based on TZC configuration. A 64bit address is
* the max and expected case. * 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 < region_top)));
/* region_base and (region_top + 1) must be 4KB aligned */ /* region_base and (region_top + 1) must be 4KB aligned */
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <arch.h>
#include <arch_helpers.h>
#include <mmio.h> #include <mmio.h>
#include <tzc_common.h> #include <tzc_common.h>
...@@ -199,4 +201,35 @@ static unsigned int _tzc_read_peripheral_id(uintptr_t base) ...@@ -199,4 +201,35 @@ static unsigned int _tzc_read_peripheral_id(uintptr_t base)
return id; 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 #endif
...@@ -211,7 +211,7 @@ void tzc_dmc500_configure_region(int region_no, ...@@ -211,7 +211,7 @@ void tzc_dmc500_configure_region(int region_no,
* Do address range check based on DMC-TZ configuration. A 43bit address * Do address range check based on DMC-TZ configuration. A 43bit address
* is the max and expected case. * 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 < region_top)));
/* region_base and (region_top + 1) must be 4KB aligned */ /* region_base and (region_top + 1) must be 4KB aligned */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment