summaryrefslogtreecommitdiff
path: root/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0001-Platform-corstone1000-Introduce-IO-framework.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0001-Platform-corstone1000-Introduce-IO-framework.patch')
-rw-r--r--meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0001-Platform-corstone1000-Introduce-IO-framework.patch1354
1 files changed, 0 insertions, 1354 deletions
diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0001-Platform-corstone1000-Introduce-IO-framework.patch b/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0001-Platform-corstone1000-Introduce-IO-framework.patch
deleted file mode 100644
index 900fd54936..0000000000
--- a/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0001-Platform-corstone1000-Introduce-IO-framework.patch
+++ /dev/null
@@ -1,1354 +0,0 @@
-From 1db9afdbf70eb9708640debe5d7d24558fe0f63a Mon Sep 17 00:00:00 2001
-From: Mohamed Omar Asaker <mohamed.omarasaker@arm.com>
-Date: Mon, 7 Nov 2022 12:49:11 +0000
-Subject: [PATCH 01/10] Platform: corstone1000: Introduce IO framework
-
-- Introduce IO storage framework
-- Add IO flash to abstract flash implementation details from upper layer
-
-Signed-off-by: Mohamed Omar Asaker <mohamed.omarasaker@arm.com>
-Upstream-Status: Accepted [TF-Mv1.8.0]
----
- .../target/arm/corstone1000/CMakeLists.txt | 4 +
- .../ext/target/arm/corstone1000/io/io_block.c | 527 ++++++++++++++++++
- .../ext/target/arm/corstone1000/io/io_block.h | 40 ++
- .../ext/target/arm/corstone1000/io/io_defs.h | 27 +
- .../target/arm/corstone1000/io/io_driver.h | 54 ++
- .../ext/target/arm/corstone1000/io/io_flash.c | 183 ++++++
- .../ext/target/arm/corstone1000/io/io_flash.h | 37 ++
- .../target/arm/corstone1000/io/io_storage.c | 289 ++++++++++
- .../target/arm/corstone1000/io/io_storage.h | 92 +++
- 9 files changed, 1253 insertions(+)
- create mode 100644 platform/ext/target/arm/corstone1000/io/io_block.c
- create mode 100644 platform/ext/target/arm/corstone1000/io/io_block.h
- create mode 100644 platform/ext/target/arm/corstone1000/io/io_defs.h
- create mode 100644 platform/ext/target/arm/corstone1000/io/io_driver.h
- create mode 100644 platform/ext/target/arm/corstone1000/io/io_flash.c
- create mode 100644 platform/ext/target/arm/corstone1000/io/io_flash.h
- create mode 100644 platform/ext/target/arm/corstone1000/io/io_storage.c
- create mode 100644 platform/ext/target/arm/corstone1000/io/io_storage.h
-
-diff --git a/platform/ext/target/arm/corstone1000/CMakeLists.txt b/platform/ext/target/arm/corstone1000/CMakeLists.txt
-index cfbaffc995..7808efae68 100644
---- a/platform/ext/target/arm/corstone1000/CMakeLists.txt
-+++ b/platform/ext/target/arm/corstone1000/CMakeLists.txt
-@@ -125,6 +125,9 @@ target_sources(platform_bl2
- fw_update_agent/fwu_agent.c
- bl2_security_cnt.c
- $<$<NOT:$<BOOL:${PLATFORM_DEFAULT_OTP}>>:${PLATFORM_DIR}/ext/accelerator/cc312/otp_cc312.c>
-+ io/io_block.c
-+ io/io_flash.c
-+ io/io_storage.c
- )
-
- if (PLATFORM_IS_FVP)
-@@ -182,6 +185,7 @@ target_include_directories(platform_bl2
- fip_parser
- Native_Driver
- fw_update_agent
-+ io
- .
- INTERFACE
- cc312
-diff --git a/platform/ext/target/arm/corstone1000/io/io_block.c b/platform/ext/target/arm/corstone1000/io/io_block.c
-new file mode 100644
-index 0000000000..f7eaf7444c
---- /dev/null
-+++ b/platform/ext/target/arm/corstone1000/io/io_block.c
-@@ -0,0 +1,527 @@
-+/*
-+ * Copyright (c) 2022 Arm Limited. All rights reserved.
-+ *
-+ * SPDX-License-Identifier: Apache-2.0
-+ *
-+ * Licensed under the Apache License, Version 2.0 (the License); you may
-+ * not use this file except in compliance with the License.
-+ * You may obtain a copy of the License at
-+ *
-+ * http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * Unless required by applicable law or agreed to in writing, software
-+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
-+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ * See the License for the specific language governing permissions and
-+ * limitations under the License.
-+ */
-+
-+#include "io_block.h"
-+
-+#include <assert.h>
-+#include <errno.h>
-+
-+#include "io_defs.h"
-+#include "io_driver.h"
-+#include "io_storage.h"
-+
-+typedef struct {
-+ io_block_dev_spec_t *dev_spec;
-+ uintptr_t base;
-+ uint32_t file_pos;
-+ uint32_t size;
-+} block_dev_state_t;
-+
-+#define is_power_of_2(x) (((x) != 0U) && (((x) & ((x)-1U)) == 0U))
-+
-+io_type_t device_type_block(void);
-+
-+static int block_open(io_dev_info_t *dev_info, const uintptr_t spec,
-+ io_entity_t *entity);
-+static int block_seek(io_entity_t *entity, int mode, size_t offset);
-+static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
-+ size_t *length_read);
-+static int block_write(io_entity_t *entity, const uintptr_t buffer,
-+ size_t length, size_t *length_written);
-+static int block_close(io_entity_t *entity);
-+static int block_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
-+static int block_dev_close(io_dev_info_t *dev_info);
-+
-+static const io_dev_connector_t block_dev_connector = {.dev_open =
-+ block_dev_open};
-+
-+static const io_dev_funcs_t block_dev_funcs = {
-+ .type = device_type_block,
-+ .open = block_open,
-+ .seek = block_seek,
-+ .size = NULL,
-+ .read = block_read,
-+ .write = block_write,
-+ .close = block_close,
-+ .dev_init = NULL,
-+ .dev_close = block_dev_close,
-+};
-+
-+static block_dev_state_t state_pool[MAX_IO_BLOCK_DEVICES];
-+static io_dev_info_t dev_info_pool[MAX_IO_BLOCK_DEVICES];
-+
-+/* Track number of allocated block state */
-+static unsigned int block_dev_count;
-+
-+io_type_t device_type_block(void) { return IO_TYPE_BLOCK; }
-+
-+/* Locate a block state in the pool, specified by address */
-+static int find_first_block_state(const io_block_dev_spec_t *dev_spec,
-+ unsigned int *index_out) {
-+ unsigned int index;
-+ int result = -ENOENT;
-+
-+ for (index = 0U; index < MAX_IO_BLOCK_DEVICES; ++index) {
-+ /* dev_spec is used as identifier since it's unique */
-+ if (state_pool[index].dev_spec == dev_spec) {
-+ result = 0;
-+ *index_out = index;
-+ break;
-+ }
-+ }
-+ return result;
-+}
-+
-+/* Allocate a device info from the pool and return a pointer to it */
-+static int allocate_dev_info(io_dev_info_t **dev_info) {
-+ int result = -ENOMEM;
-+ assert(dev_info != NULL);
-+
-+ if (block_dev_count < MAX_IO_BLOCK_DEVICES) {
-+ unsigned int index = 0;
-+ result = find_first_block_state(NULL, &index);
-+ assert(result == 0);
-+ /* initialize dev_info */
-+ dev_info_pool[index].funcs = &block_dev_funcs;
-+ dev_info_pool[index].info = (uintptr_t)&state_pool[index];
-+ *dev_info = &dev_info_pool[index];
-+ ++block_dev_count;
-+ }
-+
-+ return result;
-+}
-+
-+/* Release a device info to the pool */
-+static int free_dev_info(io_dev_info_t *dev_info) {
-+ int result;
-+ unsigned int index = 0;
-+ block_dev_state_t *state;
-+ assert(dev_info != NULL);
-+
-+ state = (block_dev_state_t *)dev_info->info;
-+ result = find_first_block_state(state->dev_spec, &index);
-+ if (result == 0) {
-+ /* free if device info is valid */
-+ memset(state, 0, sizeof(block_dev_state_t));
-+ memset(dev_info, 0, sizeof(io_dev_info_t));
-+ --block_dev_count;
-+ }
-+
-+ return result;
-+}
-+
-+static int block_open(io_dev_info_t *dev_info, const uintptr_t spec,
-+ io_entity_t *entity) {
-+ block_dev_state_t *cur;
-+ io_block_spec_t *region;
-+
-+ assert((dev_info->info != (uintptr_t)NULL) && (spec != (uintptr_t)NULL) &&
-+ (entity->info == (uintptr_t)NULL));
-+
-+ region = (io_block_spec_t *)spec;
-+ cur = (block_dev_state_t *)dev_info->info;
-+ assert(((region->offset % cur->dev_spec->block_size) == 0) &&
-+ ((region->length % cur->dev_spec->block_size) == 0));
-+
-+ cur->base = region->offset;
-+ cur->size = region->length;
-+ cur->file_pos = 0;
-+
-+ entity->info = (uintptr_t)cur;
-+ return 0;
-+}
-+
-+/* parameter offset is relative address at here */
-+static int block_seek(io_entity_t *entity, int mode, size_t offset) {
-+ block_dev_state_t *cur;
-+
-+ assert(entity->info != (uintptr_t)NULL);
-+
-+ cur = (block_dev_state_t *)entity->info;
-+
-+ assert((offset >= 0) && ((uint32_t)offset < cur->size));
-+ switch (mode) {
-+ case IO_SEEK_SET:
-+ cur->file_pos = (uint32_t)offset;
-+ break;
-+ case IO_SEEK_CUR:
-+ cur->file_pos += (uint32_t)offset;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ assert(cur->file_pos < cur->size);
-+ return 0;
-+}
-+
-+/*
-+ * This function allows the caller to read any number of bytes
-+ * from any position. It hides from the caller that the low level
-+ * driver only can read aligned blocks of data. For this reason
-+ * we need to handle the use case where the first byte to be read is not
-+ * aligned to start of the block, the last byte to be read is also not
-+ * aligned to the end of a block, and there are zero or more blocks-worth
-+ * of data in between.
-+ *
-+ * In such a case we need to read more bytes than requested (i.e. full
-+ * blocks) and strip-out the leading bytes (aka skip) and the trailing
-+ * bytes (aka padding). See diagram below
-+ *
-+ * cur->file_pos ------------
-+ * |
-+ * cur->base |
-+ * | |
-+ * v v<---- length ---->
-+ * --------------------------------------------------------------
-+ * | | block#1 | | block#n |
-+ * | block#0 | + | ... | + |
-+ * | | <- skip -> + | | + <- padding ->|
-+ * ------------------------+----------------------+--------------
-+ * ^ ^
-+ * | |
-+ * v iteration#1 iteration#n v
-+ * --------------------------------------------------
-+ * | | | |
-+ * |<---- request ---->| ... |<----- request ---->|
-+ * | | | |
-+ * --------------------------------------------------
-+ * / / | |
-+ * / / | |
-+ * / / | |
-+ * / / | |
-+ * / / | |
-+ * / / | |
-+ * / / | |
-+ * / / | |
-+ * / / | |
-+ * / / | |
-+ * <---- request ------> <------ request ----->
-+ * --------------------- -----------------------
-+ * | | | | | |
-+ * |<-skip->|<-nbytes->| -------->|<-nbytes->|<-padding->|
-+ * | | | | | | |
-+ * --------------------- | -----------------------
-+ * ^ \ \ | | |
-+ * | \ \ | | |
-+ * | \ \ | | |
-+ * buf->offset \ \ buf->offset | |
-+ * \ \ | |
-+ * \ \ | |
-+ * \ \ | |
-+ * \ \ | |
-+ * \ \ | |
-+ * \ \ | |
-+ * \ \ | |
-+ * --------------------------------
-+ * | | | |
-+ * buffer-------------->| | ... | |
-+ * | | | |
-+ * --------------------------------
-+ * <-count#1->| |
-+ * <---------- count#n -------->
-+ * <---------- length ---------->
-+ *
-+ * Additionally, the IO driver has an underlying buffer that is at least
-+ * one block-size and may be big enough to allow.
-+ */
-+static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
-+ size_t *length_read) {
-+ block_dev_state_t *cur;
-+ io_block_spec_t *buf;
-+ io_block_ops_t *ops;
-+ int lba;
-+ size_t block_size, left;
-+ size_t nbytes; /* number of bytes read in one iteration */
-+ size_t request; /* number of requested bytes in one iteration */
-+ size_t count; /* number of bytes already read */
-+ /*
-+ * number of leading bytes from start of the block
-+ * to the first byte to be read
-+ */
-+ size_t skip;
-+
-+ /*
-+ * number of trailing bytes between the last byte
-+ * to be read and the end of the block
-+ */
-+ size_t padding;
-+
-+ assert(entity->info != (uintptr_t)NULL);
-+ cur = (block_dev_state_t *)entity->info;
-+ ops = &(cur->dev_spec->ops);
-+ buf = &(cur->dev_spec->buffer);
-+ block_size = cur->dev_spec->block_size;
-+ assert((length <= cur->size) && (length > 0U) && (ops->read != 0));
-+
-+ /*
-+ * We don't know the number of bytes that we are going
-+ * to read in every iteration, because it will depend
-+ * on the low level driver.
-+ */
-+ count = 0;
-+ for (left = length; left > 0U; left -= nbytes) {
-+ /*
-+ * We must only request operations aligned to the block
-+ * size. Therefore if file_pos is not block-aligned,
-+ * we have to request the operation to start at the
-+ * previous block boundary and skip the leading bytes. And
-+ * similarly, the number of bytes requested must be a
-+ * block size multiple
-+ */
-+ skip = cur->file_pos & (block_size - 1U);
-+
-+ /*
-+ * Calculate the block number containing file_pos
-+ * - e.g. block 3.
-+ */
-+ lba = (cur->file_pos + cur->base) / block_size;
-+
-+ if ((skip + left) > buf->length) {
-+ /*
-+ * The underlying read buffer is too small to
-+ * read all the required data - limit to just
-+ * fill the buffer, and then read again.
-+ */
-+ request = buf->length;
-+ } else {
-+ /*
-+ * The underlying read buffer is big enough to
-+ * read all the required data. Calculate the
-+ * number of bytes to read to align with the
-+ * block size.
-+ */
-+ request = skip + left;
-+ request = (request + (block_size - 1U)) & ~(block_size - 1U);
-+ }
-+ request = ops->read(lba, buf->offset, request);
-+
-+ if (request <= skip) {
-+ /*
-+ * We couldn't read enough bytes to jump over
-+ * the skip bytes, so we should have to read
-+ * again the same block, thus generating
-+ * the same error.
-+ */
-+ return -EIO;
-+ }
-+
-+ /*
-+ * Need to remove skip and padding bytes,if any, from
-+ * the read data when copying to the user buffer.
-+ */
-+ nbytes = request - skip;
-+ padding = (nbytes > left) ? nbytes - left : 0U;
-+ nbytes -= padding;
-+
-+ memcpy((void *)(buffer + count), (void *)(buf->offset + skip), nbytes);
-+
-+ cur->file_pos += nbytes;
-+ count += nbytes;
-+ }
-+ assert(count == length);
-+ *length_read = count;
-+
-+ return 0;
-+}
-+
-+/*
-+ * This function allows the caller to write any number of bytes
-+ * from any position. It hides from the caller that the low level
-+ * driver only can write aligned blocks of data.
-+ * See comments for block_read for more details.
-+ */
-+static int block_write(io_entity_t *entity, const uintptr_t buffer,
-+ size_t length, size_t *length_written) {
-+ block_dev_state_t *cur;
-+ io_block_spec_t *buf;
-+ io_block_ops_t *ops;
-+ int lba;
-+ size_t block_size, left;
-+ size_t nbytes; /* number of bytes read in one iteration */
-+ size_t request; /* number of requested bytes in one iteration */
-+ size_t count; /* number of bytes already read */
-+ /*
-+ * number of leading bytes from start of the block
-+ * to the first byte to be read
-+ */
-+ size_t skip;
-+
-+ /*
-+ * number of trailing bytes between the last byte
-+ * to be read and the end of the block
-+ */
-+ size_t padding;
-+ assert(entity->info != (uintptr_t)NULL);
-+ cur = (block_dev_state_t *)entity->info;
-+ ops = &(cur->dev_spec->ops);
-+ buf = &(cur->dev_spec->buffer);
-+ block_size = cur->dev_spec->block_size;
-+ assert((length <= cur->size) && (length > 0U) && (ops->read != 0) &&
-+ (ops->write != 0));
-+
-+ /*
-+ * We don't know the number of bytes that we are going
-+ * to write in every iteration, because it will depend
-+ * on the low level driver.
-+ */
-+ count = 0;
-+ for (left = length; left > 0U; left -= nbytes) {
-+ /*
-+ * We must only request operations aligned to the block
-+ * size. Therefore if file_pos is not block-aligned,
-+ * we have to request the operation to start at the
-+ * previous block boundary and skip the leading bytes. And
-+ * similarly, the number of bytes requested must be a
-+ * block size multiple
-+ */
-+ skip = cur->file_pos & (block_size - 1U);
-+
-+ /*
-+ * Calculate the block number containing file_pos
-+ * - e.g. block 3.
-+ */
-+ lba = (cur->file_pos + cur->base) / block_size;
-+
-+ if ((skip + left) > buf->length) {
-+ /*
-+ * The underlying read buffer is too small to
-+ * read all the required data - limit to just
-+ * fill the buffer, and then read again.
-+ */
-+ request = buf->length;
-+ } else {
-+ /*
-+ * The underlying read buffer is big enough to
-+ * read all the required data. Calculate the
-+ * number of bytes to read to align with the
-+ * block size.
-+ */
-+ request = skip + left;
-+ request = (request + (block_size - 1U)) & ~(block_size - 1U);
-+ }
-+
-+ /*
-+ * The number of bytes that we are going to write
-+ * from the user buffer will depend of the size
-+ * of the current request.
-+ */
-+ nbytes = request - skip;
-+ padding = (nbytes > left) ? nbytes - left : 0U;
-+ nbytes -= padding;
-+
-+ /*
-+ * If we have skip or padding bytes then we have to preserve
-+ * some content and it means that we have to read before
-+ * writing
-+ */
-+ if ((skip > 0U) || (padding > 0U)) {
-+ request = ops->read(lba, buf->offset, request);
-+ /*
-+ * The read may return size less than
-+ * requested. Round down to the nearest block
-+ * boundary
-+ */
-+ request &= ~(block_size - 1U);
-+ if (request <= skip) {
-+ /*
-+ * We couldn't read enough bytes to jump over
-+ * the skip bytes, so we should have to read
-+ * again the same block, thus generating
-+ * the same error.
-+ */
-+ return -EIO;
-+ }
-+ nbytes = request - skip;
-+ padding = (nbytes > left) ? nbytes - left : 0U;
-+ nbytes -= padding;
-+ }
-+
-+ memcpy((void *)(buf->offset + skip), (void *)(buffer + count), nbytes);
-+
-+ request = ops->write(lba, buf->offset, request);
-+ if (request <= skip) return -EIO;
-+
-+ /*
-+ * And the previous write operation may modify the size
-+ * of the request, so again, we have to calculate the
-+ * number of bytes that we consumed from the user
-+ * buffer
-+ */
-+ nbytes = request - skip;
-+ padding = (nbytes > left) ? nbytes - left : 0U;
-+ nbytes -= padding;
-+
-+ cur->file_pos += nbytes;
-+ count += nbytes;
-+ }
-+ assert(count == length);
-+ *length_written = count;
-+
-+ return 0;
-+}
-+
-+static int block_close(io_entity_t *entity) {
-+ entity->info = (uintptr_t)NULL;
-+ return 0;
-+}
-+
-+static int block_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info) {
-+ block_dev_state_t *cur;
-+ io_block_spec_t *buffer;
-+ io_dev_info_t *info;
-+ size_t block_size;
-+ int result;
-+ assert(dev_info != NULL);
-+ result = allocate_dev_info(&info);
-+ if (result != 0) return -ENOENT;
-+
-+ cur = (block_dev_state_t *)info->info;
-+ /* dev_spec is type of io_block_dev_spec_t. */
-+ cur->dev_spec = (io_block_dev_spec_t *)dev_spec;
-+ buffer = &(cur->dev_spec->buffer);
-+ block_size = cur->dev_spec->block_size;
-+
-+ assert((block_size > 0U) && (is_power_of_2(block_size) != 0U) &&
-+ ((buffer->length % block_size) == 0U));
-+
-+ *dev_info = info; /* cast away const */
-+ (void)block_size;
-+ (void)buffer;
-+ return 0;
-+}
-+
-+static int block_dev_close(io_dev_info_t *dev_info) {
-+ return free_dev_info(dev_info);
-+}
-+
-+/* Exported functions */
-+
-+/* Register the Block driver with the IO abstraction */
-+int register_io_dev_block(const io_dev_connector_t **dev_con) {
-+ int result;
-+
-+ assert(dev_con != NULL);
-+
-+ /*
-+ * Since dev_info isn't really used in io_register_device, always
-+ * use the same device info at here instead.
-+ */
-+ result = io_register_device(&dev_info_pool[0]);
-+ if (result == 0) *dev_con = &block_dev_connector;
-+ return result;
-+}
-diff --git a/platform/ext/target/arm/corstone1000/io/io_block.h b/platform/ext/target/arm/corstone1000/io/io_block.h
-new file mode 100644
-index 0000000000..1603aa74c5
---- /dev/null
-+++ b/platform/ext/target/arm/corstone1000/io/io_block.h
-@@ -0,0 +1,40 @@
-+/*
-+ * Copyright (c) 2022 Arm Limited. All rights reserved.
-+ *
-+ * SPDX-License-Identifier: Apache-2.0
-+ *
-+ * Licensed under the Apache License, Version 2.0 (the License); you may
-+ * not use this file except in compliance with the License.
-+ * You may obtain a copy of the License at
-+ *
-+ * http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * Unless required by applicable law or agreed to in writing, software
-+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
-+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ * See the License for the specific language governing permissions and
-+ * limitations under the License.
-+ */
-+
-+#ifndef __IO_BLOCK_H__
-+#define __IO_BLOCK_H__
-+
-+#include "io_storage.h"
-+
-+/* block devices ops */
-+typedef struct io_block_ops {
-+ size_t (*read)(int lba, uintptr_t buf, size_t size);
-+ size_t (*write)(int lba, const uintptr_t buf, size_t size);
-+} io_block_ops_t;
-+
-+typedef struct io_block_dev_spec {
-+ io_block_spec_t buffer;
-+ io_block_ops_t ops;
-+ size_t block_size;
-+} io_block_dev_spec_t;
-+
-+struct io_dev_connector;
-+
-+int register_io_dev_block(const struct io_dev_connector **dev_con);
-+
-+#endif /* __IO_BLOCK_H__ */
-\ No newline at end of file
-diff --git a/platform/ext/target/arm/corstone1000/io/io_defs.h b/platform/ext/target/arm/corstone1000/io/io_defs.h
-new file mode 100644
-index 0000000000..acba969ed6
---- /dev/null
-+++ b/platform/ext/target/arm/corstone1000/io/io_defs.h
-@@ -0,0 +1,27 @@
-+/*
-+ * Copyright (c) 2022 Arm Limited. All rights reserved.
-+ *
-+ * SPDX-License-Identifier: Apache-2.0
-+ *
-+ * Licensed under the Apache License, Version 2.0 (the License); you may
-+ * not use this file except in compliance with the License.
-+ * You may obtain a copy of the License at
-+ *
-+ * http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * Unless required by applicable law or agreed to in writing, software
-+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
-+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ * See the License for the specific language governing permissions and
-+ * limitations under the License.
-+ */
-+
-+#ifndef __IO_DEFS_H__
-+#define __IO_DEFS_H__
-+
-+#define MAX_IO_DEVICES (2)
-+#define MAX_IO_HANDLES (2)
-+#define MAX_IO_BLOCK_DEVICES (2)
-+#define MAX_IO_FLASH_DEVICES (2)
-+
-+#endif /* __IO_DEFS_H__ */
-\ No newline at end of file
-diff --git a/platform/ext/target/arm/corstone1000/io/io_driver.h b/platform/ext/target/arm/corstone1000/io/io_driver.h
-new file mode 100644
-index 0000000000..cf9e21a6d4
---- /dev/null
-+++ b/platform/ext/target/arm/corstone1000/io/io_driver.h
-@@ -0,0 +1,54 @@
-+/*
-+ * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
-+ *
-+ * SPDX-License-Identifier: BSD-3-Clause
-+ */
-+
-+#ifndef __IO_DRIVER_H__
-+#define __IO_DRIVER_H__
-+
-+#include <io_storage.h>
-+#include <stdint.h>
-+
-+/* 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, size_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/platform/ext/target/arm/corstone1000/io/io_flash.c b/platform/ext/target/arm/corstone1000/io/io_flash.c
-new file mode 100644
-index 0000000000..ff4524e9c5
---- /dev/null
-+++ b/platform/ext/target/arm/corstone1000/io/io_flash.c
-@@ -0,0 +1,183 @@
-+/*
-+ * Copyright (c) 2022 Arm Limited. All rights reserved.
-+ *
-+ * SPDX-License-Identifier: Apache-2.0
-+ *
-+ * Licensed under the Apache License, Version 2.0 (the License); you may
-+ * not use this file except in compliance with the License.
-+ * You may obtain a copy of the License at
-+ *
-+ * http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * Unless required by applicable law or agreed to in writing, software
-+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
-+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ * See the License for the specific language governing permissions and
-+ * limitations under the License.
-+ */
-+
-+#include "io_flash.h"
-+
-+#include <assert.h>
-+#include <errno.h>
-+
-+#include "Driver_Flash.h"
-+#include "io_block.h"
-+#include "io_defs.h"
-+#include "io_driver.h"
-+#include "io_storage.h"
-+
-+#if MAX_IO_FLASH_DEVICES > MAX_IO_BLOCK_DEVICES
-+#error \
-+ "FLASH devices are BLOCK devices .. MAX_IO_FLASH_DEVICES should be less or equal to MAX_IO_BLOCK_DEVICES"
-+#endif
-+
-+/* Private Prototypes */
-+
-+static int flash_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
-+static size_t flash_read(int lba, uintptr_t buf, size_t size, size_t flash_id);
-+static size_t flash_write(int lba, const uintptr_t buf, size_t size,
-+ size_t flash_id);
-+static size_t flash0_read(int lba, uintptr_t buf, size_t size);
-+static size_t flash0_write(int lba, uintptr_t buf, size_t size);
-+static size_t flash1_read(int lba, uintptr_t buf, size_t size);
-+static size_t flash1_write(int lba, uintptr_t buf, size_t size);
-+
-+/** Private Data **/
-+
-+/* Flash device data */
-+static const io_dev_connector_t flash_dev_connector = {.dev_open =
-+ flash_dev_open};
-+static size_t flash_dev_count = 0;
-+static io_flash_dev_spec_t *flash_dev_specs[MAX_IO_FLASH_DEVICES];
-+
-+/* Block device data */
-+static io_dev_connector_t block_dev_connectors[MAX_IO_FLASH_DEVICES];
-+static io_block_dev_spec_t block_dev_spec[MAX_IO_FLASH_DEVICES];
-+
-+/* Flash devices read/write function pointers */
-+static io_block_ops_t flashs_ops[MAX_IO_FLASH_DEVICES] = {
-+ [0] = {.read = flash0_read, .write = flash0_write},
-+ [1] = {.read = flash1_read, .write = flash1_write},
-+};
-+
-+/* Flash ops functions */
-+static size_t flash_read(int lba, uintptr_t buf, size_t size, size_t flash_id) {
-+ ARM_DRIVER_FLASH *flash_driver =
-+ ((ARM_DRIVER_FLASH *)flash_dev_specs[flash_id]->flash_driver);
-+ ARM_FLASH_INFO *info = flash_driver->GetInfo();
-+ uint32_t addr = info->sector_size * lba;
-+ uint32_t offset = addr - flash_dev_specs[flash_id]->base_addr;
-+ size_t rem = info->sector_count * info->sector_size - offset;
-+ size_t cnt = size < rem ? size : rem;
-+
-+ return flash_driver->ReadData(offset, buf, cnt);
-+}
-+
-+static size_t flash_write(int lba, const uintptr_t buf, size_t size,
-+ size_t flash_id) {
-+ ARM_DRIVER_FLASH *flash_driver =
-+ ((ARM_DRIVER_FLASH *)flash_dev_specs[flash_id]->flash_driver);
-+ ARM_FLASH_INFO *info = flash_driver->GetInfo();
-+ int32_t rc = 0;
-+ uint32_t addr = info->sector_size * lba;
-+ uint32_t offset = addr - flash_dev_specs[flash_id]->base_addr;
-+ size_t rem = info->sector_count * info->sector_size - offset;
-+ size_t cnt = size < rem ? size : rem;
-+
-+ flash_driver->EraseSector(offset);
-+ rc = flash_driver->ProgramData(offset, buf, cnt);
-+ return rc;
-+}
-+
-+/* Flash ops functions wrapper for each device */
-+
-+static size_t flash0_read(int lba, uintptr_t buf, size_t size) {
-+ return flash_read(lba, buf, size, 0);
-+}
-+
-+static size_t flash0_write(int lba, uintptr_t buf, size_t size) {
-+ return flash_write(lba, buf, size, 0);
-+}
-+
-+static size_t flash1_read(int lba, uintptr_t buf, size_t size) {
-+ return flash_read(lba, buf, size, 1);
-+}
-+
-+static size_t flash1_write(int lba, uintptr_t buf, size_t size) {
-+ return flash_write(lba, buf, size, 1);
-+}
-+
-+/**
-+ * Helper function to find the index of stored flash_dev_specs or
-+ * return a free slot in case of a new dev_spec
-+ */
-+static int find_flash_dev_specs(const uintptr_t dev_spec) {
-+ /* Search in the saved ones */
-+ for (int i = 0; i < flash_dev_count; ++i) {
-+ if (flash_dev_specs[i] != NULL &&
-+ flash_dev_specs[i]->flash_driver ==
-+ ((io_flash_dev_spec_t *)dev_spec)->flash_driver) {
-+ return i;
-+ }
-+ }
-+ /* Find the first empty flash_dev_specs to be used */
-+ for (int i = 0; i < flash_dev_count; ++i) {
-+ if (flash_dev_specs[i] == NULL) {
-+ return i;
-+ }
-+ }
-+ return -1;
-+}
-+
-+/**
-+ * This function should be called
-+ */
-+static int flash_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info) {
-+ ARM_DRIVER_FLASH *flash_driver;
-+ assert(dev_info != NULL);
-+ assert(dev_spec != NULL);
-+
-+ size_t index = find_flash_dev_specs(dev_spec);
-+
-+ /* Check if Flash ops functions are defined for this flash */
-+ assert(flashs_ops[index].read && flashs_ops[index].write);
-+
-+ flash_dev_specs[index] = dev_spec;
-+ flash_driver = flash_dev_specs[index]->flash_driver;
-+
-+ block_dev_spec[index].block_size = flash_driver->GetInfo()->sector_size;
-+ block_dev_spec[index].buffer.offset = flash_dev_specs[index]->buffer;
-+ block_dev_spec[index].buffer.length = flash_dev_specs[index]->bufferlen;
-+ block_dev_spec[index].ops = flashs_ops[index];
-+
-+ flash_driver->Initialize(NULL);
-+
-+ block_dev_connectors[index].dev_open(&block_dev_spec[index], dev_info);
-+
-+ return 0;
-+}
-+
-+/* Exported functions */
-+
-+/**
-+ * Register the flash device.
-+ * Internally it register a block device.
-+ */
-+int register_io_dev_flash(const io_dev_connector_t **dev_con) {
-+ int result;
-+
-+ if (flash_dev_count >= MAX_IO_FLASH_DEVICES) {
-+ return -ENOENT;
-+ }
-+ assert(dev_con != NULL);
-+
-+ result = register_io_dev_block(dev_con);
-+ if (result == 0) {
-+ /* Store the block dev connector */
-+ block_dev_connectors[flash_dev_count++] = **dev_con;
-+ /* Override dev_con with the flash dev connector */
-+ *dev_con = &flash_dev_connector;
-+ }
-+ return result;
-+}
-diff --git a/platform/ext/target/arm/corstone1000/io/io_flash.h b/platform/ext/target/arm/corstone1000/io/io_flash.h
-new file mode 100644
-index 0000000000..8bc38b5824
---- /dev/null
-+++ b/platform/ext/target/arm/corstone1000/io/io_flash.h
-@@ -0,0 +1,37 @@
-+/*
-+ * Copyright (c) 2022 Arm Limited. All rights reserved.
-+ *
-+ * SPDX-License-Identifier: Apache-2.0
-+ *
-+ * Licensed under the Apache License, Version 2.0 (the License); you may
-+ * not use this file except in compliance with the License.
-+ * You may obtain a copy of the License at
-+ *
-+ * http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * Unless required by applicable law or agreed to in writing, software
-+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
-+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ * See the License for the specific language governing permissions and
-+ * limitations under the License.
-+ */
-+
-+#ifndef __IO_FLASH_H__
-+#define __IO_FLASH_H__
-+
-+#include "io_storage.h"
-+
-+typedef struct io_flash_dev_spec {
-+ uintptr_t buffer;
-+ size_t bufferlen;
-+ uint32_t base_addr;
-+ uintptr_t flash_driver;
-+} io_flash_dev_spec_t;
-+
-+struct io_dev_connector;
-+
-+/* Register the flash driver with the IO abstraction internally it register a
-+ * block device*/
-+int register_io_dev_flash(const struct io_dev_connector **dev_con);
-+
-+#endif /* __IO_FLASH_H__ */
-diff --git a/platform/ext/target/arm/corstone1000/io/io_storage.c b/platform/ext/target/arm/corstone1000/io/io_storage.c
-new file mode 100644
-index 0000000000..f26f4980f0
---- /dev/null
-+++ b/platform/ext/target/arm/corstone1000/io/io_storage.c
-@@ -0,0 +1,289 @@
-+/*
-+ * Copyright (c) 2022 Arm Limited. All rights reserved.
-+ *
-+ * SPDX-License-Identifier: Apache-2.0
-+ *
-+ * Licensed under the Apache License, Version 2.0 (the License); you may
-+ * not use this file except in compliance with the License.
-+ * You may obtain a copy of the License at
-+ *
-+ * http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * Unless required by applicable law or agreed to in writing, software
-+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
-+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ * See the License for the specific language governing permissions and
-+ * limitations under the License.
-+ */
-+
-+#include <assert.h>
-+#include <errno.h>
-+#include <stdbool.h>
-+
-+#include "io_defs.h"
-+#include "io_driver.h"
-+
-+/* 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;
-+
-+/* Return a boolean value indicating whether a device connector is valid */
-+static bool is_valid_dev_connector(const io_dev_connector_t *dev_con) {
-+ return (dev_con != NULL) && (dev_con->dev_open != NULL);
-+}
-+
-+/* Return a boolean value indicating whether a device handle is valid */
-+static bool is_valid_dev(const uintptr_t dev_handle) {
-+ const io_dev_info_t *dev = (io_dev_info_t *)dev_handle;
-+
-+ return (dev != NULL) && (dev->funcs != NULL) &&
-+ (dev->funcs->type != NULL) && (dev->funcs->type() < IO_TYPE_MAX);
-+}
-+
-+/* Return a boolean value indicating whether an IO entity is valid */
-+static bool is_valid_entity(const uintptr_t handle) {
-+ const io_entity_t *entity = (io_entity_t *)handle;
-+
-+ return (entity != NULL) && (is_valid_dev((uintptr_t)entity->dev_handle));
-+}
-+
-+/* Return a boolean value indicating whether a seek mode is valid */
-+static bool is_valid_seek_mode(io_seek_mode_t mode) {
-+ return ((mode != IO_SEEK_INVALID) && (mode < IO_SEEK_MAX));
-+}
-+
-+/* Open a connection to a specific device */
-+static int io_storage_dev_open(const io_dev_connector_t *dev_con,
-+ const uintptr_t dev_spec,
-+ io_dev_info_t **dev_info) {
-+ assert(dev_info != NULL);
-+ assert(is_valid_dev_connector(dev_con));
-+
-+ return dev_con->dev_open(dev_spec, dev_info);
-+}
-+
-+/* 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 = -ENOENT;
-+ for (unsigned int index = 0; index < MAX_IO_HANDLES; ++index) {
-+ if (entity_map[index] == entity) {
-+ result = 0;
-+ *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 = -ENOMEM;
-+ assert(entity != NULL);
-+
-+ if (entity_count < MAX_IO_HANDLES) {
-+ unsigned int index = 0;
-+ result = find_first_entity(NULL, &index);
-+ assert(result == 0);
-+ *entity = &entity_pool[index];
-+ entity_map[index] = &entity_pool[index];
-+ ++entity_count;
-+ }
-+
-+ return result;
-+}
-+
-+/* Release an entity back to the pool */
-+static int free_entity(const io_entity_t *entity) {
-+ int result;
-+ unsigned int index = 0;
-+ assert(entity != NULL);
-+
-+ result = find_first_entity(entity, &index);
-+ if (result == 0) {
-+ entity_map[index] = NULL;
-+ --entity_count;
-+ }
-+
-+ return result;
-+}
-+
-+/* Exported API */
-+
-+/* Register an io device */
-+int io_register_device(const io_dev_info_t *dev_info) {
-+ int result = -ENOMEM;
-+ assert(dev_info != NULL);
-+
-+ if (dev_count < MAX_IO_DEVICES) {
-+ devices[dev_count] = dev_info;
-+ dev_count++;
-+ result = 0;
-+ }
-+
-+ 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) {
-+ assert(handle != NULL);
-+ return io_storage_dev_open(dev_con, dev_spec, (io_dev_info_t **)handle);
-+}
-+
-+/* 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 = 0;
-+ assert(dev_handle != (uintptr_t)NULL);
-+ assert(is_valid_dev(dev_handle));
-+
-+ io_dev_info_t *dev = (io_dev_info_t *)dev_handle;
-+
-+ /* Absence of registered function implies NOP here */
-+ if (dev->funcs->dev_init != NULL) {
-+ result = dev->funcs->dev_init(dev, init_params);
-+ }
-+
-+ return result;
-+}
-+
-+/* Close a connection to a device */
-+int io_dev_close(uintptr_t dev_handle) {
-+ int result = 0;
-+ assert(dev_handle != (uintptr_t)NULL);
-+ assert(is_valid_dev(dev_handle));
-+
-+ io_dev_info_t *dev = (io_dev_info_t *)dev_handle;
-+
-+ /* Absence of registered function implies NOP here */
-+ if (dev->funcs->dev_close != NULL) {
-+ result = dev->funcs->dev_close(dev);
-+ }
-+
-+ return result;
-+}
-+
-+/* Synchronous operations */
-+
-+/* Open an IO entity */
-+int io_open(uintptr_t dev_handle, const uintptr_t spec, uintptr_t *handle) {
-+ int result;
-+ 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 == 0) {
-+ assert(dev->funcs->open != NULL);
-+ result = dev->funcs->open(dev, spec, entity);
-+
-+ if (result == 0) {
-+ 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, int32_t offset) {
-+ int result = -ENODEV;
-+ 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);
-+
-+ return result;
-+}
-+
-+/* Determine the length of an IO entity */
-+int io_size(uintptr_t handle, size_t *length) {
-+ int result = -ENODEV;
-+ 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);
-+
-+ 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 = -ENODEV;
-+ assert(is_valid_entity(handle));
-+
-+ 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);
-+
-+ 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 = -ENODEV;
-+ assert(is_valid_entity(handle));
-+
-+ 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);
-+ }
-+
-+ return result;
-+}
-+
-+/* Close an IO entity */
-+int io_close(uintptr_t handle) {
-+ int result = 0;
-+ assert(is_valid_entity(handle));
-+
-+ io_entity_t *entity = (io_entity_t *)handle;
-+
-+ io_dev_info_t *dev = entity->dev_handle;
-+
-+ /* Absence of registered function implies NOP here */
-+ if (dev->funcs->close != NULL) result = dev->funcs->close(entity);
-+
-+ /* Ignore improbable free_entity failure */
-+ (void)free_entity(entity);
-+
-+ return result;
-+}
-diff --git a/platform/ext/target/arm/corstone1000/io/io_storage.h b/platform/ext/target/arm/corstone1000/io/io_storage.h
-new file mode 100644
-index 0000000000..0cdca5b269
---- /dev/null
-+++ b/platform/ext/target/arm/corstone1000/io/io_storage.h
-@@ -0,0 +1,92 @@
-+/*
-+ * Copyright (c) 2022 Arm Limited. All rights reserved.
-+ *
-+ * SPDX-License-Identifier: Apache-2.0
-+ *
-+ * Licensed under the Apache License, Version 2.0 (the License); you may
-+ * not use this file except in compliance with the License.
-+ * You may obtain a copy of the License at
-+ *
-+ * http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * Unless required by applicable law or agreed to in writing, software
-+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
-+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ * See the License for the specific language governing permissions and
-+ * limitations under the License.
-+ */
-+
-+#ifndef __IO_STORAGE_H__
-+#define __IO_STORAGE_H__
-+
-+#include <stddef.h>
-+#include <stdint.h>
-+
-+/* 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)
-+
-+/* 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_DUMMY,
-+ IO_TYPE_FIRMWARE_IMAGE_PACKAGE,
-+ IO_TYPE_BLOCK,
-+ IO_TYPE_MTD,
-+ IO_TYPE_MMC,
-+ IO_TYPE_STM32IMAGE,
-+ IO_TYPE_ENCRYPTED,
-+ 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;
-+
-+/* 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;
-+
-+
-+/* Open a connection to a device */
-+int io_dev_open(const struct io_dev_connector *dev_con,
-+ const uintptr_t dev_spec, uintptr_t *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);
-+
-+/* 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, int32_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_STORAGE_H__ */
---
-2.25.1
-