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 #include -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 @@ } -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 @@ * 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 @@ * 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 @@ 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); } diff --git a/include/drivers/arm/tzc400.h b/include/drivers/arm/tzc400.h index 03fce54..ff8b49a 100644 --- a/include/drivers/arm/tzc400.h +++ b/include/drivers/arm/tzc400.h @@ -182,27 +182,17 @@ TZC_REGION_S_RDWR = (TZC_REGION_S_RD | TZC_REGION_S_WR) } tzc_region_attributes_t; -/* - * 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; - uint32_t aid_width; - uint8_t addr_width; - uint8_t num_filters; - uint8_t num_regions; -} tzc_instance_t ; -void tzc_init(tzc_instance_t *controller); -void tzc_configure_region(const tzc_instance_t *controller, 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); -void tzc_enable_filters(const tzc_instance_t *controller); -void tzc_disable_filters(const tzc_instance_t *controller); -void tzc_set_action(const tzc_instance_t *controller, tzc_action_t action); +void tzc_init(uint64_t base); +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); +void tzc_enable_filters(void); +void tzc_disable_filters(void); +void tzc_set_action(tzc_action_t action); #endif /* __TZC400__ */ diff --git a/plat/fvp/fvp_def.h b/plat/fvp/fvp_def.h index dee2a19..b2c26fc 100644 --- a/plat/fvp/fvp_def.h +++ b/plat/fvp/fvp_def.h @@ -239,9 +239,6 @@ * The NSAIDs for this platform as used to program the TZC400. */ -/* The FVP has 4 bits of NSAIDs. Used with TZC FAIL_ID (ACE Lite ID width) */ -#define FVP_AID_WIDTH 4 - /* NSAIDs used by devices in TZC filter 0 on FVP */ #define FVP_NSAID_DEFAULT 0 #define FVP_NSAID_PCI 1 diff --git a/plat/fvp/fvp_security.c b/plat/fvp/fvp_security.c index 0adbbc5..06ab575 100644 --- a/plat/fvp/fvp_security.c +++ b/plat/fvp/fvp_security.c @@ -46,8 +46,6 @@ */ void fvp_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 @@ -71,9 +69,7 @@ * - 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); + tzc_init(TZC400_BASE); /* * Currently only filters 0 and 2 are connected on Base FVP. @@ -87,7 +83,7 @@ */ /* Disable all filters before programming. */ - tzc_disable_filters(&controller); + tzc_disable_filters(); /* * Allow only non-secure access to all DRAM to supported devices. @@ -101,7 +97,7 @@ */ /* Set to cover the first block of DRAM */ - tzc_configure_region(&controller, FILTER_SHIFT(0), 1, + tzc_configure_region(FILTER_SHIFT(0), 1, DRAM1_BASE, DRAM1_END - DRAM1_SEC_SIZE, TZC_REGION_S_NONE, TZC_REGION_ACCESS_RDWR(FVP_NSAID_DEFAULT) | @@ -111,13 +107,13 @@ TZC_REGION_ACCESS_RDWR(FVP_NSAID_VIRTIO_OLD)); /* Set to cover the secure reserved region */ - tzc_configure_region(&controller, FILTER_SHIFT(0), 3, + tzc_configure_region(FILTER_SHIFT(0), 3, (DRAM1_END - DRAM1_SEC_SIZE) + 1 , DRAM1_END, TZC_REGION_S_RDWR, 0x0); /* Set to cover the second block of DRAM */ - tzc_configure_region(&controller, FILTER_SHIFT(0), 2, + tzc_configure_region(FILTER_SHIFT(0), 2, DRAM2_BASE, DRAM2_END, TZC_REGION_S_NONE, TZC_REGION_ACCESS_RDWR(FVP_NSAID_DEFAULT) | TZC_REGION_ACCESS_RDWR(FVP_NSAID_PCI) | @@ -130,8 +126,8 @@ * 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); + tzc_set_action(TZC_ACTION_ERR); /* Enable filters. */ - tzc_enable_filters(&controller); + tzc_enable_filters(); }