summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorDan Handley <dan.handley@arm.com>2014-08-04 19:53:05 +0100
committerDan Handley <dan.handley@arm.com>2014-08-14 11:17:52 +0100
commit3279f6251ebead329e4b0af2e42a7eae157bba52 (patch)
tree1b326600f8bd492002aa2603ad51451af8802df0 /drivers
parent935db693285d6b22b781571e9dec748da274ffe1 (diff)
Simplify interface to TZC-400 driver
The TZC-400 driver previously allowed the possibility of multiple controller instances to be present in the same executable. This was unnecessary since there will only ever be one instance. This change simplifies the tzc_init() function to only take the base address argument needed by implementation, conforming to the driver initialization model of other drivers. It also hides some of the implementation details that were previously exposed by the API. The FVP port has been updated accordingly. THIS CHANGE REQUIRES ALL PLATFORM PORTS THAT USE THE TZC-400 DRIVER TO BE UPDATED Fixes ARM-software/tf-issues#181 Change-Id: I7b721edf947064989958d8f457d6462d92e742c8
Diffstat (limited to 'drivers')
-rw-r--r--drivers/arm/tzc400/tzc400.c137
1 files changed, 86 insertions, 51 deletions
diff --git a/drivers/arm/tzc400/tzc400.c b/drivers/arm/tzc400/tzc400.c
index 715ea6c..3ab1f31 100644
--- a/drivers/arm/tzc400/tzc400.c
+++ b/drivers/arm/tzc400/tzc400.c
@@ -34,54 +34,88 @@
#include <stddef.h>
#include <tzc400.h>
-static uint32_t tzc_read_build_config(uint64_t base)
+/*
+ * Implementation defined values used to validate inputs later.
+ * Filters : max of 4 ; 0 to 3
+ * Regions : max of 9 ; 0 to 8
+ * Address width : Values between 32 to 64
+ */
+typedef struct tzc_instance {
+ uint64_t base;
+ uint8_t addr_width;
+ uint8_t num_filters;
+ uint8_t num_regions;
+} tzc_instance_t;
+
+tzc_instance_t tzc;
+
+
+static inline uint32_t tzc_read_build_config(uint64_t base)
{
return mmio_read_32(base + BUILD_CONFIG_OFF);
}
-static uint32_t tzc_read_gate_keeper(uint64_t base)
+static inline uint32_t tzc_read_gate_keeper(uint64_t base)
{
return mmio_read_32(base + GATE_KEEPER_OFF);
}
-static void tzc_write_gate_keeper(uint64_t base, uint32_t val)
+static inline void tzc_write_gate_keeper(uint64_t base, uint32_t val)
{
mmio_write_32(base + GATE_KEEPER_OFF, val);
}
-static void tzc_write_action(uint64_t base, tzc_action_t action)
+static inline void tzc_write_action(uint64_t base, tzc_action_t action)
{
mmio_write_32(base + ACTION_OFF, action);
}
-static void tzc_write_region_base_low(uint64_t base, uint32_t region, uint32_t val)
+static inline void tzc_write_region_base_low(uint64_t base,
+ uint32_t region,
+ uint32_t val)
{
- mmio_write_32(base + REGION_BASE_LOW_OFF + REGION_NUM_OFF(region), val);
+ mmio_write_32(base + REGION_BASE_LOW_OFF +
+ REGION_NUM_OFF(region), val);
}
-static void tzc_write_region_base_high(uint64_t base, uint32_t region, uint32_t val)
+static inline void tzc_write_region_base_high(uint64_t base,
+ uint32_t region,
+ uint32_t val)
{
- mmio_write_32(base + REGION_BASE_HIGH_OFF + REGION_NUM_OFF(region), val);
+ mmio_write_32(base + REGION_BASE_HIGH_OFF +
+ REGION_NUM_OFF(region), val);
}
-static void tzc_write_region_top_low(uint64_t base, uint32_t region, uint32_t val)
+static inline void tzc_write_region_top_low(uint64_t base,
+ uint32_t region,
+ uint32_t val)
{
- mmio_write_32(base + REGION_TOP_LOW_OFF + REGION_NUM_OFF(region), val);
+ mmio_write_32(base + REGION_TOP_LOW_OFF +
+ REGION_NUM_OFF(region), val);
}
-static void tzc_write_region_top_high(uint64_t base, uint32_t region, uint32_t val)
+static inline void tzc_write_region_top_high(uint64_t base,
+ uint32_t region,
+ uint32_t val)
{
- mmio_write_32(base + REGION_TOP_HIGH_OFF + REGION_NUM_OFF(region), val);
+ mmio_write_32(base + REGION_TOP_HIGH_OFF +
+ REGION_NUM_OFF(region), val);
}
-static void tzc_write_region_attributes(uint64_t base, uint32_t region, uint32_t val)
+static inline void tzc_write_region_attributes(uint64_t base,
+ uint32_t region,
+ uint32_t val)
{
- mmio_write_32(base + REGION_ATTRIBUTES_OFF + REGION_NUM_OFF(region), val);
+ mmio_write_32(base + REGION_ATTRIBUTES_OFF +
+ REGION_NUM_OFF(region), val);
}
-static void tzc_write_region_id_access(uint64_t base, uint32_t region, uint32_t val)
+static inline void tzc_write_region_id_access(uint64_t base,
+ uint32_t region,
+ uint32_t val)
{
- mmio_write_32(base + REGION_ID_ACCESS_OFF + REGION_NUM_OFF(region), val);
+ mmio_write_32(base + REGION_ID_ACCESS_OFF +
+ REGION_NUM_OFF(region), val);
}
static uint32_t tzc_read_component_id(uint64_t base)
@@ -130,29 +164,30 @@ static void tzc_set_gate_keeper(uint64_t base, uint8_t filter, uint32_t val)
}
-void tzc_init(tzc_instance_t *controller)
+void tzc_init(uint64_t base)
{
uint32_t tzc_id, tzc_build;
- assert(controller != NULL);
+ assert(base);
+ tzc.base = base;
/*
* We expect to see a tzc400. Check component ID. The TZC-400 TRM shows
* component ID is expected to be "0xB105F00D".
*/
- tzc_id = tzc_read_component_id(controller->base);
+ tzc_id = tzc_read_component_id(tzc.base);
if (tzc_id != TZC400_COMPONENT_ID) {
ERROR("TZC : Wrong device ID (0x%x).\n", tzc_id);
panic();
}
/* Save values we will use later. */
- tzc_build = tzc_read_build_config(controller->base);
- controller->num_filters = ((tzc_build >> BUILD_CONFIG_NF_SHIFT) &
+ tzc_build = tzc_read_build_config(tzc.base);
+ tzc.num_filters = ((tzc_build >> BUILD_CONFIG_NF_SHIFT) &
BUILD_CONFIG_NF_MASK) + 1;
- controller->addr_width = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) &
+ tzc.addr_width = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) &
BUILD_CONFIG_AW_MASK) + 1;
- controller->num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) &
+ tzc.num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) &
BUILD_CONFIG_NR_MASK) + 1;
}
@@ -166,29 +201,25 @@ void tzc_init(tzc_instance_t *controller)
* this cannot be changed. It is, however, possible to change some region 0
* permissions.
*/
-void tzc_configure_region(const tzc_instance_t *controller,
- uint32_t filters,
+void tzc_configure_region(uint32_t filters,
uint8_t region,
uint64_t region_base,
uint64_t region_top,
tzc_region_attributes_t sec_attr,
uint32_t ns_device_access)
{
- uint64_t max_addr;
-
- assert(controller != NULL);
+ assert(tzc.base);
/* Do range checks on filters and regions. */
- assert(((filters >> controller->num_filters) == 0) &&
- (region < controller->num_regions));
+ assert(((filters >> tzc.num_filters) == 0) &&
+ (region < tzc.num_regions));
/*
* Do address range check based on TZC configuration. A 64bit address is
* the max and expected case.
*/
- max_addr = UINT64_MAX >> (64 - controller->addr_width);
- if ((region_top > max_addr) || (region_base >= region_top))
- assert(0);
+ assert(((region_top <= (UINT64_MAX >> (64 - tzc.addr_width))) &&
+ (region_base < region_top)));
/* region_base and (region_top + 1) must be 4KB aligned */
assert(((region_base | (region_top + 1)) & (4096 - 1)) == 0);
@@ -200,46 +231,50 @@ void tzc_configure_region(const tzc_instance_t *controller,
* All the address registers are 32 bits wide and have a LOW and HIGH
* component used to construct a up to a 64bit address.
*/
- tzc_write_region_base_low(controller->base, region, (uint32_t)(region_base));
- tzc_write_region_base_high(controller->base, region, (uint32_t)(region_base >> 32));
+ tzc_write_region_base_low(tzc.base, region,
+ (uint32_t)(region_base));
+ tzc_write_region_base_high(tzc.base, region,
+ (uint32_t)(region_base >> 32));
- tzc_write_region_top_low(controller->base, region, (uint32_t)(region_top));
- tzc_write_region_top_high(controller->base, region, (uint32_t)(region_top >> 32));
+ tzc_write_region_top_low(tzc.base, region,
+ (uint32_t)(region_top));
+ tzc_write_region_top_high(tzc.base, region,
+ (uint32_t)(region_top >> 32));
/* Assign the region to a filter and set secure attributes */
- tzc_write_region_attributes(controller->base, region,
+ tzc_write_region_attributes(tzc.base, region,
(sec_attr << REGION_ATTRIBUTES_SEC_SHIFT) | filters);
/*
* Specify which non-secure devices have permission to access this
* region.
*/
- tzc_write_region_id_access(controller->base, region, ns_device_access);
+ tzc_write_region_id_access(tzc.base, region, ns_device_access);
}
-void tzc_set_action(const tzc_instance_t *controller, tzc_action_t action)
+void tzc_set_action(tzc_action_t action)
{
- assert(controller != NULL);
+ assert(tzc.base);
/*
* - Currently no handler is provided to trap an error via interrupt
* or exception.
* - The interrupt action has not been tested.
*/
- tzc_write_action(controller->base, action);
+ tzc_write_action(tzc.base, action);
}
-void tzc_enable_filters(const tzc_instance_t *controller)
+void tzc_enable_filters(void)
{
uint32_t state;
uint32_t filter;
- assert(controller != NULL);
+ assert(tzc.base);
- for (filter = 0; filter < controller->num_filters; filter++) {
- state = tzc_get_gate_keeper(controller->base, filter);
+ for (filter = 0; filter < tzc.num_filters; filter++) {
+ state = tzc_get_gate_keeper(tzc.base, filter);
if (state) {
/* The TZC filter is already configured. Changing the
* programmer's view in an active system can cause
@@ -252,21 +287,21 @@ void tzc_enable_filters(const tzc_instance_t *controller)
filter);
panic();
}
- tzc_set_gate_keeper(controller->base, filter, 1);
+ tzc_set_gate_keeper(tzc.base, filter, 1);
}
}
-void tzc_disable_filters(const tzc_instance_t *controller)
+void tzc_disable_filters(void)
{
uint32_t filter;
- assert(controller != NULL);
+ assert(tzc.base);
/*
* We don't do the same state check as above as the Gatekeepers are
* disabled after reset.
*/
- for (filter = 0; filter < controller->num_filters; filter++)
- tzc_set_gate_keeper(controller->base, filter, 0);
+ for (filter = 0; filter < tzc.num_filters; filter++)
+ tzc_set_gate_keeper(tzc.base, filter, 0);
}