summaryrefslogtreecommitdiff
path: root/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0002-Platform-corstone1000-Add-IO-test-in-ci_regressions.patch
diff options
context:
space:
mode:
authorAndrew Geissler <geissonator@yahoo.com>2023-03-31 17:57:23 +0300
committerAndrew Geissler <geissonator@yahoo.com>2023-03-31 18:06:58 +0300
commit2daf84b2d486da0b21344da999553c8fa1228195 (patch)
tree04a2402d258019103ad1a4c9da71d78301cd5d42 /meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0002-Platform-corstone1000-Add-IO-test-in-ci_regressions.patch
parentced6278a187ae9eefe16fe59398f714857b7f76e (diff)
downloadopenbmc-2daf84b2d486da0b21344da999553c8fa1228195.tar.xz
subtree updates: raspberrypi security arm
meta-arm: eb9c47a4e1..9b6c8c95e4: Abdellatif El Khlifi (1): CI: append classes to INHERIT in the common fvp.yml Adam Johnston (1): arm-bsp/linux-yocto: Update N1SDP PCI quirk patch Jon Mason (10): CI: add yml files for defaults CI: add support for dev kernel, rt kernel, and poky-tiny arm-bsp/fvp-base: update to u-boot 2023.01 arm-bsp/fvp-base-arm32: remove support ci: add external-toolchain to qemuarm-secureboot arm-bsp/optee: remove unused recipes arm/optee: optee-os include cleanup arm/optee-os: update to 3.20.0 arm/edk2: update version and relocate edk2-basetools to be with edk2 arm-bsp/fvp-base: Add edk2 build testing Ross Burton (7): arm-bsp/linux-arm64-ack: update Upstream-Status tags CI: add CI_CLEAN_REPOS variable to allow cleaning the repo reference cache arm/scp-firmware: fix up whitespace arm/scp-firmware: enable verbose builds arm/scp-firmware: remove textrel from INSANE_SKIP arm/scp-firmware: improve debug packaging CI: mask poky's llvm if we're using clang Rui Miguel Silva (1): arm-bsp/optee: bump corstone1000 to v3.20 Satish Kumar (1): arm-bsp/corstone1000: new gpt based disk layout and fwu metadata Xueliang Zhong (1): arm-bsp/n1sdp: update to linux yocto kernel 6.1 meta-security: c06b9a18a6..a397a38ed9: Armin Kuster (16): openscap: update to 1.3.6 openscap: update to 1.3.7 openscap git: add DEFAULT_PREFERENCE python3-fail2ban: update to 1.0.2 python3-privacyidea: update to 3.8.1 libhtp: update to 0.5.42 lkrg-modules: update to 0.9.6 chkrootkit: update to 0.57 fscrypt: update to 1.1.0 libmspack: update to 1.11 firejail: update 0.9.72 suricata: update to 6.0.10 apparmor: update to 3.1.3 krill: update 0.12.3 cryptmout: update to 6.2.0 packagegroup-core-security: refactor the inclusion of krill Eero Aaltonen (1): dm-verity-img.bbclass: fix syntax warning Jose Quaresma (3): meta-hardening/layer: lower the priority from 10 to 6 meta-security-compliance/layer: lower the priority from 10 to 6 meta-tpm/layer: lower the priority from 10 to 6 Kevin Hao (1): dm-verity-img.bbclass: Fix the hash offset alignment issue Mikko Rapeli (1): ima-evm-utils: disable documentation from build Paul Gortmaker (3): dm-verity: update beaglebone wic to match meta-yocto dm-verity: add basic non-arch/non-BSP yocto specific settings dm-verity: document board specifics for Beaglebone Black Peter Marko (1): tpm2-tss: correct CVE product meta-raspberrypi: e15b876155..3afdbbf782: Carlos Alberto Lopez Perez (1): mesa-demos: enable build with userland graphics drivers. Khem Raj (6): linux-raspberrypi: Add recipes for 6.1 kernel psplash: Make psplash wait for the framebuffer to be ready rpi-default-versions: Use 6.1 kernel as default gstreamer1.0-plugins-bad: Drop gpl packageconfig rpidistro-ffmpeg: Pin to use gcc always rpidistro-vlc: Fix build with clang16 Signed-off-by: Andrew Geissler <geissonator@yahoo.com> Change-Id: Ie6e60085306d31972098b87738eb550e5140b92a
Diffstat (limited to 'meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0002-Platform-corstone1000-Add-IO-test-in-ci_regressions.patch')
-rw-r--r--meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0002-Platform-corstone1000-Add-IO-test-in-ci_regressions.patch646
1 files changed, 646 insertions, 0 deletions
diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0002-Platform-corstone1000-Add-IO-test-in-ci_regressions.patch b/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0002-Platform-corstone1000-Add-IO-test-in-ci_regressions.patch
new file mode 100644
index 0000000000..a4da13ecfc
--- /dev/null
+++ b/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0002-Platform-corstone1000-Add-IO-test-in-ci_regressions.patch
@@ -0,0 +1,646 @@
+From 3bca7e6bae9a5017fff83b0a7d2d0d78b422a741 Mon Sep 17 00:00:00 2001
+From: Mohamed Omar Asaker <mohamed.omarasaker@arm.com>
+Date: Mon, 7 Nov 2022 12:51:58 +0000
+Subject: [PATCH 02/10] Platform: corstone1000: Add IO test in ci_regressions
+
+The test is simply writing data on the edge of a block
+then reading back again.
+this test is preformed on two flash devices:
+- Nor Flash
+- Flash emu in the SRAM for testing
+
+Signed-off-by: Mohamed Omar Asaker <mohamed.omarasaker@arm.com>
+Change-Id: I4950086e9e3dcbde29ab5b4ed5fe61fec7ebec86
+Upstream-Status: Accepted [TF-Mv1.8.0]
+---
+ .../ci_regression_tests/CMakeLists.txt | 10 +
+ .../Driver_Flash_SRAM_Emu.c | 327 ++++++++++++++++++
+ .../ci_regression_tests/s_io_storage_test.c | 147 ++++++++
+ .../ci_regression_tests/s_io_storage_test.h | 15 +
+ .../corstone1000/ci_regression_tests/s_test.c | 5 +
+ .../ci_regression_tests/s_test_config.cmake | 5 +
+ .../ci_regression_tests/test_flash.h | 25 ++
+ 7 files changed, 534 insertions(+)
+ create mode 100644 platform/ext/target/arm/corstone1000/ci_regression_tests/Driver_Flash_SRAM_Emu.c
+ create mode 100644 platform/ext/target/arm/corstone1000/ci_regression_tests/s_io_storage_test.c
+ create mode 100644 platform/ext/target/arm/corstone1000/ci_regression_tests/s_io_storage_test.h
+ create mode 100644 platform/ext/target/arm/corstone1000/ci_regression_tests/test_flash.h
+
+diff --git a/platform/ext/target/arm/corstone1000/ci_regression_tests/CMakeLists.txt b/platform/ext/target/arm/corstone1000/ci_regression_tests/CMakeLists.txt
+index 9543e29e55..405b2b3702 100644
+--- a/platform/ext/target/arm/corstone1000/ci_regression_tests/CMakeLists.txt
++++ b/platform/ext/target/arm/corstone1000/ci_regression_tests/CMakeLists.txt
+@@ -17,12 +17,18 @@ target_sources(tfm_test_suite_extra_s
+ PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}/s_test.c
+ ../Native_Driver/firewall.c
++ ../io/io_storage.c
++ ../io/io_block.c
++ ../io/io_flash.c
++ Driver_Flash_SRAM_Emu.c
++ s_io_storage_test.c
+ )
+
+ target_include_directories(tfm_test_suite_extra_s
+ PRIVATE
+ ../Device/Include
+ ../Native_Driver
++ ../io
+ )
+
+ target_link_libraries(tfm_test_suite_extra_s
+@@ -33,4 +39,8 @@ target_link_libraries(tfm_test_suite_extra_s
+ target_compile_definitions(tfm_test_suite_extra_s
+ PRIVATE
+ $<$<BOOL:${PLATFORM_IS_FVP}>:PLATFORM_IS_FVP>
++ TEST_FLASH_SIZE_IN_BYTES=${TEST_FLASH_SIZE_IN_BYTES}
++ TEST_FLASH_SECTOR_SIZE_IN_BYTES=${TEST_FLASH_SECTOR_SIZE_IN_BYTES}
++ TEST_FLASH_PAGE_SIZE=${TEST_FLASH_PAGE_SIZE}
++ TEST_FLASH_PROGRAM_UNIT=${TEST_FLASH_PROGRAM_UNIT}
+ )
+diff --git a/platform/ext/target/arm/corstone1000/ci_regression_tests/Driver_Flash_SRAM_Emu.c b/platform/ext/target/arm/corstone1000/ci_regression_tests/Driver_Flash_SRAM_Emu.c
+new file mode 100644
+index 0000000000..06b6b51c09
+--- /dev/null
++++ b/platform/ext/target/arm/corstone1000/ci_regression_tests/Driver_Flash_SRAM_Emu.c
+@@ -0,0 +1,327 @@
++/*
++ * Copyright (c) 2013-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
++ *
++ * 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 <string.h>
++#include <stdint.h>
++#include "Driver_Flash.h"
++#include "test_flash.h"
++#include "tfm_sp_log.h"
++
++#ifndef ARG_UNUSED
++#define ARG_UNUSED(arg) ((void)arg)
++#endif
++
++/* Driver version */
++#define ARM_FLASH_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 1)
++#define ARM_FLASH_DRV_ERASE_VALUE 0xFF
++
++
++/**
++ * There is no real flash memory. This driver just emulates a flash
++ * interface and behaviour on top of the SRAM memory.
++ */
++
++/**
++ * Data width values for ARM_FLASH_CAPABILITIES::data_width
++ * \ref ARM_FLASH_CAPABILITIES
++ */
++ enum {
++ DATA_WIDTH_8BIT = 0u,
++ DATA_WIDTH_16BIT,
++ DATA_WIDTH_32BIT,
++ DATA_WIDTH_ENUM_SIZE
++};
++
++static const uint32_t data_width_byte[DATA_WIDTH_ENUM_SIZE] = {
++ sizeof(uint8_t),
++ sizeof(uint16_t),
++ sizeof(uint32_t),
++};
++
++
++/*
++ * ARM FLASH device structure
++ *
++ */
++struct arm_flash_dev_t {
++ const uint8_t* memory_base; /*!< FLASH memory base address */
++ ARM_FLASH_INFO *data; /*!< FLASH data */
++};
++
++/* Flash emulated memory */
++static uint8_t flash_memory[TEST_FLASH_SIZE_IN_BYTES]
++ __attribute__((aligned(TEST_FLASH_SECTOR_SIZE_IN_BYTES)));
++
++/* Flash Status */
++static ARM_FLASH_STATUS FlashStatus = {0, 0, 0};
++
++/* Driver Version */
++static const ARM_DRIVER_VERSION DriverVersion = {
++ ARM_FLASH_API_VERSION,
++ ARM_FLASH_DRV_VERSION
++};
++
++/* Driver Capabilities */
++static const ARM_FLASH_CAPABILITIES DriverCapabilities = {
++ 0, /* event_ready */
++ 0, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */
++ 1 /* erase_chip */
++};
++
++static int32_t is_range_valid(struct arm_flash_dev_t *flash_dev,
++ uint32_t offset)
++{
++ uint32_t flash_limit = 0;
++ int32_t rc = 0;
++
++ flash_limit = (flash_dev->data->sector_count * flash_dev->data->sector_size);
++ if (offset > flash_limit) {
++ rc = -1;
++ }
++ return rc;
++}
++
++static int32_t is_write_aligned(struct arm_flash_dev_t *flash_dev,
++ uint32_t param)
++{
++ int32_t rc = 0;
++
++ if ((param % flash_dev->data->program_unit) != 0) {
++ rc = -1;
++ }
++ return rc;
++}
++
++static int32_t is_sector_aligned(struct arm_flash_dev_t *flash_dev,
++ uint32_t offset)
++{
++ int32_t rc = 0;
++
++ if ((offset % flash_dev->data->sector_size) != 0) {
++ rc = -1;
++ }
++ return rc;
++}
++
++static int32_t is_flash_ready_to_write(const uint8_t *start_addr, uint32_t cnt)
++{
++ int32_t rc = 0;
++ uint32_t i;
++
++ for (i = 0; i < cnt; i++) {
++ if(start_addr[i] != ARM_FLASH_DRV_ERASE_VALUE) {
++ rc = -1;
++ break;
++ }
++ }
++
++ return rc;
++}
++
++static ARM_FLASH_INFO ARM_TEST_FLASH_DEV_DATA = {
++ .sector_info = NULL,/* Uniform sector layout */
++ .sector_count = TEST_FLASH_SIZE_IN_BYTES / TEST_FLASH_SECTOR_SIZE_IN_BYTES,
++ .sector_size = TEST_FLASH_SECTOR_SIZE_IN_BYTES,
++ .page_size = TEST_FLASH_PAGE_SIZE,
++ .program_unit = TEST_FLASH_PROGRAM_UNIT,
++ .erased_value = ARM_FLASH_DRV_ERASE_VALUE};
++
++static struct arm_flash_dev_t ARM_TEST_FLASH_DEV = {
++ .memory_base = flash_memory,
++ .data = &(ARM_TEST_FLASH_DEV_DATA)};
++
++static struct arm_flash_dev_t *TEST_FLASH_DEV = &ARM_TEST_FLASH_DEV;
++
++/*
++ * Functions
++ */
++
++static ARM_DRIVER_VERSION ARM_Flash_GetVersion(void)
++{
++ return DriverVersion;
++}
++
++static ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities(void)
++{
++ return DriverCapabilities;
++}
++
++static int32_t ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)
++{
++ ARG_UNUSED(cb_event);
++
++ if (DriverCapabilities.data_width >= DATA_WIDTH_ENUM_SIZE) {
++ return ARM_DRIVER_ERROR;
++ }
++
++ /* Nothing to be done */
++ return ARM_DRIVER_OK;
++}
++
++static int32_t ARM_Flash_Uninitialize(void)
++{
++ /* Nothing to be done */
++ return ARM_DRIVER_OK;
++}
++
++static int32_t ARM_Flash_PowerControl(ARM_POWER_STATE state)
++{
++ switch (state) {
++ case ARM_POWER_FULL:
++ /* Nothing to be done */
++ return ARM_DRIVER_OK;
++ break;
++
++ case ARM_POWER_OFF:
++ case ARM_POWER_LOW:
++ default:
++ return ARM_DRIVER_ERROR_UNSUPPORTED;
++ }
++}
++
++static int32_t ARM_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt)
++{
++ int32_t rc = 0;
++
++ /* The addr given is a relative address*/
++ uint32_t offset = addr;
++ addr += (uint32_t)(TEST_FLASH_DEV->memory_base);
++
++ /* Conversion between data items and bytes */
++ cnt *= data_width_byte[DriverCapabilities.data_width];
++
++ /* Check flash memory boundaries */
++ rc = is_range_valid(TEST_FLASH_DEV, offset + cnt);
++ if (rc != 0) {
++ return ARM_DRIVER_ERROR_PARAMETER;
++ }
++
++ /* Flash interface just emulated over SRAM, use memcpy */
++ memcpy(data, (void *)addr, cnt);
++
++ /* Conversion between bytes and data items */
++ cnt /= data_width_byte[DriverCapabilities.data_width];
++
++ return cnt;
++}
++
++static int32_t ARM_Flash_ProgramData(uint32_t addr, const void *data,
++ uint32_t cnt)
++{
++ int32_t rc = 0;
++
++ /* The addr given is a relative address*/
++ uint32_t offset = addr;
++ addr += (uint32_t)(TEST_FLASH_DEV->memory_base);
++
++ /* Conversion between data items and bytes */
++ cnt *= data_width_byte[DriverCapabilities.data_width];
++
++ /* Check flash memory boundaries and alignment with minimal write size */
++ rc = is_range_valid(TEST_FLASH_DEV, offset + cnt);
++ rc |= is_write_aligned(TEST_FLASH_DEV, offset);
++ rc |= is_write_aligned(TEST_FLASH_DEV, cnt);
++ if (rc != 0) {
++ return ARM_DRIVER_ERROR_PARAMETER;
++ }
++
++ /* Check if the flash area to write the data was erased previously */
++ rc = is_flash_ready_to_write((const uint8_t*)addr, cnt);
++ if (rc != 0) {
++ return ARM_DRIVER_ERROR;
++ }
++
++ /* Flash interface just emulated over SRAM, use memcpy */
++ memcpy((void *)addr, data, cnt);
++
++ /* Conversion between bytes and data items */
++ cnt /= data_width_byte[DriverCapabilities.data_width];
++
++ return cnt;
++}
++
++static int32_t ARM_Flash_EraseSector(uint32_t addr)
++{
++ uint32_t rc = 0;
++
++ /* The addr given is a relative address*/
++ uint32_t offset = addr;
++ addr += (uint32_t)(TEST_FLASH_DEV->memory_base);
++
++ rc = is_range_valid(TEST_FLASH_DEV, offset);
++ rc |= is_sector_aligned(TEST_FLASH_DEV, offset);
++ if (rc != 0) {
++ return ARM_DRIVER_ERROR_PARAMETER;
++ }
++
++ /* Flash interface just emulated over SRAM, use memset */
++ memset((void *)addr,
++ TEST_FLASH_DEV->data->erased_value,
++ TEST_FLASH_DEV->data->sector_size);
++ return ARM_DRIVER_OK;
++}
++
++static int32_t ARM_Flash_EraseChip(void)
++{
++ uint32_t i;
++ uint32_t addr = TEST_FLASH_DEV->memory_base;
++ int32_t rc = ARM_DRIVER_ERROR_UNSUPPORTED;
++
++ /* Check driver capability erase_chip bit */
++ if (DriverCapabilities.erase_chip == 1) {
++ for (i = 0; i < TEST_FLASH_DEV->data->sector_count; i++) {
++ /* Flash interface just emulated over SRAM, use memset */
++ memset((void *)addr,
++ TEST_FLASH_DEV->data->erased_value,
++ TEST_FLASH_DEV->data->sector_size);
++
++ addr += TEST_FLASH_DEV->data->sector_size;
++ rc = ARM_DRIVER_OK;
++ }
++ }
++ return rc;
++}
++
++static ARM_FLASH_STATUS ARM_Flash_GetStatus(void)
++{
++ return FlashStatus;
++}
++
++static ARM_FLASH_INFO * ARM_Flash_GetInfo(void)
++{
++ return TEST_FLASH_DEV->data;
++}
++
++
++/* Global Variables */
++
++ARM_DRIVER_FLASH Driver_TEST_FLASH = {
++ ARM_Flash_GetVersion,
++ ARM_Flash_GetCapabilities,
++ ARM_Flash_Initialize,
++ ARM_Flash_Uninitialize,
++ ARM_Flash_PowerControl,
++ ARM_Flash_ReadData,
++ ARM_Flash_ProgramData,
++ ARM_Flash_EraseSector,
++ ARM_Flash_EraseChip,
++ ARM_Flash_GetStatus,
++ ARM_Flash_GetInfo
++};
++
++uintptr_t flash_base_address = flash_memory;
+diff --git a/platform/ext/target/arm/corstone1000/ci_regression_tests/s_io_storage_test.c b/platform/ext/target/arm/corstone1000/ci_regression_tests/s_io_storage_test.c
+new file mode 100644
+index 0000000000..f8be384a74
+--- /dev/null
++++ b/platform/ext/target/arm/corstone1000/ci_regression_tests/s_io_storage_test.c
+@@ -0,0 +1,147 @@
++/*
++ * Copyright (c) 2022, Arm Limited. All rights reserved.
++ *
++ * SPDX-License-Identifier: BSD-3-Clause
++ *
++ */
++
++#include "s_io_storage_test.h"
++
++#include "Driver_Flash.h"
++#include "flash_layout.h"
++#include "io_block.h"
++#include "io_driver.h"
++#include "io_flash.h"
++#include "tfm_sp_log.h"
++
++#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(*(array)))
++
++extern ARM_DRIVER_FLASH Driver_FLASH0;
++extern ARM_DRIVER_FLASH Driver_TEST_FLASH;
++extern uintptr_t flash_base_address;
++
++void s_test_io_storage_multiple_flash_simultaneous(struct test_result_t *ret) {
++ /* FLASH0 */
++ static io_dev_connector_t* flash0_dev_con;
++ static uint8_t local_block_flash0[FLASH_SECTOR_SIZE];
++ ARM_FLASH_INFO* flash0_info = Driver_FLASH0.GetInfo();
++ size_t flash0_block_size = flash0_info->sector_size;
++ io_flash_dev_spec_t flash0_dev_spec = {
++ .buffer = local_block_flash0,
++ .bufferlen = flash0_block_size,
++ .base_addr = FLASH_BASE_ADDRESS,
++ .flash_driver = &Driver_FLASH0,
++ };
++ io_block_spec_t flash0_spec = {
++ .offset = FLASH_BASE_ADDRESS,
++ .length = flash0_info->sector_count * flash0_info->sector_size};
++ uintptr_t flash0_dev_handle = NULL;
++ uintptr_t flash0_handle = NULL;
++
++ /* EMU TEST FLASH */
++ static io_dev_connector_t* flash_emu_dev_con;
++ static uint8_t local_block_flash_emu[TEST_FLASH_SECTOR_SIZE_IN_BYTES]
++ __attribute__((aligned(TEST_FLASH_SECTOR_SIZE_IN_BYTES)));
++ ARM_FLASH_INFO* flash_emu_info = Driver_TEST_FLASH.GetInfo();
++ size_t flash_emu_block_size = flash_emu_info->sector_size;
++ io_flash_dev_spec_t flash_emu_dev_spec = {
++ .buffer = local_block_flash_emu,
++ .bufferlen = flash_emu_block_size,
++ .base_addr = flash_base_address,
++ .flash_driver = &Driver_TEST_FLASH,
++ };
++ io_block_spec_t flash_emu_spec = {
++ .offset = flash_base_address,
++ .length = flash_emu_info->sector_count * flash_emu_info->sector_size};
++ uintptr_t flash_emu_dev_handle = NULL;
++ uintptr_t flash_emu_handle = NULL;
++
++ /* Common */
++ int rc = -1;
++ static uint8_t test_data[] = {0xEE, 0xDD, 0xCC, 0xBB, 0xAA,
++ 0x10, 0x50, 0xA0, 0xD0, 0x51,
++ 0x55, 0x44, 0x33, 0x22, 0x11};
++ static uint8_t actual_data[15];
++ size_t bytes_written_count = 0;
++ size_t bytes_read_count = 0;
++
++ memset(local_block_flash0, -1, sizeof(local_block_flash0));
++ memset(local_block_flash_emu, -1, sizeof(local_block_flash_emu));
++
++ /* Register */
++ register_io_dev_flash(&flash0_dev_con);
++ register_io_dev_flash(&flash_emu_dev_con);
++
++ io_dev_open(flash0_dev_con, &flash0_dev_spec, &flash0_dev_handle);
++ io_dev_open(flash_emu_dev_con, &flash_emu_dev_spec, &flash_emu_dev_handle);
++
++ /* Write Data */
++ io_open(flash0_dev_handle, &flash0_spec, &flash0_handle);
++ io_open(flash_emu_dev_handle, &flash_emu_spec, &flash_emu_handle);
++
++ io_seek(flash0_handle, IO_SEEK_SET,
++ BANK_1_PARTITION_OFFSET + flash0_info->sector_size - 7);
++ io_seek(flash_emu_handle, IO_SEEK_SET, flash_emu_info->sector_size - 7);
++
++ io_write(flash0_handle, test_data, ARRAY_LENGTH(test_data),
++ &bytes_written_count);
++ if (bytes_written_count != ARRAY_LENGTH(test_data)) {
++ LOG_ERRFMT("io_write failed to write %d bytes for flash0",
++ ARRAY_LENGTH(test_data));
++ LOG_ERRFMT("bytes_written_count %d for flash0", bytes_written_count);
++ ret->val = TEST_FAILED;
++ }
++ io_write(flash_emu_handle, test_data, ARRAY_LENGTH(test_data),
++ &bytes_written_count);
++ if (bytes_written_count != ARRAY_LENGTH(test_data)) {
++ LOG_ERRFMT("io_write failed to write %d bytes for flash emu",
++ ARRAY_LENGTH(test_data));
++ LOG_ERRFMT("bytes_written_count %d for flash emu", bytes_written_count);
++ ret->val = TEST_FAILED;
++ }
++ io_close(flash0_handle);
++ io_close(flash_emu_handle);
++
++ /* Read Data */
++ io_open(flash0_dev_handle, &flash0_spec, &flash0_handle);
++ io_open(flash_emu_dev_handle, &flash_emu_spec, &flash_emu_handle);
++
++ io_seek(flash0_handle, IO_SEEK_SET,
++ BANK_1_PARTITION_OFFSET + flash0_info->sector_size - 7);
++ io_seek(flash_emu_handle, IO_SEEK_SET, flash_emu_info->sector_size - 7);
++
++ /* Flash0 */
++ io_read(flash0_handle, actual_data, ARRAY_LENGTH(actual_data),
++ &bytes_read_count);
++ if (bytes_read_count != ARRAY_LENGTH(test_data)) {
++ LOG_ERRFMT("io_read failed to read %d bytes for flash0",
++ ARRAY_LENGTH(test_data));
++ LOG_ERRFMT("bytes_read_count %d for flash0", bytes_read_count);
++ ret->val = TEST_FAILED;
++ }
++ if (memcmp((uint8_t*)test_data, actual_data, ARRAY_LENGTH(actual_data)) !=
++ 0) {
++ LOG_ERRFMT("Data written != Data read\r\n");
++ ret->val = TEST_FAILED;
++ }
++
++ memset(actual_data, -1, sizeof(actual_data));
++
++ /* Flash Emu */
++ io_read(flash_emu_handle, actual_data, ARRAY_LENGTH(actual_data),
++ &bytes_read_count);
++ if (bytes_read_count != ARRAY_LENGTH(test_data)) {
++ LOG_ERRFMT("io_read failed to read %d bytes for flash emu",
++ ARRAY_LENGTH(test_data));
++ LOG_ERRFMT("bytes_read_count %d for flash emu", bytes_read_count);
++ ret->val = TEST_FAILED;
++ }
++ if (memcmp((uint8_t*)test_data, actual_data, ARRAY_LENGTH(actual_data)) !=
++ 0) {
++ LOG_ERRFMT("Data written != Data read\r\n");
++ ret->val = TEST_FAILED;
++ }
++
++ LOG_INFFMT("PASS: %s\n\r", __func__);
++ ret->val = TEST_PASSED;
++}
+\ No newline at end of file
+diff --git a/platform/ext/target/arm/corstone1000/ci_regression_tests/s_io_storage_test.h b/platform/ext/target/arm/corstone1000/ci_regression_tests/s_io_storage_test.h
+new file mode 100644
+index 0000000000..fa9012776f
+--- /dev/null
++++ b/platform/ext/target/arm/corstone1000/ci_regression_tests/s_io_storage_test.h
+@@ -0,0 +1,15 @@
++/*
++ * Copyright (c) 2022, Arm Limited. All rights reserved.
++ *
++ * SPDX-License-Identifier: BSD-3-Clause
++ *
++ */
++
++#ifndef __S_IO_STORAGE_TEST_H__
++#define __S_IO_STORAGE_TEST_H__
++
++#include "extra_s_tests.h"
++
++void s_test_io_storage_multiple_flash_simultaneous(struct test_result_t *ret);
++
++#endif /* __S_IO_STORAGE_TEST_H__ */
+\ No newline at end of file
+diff --git a/platform/ext/target/arm/corstone1000/ci_regression_tests/s_test.c b/platform/ext/target/arm/corstone1000/ci_regression_tests/s_test.c
+index a0bf47a04b..9a8453ff57 100644
+--- a/platform/ext/target/arm/corstone1000/ci_regression_tests/s_test.c
++++ b/platform/ext/target/arm/corstone1000/ci_regression_tests/s_test.c
+@@ -11,6 +11,7 @@
+ #include "platform_base_address.h"
+ #include "firewall.h"
+ #include "tfm_sp_log.h"
++#include "s_io_storage_test.h"
+
+ /* TODO: if needed each test function can be made as a separate test case, in
+ * such case EXTRA_TEST_XX definitions can be removed */
+@@ -19,6 +20,8 @@
+
+ #define DISABLED_TEST 0
+
++int test_io_storage_multiple_flash_simultaneous(void);
++
+ enum host_firewall_host_comp_id_t {
+ HOST_FCTRL = (0x00u),
+ COMP_SYSPERIPH,
+@@ -184,6 +187,8 @@ void s_test(struct test_result_t *ret)
+ static struct test_t plat_s_t[] = {
+ {&s_test, "TFM_S_EXTRA_TEST_1001",
+ "Extra Secure test"},
++ {&s_test_io_storage_multiple_flash_simultaneous, "TFM_S_EXTRA_TEST_1002",
++ "Extra Secure test: io storage access multiple flash simultaneous"},
+ };
+
+ void register_testsuite_extra_s_interface(struct test_suite_t *p_test_suite)
+diff --git a/platform/ext/target/arm/corstone1000/ci_regression_tests/s_test_config.cmake b/platform/ext/target/arm/corstone1000/ci_regression_tests/s_test_config.cmake
+index bb8d26bf1c..05b7cd7852 100644
+--- a/platform/ext/target/arm/corstone1000/ci_regression_tests/s_test_config.cmake
++++ b/platform/ext/target/arm/corstone1000/ci_regression_tests/s_test_config.cmake
+@@ -6,3 +6,8 @@
+ #-------------------------------------------------------------------------------
+
+ ############ Define secure test specific cmake configurations here #############
++
++set (TEST_FLASH_SIZE_IN_BYTES 48U CACHE STRING "The size of the emulated flash used in io tests")
++set (TEST_FLASH_SECTOR_SIZE_IN_BYTES 16U CACHE STRING "The sector size of the emulated flash used in io tests")
++set (TEST_FLASH_PAGE_SIZE 8U CACHE STRING "The page size of the emulated flash used in io tests")
++set (TEST_FLASH_PROGRAM_UNIT 1U CACHE STRING "The program unit of the emulated flash used in io tests")
+diff --git a/platform/ext/target/arm/corstone1000/ci_regression_tests/test_flash.h b/platform/ext/target/arm/corstone1000/ci_regression_tests/test_flash.h
+new file mode 100644
+index 0000000000..4d073a1d71
+--- /dev/null
++++ b/platform/ext/target/arm/corstone1000/ci_regression_tests/test_flash.h
+@@ -0,0 +1,25 @@
++/*
++ * Copyright (c) 2017-2022 Arm Limited. All rights reserved.
++ *
++ * 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 __TEST_FLASH_H__
++#define __TEST_FLASH_H__
++
++#define TEST_FLASH_SIZE_IN_BYTES (48) // 48 bytes
++#define TEST_FLASH_SECTOR_SIZE_IN_BYTES (16) // 16 bytes
++#define TEST_FLASH_PAGE_SIZE (8U) // 8 bytes
++#define TEST_FLASH_PROGRAM_UNIT (1U) /* 1 B */
++
++#endif /* __TEST_FLASH_H__ */
+--
+2.25.1
+