diff --git a/Makefile b/Makefile index fcbf773..89e882a 100644 --- a/Makefile +++ b/Makefile @@ -102,7 +102,6 @@ lib/aarch64/misc_helpers.S \ lib/aarch64/xlat_helpers.c \ lib/stdlib/std.c \ - lib/io_storage.c \ plat/common/aarch64/platform_helpers.S BUILD_BASE := ./build @@ -180,6 +179,7 @@ -Iinclude/common \ -Iinclude/drivers \ -Iinclude/drivers/arm \ + -Iinclude/drivers/io \ -Iinclude/lib \ -Iinclude/lib/aarch64 \ -Iinclude/plat/common \ diff --git a/docs/porting-guide.md b/docs/porting-guide.md index eb3b86d..3070775 100644 --- a/docs/porting-guide.md +++ b/docs/porting-guide.md @@ -218,6 +218,21 @@ the secure memory identified by `TSP_SEC_MEM_BASE` and `TSP_SEC_MEM_SIZE` constants. +If the platform port uses the IO storage framework, the following constants +must also be defined: + +* **#define : MAX_IO_DEVICES** + + Defines the maximum number of registered IO devices. Attempting to register + more devices than this value using `io_register_device()` will fail with + IO_RESOURCES_EXHAUSTED. + +* **#define : MAX_IO_HANDLES** + + Defines the maximum number of open IO handles. Attempting to open more IO + entities than this value using `io_open()` will fail with + IO_RESOURCES_EXHAUSTED. + The following constants are optional. They should be defined when the platform memory layout implies some image overlaying like on FVP. diff --git a/drivers/arm/cci400/cci400.c b/drivers/arm/cci400/cci400.c index af10f21..6a8737a 100644 --- a/drivers/arm/cci400/cci400.c +++ b/drivers/arm/cci400/cci400.c @@ -28,34 +28,80 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include +#include #include #include -#include + +#define MAX_CLUSTERS 2 + +static unsigned long cci_base_addr; +static unsigned int cci_cluster_ix_to_iface[MAX_CLUSTERS]; + + +void cci_init(unsigned long cci_base, + int slave_iface3_cluster_ix, + int slave_iface4_cluster_ix) +{ + /* + * Check the passed arguments are valid. The cluster indices must be + * less than MAX_CLUSTERS, not the same as each other and at least one + * of them must be refer to a valid cluster index. + */ + assert(cci_base); + assert(slave_iface3_cluster_ix < MAX_CLUSTERS); + assert(slave_iface4_cluster_ix < MAX_CLUSTERS); + assert(slave_iface3_cluster_ix != slave_iface4_cluster_ix); + assert((slave_iface3_cluster_ix >= 0) || + (slave_iface3_cluster_ix >= 0)); + + cci_base_addr = cci_base; + if (slave_iface3_cluster_ix >= 0) + cci_cluster_ix_to_iface[slave_iface3_cluster_ix] = + SLAVE_IFACE3_OFFSET; + if (slave_iface4_cluster_ix >= 0) + cci_cluster_ix_to_iface[slave_iface4_cluster_ix] = + SLAVE_IFACE4_OFFSET; +} static inline unsigned long get_slave_iface_base(unsigned long mpidr) { - return CCI400_BASE + SLAVE_IFACE_OFFSET(CCI400_SL_IFACE_INDEX(mpidr)); + /* + * We assume the TF topology code allocates affinity instances + * consecutively from zero. + * It is a programming error if this is called without initializing + * the slave interface to use for this cluster. + */ + unsigned int cluster_id = + (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + + assert(cluster_id < MAX_CLUSTERS); + assert(cci_cluster_ix_to_iface[cluster_id] != 0); + + return cci_base_addr + cci_cluster_ix_to_iface[cluster_id]; } -void cci_enable_coherency(unsigned long mpidr) +void cci_enable_cluster_coherency(unsigned long mpidr) { + assert(cci_base_addr); /* Enable Snoops and DVM messages */ mmio_write_32(get_slave_iface_base(mpidr) + SNOOP_CTRL_REG, DVM_EN_BIT | SNOOP_EN_BIT); /* Wait for the dust to settle down */ - while (mmio_read_32(CCI400_BASE + STATUS_REG) & CHANGE_PENDING_BIT) + while (mmio_read_32(cci_base_addr + STATUS_REG) & CHANGE_PENDING_BIT) ; } -void cci_disable_coherency(unsigned long mpidr) +void cci_disable_cluster_coherency(unsigned long mpidr) { + assert(cci_base_addr); /* Disable Snoops and DVM messages */ mmio_write_32(get_slave_iface_base(mpidr) + SNOOP_CTRL_REG, ~(DVM_EN_BIT | SNOOP_EN_BIT)); /* Wait for the dust to settle down */ - while (mmio_read_32(CCI400_BASE + STATUS_REG) & CHANGE_PENDING_BIT) + while (mmio_read_32(cci_base_addr + STATUS_REG) & CHANGE_PENDING_BIT) ; } 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/drivers/io/io_storage.c b/drivers/io/io_storage.c new file mode 100644 index 0000000..a3a8186 --- /dev/null +++ b/drivers/io/io_storage.c @@ -0,0 +1,373 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + + +/* Storage for a fixed maximum number of IO entities, definable by platform */ +static io_entity_t entity_pool[MAX_IO_HANDLES]; + +/* Simple way of tracking used storage - each entry is NULL or a pointer to an + * entity */ +static io_entity_t *entity_map[MAX_IO_HANDLES]; + +/* Track number of allocated entities */ +static unsigned int entity_count; + +/* Array of fixed maximum of registered devices, definable by platform */ +static const io_dev_info_t *devices[MAX_IO_DEVICES]; + +/* Number of currently registered devices */ +static unsigned int dev_count; + + +#if DEBUG /* Extra validation functions only used in debug builds */ + +/* Return a boolean value indicating whether a device connector is valid */ +static int is_valid_dev_connector(const io_dev_connector_t *dev_con) +{ + int result = (dev_con != NULL) && (dev_con->dev_open != NULL); + return result; +} + + +/* Return a boolean value indicating whether a device handle is valid */ +static int is_valid_dev(const uintptr_t dev_handle) +{ + const io_dev_info_t *dev = (io_dev_info_t *)dev_handle; + int result = (dev != NULL) && (dev->funcs != NULL) && + (dev->funcs->type != NULL) && + (dev->funcs->type() < IO_TYPE_MAX); + return result; +} + + +/* Return a boolean value indicating whether an IO entity is valid */ +static int is_valid_entity(const uintptr_t handle) +{ + const io_entity_t *entity = (io_entity_t *)handle; + int result = (entity != NULL) && + (is_valid_dev((uintptr_t)entity->dev_handle)); + return result; +} + + +/* Return a boolean value indicating whether a seek mode is valid */ +static int is_valid_seek_mode(io_seek_mode_t mode) +{ + return ((mode != IO_SEEK_INVALID) && (mode < IO_SEEK_MAX)); +} + +#endif /* End of debug-only validation functions */ + + +/* Open a connection to a specific device */ +static int dev_open(const io_dev_connector_t *dev_con, const uintptr_t dev_spec, + io_dev_info_t **dev_info) +{ + int result = IO_FAIL; + assert(dev_info != NULL); + assert(is_valid_dev_connector(dev_con)); + + result = dev_con->dev_open(dev_spec, dev_info); + return result; +} + + +/* Set a handle to track an entity */ +static void set_handle(uintptr_t *handle, io_entity_t *entity) +{ + assert(handle != NULL); + *handle = (uintptr_t)entity; +} + + +/* Locate an entity in the pool, specified by address */ +static int find_first_entity(const io_entity_t *entity, unsigned int *index_out) +{ + int result = IO_FAIL; + for (int index = 0; index < MAX_IO_HANDLES; ++index) { + if (entity_map[index] == entity) { + result = IO_SUCCESS; + *index_out = index; + break; + } + } + return result; +} + + +/* Allocate an entity from the pool and return a pointer to it */ +static int allocate_entity(io_entity_t **entity) +{ + int result = IO_FAIL; + assert(entity != NULL); + + if (entity_count < MAX_IO_HANDLES) { + unsigned int index = 0; + result = find_first_entity(NULL, &index); + assert(result == IO_SUCCESS); + *entity = entity_map[index] = &entity_pool[index]; + ++entity_count; + } else + result = IO_RESOURCES_EXHAUSTED; + + return result; +} + + +/* Release an entity back to the pool */ +static int free_entity(const io_entity_t *entity) +{ + int result = IO_FAIL; + unsigned int index = 0; + assert(entity != NULL); + + result = find_first_entity(entity, &index); + if (result == IO_SUCCESS) { + entity_map[index] = NULL; + --entity_count; + } + + return result; +} + + +/* Exported API */ + +/* Register a device driver */ +int io_register_device(const io_dev_info_t *dev_info) +{ + int result = IO_FAIL; + assert(dev_info != NULL); + + if (dev_count < MAX_IO_DEVICES) { + devices[dev_count] = dev_info; + dev_count++; + result = IO_SUCCESS; + } else { + result = IO_RESOURCES_EXHAUSTED; + } + + return result; +} + + +/* Open a connection to an IO device */ +int io_dev_open(const io_dev_connector_t *dev_con, const uintptr_t dev_spec, + uintptr_t *handle) +{ + int result = IO_FAIL; + assert(handle != NULL); + + result = dev_open(dev_con, dev_spec, (io_dev_info_t **)handle); + return result; +} + + +/* Initialise an IO device explicitly - to permit lazy initialisation or + * re-initialisation */ +int io_dev_init(uintptr_t dev_handle, const uintptr_t init_params) +{ + int result = IO_FAIL; + assert(dev_handle != (uintptr_t)NULL); + assert(is_valid_dev(dev_handle)); + + io_dev_info_t *dev = (io_dev_info_t *)dev_handle; + + if (dev->funcs->dev_init != NULL) { + result = dev->funcs->dev_init(dev, init_params); + } else { + /* Absence of registered function implies NOP here */ + result = IO_SUCCESS; + } + return result; +} + + +/* TODO: Consider whether an explicit "shutdown" API should be included */ + +/* Close a connection to a device */ +int io_dev_close(uintptr_t dev_handle) +{ + int result = IO_FAIL; + assert(dev_handle != (uintptr_t)NULL); + assert(is_valid_dev(dev_handle)); + + io_dev_info_t *dev = (io_dev_info_t *)dev_handle; + + if (dev->funcs->dev_close != NULL) { + result = dev->funcs->dev_close(dev); + } else { + /* Absence of registered function implies NOP here */ + result = IO_SUCCESS; + } + + return result; +} + + +/* Synchronous operations */ + + +/* Open an IO entity */ +int io_open(uintptr_t dev_handle, const uintptr_t spec, uintptr_t *handle) +{ + int result = IO_FAIL; + assert((spec != (uintptr_t)NULL) && (handle != NULL)); + assert(is_valid_dev(dev_handle)); + + io_dev_info_t *dev = (io_dev_info_t *)dev_handle; + io_entity_t *entity; + + result = allocate_entity(&entity); + + if (result == IO_SUCCESS) { + assert(dev->funcs->open != NULL); + result = dev->funcs->open(dev, spec, entity); + + if (result == IO_SUCCESS) { + entity->dev_handle = dev; + set_handle(handle, entity); + } else + free_entity(entity); + } + return result; +} + + +/* Seek to a specific position in an IO entity */ +int io_seek(uintptr_t handle, io_seek_mode_t mode, ssize_t offset) +{ + int result = IO_FAIL; + assert(is_valid_entity(handle) && is_valid_seek_mode(mode)); + + io_entity_t *entity = (io_entity_t *)handle; + + io_dev_info_t *dev = entity->dev_handle; + + if (dev->funcs->seek != NULL) + result = dev->funcs->seek(entity, mode, offset); + else + result = IO_NOT_SUPPORTED; + + return result; +} + + +/* Determine the length of an IO entity */ +int io_size(uintptr_t handle, size_t *length) +{ + int result = IO_FAIL; + assert(is_valid_entity(handle) && (length != NULL)); + + io_entity_t *entity = (io_entity_t *)handle; + + io_dev_info_t *dev = entity->dev_handle; + + if (dev->funcs->size != NULL) + result = dev->funcs->size(entity, length); + else + result = IO_NOT_SUPPORTED; + + return result; +} + + +/* Read data from an IO entity */ +int io_read(uintptr_t handle, + uintptr_t buffer, + size_t length, + size_t *length_read) +{ + int result = IO_FAIL; + assert(is_valid_entity(handle) && (buffer != (uintptr_t)NULL)); + + io_entity_t *entity = (io_entity_t *)handle; + + io_dev_info_t *dev = entity->dev_handle; + + if (dev->funcs->read != NULL) + result = dev->funcs->read(entity, buffer, length, length_read); + else + result = IO_NOT_SUPPORTED; + + return result; +} + + +/* Write data to an IO entity */ +int io_write(uintptr_t handle, + const uintptr_t buffer, + size_t length, + size_t *length_written) +{ + int result = IO_FAIL; + assert(is_valid_entity(handle) && (buffer != (uintptr_t)NULL)); + + io_entity_t *entity = (io_entity_t *)handle; + + io_dev_info_t *dev = entity->dev_handle; + + if (dev->funcs->write != NULL) { + result = dev->funcs->write(entity, buffer, length, + length_written); + } else + result = IO_NOT_SUPPORTED; + + return result; +} + + +/* Close an IO entity */ +int io_close(uintptr_t handle) +{ + int result = IO_FAIL; + assert(is_valid_entity(handle)); + + io_entity_t *entity = (io_entity_t *)handle; + + io_dev_info_t *dev = entity->dev_handle; + + if (dev->funcs->close != NULL) + result = dev->funcs->close(entity); + else { + /* Absence of registered function implies NOP here */ + result = IO_SUCCESS; + } + /* Ignore improbable free_entity failure */ + (void)free_entity(entity); + + return result; +} diff --git a/include/drivers/arm/cci400.h b/include/drivers/arm/cci400.h index 6246e48..7756bdf 100644 --- a/include/drivers/arm/cci400.h +++ b/include/drivers/arm/cci400.h @@ -37,7 +37,8 @@ #define SLAVE_IFACE2_OFFSET 0x3000 #define SLAVE_IFACE1_OFFSET 0x2000 #define SLAVE_IFACE0_OFFSET 0x1000 -#define SLAVE_IFACE_OFFSET(index) SLAVE_IFACE0_OFFSET + (0x1000 * index) +#define SLAVE_IFACE_OFFSET(index) SLAVE_IFACE0_OFFSET + \ + (0x1000 * (index)) /* Control and ID register offsets */ #define CTRL_OVERRIDE_REG 0x0 @@ -68,8 +69,22 @@ #ifndef __ASSEMBLY__ /* Function declarations */ -void cci_enable_coherency(unsigned long mpidr); -void cci_disable_coherency(unsigned long mpidr); + +/* + * The CCI-400 driver must be initialized with the base address of the + * CCI-400 device in the platform memory map, and the cluster indices for + * the CCI-400 slave interfaces 3 and 4 respectively. These are the fully + * coherent ACE slave interfaces of CCI-400. + * The cluster indices must either be 0 or 1, corresponding to the level 1 + * affinity instance of the mpidr representing the cluster. A negative cluster + * index indicates that no cluster is present on that slave interface. + */ +void cci_init(unsigned long cci_base, + int slave_iface3_cluster_ix, + int slave_iface4_cluster_ix); + +void cci_enable_cluster_coherency(unsigned long mpidr); +void cci_disable_cluster_coherency(unsigned long mpidr); #endif /* __ASSEMBLY__ */ #endif /* __CCI_400_H__ */ 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/include/drivers/io/io_driver.h b/include/drivers/io/io_driver.h new file mode 100644 index 0000000..adb38b0 --- /dev/null +++ b/include/drivers/io/io_driver.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __IO_DRIVER_H__ +#define __IO_DRIVER_H__ + +#include +#include + + +/* Generic IO entity structure,representing an accessible IO construct on the + * device, such as a file */ +typedef struct io_entity { + struct io_dev_info *dev_handle; + uintptr_t info; +} io_entity_t; + + +/* Device info structure, providing device-specific functions and a means of + * adding driver-specific state */ +typedef struct io_dev_info { + const struct io_dev_funcs *funcs; + uintptr_t info; +} io_dev_info_t; + + +/* Structure used to create a connection to a type of device */ +typedef struct io_dev_connector { + /* dev_open opens a connection to a particular device driver */ + int (*dev_open)(const uintptr_t dev_spec, io_dev_info_t **dev_info); +} io_dev_connector_t; + + +/* Structure to hold device driver function pointers */ +typedef struct io_dev_funcs { + io_type_t (*type)(void); + int (*open)(io_dev_info_t *dev_info, const uintptr_t spec, + io_entity_t *entity); + int (*seek)(io_entity_t *entity, int mode, ssize_t offset); + int (*size)(io_entity_t *entity, size_t *length); + int (*read)(io_entity_t *entity, uintptr_t buffer, size_t length, + size_t *length_read); + int (*write)(io_entity_t *entity, const uintptr_t buffer, + size_t length, size_t *length_written); + int (*close)(io_entity_t *entity); + int (*dev_init)(io_dev_info_t *dev_info, const uintptr_t init_params); + int (*dev_close)(io_dev_info_t *dev_info); +} io_dev_funcs_t; + + +/* Operations intended to be performed during platform initialisation */ + +/* Register an IO device */ +int io_register_device(const io_dev_info_t *dev_info); + +#endif /* __IO_DRIVER_H__ */ diff --git a/include/drivers/io/io_fip.h b/include/drivers/io/io_fip.h new file mode 100644 index 0000000..90b2fd0 --- /dev/null +++ b/include/drivers/io/io_fip.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014 ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __IO_FIP_H__ +#define __IO_FIP_H__ + +struct io_dev_connector; + +int register_io_dev_fip(const struct io_dev_connector **dev_con); + +#endif /* __IO_FIP_H__ */ diff --git a/include/drivers/io/io_memmap.h b/include/drivers/io/io_memmap.h new file mode 100644 index 0000000..7ee60fe --- /dev/null +++ b/include/drivers/io/io_memmap.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __IO_MEMMAP_H__ +#define __IO_MEMMAP_H__ + +struct io_dev_connector; + +int register_io_dev_memmap(const struct io_dev_connector **dev_con); + +#endif /* __IO_MEMMAP_H__ */ diff --git a/include/drivers/io/io_semihosting.h b/include/drivers/io/io_semihosting.h new file mode 100644 index 0000000..8902a6f --- /dev/null +++ b/include/drivers/io/io_semihosting.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __IO_SH_H__ +#define __IO_SH_H__ + +struct io_dev_connector; + +int register_io_dev_sh(const struct io_dev_connector **dev_con); + +#endif /* __IO_SH_H__ */ diff --git a/include/drivers/io/io_storage.h b/include/drivers/io/io_storage.h new file mode 100644 index 0000000..ae1158c --- /dev/null +++ b/include/drivers/io/io_storage.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __IO_H__ +#define __IO_H__ + +#include +#include /* For ssize_t */ + + +/* Device type which can be used to enable policy decisions about which device + * to access */ +typedef enum { + IO_TYPE_INVALID, + IO_TYPE_SEMIHOSTING, + IO_TYPE_MEMMAP, + IO_TYPE_FIRMWARE_IMAGE_PACKAGE, + IO_TYPE_MAX +} io_type_t; + + +/* Modes used when seeking data on a supported device */ +typedef enum { + IO_SEEK_INVALID, + IO_SEEK_SET, + IO_SEEK_END, + IO_SEEK_CUR, + IO_SEEK_MAX +} io_seek_mode_t; + + +/* Connector type, providing a means of identifying a device to open */ +struct io_dev_connector; + + +/* File specification - used to refer to data on a device supporting file-like + * entities */ +typedef struct io_file_spec { + const char *path; + unsigned int mode; +} io_file_spec_t; + + +/* Block specification - used to refer to data on a device supporting + * block-like entities */ +typedef struct io_block_spec { + size_t offset; + size_t length; +} io_block_spec_t; + + +/* Access modes used when accessing data on a device */ +#define IO_MODE_INVALID (0) +#define IO_MODE_RO (1 << 0) +#define IO_MODE_RW (1 << 1) + + +/* Return codes reported by 'io_*' APIs */ +#define IO_SUCCESS (0) +#define IO_FAIL (-1) +#define IO_NOT_SUPPORTED (-2) +#define IO_RESOURCES_EXHAUSTED (-3) + + +/* Open a connection to a device */ +int io_dev_open(const struct io_dev_connector *dev_con, + const uintptr_t dev_spec, + uintptr_t *dev_handle); + + +/* Initialise a device explicitly - to permit lazy initialisation or + * re-initialisation */ +int io_dev_init(uintptr_t dev_handle, const uintptr_t init_params); + +/* TODO: Consider whether an explicit "shutdown" API should be included */ + +/* Close a connection to a device */ +int io_dev_close(uintptr_t dev_handle); + + +/* Synchronous operations */ +int io_open(uintptr_t dev_handle, const uintptr_t spec, uintptr_t *handle); + +int io_seek(uintptr_t handle, io_seek_mode_t mode, ssize_t offset); + +int io_size(uintptr_t handle, size_t *length); + +int io_read(uintptr_t handle, uintptr_t buffer, size_t length, + size_t *length_read); + +int io_write(uintptr_t handle, const uintptr_t buffer, size_t length, + size_t *length_written); + +int io_close(uintptr_t handle); + + +#endif /* __IO_H__ */ diff --git a/include/drivers/io_driver.h b/include/drivers/io_driver.h deleted file mode 100644 index 867abbf..0000000 --- a/include/drivers/io_driver.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __IO_DRIVER_H__ -#define __IO_DRIVER_H__ - -#include -#include /* For MAX_IO_DEVICES */ -#include - - -/* Generic IO entity structure,representing an accessible IO construct on the - * device, such as a file */ -typedef struct io_entity { - struct io_dev_info *dev_handle; - uintptr_t info; -} io_entity_t; - - -/* Device info structure, providing device-specific functions and a means of - * adding driver-specific state */ -typedef struct io_dev_info { - const struct io_dev_funcs *funcs; - uintptr_t info; -} io_dev_info_t; - - -/* Structure used to create a connection to a type of device */ -typedef struct io_dev_connector { - /* dev_open opens a connection to a particular device driver */ - int (*dev_open)(const uintptr_t dev_spec, io_dev_info_t **dev_info); -} io_dev_connector_t; - - -/* Structure to hold device driver function pointers */ -typedef struct io_dev_funcs { - io_type_t (*type)(void); - int (*open)(io_dev_info_t *dev_info, const uintptr_t spec, - io_entity_t *entity); - int (*seek)(io_entity_t *entity, int mode, ssize_t offset); - int (*size)(io_entity_t *entity, size_t *length); - int (*read)(io_entity_t *entity, uintptr_t buffer, size_t length, - size_t *length_read); - int (*write)(io_entity_t *entity, const uintptr_t buffer, - size_t length, size_t *length_written); - int (*close)(io_entity_t *entity); - int (*dev_init)(io_dev_info_t *dev_info, const uintptr_t init_params); - int (*dev_close)(io_dev_info_t *dev_info); -} io_dev_funcs_t; - - -/* IO platform data - used to track devices registered for a specific - * platform */ -typedef struct io_plat_data { - const io_dev_info_t *devices[MAX_IO_DEVICES]; - unsigned int dev_count; -} io_plat_data_t; - - -/* Operations intended to be performed during platform initialisation */ - -/* Initialise the IO layer */ -void io_init(io_plat_data_t *data); - -/* Register a device driver */ -int io_register_device(const io_dev_info_t *dev_info); - -#endif /* __IO_DRIVER_H__ */ diff --git a/include/drivers/io_fip.h b/include/drivers/io_fip.h deleted file mode 100644 index 90b2fd0..0000000 --- a/include/drivers/io_fip.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2014 ARM Limited and Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __IO_FIP_H__ -#define __IO_FIP_H__ - -struct io_dev_connector; - -int register_io_dev_fip(const struct io_dev_connector **dev_con); - -#endif /* __IO_FIP_H__ */ diff --git a/include/drivers/io_memmap.h b/include/drivers/io_memmap.h deleted file mode 100644 index 7ee60fe..0000000 --- a/include/drivers/io_memmap.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __IO_MEMMAP_H__ -#define __IO_MEMMAP_H__ - -struct io_dev_connector; - -int register_io_dev_memmap(const struct io_dev_connector **dev_con); - -#endif /* __IO_MEMMAP_H__ */ diff --git a/include/drivers/io_semihosting.h b/include/drivers/io_semihosting.h deleted file mode 100644 index 8902a6f..0000000 --- a/include/drivers/io_semihosting.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __IO_SH_H__ -#define __IO_SH_H__ - -struct io_dev_connector; - -int register_io_dev_sh(const struct io_dev_connector **dev_con); - -#endif /* __IO_SH_H__ */ diff --git a/include/lib/io_storage.h b/include/lib/io_storage.h deleted file mode 100644 index ae1158c..0000000 --- a/include/lib/io_storage.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __IO_H__ -#define __IO_H__ - -#include -#include /* For ssize_t */ - - -/* Device type which can be used to enable policy decisions about which device - * to access */ -typedef enum { - IO_TYPE_INVALID, - IO_TYPE_SEMIHOSTING, - IO_TYPE_MEMMAP, - IO_TYPE_FIRMWARE_IMAGE_PACKAGE, - IO_TYPE_MAX -} io_type_t; - - -/* Modes used when seeking data on a supported device */ -typedef enum { - IO_SEEK_INVALID, - IO_SEEK_SET, - IO_SEEK_END, - IO_SEEK_CUR, - IO_SEEK_MAX -} io_seek_mode_t; - - -/* Connector type, providing a means of identifying a device to open */ -struct io_dev_connector; - - -/* File specification - used to refer to data on a device supporting file-like - * entities */ -typedef struct io_file_spec { - const char *path; - unsigned int mode; -} io_file_spec_t; - - -/* Block specification - used to refer to data on a device supporting - * block-like entities */ -typedef struct io_block_spec { - size_t offset; - size_t length; -} io_block_spec_t; - - -/* Access modes used when accessing data on a device */ -#define IO_MODE_INVALID (0) -#define IO_MODE_RO (1 << 0) -#define IO_MODE_RW (1 << 1) - - -/* Return codes reported by 'io_*' APIs */ -#define IO_SUCCESS (0) -#define IO_FAIL (-1) -#define IO_NOT_SUPPORTED (-2) -#define IO_RESOURCES_EXHAUSTED (-3) - - -/* Open a connection to a device */ -int io_dev_open(const struct io_dev_connector *dev_con, - const uintptr_t dev_spec, - uintptr_t *dev_handle); - - -/* Initialise a device explicitly - to permit lazy initialisation or - * re-initialisation */ -int io_dev_init(uintptr_t dev_handle, const uintptr_t init_params); - -/* TODO: Consider whether an explicit "shutdown" API should be included */ - -/* Close a connection to a device */ -int io_dev_close(uintptr_t dev_handle); - - -/* Synchronous operations */ -int io_open(uintptr_t dev_handle, const uintptr_t spec, uintptr_t *handle); - -int io_seek(uintptr_t handle, io_seek_mode_t mode, ssize_t offset); - -int io_size(uintptr_t handle, size_t *length); - -int io_read(uintptr_t handle, uintptr_t buffer, size_t length, - size_t *length_read); - -int io_write(uintptr_t handle, const uintptr_t buffer, size_t length, - size_t *length_written); - -int io_close(uintptr_t handle); - - -#endif /* __IO_H__ */ diff --git a/lib/io_storage.c b/lib/io_storage.c deleted file mode 100644 index 204310a..0000000 --- a/lib/io_storage.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include - - -#define MAX_DEVICES(plat_data) \ - (sizeof((plat_data)->devices)/sizeof((plat_data)->devices[0])) - - -/* Storage for a fixed maximum number of IO entities, definable by platform */ -static io_entity_t entity_pool[MAX_IO_HANDLES]; - -/* Simple way of tracking used storage - each entry is NULL or a pointer to an - * entity */ -static io_entity_t *entity_map[MAX_IO_HANDLES]; - -/* Track number of allocated entities */ -static unsigned int entity_count; - - -/* Used to keep a reference to platform-specific data */ -static io_plat_data_t *platform_data; - - -#if DEBUG /* Extra validation functions only used in debug builds */ - -/* Return a boolean value indicating whether a device connector is valid */ -static int is_valid_dev_connector(const io_dev_connector_t *dev_con) -{ - int result = (dev_con != NULL) && (dev_con->dev_open != NULL); - return result; -} - - -/* Return a boolean value indicating whether a device handle is valid */ -static int is_valid_dev(const uintptr_t dev_handle) -{ - const io_dev_info_t *dev = (io_dev_info_t *)dev_handle; - int result = (dev != NULL) && (dev->funcs != NULL) && - (dev->funcs->type != NULL) && - (dev->funcs->type() < IO_TYPE_MAX); - return result; -} - - -/* Return a boolean value indicating whether an IO entity is valid */ -static int is_valid_entity(const uintptr_t handle) -{ - const io_entity_t *entity = (io_entity_t *)handle; - int result = (entity != NULL) && - (is_valid_dev((uintptr_t)entity->dev_handle)); - return result; -} - - -/* Return a boolean value indicating whether a seek mode is valid */ -static int is_valid_seek_mode(io_seek_mode_t mode) -{ - return ((mode != IO_SEEK_INVALID) && (mode < IO_SEEK_MAX)); -} - -#endif /* End of debug-only validation functions */ - - -/* Open a connection to a specific device */ -static int dev_open(const io_dev_connector_t *dev_con, const uintptr_t dev_spec, - io_dev_info_t **dev_info) -{ - int result = IO_FAIL; - assert(dev_info != NULL); - assert(is_valid_dev_connector(dev_con)); - - result = dev_con->dev_open(dev_spec, dev_info); - return result; -} - - -/* Set a handle to track an entity */ -static void set_handle(uintptr_t *handle, io_entity_t *entity) -{ - assert(handle != NULL); - *handle = (uintptr_t)entity; -} - - -/* Locate an entity in the pool, specified by address */ -static int find_first_entity(const io_entity_t *entity, unsigned int *index_out) -{ - int result = IO_FAIL; - for (int index = 0; index < MAX_IO_HANDLES; ++index) { - if (entity_map[index] == entity) { - result = IO_SUCCESS; - *index_out = index; - break; - } - } - return result; -} - - -/* Allocate an entity from the pool and return a pointer to it */ -static int allocate_entity(io_entity_t **entity) -{ - int result = IO_FAIL; - assert(entity != NULL); - - if (entity_count < MAX_IO_HANDLES) { - unsigned int index = 0; - result = find_first_entity(NULL, &index); - assert(result == IO_SUCCESS); - *entity = entity_map[index] = &entity_pool[index]; - ++entity_count; - } else - result = IO_RESOURCES_EXHAUSTED; - - return result; -} - - -/* Release an entity back to the pool */ -static int free_entity(const io_entity_t *entity) -{ - int result = IO_FAIL; - unsigned int index = 0; - assert(entity != NULL); - - result = find_first_entity(entity, &index); - if (result == IO_SUCCESS) { - entity_map[index] = NULL; - --entity_count; - } - - return result; -} - - -/* Exported API */ - - -/* Initialise the IO layer */ -void io_init(io_plat_data_t *data) -{ - assert(data != NULL); - platform_data = data; -} - - -/* Register a device driver */ -int io_register_device(const io_dev_info_t *dev_info) -{ - int result = IO_FAIL; - assert(dev_info != NULL); - assert(platform_data != NULL); - - unsigned int dev_count = platform_data->dev_count; - - if (dev_count < MAX_DEVICES(platform_data)) { - platform_data->devices[dev_count] = dev_info; - platform_data->dev_count++; - result = IO_SUCCESS; - } else { - result = IO_RESOURCES_EXHAUSTED; - } - - return result; -} - - -/* Open a connection to an IO device */ -int io_dev_open(const io_dev_connector_t *dev_con, const uintptr_t dev_spec, - uintptr_t *handle) -{ - int result = IO_FAIL; - assert(handle != NULL); - - result = dev_open(dev_con, dev_spec, (io_dev_info_t **)handle); - return result; -} - - -/* Initialise an IO device explicitly - to permit lazy initialisation or - * re-initialisation */ -int io_dev_init(uintptr_t dev_handle, const uintptr_t init_params) -{ - int result = IO_FAIL; - assert(dev_handle != (uintptr_t)NULL); - assert(is_valid_dev(dev_handle)); - - io_dev_info_t *dev = (io_dev_info_t *)dev_handle; - - if (dev->funcs->dev_init != NULL) { - result = dev->funcs->dev_init(dev, init_params); - } else { - /* Absence of registered function implies NOP here */ - result = IO_SUCCESS; - } - return result; -} - - -/* TODO: Consider whether an explicit "shutdown" API should be included */ - -/* Close a connection to a device */ -int io_dev_close(uintptr_t dev_handle) -{ - int result = IO_FAIL; - assert(dev_handle != (uintptr_t)NULL); - assert(is_valid_dev(dev_handle)); - - io_dev_info_t *dev = (io_dev_info_t *)dev_handle; - - if (dev->funcs->dev_close != NULL) { - result = dev->funcs->dev_close(dev); - } else { - /* Absence of registered function implies NOP here */ - result = IO_SUCCESS; - } - - return result; -} - - -/* Synchronous operations */ - - -/* Open an IO entity */ -int io_open(uintptr_t dev_handle, const uintptr_t spec, uintptr_t *handle) -{ - int result = IO_FAIL; - assert((spec != (uintptr_t)NULL) && (handle != NULL)); - assert(is_valid_dev(dev_handle)); - - io_dev_info_t *dev = (io_dev_info_t *)dev_handle; - io_entity_t *entity; - - result = allocate_entity(&entity); - - if (result == IO_SUCCESS) { - assert(dev->funcs->open != NULL); - result = dev->funcs->open(dev, spec, entity); - - if (result == IO_SUCCESS) { - entity->dev_handle = dev; - set_handle(handle, entity); - } else - free_entity(entity); - } - return result; -} - - -/* Seek to a specific position in an IO entity */ -int io_seek(uintptr_t handle, io_seek_mode_t mode, ssize_t offset) -{ - int result = IO_FAIL; - assert(is_valid_entity(handle) && is_valid_seek_mode(mode)); - - io_entity_t *entity = (io_entity_t *)handle; - - io_dev_info_t *dev = entity->dev_handle; - - if (dev->funcs->seek != NULL) - result = dev->funcs->seek(entity, mode, offset); - else - result = IO_NOT_SUPPORTED; - - return result; -} - - -/* Determine the length of an IO entity */ -int io_size(uintptr_t handle, size_t *length) -{ - int result = IO_FAIL; - assert(is_valid_entity(handle) && (length != NULL)); - - io_entity_t *entity = (io_entity_t *)handle; - - io_dev_info_t *dev = entity->dev_handle; - - if (dev->funcs->size != NULL) - result = dev->funcs->size(entity, length); - else - result = IO_NOT_SUPPORTED; - - return result; -} - - -/* Read data from an IO entity */ -int io_read(uintptr_t handle, - uintptr_t buffer, - size_t length, - size_t *length_read) -{ - int result = IO_FAIL; - assert(is_valid_entity(handle) && (buffer != (uintptr_t)NULL)); - - io_entity_t *entity = (io_entity_t *)handle; - - io_dev_info_t *dev = entity->dev_handle; - - if (dev->funcs->read != NULL) - result = dev->funcs->read(entity, buffer, length, length_read); - else - result = IO_NOT_SUPPORTED; - - return result; -} - - -/* Write data to an IO entity */ -int io_write(uintptr_t handle, - const uintptr_t buffer, - size_t length, - size_t *length_written) -{ - int result = IO_FAIL; - assert(is_valid_entity(handle) && (buffer != (uintptr_t)NULL)); - - io_entity_t *entity = (io_entity_t *)handle; - - io_dev_info_t *dev = entity->dev_handle; - - if (dev->funcs->write != NULL) { - result = dev->funcs->write(entity, buffer, length, - length_written); - } else - result = IO_NOT_SUPPORTED; - - return result; -} - - -/* Close an IO entity */ -int io_close(uintptr_t handle) -{ - int result = IO_FAIL; - assert(is_valid_entity(handle)); - - io_entity_t *entity = (io_entity_t *)handle; - - io_dev_info_t *dev = entity->dev_handle; - - if (dev->funcs->close != NULL) - result = dev->funcs->close(entity); - else { - /* Absence of registered function implies NOP here */ - result = IO_SUCCESS; - } - /* Ignore improbable free_entity failure */ - (void)free_entity(entity); - - return result; -} diff --git a/plat/fvp/aarch64/fvp_common.c b/plat/fvp/aarch64/fvp_common.c index 5041511..89fd8b3 100644 --- a/plat/fvp/aarch64/fvp_common.c +++ b/plat/fvp/aarch64/fvp_common.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -243,15 +242,26 @@ return counter_base_frequency; } -void fvp_cci_setup(void) +void fvp_cci_init(void) { /* - * Enable CCI-400 for this cluster. No need + * Initialize CCI-400 driver + */ + if (plat_config.flags & CONFIG_HAS_CCI) + cci_init(CCI400_BASE, + CCI400_SL_IFACE3_CLUSTER_IX, + CCI400_SL_IFACE4_CLUSTER_IX); +} + +void fvp_cci_enable(void) +{ + /* + * Enable CCI-400 coherency for this cluster. No need * for locks as no other cpu is active at the * moment */ if (plat_config.flags & CONFIG_HAS_CCI) - cci_enable_coherency(read_mpidr()); + cci_enable_cluster_coherency(read_mpidr()); } void fvp_gic_init(void) diff --git a/plat/fvp/bl1_fvp_setup.c b/plat/fvp/bl1_fvp_setup.c index 0cdb97a..b1205d4 100644 --- a/plat/fvp/bl1_fvp_setup.c +++ b/plat/fvp/bl1_fvp_setup.c @@ -110,7 +110,8 @@ ******************************************************************************/ void bl1_plat_arch_setup(void) { - fvp_cci_setup(); + fvp_cci_init(); + fvp_cci_enable(); fvp_configure_mmu_el3(bl1_tzram_layout.total_base, bl1_tzram_layout.total_size, diff --git a/plat/fvp/bl31_fvp_setup.c b/plat/fvp/bl31_fvp_setup.c index 0693a12..69efc9c 100644 --- a/plat/fvp/bl31_fvp_setup.c +++ b/plat/fvp/bl31_fvp_setup.c @@ -230,9 +230,9 @@ ******************************************************************************/ void bl31_plat_arch_setup(void) { + fvp_cci_init(); #if RESET_TO_BL31 - fvp_cci_setup(); - + fvp_cci_enable(); #endif fvp_configure_mmu_el3(BL31_RO_BASE, (BL31_COHERENT_RAM_LIMIT - BL31_RO_BASE), diff --git a/plat/fvp/fvp_def.h b/plat/fvp/fvp_def.h index b371ea9..b2c26fc 100644 --- a/plat/fvp/fvp_def.h +++ b/plat/fvp/fvp_def.h @@ -184,11 +184,8 @@ * CCI-400 related constants ******************************************************************************/ #define CCI400_BASE 0x2c090000 -#define CCI400_SL_IFACE_CLUSTER0 3 -#define CCI400_SL_IFACE_CLUSTER1 4 -#define CCI400_SL_IFACE_INDEX(mpidr) (mpidr & MPIDR_CLUSTER_MASK ? \ - CCI400_SL_IFACE_CLUSTER1 : \ - CCI400_SL_IFACE_CLUSTER0) +#define CCI400_SL_IFACE3_CLUSTER_IX 0 +#define CCI400_SL_IFACE4_CLUSTER_IX 1 /******************************************************************************* * GIC-400 & interrupt handling related constants @@ -242,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_io_storage.c b/plat/fvp/fvp_io_storage.c index 1f695a6..b4a04f1 100644 --- a/plat/fvp/fvp_io_storage.c +++ b/plat/fvp/fvp_io_storage.c @@ -35,12 +35,11 @@ #include #include #include +#include #include /* For FOPEN_MODE_... */ #include -#include "fvp_def.h" /* IO devices */ -static io_plat_data_t io_data; static const io_dev_connector_t *sh_dev_con; static uintptr_t sh_dev_spec; static uintptr_t sh_init_params; @@ -172,9 +171,6 @@ { int io_result = IO_FAIL; - /* Initialise the IO layer */ - io_init(&io_data); - /* Register the IO devices on this platform */ io_result = register_io_dev_sh(&sh_dev_con); assert(io_result == IO_SUCCESS); diff --git a/plat/fvp/fvp_pm.c b/plat/fvp/fvp_pm.c index 82a663b..b7e49a2 100644 --- a/plat/fvp/fvp_pm.c +++ b/plat/fvp/fvp_pm.c @@ -140,7 +140,7 @@ * turned off */ if (get_plat_config()->flags & CONFIG_HAS_CCI) - cci_disable_coherency(mpidr); + cci_disable_cluster_coherency(mpidr); /* * Program the power controller to turn the @@ -215,7 +215,7 @@ * turned off */ if (get_plat_config()->flags & CONFIG_HAS_CCI) - cci_disable_coherency(mpidr); + cci_disable_cluster_coherency(mpidr); /* * Program the power controller to turn the @@ -302,7 +302,7 @@ */ fvp_pwrc_write_pponr(mpidr); - fvp_cci_setup(); + fvp_cci_enable(); } break; diff --git a/plat/fvp/fvp_private.h b/plat/fvp/fvp_private.h index 054baa8..2dcb327 100644 --- a/plat/fvp/fvp_private.h +++ b/plat/fvp/fvp_private.h @@ -77,7 +77,8 @@ unsigned long); int fvp_config_setup(void); -void fvp_cci_setup(void); +void fvp_cci_init(void); +void fvp_cci_enable(void); void fvp_gic_init(void); 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(); } diff --git a/plat/fvp/include/plat_macros.S b/plat/fvp/include/plat_macros.S index 727b958..5d11d36 100644 --- a/plat/fvp/include/plat_macros.S +++ b/plat/fvp/include/plat_macros.S @@ -30,7 +30,7 @@ #include #include #include -#include "platform_def.h" +#include "../fvp_def.h" .section .rodata.gic_reg_name, "aS" gic_regs: diff --git a/plat/fvp/include/platform_def.h b/plat/fvp/include/platform_def.h index 734f28c..c87ba54 100644 --- a/plat/fvp/include/platform_def.h +++ b/plat/fvp/include/platform_def.h @@ -157,17 +157,6 @@ #define IRQ_SEC_PHY_TIMER 29 /******************************************************************************* - * CCI-400 related constants - ******************************************************************************/ -#define CCI400_BASE 0x2c090000 -#define CCI400_SL_IFACE_CLUSTER0 3 -#define CCI400_SL_IFACE_CLUSTER1 4 -#define CCI400_SL_IFACE_INDEX(mpidr) (mpidr & MPIDR_CLUSTER_MASK ? \ - CCI400_SL_IFACE_CLUSTER1 : \ - CCI400_SL_IFACE_CLUSTER0) - - -/******************************************************************************* * Declarations and constants to access the mailboxes safely. Each mailbox is * aligned on the biggest cache line size in the platform. This is known only * to the platform as it might have a combination of integrated and external diff --git a/plat/fvp/platform.mk b/plat/fvp/platform.mk index 8a33a60..ffed7e4 100644 --- a/plat/fvp/platform.mk +++ b/plat/fvp/platform.mk @@ -66,6 +66,7 @@ drivers/io/io_fip.c \ drivers/io/io_memmap.c \ drivers/io/io_semihosting.c \ + drivers/io/io_storage.c \ lib/aarch64/xlat_tables.c \ lib/semihosting/semihosting.c \ lib/semihosting/aarch64/semihosting_call.S \