RSS: Add GPT and FIP support
Change RSS from using fixed locations in host flash to loading images
from FIPs (which are at fixed locations). Additionally, add GPT support
(via RSS_GPT_SUPPORT) to support FIPs being at non-fixed locations.
Change-Id: Ia189d2544c6ccee8d6171583e33a54d77746963b
Signed-off-by: Raef Coles <raef.coles@arm.com>
diff --git a/bl1/bl1_2/lib/image.c b/bl1/bl1_2/lib/image.c
index 1a08ed6..be38050 100644
--- a/bl1/bl1_2/lib/image.c
+++ b/bl1/bl1_2/lib/image.c
@@ -16,7 +16,7 @@
extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
#endif /* !TFM_BL1_MEMORY_MAPPED_FLASH */
-int32_t __WEAK bl1_image_get_flash_offset(uint32_t image_id)
+uint32_t __WEAK bl1_image_get_flash_offset(uint32_t image_id)
{
switch (image_id) {
case 0:
diff --git a/bl1/bl1_2/lib/interface/image.h b/bl1/bl1_2/lib/interface/image.h
index dfb0087..ccf6f2b 100644
--- a/bl1/bl1_2/lib/interface/image.h
+++ b/bl1/bl1_2/lib/interface/image.h
@@ -47,7 +47,7 @@
} protected_values;
};
-int32_t bl1_image_get_flash_offset(uint32_t image_id);
+uint32_t bl1_image_get_flash_offset(uint32_t image_id);
fih_int bl1_image_copy_to_sram(uint32_t image_id, uint8_t *out);
diff --git a/docs/platform/arm/rss/readme.rst b/docs/platform/arm/rss/readme.rst
index fd185f2..d4cb7a6 100644
--- a/docs/platform/arm/rss/readme.rst
+++ b/docs/platform/arm/rss/readme.rst
@@ -78,62 +78,100 @@
----------------
To run the built images, they need to be concatenated into binaries that can be
-placed in ROM and flash. To do this, navigate to the TF-M build directory and
-run the following ``srec_cat`` commands::
+placed in ROM and flash. To create the ROM image, navigate to the TF-M build
+directory and run the following ``srec_cat`` command::
srec_cat \
bl1_1.bin -Binary -offset 0x0 \
bl1_provisioning_bundle.bin -Binary -offset 0xE000 \
-o rom.bin -Binary
- srec_cat \
- bl2_signed.bin -Binary -offset 0x0 \
- bl2_signed.bin -Binary -offset 0x10000 \
- tfm_s_ns_signed.bin -Binary -offset 0x020000 \
- tfm_s_ns_signed.bin -Binary -offset 0x0E0000 \
- <Host AP BL1 image> -Binary -offset 0x1A0000 \
- <SCP BL1 image> -Binary -offset 0x220000 \
- <Host AP BL1 image> -Binary -offset 0x2A0000 \
- <SCP BL1 image> -Binary -offset 0x320000 \
- -o flash.bin -Binary
+For development purposes, the OTP image is included as a provisioning bundle in
+the ROM image and provisioned into OTP by BL1_1.
-If XIP mode is enabled, the following ``srec_cat`` command should be run to
+To create the flash image, the following ``fiptool`` command should be run.
+``fiptool`` documentation can be found `here <https://trustedfirmware-a.readthedocs.io/en/latest/getting_started/tools-build.html?highlight=fiptool#building-and-using-the-fip-tool>`_.
+Note that an up-to-date fiptool that supports the RSS UUIDs must be used.::
+
+ fiptool create \
+ --align 8192 --rss-bl2 bl2_signed.bin \
+ --align 8192 --rss-ns tfm_ns_signed.bin \
+ --align 8192 --rss-s tfm_s_signed.bin \
+ --align 8192 --rss-scp-bl1 <signed Host SCP BL1 image> \
+ --align 8192 --rss-ap-bl1 <signed Host AP BL1 image> \
+ fip.bin
+
+If you already have a ``fip.bin`` containing host firmware images, RSS FIP
+images can be patched in::
+
+ fiptool update --align 8192 --rss-bl2 bl2_signed.bin fip.bin
+ fiptool update --align 8192 --rss-ns tfm_ns.bin fip.bin
+ fiptool update --align 8192 --rss-s tfm_s.bin fip.bin
+
+If XIP mode is enabled, the following ``fiptool`` command should be run to
create the flash image::
- srec_cat \
- bl2_signed.bin -Binary -offset 0x0 \
- bl2_signed.bin -Binary -offset 0x10000 \
- tfm_s.bin -Binary -offset 0x020000 \
- tfm_ns.bin -Binary -offset 0x080000 \
- tfm_s.bin -Binary -offset 0x0E0000 \
- tfm_ns.bin -Binary -offset 0x140000 \
- <Host AP BL1 image> -Binary -offset 0x1A0000 \
- <SCP BL1 image> -Binary -offset 0x220000 \
- <Host AP BL1 image> -Binary -offset 0x2A0000 \
- <SCP BL1 image> -Binary -offset 0x320000 \
- tfm_s_sic_tables_signed.bin -Binary -offset 0x3A0000 \
- tfm_ns_sic_tables_signed.bin -Binary -offset 0x3AA000 \
- tfm_s_sic_tables_signed.bin -Binary -offset 0x3B4000 \
- tfm_ns_sic_tables_signed.bin -Binary -offset 0x3BE000 \
- -o flash.bin -Binary
+ fiptool create \
+ --align 8192 --rss-bl2 bl2_signed.bin \
+ --align 8192 --rss-ns tfm_ns.bin \
+ --align 8192 --rss-s tfm_s.bin \
+ --align 8192 --rss-sic-tables-ns tfm_ns_sic_tables_signed.bin \
+ --align 8192 --rss-sic-tables-s tfm_s_sic_tables_signed.bin \
+ --align 8192 --rss-scp-bl1 <signed Host SCP BL1 image> \
+ --align 8192 --rss-ap-bl1 <signed Host AP BL1 image> \
+ fip.bin
-Once the flash image is created, it can be combined with the host FIP to create
-a combined host flash image::
+Once the FIP is prepared, a host flash image can be created using ``srec_cat``::
srec_cat \
- fip-tc.bin -Binary -offset 0x0\
- flash.bin -Binary -offset 0x02200000 \
+ fip.bin -Binary -offset 0x0 \
-o host_flash.bin -Binary
-For development purposes, the OTP image is included as a provisioning bundle in
-the ROM image and provisioned into OTP by BL1_1. The flash image should include
-the signed host images from the previous section. For each boot image, there is
-a primary and secondary image; if these are different then BL2 will load the one
-with the higher version number.
+If GPT support is enabled, and a host ``fip.bin`` and ``fip_gpt.bin`` has been
+obtained, RSS images can be inserted by first patching the host FIP and then
+inserting that patched FIP into the GPT image::
+
+ sector_size=$(gdisk -l fip_gpt.bin | grep -i "sector size (logical):" | \
+ sed 's/.*logical): \([0-9]*\) bytes/\1/')
+
+ fip_label=" FIP_A$"
+ fip_start_sector=$(gdisk -l fip_gpt.bin | grep "$fip_label" | awk '{print $2}')
+ fip_sector_am=$(gdisk -l fip_gpt.bin | grep "$fip_label" | awk '{print $3 - $2}')
+
+ dd if=fip.bin of=fip_gpt.bin bs=$sector_size seek=$fip_start_sector \
+ count=$fip_sector_am conv=notrunc
+
+ fip_label = " FIP_B$"
+ fip_start_sector = $(gdisk -l fip_gpt.bin | grep "$fip_label" | awk '{print $2}')
+ fip_sector_am = $(gdisk -l fip_gpt.bin | grep "$fip_label" | awk '{print $3 - $2}')
+
+ dd if=fip.bin of=fip_gpt.bin bs=$sector_size seek=$fip_start_sector \
+ count=$fip_sector_am conv=notrunc
+
+To patch a ``fip_gpt.bin`` without having an initial ``fip.bin``, the FIP can be
+extracted from the GPT image using the following commands (and can then be
+patched and reinserted using the above commands)::
+
+ sector_size=$(gdisk -l fip_gpt.bin | grep -i "sector size (logical):" | \
+ sed 's/.*logical): \([0-9]*\) bytes/\1/')
+
+ fip_label=" FIP_A$"
+ fip_start_sector=$(gdisk -l fip_gpt.bin | grep "$fip_label" | awk '{print $2}')
+ fip_sector_am=$(gdisk -l fip_gpt.bin | grep "$fip_label" | awk '{print $3 - $2}')
+
+ dd if=fip_gpt.bin of=fip.bin bs=$sector_size skip=$fip_start_sector \
+ count=$fip_sector_am conv=notrunc
+
+Once the ``fip_gpt.bin`` is prepared, it is placed at the base of the host flash
+image::
+
+ srec_cat \
+ fip_gpt.bin -Binary -offset 0x0 \
+ -o host_flash.bin -Binary
The ROM binary should be placed in RSS ROM at ``0x11000000`` and the host flash
binary should be placed at the base of the host flash. For the TC platform,
-this is at ``0x08000000``.
+this is at ``0x80000000``.
--------------
diff --git a/platform/ext/target/arm/rss/common/CMakeLists.txt b/platform/ext/target/arm/rss/common/CMakeLists.txt
index ee26e60..a71bf1e 100644
--- a/platform/ext/target/arm/rss/common/CMakeLists.txt
+++ b/platform/ext/target/arm/rss/common/CMakeLists.txt
@@ -22,6 +22,7 @@
INTERFACE
$<$<BOOL:${RSS_XIP}>:RSS_XIP>
$<$<BOOL:${RSS_DEBUG_UART}>:RSS_DEBUG_UART>
+ $<$<BOOL:${RSS_GPT_SUPPORT}>:RSS_GPT_SUPPORT>
)
#========================= Platform common defs ===============================#
@@ -262,6 +263,9 @@
native_drivers/lcm_drv.c
otp_lcm.c
nv_counters.c
+ fip_parser/fip_parser.c
+ fip_parser/host_flash_atu.c
+ $<$<BOOL:${RSS_GPT_SUPPORT}>:${CMAKE_CURRENT_SOURCE_DIR}/fip_parser/gpt.c>
)
target_include_directories(platform_bl2
@@ -281,6 +285,7 @@
PRIVATE
${PLATFORM_DIR}/..
native_drivers
+ ./fip_parser
)
target_compile_definitions(platform_bl2
@@ -309,9 +314,9 @@
target_sources(platform_bl1
PRIVATE
./bl1/boot_hal_bl1.c
- $<$<NOT:$<BOOL:${TFM_BL1_MEMORY_MAPPED_FLASH}>>:${CMAKE_CURRENT_SOURCE_DIR}/cmsis_drivers/Driver_Flash.c>
- $<$<NOT:$<BOOL:${TFM_BL1_MEMORY_MAPPED_FLASH}>>:${CMAKE_CURRENT_SOURCE_DIR}/native_drivers/cfi_drv.c>
- $<$<NOT:$<BOOL:${TFM_BL1_MEMORY_MAPPED_FLASH}>>:${CMAKE_CURRENT_SOURCE_DIR}/native_drivers/spi_strataflashj3_flash_lib.c>
+ cmsis_drivers/Driver_Flash.c
+ native_drivers/cfi_drv.c
+ native_drivers/spi_strataflashj3_flash_lib.c
./device/source/device_definition.c
./device/source/host_device_definition.c
./device/source/system_core_init.c
@@ -325,6 +330,9 @@
./otp_lcm.c
./nv_counters.c
./tfm_hal_platform_reset.c
+ ./fip_parser/fip_parser.c
+ ./fip_parser/host_flash_atu.c
+ $<$<BOOL:${RSS_GPT_SUPPORT}>:${CMAKE_CURRENT_SOURCE_DIR}/fip_parser/gpt.c>
)
target_include_directories(platform_bl1_interface
@@ -335,6 +343,7 @@
./device/config
./device/include
./native_drivers
+ ./fip_parser
)
target_compile_definitions(platform_bl1
diff --git a/platform/ext/target/arm/rss/common/bl1/boot_hal_bl1.c b/platform/ext/target/arm/rss/common/bl1/boot_hal_bl1.c
index 80ef504..a54ee7e 100644
--- a/platform/ext/target/arm/rss/common/bl1/boot_hal_bl1.c
+++ b/platform/ext/target/arm/rss/common/bl1/boot_hal_bl1.c
@@ -27,17 +27,31 @@
#endif /* CRYPTO_HW_ACCELERATOR */
#include <string.h>
#include "cmsis_compiler.h"
+#include "fip_parser.h"
+#include "host_flash_atu.h"
+#include "plat_def_fip_uuid.h"
extern uint8_t computed_bl1_2_hash[];
extern uint32_t platform_code_is_bl1_2;
+uint32_t image_offsets[2];
-#ifndef TFM_BL1_MEMORY_MAPPED_FLASH
/* Flash device name must be specified by target */
extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
-#endif /* !TFM_BL1_MEMORY_MAPPED_FLASH */
REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base);
+uint32_t bl1_image_get_flash_offset(uint32_t image_id)
+{
+ switch (image_id) {
+ case 0:
+ return HOST_FLASH0_IMAGE0_BASE_S - FLASH_BASE_ADDRESS + image_offsets[0];
+ case 1:
+ return HOST_FLASH0_IMAGE1_BASE_S - FLASH_BASE_ADDRESS + image_offsets[1];
+ default:
+ FIH_PANIC;
+ }
+}
+
static int32_t init_atu_regions(void)
{
enum atu_error_t err;
@@ -53,26 +67,6 @@
}
#endif /* !RSS_DEBUG_UART */
- /* Initialize BL2 slot 0 region */
- err = atu_initialize_region(&ATU_DEV_S,
- 0,
- HOST_FLASH0_BASE_S + FLASH_AREA_0_OFFSET,
- HOST_FLASH0_BASE + FLASH_AREA_0_OFFSET,
- FLASH_AREA_0_SIZE);
- if (err != ATU_ERR_NONE) {
- return 1;
- }
-
- /* Initialize BL2 slot 1 region */
- err = atu_initialize_region(&ATU_DEV_S,
- 1,
- HOST_FLASH0_BASE_S + FLASH_AREA_1_OFFSET,
- HOST_FLASH0_BASE + FLASH_AREA_1_OFFSET,
- FLASH_AREA_1_SIZE);
- if (err != ATU_ERR_NONE) {
- return 1;
- }
-
return 0;
}
@@ -101,12 +95,10 @@
stdio_init();
#endif /* defined(TFM_BL1_LOGGING) || defined(TEST_BL1_1) || defined(TEST_BL1_2) */
-#ifndef TFM_BL1_MEMORY_MAPPED_FLASH
result = FLASH_DEV_NAME.Initialize(NULL);
if (result != ARM_DRIVER_OK) {
return 1;
}
-#endif /* !TFM_BL1_MEMORY_MAPPED_FLASH */
result = bl1_trng_generate_random(prbg_seed, sizeof(prbg_seed));
if (result != 0) {
@@ -118,6 +110,11 @@
return result;
}
+ result = host_flash_atu_init_regions_for_image(UUID_RSS_FIRMWARE_BL2, image_offsets);
+ if (result) {
+ return result;
+ }
+
if(!platform_code_is_bl1_2) {
/* Clear boot data area */
memset((void*)BOOT_TFM_SHARED_DATA_BASE, 0, BOOT_TFM_SHARED_DATA_SIZE);
@@ -173,6 +170,14 @@
static struct boot_arm_vector_table *vt_cpy;
int32_t result;
+ if (platform_code_is_bl1_2) {
+ result = host_flash_atu_uninit_regions();
+ if (result) {
+ while(1){}
+ }
+ }
+
+
result = invalidate_hardware_keys();
if (result) {
while(1){}
@@ -185,12 +190,10 @@
}
#endif /* CRYPTO_HW_ACCELERATOR */
-#ifndef TFM_BL1_MEMORY_MAPPED_FLASH
result = FLASH_DEV_NAME.Uninitialize();
if (result != ARM_DRIVER_OK) {
while (1){}
}
-#endif /* TFM_BL1_MEMORY_MAPPED_FLASH */
#if defined(TFM_BL1_LOGGING) || defined(TEST_BL1_1) || defined(TEST_BL1_2)
stdio_uninit();
@@ -224,8 +227,6 @@
/* The KMU requires word alignment */
uint8_t __ALIGNED(4) tmp_buf[32];
- (void)image_id;
-
rc = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t *)&lcs);
if (rc) {
return rc;
diff --git a/platform/ext/target/arm/rss/common/cmsis_drivers/Driver_Flash.c b/platform/ext/target/arm/rss/common/cmsis_drivers/Driver_Flash.c
index b08ccd7..2369c9b 100644
--- a/platform/ext/target/arm/rss/common/cmsis_drivers/Driver_Flash.c
+++ b/platform/ext/target/arm/rss/common/cmsis_drivers/Driver_Flash.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2022 Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -108,7 +108,7 @@
#if (RTE_FLASH0)
static ARM_FLASH_INFO ARM_FLASH0_DEV_DATA = {
.sector_info = NULL, /* Uniform sector layout */
- .sector_count = HOST_FLASH0_SIZE / 0x1000,
+ .sector_count = HOST_ACCESS_SIZE / 0x1000,
.sector_size = 0x1000,
.page_size = 256U,
.program_unit = 1U,
diff --git a/platform/ext/target/arm/rss/common/device/source/host_device_definition.c b/platform/ext/target/arm/rss/common/device/source/host_device_definition.c
index 5f359e3..978d232 100644
--- a/platform/ext/target/arm/rss/common/device/source/host_device_definition.c
+++ b/platform/ext/target/arm/rss/common/device/source/host_device_definition.c
@@ -84,7 +84,10 @@
#if (defined (SPI_STRATAFLASHJ3_S) && defined (CFI_S))
static const struct cfi_dev_cfg_t CFI_DEV_CFG_S = {
- .base = HOST_FLASH0_BASE_S
+ /* Define the flash base/size to be the same as the host access area, as the
+ * flash may not be mapped contiguously or predictably within that area.
+ */
+ .base = HOST_ACCESS_BASE_S,
};
struct cfi_dev_t CFI_DEV_S = {
.cfg = &CFI_DEV_CFG_S,
diff --git a/platform/ext/target/arm/rss/common/fip_parser/fip_parser.c b/platform/ext/target/arm/rss/common/fip_parser/fip_parser.c
new file mode 100644
index 0000000..dd8fbc5
--- /dev/null
+++ b/platform/ext/target/arm/rss/common/fip_parser/fip_parser.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "fip_parser.h"
+
+#include "flash_layout.h"
+#include "Driver_Flash.h"
+
+#include <string.h>
+
+extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
+
+int fip_get_entry_by_uuid(uint32_t fip_base, uint32_t atu_slot_size, uuid_t uuid,
+ uint64_t *offset, size_t *size)
+{
+ ARM_FLASH_CAPABILITIES DriverCapabilities = FLASH_DEV_NAME.GetCapabilities();
+ /* Valid entries for data item width */
+ uint32_t data_width_byte[] = {
+ sizeof(uint8_t),
+ sizeof(uint16_t),
+ sizeof(uint32_t),
+ };
+ size_t data_width = data_width_byte[DriverCapabilities.data_width];
+ int rc;
+ uint32_t idx = 0;
+ fip_toc_header_t toc_header;
+ fip_toc_entry_t toc_entry;
+ uuid_t null_uuid;
+
+ /* The NULL UUID is all-zeroes */
+ memset(&null_uuid, 0, sizeof(null_uuid));
+
+ rc = FLASH_DEV_NAME.ReadData(fip_base - FLASH_BASE_ADDRESS, &toc_header,
+ sizeof(toc_header) / data_width);
+ if (rc != sizeof(toc_header) / data_width) {
+ return rc;
+ }
+
+ if (toc_header.name != TOC_HEADER_NAME) {
+ return 2;
+ }
+
+ idx += sizeof(toc_header);
+
+ do {
+ /* Prevent reading out of bounds */
+ if (idx + sizeof(toc_entry) > atu_slot_size) {
+ return 3;
+ }
+
+ rc = FLASH_DEV_NAME.ReadData(fip_base + idx - FLASH_BASE_ADDRESS,
+ &toc_entry, sizeof(toc_entry) / data_width);
+ if (rc != sizeof(toc_entry) / data_width) {
+ return rc;
+ }
+
+ if (!memcmp(&uuid, &toc_entry.uuid, sizeof(uuid))) {
+ *offset = toc_entry.offset_address;
+
+ /* We can't deal with partitions that are greater than UINT32_MAX,
+ * since they aren't wholly mappable into the RSS memory space. This
+ * is in reality bounded by the ATU mappable size, but that'll be
+ * checked once the ATU region is set up, this just allows us to
+ * perform safe type-conversion.
+ */
+ if (toc_entry.size > UINT32_MAX) {
+ return 1;
+ }
+
+ *size = (uint32_t)toc_entry.size;
+
+ return 0;
+ }
+
+ idx += sizeof(toc_entry);
+ /* The FIP's TOC ends in an entry with a NULL UUID. This entry's size is
+ * the size of the whole FIP. */
+ } while (memcmp(&null_uuid, &toc_entry.uuid, sizeof(uuid_t)));
+
+ /* UUID not found, return error. */
+ return 3;
+}
diff --git a/platform/ext/target/arm/rss/common/fip_parser/fip_parser.h b/platform/ext/target/arm/rss/common/fip_parser/fip_parser.h
new file mode 100644
index 0000000..b613a46
--- /dev/null
+++ b/platform/ext/target/arm/rss/common/fip_parser/fip_parser.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __FIP_PARSER_H__
+#define __FIP_PARSER_H__
+
+#include "firmware_image_package.h"
+#include "stddef.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Parse a FIP and retrieve the offset and size of one
+ * of the firmware images (specified by UUID).
+ *
+ * \param[in] fip_base The RSS address mapped to the FIP base address in
+ * host flash.
+ * \param[in] atu_slot_size The size of the ATU region that was mapped for
+ * access to this FIP. This is used to prevent reads
+ * outside the mapped region.
+ * \param[in] uuid The UUID of the firmware image to get the offset
+ * and size of.
+ *
+ * \param[out] offset The offset in host flash of the firmware image.
+ * \param[out] size The size of the firmware image.
+ *
+ * \return 0 if operation completed successfully, another
+ * value on error.
+ */
+int fip_get_entry_by_uuid(uint32_t fip_base, uint32_t atu_slot_size, uuid_t uuid,
+ uint64_t *offset, size_t *size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __FIP_PARSER_H__ */
diff --git a/platform/ext/target/arm/rss/common/fip_parser/firmware_image_package.h b/platform/ext/target/arm/rss/common/fip_parser/firmware_image_package.h
new file mode 100644
index 0000000..7f0a618
--- /dev/null
+++ b/platform/ext/target/arm/rss/common/fip_parser/firmware_image_package.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FIRMWARE_IMAGE_PACKAGE_H
+#define FIRMWARE_IMAGE_PACKAGE_H
+
+#include <stdint.h>
+
+#include "uuid.h"
+
+/* This is used as a signature to validate the blob header */
+#define TOC_HEADER_NAME 0xAA640001
+
+typedef struct fip_toc_header {
+ uint32_t name;
+ uint32_t serial_number;
+ uint64_t flags;
+} fip_toc_header_t;
+
+typedef struct fip_toc_entry {
+ uuid_t uuid;
+ uint64_t offset_address;
+ uint64_t size;
+ uint64_t flags;
+} fip_toc_entry_t;
+
+#endif /* FIRMWARE_IMAGE_PACKAGE_H */
diff --git a/platform/ext/target/arm/rss/common/fip_parser/gpt.c b/platform/ext/target/arm/rss/common/fip_parser/gpt.c
new file mode 100644
index 0000000..74d157b
--- /dev/null
+++ b/platform/ext/target/arm/rss/common/fip_parser/gpt.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "gpt.h"
+
+#include "flash_layout.h"
+#include "Driver_Flash.h"
+
+#include <string.h>
+
+extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
+
+/* GPT has UTF-16LE strings, but we don't want to support them. FIP partitions
+ * are always labelled using ANSI characters, so this function compares the
+ * digits of the UTF-16LE string to an ANSI string.
+ */
+static int gpt_strncmp(uint16_t *gpt_str, size_t gpt_maxlen, uint8_t *str,
+ size_t str_len)
+{
+ size_t idx;
+
+ if (str_len > gpt_maxlen) {
+ return 1;
+ }
+
+ for (idx = 0; idx < str_len; idx++) {
+ if (str[idx] != gpt_str[idx]) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int gpt_get_header(uint32_t table_base, size_t atu_slot_size,
+ gpt_header_t *header)
+{
+ ARM_FLASH_CAPABILITIES DriverCapabilities = FLASH_DEV_NAME.GetCapabilities();
+ /* Valid entries for data item width */
+ uint32_t data_width_byte[] = {
+ sizeof(uint8_t),
+ sizeof(uint16_t),
+ sizeof(uint32_t),
+ };
+ size_t data_width = data_width_byte[DriverCapabilities.data_width];
+ int rc;
+
+ if (atu_slot_size < sizeof(gpt_header_t)) {
+ return 1;
+ }
+
+ rc = FLASH_DEV_NAME.ReadData(table_base - FLASH_BASE_ADDRESS, header,
+ sizeof(gpt_header_t) / data_width);
+ if (rc != sizeof(gpt_header_t) / data_width) {
+ return rc;
+ }
+
+ if (memcmp(header->signature, "EFI PART", sizeof(header->signature))) {
+ return 1;
+ }
+
+ return 0;
+}
+
+int gpt_get_list_entry_by_name(uint32_t list_base, uint32_t list_num_entries,
+ size_t list_entry_size, uint8_t *name,
+ size_t name_size, size_t atu_slot_size,
+ gpt_entry_t *entry)
+{
+ ARM_FLASH_CAPABILITIES DriverCapabilities = FLASH_DEV_NAME.GetCapabilities();
+ /* Valid entries for data item width */
+ uint32_t data_width_byte[] = {
+ sizeof(uint8_t),
+ sizeof(uint16_t),
+ sizeof(uint32_t),
+ };
+ size_t data_width = data_width_byte[DriverCapabilities.data_width];
+ int rc;
+ uint64_t idx;
+
+ /* List entry is using names larger than EFI_NAMELEN_MAX - this is either an
+ * RSS GPT config error or an out-of-spec GPT partition, either way we fail
+ * here.
+ */
+ if (list_entry_size > sizeof(gpt_entry_t)) {
+ return 1;
+ }
+
+ /* Check for overflow */
+ if (list_base + list_num_entries * list_entry_size < list_base ||
+ list_num_entries * list_entry_size > atu_slot_size) {
+ return 1;
+ }
+
+ for (idx = list_base;
+ idx < list_base + list_num_entries * list_entry_size;
+ idx += list_entry_size) {
+ rc = FLASH_DEV_NAME.ReadData(idx - FLASH_BASE_ADDRESS, entry,
+ sizeof(gpt_entry_t));
+ if (rc != sizeof(gpt_entry_t) / data_width) {
+ return rc;
+ }
+
+ if (gpt_strncmp(entry->name,
+ list_entry_size - offsetof(gpt_entry_t, name),
+ name, name_size)) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
diff --git a/platform/ext/target/arm/rss/common/fip_parser/gpt.h b/platform/ext/target/arm/rss/common/fip_parser/gpt.h
new file mode 100644
index 0000000..b52f3f6
--- /dev/null
+++ b/platform/ext/target/arm/rss/common/fip_parser/gpt.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef GPT_H
+#define GPT_H
+
+#include "stdint.h"
+#include "stddef.h"
+#include "uuid.h"
+
+#define PARTITION_TYPE_GPT 0xee
+#define EFI_NAMELEN_MAX 36
+#define GPT_HEADER_OFFSET PLAT_PARTITION_BLOCK_SIZE
+#define GPT_ENTRY_OFFSET (GPT_HEADER_OFFSET + PLAT_PARTITION_BLOCK_SIZE)
+#define GPT_SIGNATURE "EFI PART"
+#define PRIMARY_FIP_GPT_NAME "FIP_A"
+#define SECONDARY_FIP_GPT_NAME "FIP_B"
+
+typedef struct gpt_entry {
+ struct efi_guid type_uuid;
+ struct efi_guid unique_uuid;
+ uint64_t first_lba;
+ uint64_t last_lba;
+ uint64_t attr;
+ uint16_t name[EFI_NAMELEN_MAX];
+} gpt_entry_t;
+
+typedef struct gpt_header {
+ uint8_t signature[8];
+ uint32_t revision;
+ uint32_t size;
+ uint32_t header_crc;
+ uint32_t reserved;
+ uint64_t current_lba;
+ uint64_t backup_lba;
+ uint64_t first_lba;
+ uint64_t last_lba;
+ struct efi_guid disk_uuid;
+ /* starting LBA of array of partition entries */
+ uint64_t list_lba;
+ /* number of partition entries in array */
+ uint32_t list_num;
+ /* size of a single partition entry (usually 128) */
+ uint32_t list_entry_size;
+ uint32_t list_crc;
+} gpt_header_t;
+
+/**
+ * \brief Read a GPT header from flash into a struct.
+ *
+ * \param[in] table_base The RSS address mapped to the GPT table base in
+ * host flash.
+ * \param[in] atu_slot_size The size of the ATU region that was mapped for
+ * access to this FIP. This is used to prevent reads
+ * outside the mapped region.
+ * \param[out] header Pointer to a gpt_header_t struct that will be
+ * filled with the header data.
+ * \return 0 if operation completed successfully, another
+ * value on error.
+ */
+int gpt_get_header(uint32_t table_base, size_t atu_slot_size,
+ gpt_header_t *header);
+
+/**
+ * \brief Read a GPT list entry from flash into a struct.
+ * Which list entry should be read is determined
+ * by matching the name of the partition.
+ *
+ * \param[in] list_base The RSS address mapped to the GPT entry list base
+ * in host flash.
+ * \param[in] list_num_entries The number of entries in the GPT entry list, as
+ * read from the header.
+ * \param[in] list_entry_size The size of entries in the GPT entry list, as
+ * read from the header.
+ * \param[in] name The name of the partition whose list entry
+ * should be read into the struct. Unlike the GPT
+ * list entry spec, this must be an ascii-encoded
+ * string.
+ * \param[in] name_size The size of the name string.
+ * \param[in] atu_slot_size The size of the ATU region that was mapped for
+ * access to this FIP. This is used to prevent
+ * reads outside the mapped region.
+ * \param[out] entry Pointer to a gpt_entry_t struct that will be
+ * filled with the list entry data.
+ * \return 0 if operation completed successfully, another
+ * value on error.
+ */
+int gpt_get_list_entry_by_name(uint32_t list_base, uint32_t list_num_entries,
+ size_t list_entry_size, uint8_t *name,
+ size_t name_size, size_t atu_slot_size,
+ gpt_entry_t *entry);
+
+#endif /* GPT_H */
diff --git a/platform/ext/target/arm/rss/common/fip_parser/host_flash_atu.c b/platform/ext/target/arm/rss/common/fip_parser/host_flash_atu.c
new file mode 100644
index 0000000..e9098c2
--- /dev/null
+++ b/platform/ext/target/arm/rss/common/fip_parser/host_flash_atu.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "host_flash_atu.h"
+
+#include "flash_layout.h"
+#include "device_definition.h"
+#include "gpt.h"
+#include "fip_parser.h"
+#include "plat_def_fip_uuid.h"
+#include "host_base_address.h"
+#include "platform_base_address.h"
+
+#include <string.h>
+
+#define RSS_ATU_REGION_TEMP_SLOT 2
+#define RSS_ATU_REGION_INPUT_IMAGE_SLOT_0 3
+#define RSS_ATU_REGION_INPUT_IMAGE_SLOT_1 4
+#define RSS_ATU_REGION_OUTPUT_IMAGE_SLOT 5
+
+static inline uint32_t round_down(uint32_t num, uint32_t boundary)
+{
+ return num - (num % boundary);
+}
+
+static inline uint32_t round_up(uint32_t num, uint32_t boundary)
+{
+ return (num + boundary - 1) - ((num + boundary - 1) % boundary);
+}
+
+static int setup_aligned_atu_slot(uint64_t physical_address, uint32_t size,
+ uint32_t boundary, uint32_t atu_slot,
+ uint32_t logical_address,
+ uint32_t *alignment_offset,
+ size_t *atu_slot_size)
+{
+ uint64_t aligned_physical_address;
+ int err;
+
+ aligned_physical_address = round_down(physical_address, boundary);
+ *atu_slot_size = round_up(physical_address + size, boundary)
+ - (physical_address);
+
+ *alignment_offset = physical_address - aligned_physical_address;
+
+ /* Sanity check our parameters, as we do _not_ trust them. We can only map
+ * within the host flash, the parameters must not overflow, and we cannot
+ * map further than the bounds of the logical address slot.
+ */
+ if (aligned_physical_address < HOST_FLASH0_BASE
+ || aligned_physical_address + *atu_slot_size > HOST_FLASH0_BASE + HOST_FLASH0_SIZE
+ || aligned_physical_address + *atu_slot_size < aligned_physical_address
+ || aligned_physical_address + *atu_slot_size < *atu_slot_size
+ || *atu_slot_size > 0x100000 /* Max image slot size */
+ || *alignment_offset > boundary) {
+ return 1;
+ }
+
+ err = atu_initialize_region(&ATU_DEV_S, atu_slot, logical_address,
+ aligned_physical_address, *atu_slot_size);
+ if (err != ATU_ERR_NONE) {
+ return 1;
+ }
+
+ return 0;
+}
+
+int host_flash_atu_setup_image_input_slots_from_fip(uint64_t fip_offset,
+ uint32_t slot,
+ uintptr_t logical_address,
+ uuid_t image_uuid,
+ uint32_t *logical_address_offset)
+{
+ enum atu_error_t err;
+ int rc;
+ uint64_t region_offset;
+ size_t region_size;
+ uint64_t physical_address = HOST_FLASH0_BASE + fip_offset;
+ uint32_t alignment_offset;
+ size_t atu_slot_size;
+ size_t page_size = get_page_size(&ATU_DEV_S);
+
+ /* There's no way to tell how big the FIP TOC will be before reading it, so
+ * we just map 0x1000.
+ */
+ rc = setup_aligned_atu_slot(physical_address, 0x1000, page_size,
+ RSS_ATU_REGION_TEMP_SLOT,
+ HOST_FLASH0_TEMP_BASE_S, &alignment_offset,
+ &atu_slot_size);
+ if (rc) {
+ return rc;
+ }
+
+ rc = fip_get_entry_by_uuid(HOST_FLASH0_TEMP_BASE_S + alignment_offset,
+ atu_slot_size - alignment_offset,
+ image_uuid, ®ion_offset, ®ion_size);
+ if (rc) {
+ return rc;
+ }
+
+ err = atu_uninitialize_region(&ATU_DEV_S, RSS_ATU_REGION_TEMP_SLOT);
+ if (err != ATU_ERR_NONE) {
+ return 1;
+ }
+
+ /* Initialize primary input region */
+ rc = setup_aligned_atu_slot(physical_address + region_offset, region_size,
+ page_size, slot, logical_address,
+ &alignment_offset, &atu_slot_size);
+ if (rc) {
+ return rc;
+ }
+
+ *logical_address_offset = alignment_offset;
+
+ return 0;
+}
+
+int host_flash_atu_get_fip_offsets(bool fip_found[2], uint64_t fip_offsets[2])
+{
+#ifdef RSS_GPT_SUPPORT
+ int rc;
+ enum atu_error_t err;
+ gpt_header_t header;
+ gpt_entry_t entry;
+ size_t page_size = get_page_size(&ATU_DEV_S);
+ uint64_t physical_address;
+ uint32_t alignment_offset;
+ size_t atu_slot_size;
+#endif /* RSS_GPT_SUPPORT */
+
+#ifdef RSS_GPT_SUPPORT
+ physical_address = HOST_FLASH0_BASE + FLASH_AREA_IMAGE_SECTOR_SIZE;
+ rc = setup_aligned_atu_slot(physical_address, FLASH_AREA_IMAGE_SECTOR_SIZE,
+ page_size, RSS_ATU_REGION_TEMP_SLOT,
+ HOST_FLASH0_TEMP_BASE_S, &alignment_offset,
+ &atu_slot_size);
+ if (rc) {
+ return rc;
+ }
+
+ rc = gpt_get_header(HOST_FLASH0_TEMP_BASE_S + alignment_offset,
+ atu_slot_size - alignment_offset, &header);
+ if (rc) {
+ return rc;
+ }
+
+ err = atu_uninitialize_region(&ATU_DEV_S,
+ RSS_ATU_REGION_TEMP_SLOT);
+ if (err != ATU_ERR_NONE) {
+ return 1;
+ }
+
+ physical_address = HOST_FLASH0_BASE
+ + header.list_lba * FLASH_AREA_IMAGE_SECTOR_SIZE;
+ rc = setup_aligned_atu_slot(physical_address,
+ header.list_entry_size * header.list_num, page_size,
+ RSS_ATU_REGION_TEMP_SLOT,
+ HOST_FLASH0_TEMP_BASE_S, &alignment_offset,
+ &atu_slot_size);
+ if (rc) {
+ return rc;
+ }
+
+ rc = gpt_get_list_entry_by_name(HOST_FLASH0_TEMP_BASE_S + alignment_offset,
+ header.list_num, header.list_entry_size,
+ (uint8_t *)PRIMARY_FIP_GPT_NAME,
+ sizeof(PRIMARY_FIP_GPT_NAME),
+ atu_slot_size - alignment_offset, &entry);
+ if (rc == 0) {
+ fip_found[0] = true;
+ fip_offsets[0] = entry.first_lba * FLASH_AREA_IMAGE_SECTOR_SIZE;
+ } else {
+ fip_found[0] = false;
+ }
+
+ rc = gpt_get_list_entry_by_name(HOST_FLASH0_TEMP_BASE_S + alignment_offset,
+ header.list_num, header.list_entry_size,
+ (uint8_t *)SECONDARY_FIP_GPT_NAME,
+ sizeof(SECONDARY_FIP_GPT_NAME),
+ atu_slot_size - alignment_offset, &entry);
+ if (rc == 0) {
+ fip_found[1] = true;
+ fip_offsets[1] = entry.first_lba * FLASH_AREA_IMAGE_SECTOR_SIZE;
+ } else {
+ fip_found[1] = false;
+ }
+
+ err = atu_uninitialize_region(&ATU_DEV_S,
+ RSS_ATU_REGION_TEMP_SLOT);
+ if (err != ATU_ERR_NONE) {
+ return 1;
+ }
+#else
+ fip_found[0] = true;
+ fip_offsets[0] = FLASH_FIP_A_OFFSET;
+ fip_found[1] = true;
+ fip_offsets[1] = FLASH_FIP_B_OFFSET;
+#endif /* RSS_GPT_SUPPORT */
+
+ return 0;
+}
+
+static int setup_image_input_slots(uuid_t image_uuid, uint32_t offsets[2])
+{
+ int rc;
+ bool fip_found[2];
+ uint64_t fip_offsets[2];
+ bool fip_mapped[2] = {false};
+
+ rc = host_flash_atu_get_fip_offsets(fip_found, fip_offsets);
+ if (rc) {
+ return rc;
+ }
+
+ /* MCUBoot requires that we map both regions. If we can only have the offset
+ * of one, then map it to both slots.
+ */
+ if (fip_found[0] && !fip_found[1]) {
+ fip_offsets[1] = fip_offsets[0];
+ } else if (fip_found[1] && !fip_found[0]) {
+ fip_offsets[0] = fip_offsets[1];
+ } else if (!fip_found[0] && !fip_found[1]) {
+ return 1;
+ }
+
+ rc = host_flash_atu_setup_image_input_slots_from_fip(fip_offsets[0],
+ RSS_ATU_REGION_INPUT_IMAGE_SLOT_0,
+ HOST_FLASH0_IMAGE0_BASE_S, image_uuid,
+ &offsets[0]);
+ if (rc == 0) {
+ fip_mapped[0] = true;
+ }
+
+ rc = host_flash_atu_setup_image_input_slots_from_fip(fip_offsets[1],
+ RSS_ATU_REGION_INPUT_IMAGE_SLOT_1,
+ HOST_FLASH0_IMAGE1_BASE_S, image_uuid,
+ &offsets[1]);
+ if (rc == 0) {
+ fip_mapped[1] = true;
+ }
+
+
+ /* If one of the mappings failed (more common without GPT support since in
+ * that case we're just hoping there's a FIP at the offset) then map the
+ * other one into the slot. At this stage if a backup map fails then it's an
+ * error since otherwise MCUBoot will attempt to access unmapped ATU space
+ * and fault.
+ */
+ if (fip_mapped[0] && !fip_mapped[1]) {
+ rc = host_flash_atu_setup_image_input_slots_from_fip(fip_offsets[0],
+ RSS_ATU_REGION_INPUT_IMAGE_SLOT_1,
+ HOST_FLASH0_IMAGE1_BASE_S,
+ image_uuid, &offsets[1]);
+ if (rc) {
+ return rc;
+ }
+ } else if (fip_mapped[1] && !fip_mapped[0]) {
+ rc = host_flash_atu_setup_image_input_slots_from_fip(fip_offsets[1],
+ RSS_ATU_REGION_INPUT_IMAGE_SLOT_0,
+ HOST_FLASH0_IMAGE0_BASE_S,
+ image_uuid, &offsets[0]);
+ if (rc) {
+ return rc;
+ }
+ } else if (!fip_mapped[0] && !fip_mapped[1]) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static int setup_image_output_slots(uuid_t image_uuid)
+{
+ uuid_t case_uuid;
+ enum atu_error_t atu_err;
+
+ case_uuid = UUID_RSS_FIRMWARE_SCP_BL1;
+ if (memcmp(&image_uuid, &case_uuid, sizeof(uuid_t)) == 0) {
+ /* Initialize SCP ATU output region */
+ atu_err = atu_initialize_region(&ATU_DEV_S,
+ RSS_ATU_REGION_OUTPUT_IMAGE_SLOT,
+ HOST_BOOT_IMAGE1_LOAD_BASE_S,
+ SCP_BL1_SRAM_BASE, SCP_BL1_MAX_SIZE);
+ if (atu_err != ATU_ERR_NONE) {
+ return 1;
+ }
+
+ return 0;
+ }
+
+ case_uuid = UUID_RSS_FIRMWARE_AP_BL1;
+ if (memcmp(&image_uuid, &case_uuid, sizeof(uuid_t)) == 0) {
+ /* Initialize AP ATU region */
+ atu_err = atu_initialize_region(&ATU_DEV_S,
+ RSS_ATU_REGION_OUTPUT_IMAGE_SLOT,
+ HOST_BOOT_IMAGE0_LOAD_BASE_S,
+ AP_BL1_SRAM_BASE, AP_BL1_MAX_SIZE);
+ if (atu_err != ATU_ERR_NONE) {
+ return 1;
+ }
+
+ return 0;
+ }
+
+ return 0;
+}
+
+int host_flash_atu_init_regions_for_image(uuid_t image_uuid, uint32_t offsets[2])
+{
+ int rc;
+
+ rc = setup_image_input_slots(image_uuid, offsets);
+ if (rc) {
+ return rc;
+ }
+
+ rc = setup_image_output_slots(image_uuid);
+ if (rc) {
+ return rc;
+ }
+
+ return 0;
+}
+
+int host_flash_atu_uninit_regions(void)
+{
+ enum atu_error_t atu_err;
+
+ atu_err = atu_uninitialize_region(&ATU_DEV_S,
+ RSS_ATU_REGION_INPUT_IMAGE_SLOT_0);
+ if (atu_err != ATU_ERR_NONE) {
+ return 1;
+ }
+
+ atu_err = atu_uninitialize_region(&ATU_DEV_S,
+ RSS_ATU_REGION_INPUT_IMAGE_SLOT_1);
+ if (atu_err != ATU_ERR_NONE) {
+ return 1;
+ }
+
+ atu_err = atu_uninitialize_region(&ATU_DEV_S,
+ RSS_ATU_REGION_OUTPUT_IMAGE_SLOT);
+ if (atu_err != ATU_ERR_NONE) {
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/platform/ext/target/arm/rss/common/fip_parser/host_flash_atu.h b/platform/ext/target/arm/rss/common/fip_parser/host_flash_atu.h
new file mode 100644
index 0000000..62d65fe
--- /dev/null
+++ b/platform/ext/target/arm/rss/common/fip_parser/host_flash_atu.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __HOST_FLASH_ATU_H__
+#define __HOST_FLASH_ATU_H__
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#include "uuid.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Gets the offsets of the FIPs in host flash. If GPT is
+ * supported these are parsed from the GPT partition
+ * list, else the hardcoded values are returned.
+ *
+ * \param[out] fip_found Which fips were found. If fip_found[x] is 0, then the
+ * value of fip_offsets[x] is undefined.
+ * \param[out] fip_offsets The FIP offsets.
+ *
+ * \return 0 on success, non-zero on failure.
+ */
+int host_flash_atu_get_fip_offsets(bool fip_found[2], uint64_t fip_offsets[2]);
+
+/**
+ * \brief Set up the input ATU slots so that an
+ * image can be loaded from host flash.
+ * Parses a FIP via an intermediate ATU slot
+ * to find the image offset.
+ *
+ * \param[in] fip_offset The host flash offset of the FIP that
+ * should be parsed to find the image offset.
+ *
+ * \param[in] slot The ATU slot that should be setup as the
+ * image input slot.
+ *
+ * \param[in] logical_address The address in RSS memory to which the ATU
+ * should map the image.
+ *
+ * \param[in] image_uuid The UUID of the image that should be have
+ * its slot set up. This is used when parsing
+ * the FIP for the offset.
+ *
+ * \param[out] logical_address_offset The offset that the image has been mapped
+ * at (so the base of the image is
+ * logical_address + logical_address_offset).
+ * This is required because images may not be
+ * aligned to the ATU page size.
+ *
+ * \return 0 on success, non-zero on failure.
+ */
+int host_flash_atu_setup_image_input_slots_from_fip(uint64_t fip_offset,
+ uint32_t slot,
+ uintptr_t logical_address,
+ uuid_t image_uuid,
+ uint32_t *logical_address_offset);
+
+/**
+ * \brief Setup the input and output slots for a
+ * given image. returns the offsets from the
+ * expected logical address that the image
+ * has been mapped to (to account for images
+ * not being aligned to the ATU page size).
+ *
+ * \param[in] image_uuid The UUID of the image that should be have
+ * its input and output slots set up.
+ *
+ * \param[out] offsets The offsets that the primary and secondary
+ * images for that particular UUID have been
+ * mapped at (offset from their expected
+ * logical addresses).
+ *
+ * \return 0 on success, non-zero on failure.
+ */
+int host_flash_atu_init_regions_for_image(uuid_t image_uuid, uint32_t offsets[2]);
+
+/**
+ * \brief Teardown all image input and output slots.
+ * Should be called between mapping different
+ * images.
+ *
+ * \return 0 on success, non-zero on failure.
+ */
+int host_flash_atu_uninit_regions(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HOST_FLASH_ATU_H__ */
diff --git a/platform/ext/target/arm/rss/common/fip_parser/uuid.h b/platform/ext/target/arm/rss/common/fip_parser/uuid.h
new file mode 100644
index 0000000..0ff01bb
--- /dev/null
+++ b/platform/ext/target/arm/rss/common/fip_parser/uuid.h
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 2002 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Portions copyright (c) 2014-2020, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef UUID_H
+#define UUID_H
+
+/* Length of a node address (an IEEE 802 address). */
+#define _UUID_NODE_LEN 6
+
+/* Length of UUID string including dashes. */
+#define _UUID_STR_LEN 36
+
+/*
+ * See also:
+ * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
+ * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm
+ *
+ * A DCE 1.1 compatible source representation of UUIDs.
+ */
+struct uuid {
+ uint8_t time_low[4];
+ uint8_t time_mid[2];
+ uint8_t time_hi_and_version[2];
+ uint8_t clock_seq_hi_and_reserved;
+ uint8_t clock_seq_low;
+ uint8_t node[_UUID_NODE_LEN];
+};
+
+struct efi_guid {
+ uint32_t time_low;
+ uint16_t time_mid;
+ uint16_t time_hi_and_version;
+ uint8_t clock_seq_and_node[8];
+};
+
+union uuid_helper_t {
+ struct uuid uuid_struct;
+ struct efi_guid efi_guid;
+};
+
+/* XXX namespace pollution? */
+typedef struct uuid uuid_t;
+
+#endif /* UUID_H */
diff --git a/platform/ext/target/arm/rss/common/partition/platform_base_address.h b/platform/ext/target/arm/rss/common/partition/platform_base_address.h
index 17435d0..98f2997 100644
--- a/platform/ext/target/arm/rss/common/partition/platform_base_address.h
+++ b/platform/ext/target/arm/rss/common/partition/platform_base_address.h
@@ -133,16 +133,20 @@
/* Secure Host region */
#define HOST_ACCESS_BASE_S 0x70000000 /* Can access the Host region based on ATU config */
-#define HOST_ACCESS_LIMIT_S (HOST_ACCESS_BASE_S + HOST_ACCESS_SIZE - 1)
+#define HOST_ACCESS_LIMIT_S ((uint32_t)HOST_ACCESS_BASE_S + (uint32_t)HOST_ACCESS_SIZE - 1)
/* ATU regions open in bootloader and runtime */
#define HOST_UART0_BASE_S (HOST_ACCESS_BASE_S + 0xFF00000) /* UART 0 Secure base address */
/* ATU regions open in BL1 */
-#define HOST_FLASH0_BASE_S (HOST_ACCESS_BASE_S + 0x200000) /* Host flash 0 address */
+#define HOST_FLASH0_TEMP_BASE_S (HOST_ACCESS_BASE_S + 0x200000) /* Temporary address for mapping host flash areas */
+#define HOST_FLASH0_IMAGE0_BASE_S (HOST_ACCESS_BASE_S + 0x300000) /* Host flash image 0 input secure address */
+#define HOST_FLASH0_IMAGE1_BASE_S (HOST_ACCESS_BASE_S + 0x400000) /* Host flash image 1 input secure address */
/* ATU regions open in BL2 */
-#define HOST_BOOT_IMAGE0_LOAD_BASE_S (HOST_ACCESS_BASE_S + 0x000000) /* Host boot image 0 output address */
-#define HOST_BOOT_IMAGE1_LOAD_BASE_S (HOST_ACCESS_BASE_S + 0x100000) /* Host boot image 1 output address */
-#define HOST_FLASH0_BASE_S (HOST_ACCESS_BASE_S + 0x200000) /* Host flash 0 address */
+#define HOST_BOOT_IMAGE0_LOAD_BASE_S (HOST_ACCESS_BASE_S + 0x000000) /* Host boot image 0 output secure address */
+#define HOST_BOOT_IMAGE1_LOAD_BASE_S (HOST_ACCESS_BASE_S + 0x100000) /* Host boot image 1 output secure address */
+#define HOST_FLASH0_TEMP0_BASE_S (HOST_ACCESS_BASE_S + 0x200000) /* Temporary secure address for mapping host flash areas */
+#define HOST_FLASH0_IMAGE0_BASE_S (HOST_ACCESS_BASE_S + 0x300000) /* Host flash image 0 input secure address */
+#define HOST_FLASH0_IMAGE1_BASE_S (HOST_ACCESS_BASE_S + 0x400000) /* Host flash image 1 input secure address */
/* ATU regions open at runtime */
#define FWU_HOST_IMAGE_BASE_S (HOST_ACCESS_BASE_S + 0x000000) /* Region to allow writing new RSS FW images */
#define HOST_COMMS_MAPPABLE_BASE_S (HOST_ACCESS_BASE_S + 0x100000) /* Region into which to map host comms pointers */
diff --git a/platform/ext/target/arm/rss/common/target_cfg.c b/platform/ext/target/arm/rss/common/target_cfg.c
index c053d0c..23943df 100644
--- a/platform/ext/target/arm/rss/common/target_cfg.c
+++ b/platform/ext/target/arm/rss/common/target_cfg.c
@@ -36,6 +36,14 @@
#endif
const struct memory_region_limits memory_regions = {
+#ifdef RSS_XIP
+ .non_secure_code_start = RSS_RUNTIME_NS_XIP_BASE_NS,
+
+ .non_secure_partition_base = RSS_RUNTIME_NS_XIP_BASE_NS,
+
+ .non_secure_partition_limit = RSS_RUNTIME_NS_XIP_BASE_NS +
+ NS_PARTITION_SIZE - 1,
+#else
.non_secure_code_start =
(uint32_t)®ION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
BL2_HEADER_SIZE,
@@ -46,6 +54,7 @@
.non_secure_partition_limit =
(uint32_t)®ION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
NS_PARTITION_SIZE - 1,
+#endif /* RSS_XIP */
#ifndef TFM_MULTI_CORE_TOPOLOGY
.veneer_base = (uint32_t)®ION_NAME(Image$$, ER_VENEER, $$Base),
diff --git a/platform/ext/target/arm/rss/tc/CMakeLists.txt b/platform/ext/target/arm/rss/tc/CMakeLists.txt
index 59d8709..cf709bb 100644
--- a/platform/ext/target/arm/rss/tc/CMakeLists.txt
+++ b/platform/ext/target/arm/rss/tc/CMakeLists.txt
@@ -28,7 +28,6 @@
PRIVATE
bl2/boot_hal_bl2.c
bl2/flash_map_bl2.c
- bl2/host_flash_atu.c
$<$<BOOL:${RSS_XIP}>:${CMAKE_CURRENT_SOURCE_DIR}/bl2/sic_boot.c>
)
diff --git a/platform/ext/target/arm/rss/tc/bl2/boot_hal_bl2.c b/platform/ext/target/arm/rss/tc/bl2/boot_hal_bl2.c
index 3e0a4ec..294c3e2 100644
--- a/platform/ext/target/arm/rss/tc/bl2/boot_hal_bl2.c
+++ b/platform/ext/target/arm/rss/tc/bl2/boot_hal_bl2.c
@@ -28,12 +28,16 @@
#include "Driver_Flash.h"
#include "host_flash_atu.h"
#include "sic_boot.h"
+#include "plat_def_fip_uuid.h"
+#include "flash_map/flash_map.h"
#ifdef FLASH_DEV_NAME
extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
#endif /* FLASH_DEV_NAME */
extern struct boot_rsp rsp;
+extern struct flash_area flash_map[];
+extern const int flash_map_entry_num;
int32_t boot_platform_post_init(void)
{
@@ -86,9 +90,65 @@
return 0;
}
+static struct flash_area *flash_map_slot_from_flash_area_id(uint32_t area_id)
+{
+ uint32_t idx;
+ for (idx = 0; idx < flash_map_entry_num; idx++) {
+ if (area_id == flash_map[idx].fa_id) {
+ return &flash_map[idx];
+ }
+ }
+ return NULL;
+}
+
int boot_platform_pre_load(uint32_t image_id)
{
- return host_flash_atu_pre_load(image_id);
+ uuid_t uuid;
+ uint32_t offsets[2];
+ struct flash_area *flash_area_primary =
+ flash_map_slot_from_flash_area_id(FLASH_AREA_IMAGE_PRIMARY(image_id));
+ struct flash_area *flash_area_secondary =
+ flash_map_slot_from_flash_area_id(FLASH_AREA_IMAGE_SECONDARY(image_id));
+ int rc;
+
+ if (flash_area_primary == NULL || flash_area_secondary == NULL) {
+ return 1;
+ }
+
+ switch(image_id) {
+ case RSS_BL2_IMAGE_SCP:
+ uuid = UUID_RSS_FIRMWARE_SCP_BL1;
+ break;
+ case RSS_BL2_IMAGE_AP:
+ uuid = UUID_RSS_FIRMWARE_AP_BL1;
+ break;
+ case RSS_BL2_IMAGE_NS:
+#ifndef RSS_XIP
+ uuid = UUID_RSS_FIRMWARE_NS;
+#else
+ uuid = UUID_RSS_SIC_TABLES_NS;
+#endif /* RSS_XIP */
+ break;
+ case RSS_BL2_IMAGE_S:
+#ifndef RSS_XIP
+ uuid = UUID_RSS_FIRMWARE_S;
+#else
+ uuid = UUID_RSS_SIC_TABLES_S;
+#endif /* RSS_XIP */
+ break;
+ default:
+ return 1;
+ }
+
+ rc = host_flash_atu_init_regions_for_image(uuid, offsets);
+ if (rc) {
+ return rc;
+ }
+
+ flash_area_primary->fa_off += offsets[0];
+ flash_area_secondary->fa_off += offsets[1];
+
+ return 0;
}
int boot_platform_post_load(uint32_t image_id)
@@ -131,7 +191,7 @@
mhu_v2_x_channel_send(&MHU_RSS_TO_SCP_DEV, 0, 1);
}
- err = host_flash_atu_post_load(image_id);
+ err = host_flash_atu_uninit_regions();
if (err) {
return err;
}
diff --git a/platform/ext/target/arm/rss/tc/bl2/flash_map_bl2.c b/platform/ext/target/arm/rss/tc/bl2/flash_map_bl2.c
index fdd4693..32919d2 100644
--- a/platform/ext/target/arm/rss/tc/bl2/flash_map_bl2.c
+++ b/platform/ext/target/arm/rss/tc/bl2/flash_map_bl2.c
@@ -22,7 +22,7 @@
};
const int flash_driver_entry_num = ARRAY_SIZE(flash_driver);
-const struct flash_area flash_map[] = {
+struct flash_area flash_map[] = {
#ifdef RSS_XIP
{
.fa_id = FLASH_AREA_10_ID,
diff --git a/platform/ext/target/arm/rss/tc/bl2/host_flash_atu.c b/platform/ext/target/arm/rss/tc/bl2/host_flash_atu.c
deleted file mode 100644
index 2d9747c..0000000
--- a/platform/ext/target/arm/rss/tc/bl2/host_flash_atu.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#include "host_flash_atu.h"
-
-#include "bl2_image_id.h"
-#include "flash_layout.h"
-#include "device_definition.h"
-#include "flash_map/flash_map.h"
-
-#define RSS_ATU_REGION_INPUT_IMAGE_SLOT_0 2
-#define RSS_ATU_REGION_INPUT_IMAGE_SLOT_1 3
-#define RSS_ATU_REGION_OUTPUT_IMAGE_SLOT 4
-
-#define HOST_BOOT_AP_LOAD_BASE_S HOST_BOOT_IMAGE0_LOAD_BASE_S
-#define HOST_BOOT_SCP_LOAD_BASE_S HOST_BOOT_IMAGE1_LOAD_BASE_S
-
-extern struct flash_area flash_map[];
-extern int flash_map_entry_num;
-
-static struct flash_area *flash_map_slot_from_flash_area_id(uint32_t area_id)
-{
- uint32_t idx;
-
- for (idx = 0; idx < flash_map_entry_num; idx++) {
- if (area_id == flash_map[idx].fa_id) {
- return &flash_map[idx];
- }
- }
-
- return NULL;
-}
-
-static int setup_image_input_slots(uint32_t image_id)
-{
- enum atu_error_t err;
- struct flash_area *flash_area_primary =
- flash_map_slot_from_flash_area_id(FLASH_AREA_IMAGE_PRIMARY(image_id));
- struct flash_area *flash_area_secondary =
- flash_map_slot_from_flash_area_id(FLASH_AREA_IMAGE_SECONDARY(image_id));
-
- if (flash_area_primary == NULL || flash_area_secondary == NULL) {
- return 1;
- }
-
- /* Initialize primary input region */
- err = atu_initialize_region(&ATU_DEV_S,
- RSS_ATU_REGION_INPUT_IMAGE_SLOT_0,
- HOST_FLASH0_BASE_S + flash_area_primary->fa_off,
- HOST_FLASH0_BASE + flash_area_primary->fa_off,
- flash_area_primary->fa_size);
- if (err != ATU_ERR_NONE) {
- return 1;
- }
-
- /* Initialize secondary input region */
- err = atu_initialize_region(&ATU_DEV_S,
- RSS_ATU_REGION_INPUT_IMAGE_SLOT_1,
- HOST_FLASH0_BASE_S + flash_area_secondary->fa_off,
- HOST_FLASH0_BASE + flash_area_secondary->fa_off,
- flash_area_secondary->fa_size);
- if (err != ATU_ERR_NONE) {
- return 1;
- }
-
- return 0;
-}
-
-int host_flash_atu_pre_load(uint32_t image_id)
-{
- int err;
- enum atu_error_t atu_err;
-
- err = setup_image_input_slots(image_id);
- if (err != 0) {
- return err;
- }
-
- switch (image_id) {
- case RSS_BL2_IMAGE_SCP:
- /* Initialize SCP ATU output region */
- atu_err = atu_initialize_region(&ATU_DEV_S,
- RSS_ATU_REGION_OUTPUT_IMAGE_SLOT,
- HOST_BOOT_SCP_LOAD_BASE_S,
- SCP_BL1_SRAM_BASE, SCP_BL1_MAX_SIZE);
- if (atu_err != ATU_ERR_NONE) {
- return 1;
- }
- break;
- case RSS_BL2_IMAGE_AP:
- /* Initialize AP ATU region */
- atu_err = atu_initialize_region(&ATU_DEV_S,
- RSS_ATU_REGION_OUTPUT_IMAGE_SLOT,
- HOST_BOOT_AP_LOAD_BASE_S,
- AP_BL1_SRAM_BASE, AP_BL1_MAX_SIZE);
- if (atu_err != ATU_ERR_NONE) {
- return 1;
- }
- break;
- case RSS_BL2_IMAGE_NS:
-#ifndef RSS_XIP
- /* Initialize AP ATU region */
- atu_err = atu_initialize_region(&ATU_DEV_S,
- RSS_ATU_REGION_OUTPUT_IMAGE_SLOT,
- HOST_BOOT_AP_LOAD_BASE_S,
- AP_BL1_SRAM_BASE, AP_BL1_MAX_SIZE);
- if (atu_err != ATU_ERR_NONE) {
- return 1;
- }
-#endif /* !RSS_XIP */
- break;
- case RSS_BL2_IMAGE_S:
-#ifndef RSS_XIP
- /* Initialize AP ATU region */
- atu_err = atu_initialize_region(&ATU_DEV_S,
- RSS_ATU_REGION_OUTPUT_IMAGE_SLOT,
- HOST_BOOT_AP_LOAD_BASE_S,
- AP_BL1_SRAM_BASE, AP_BL1_MAX_SIZE);
- if (atu_err != ATU_ERR_NONE) {
- return 1;
- }
-#endif /* !RSS_XIP */
- break;
- default:
- return 1;
- }
-
- return 0;
-}
-
-int host_flash_atu_post_load(uint32_t image_id)
-{
- enum atu_error_t atu_err;
- (void)image_id;
-
- atu_err = atu_uninitialize_region(&ATU_DEV_S,
- RSS_ATU_REGION_INPUT_IMAGE_SLOT_0);
- if (atu_err != ATU_ERR_NONE) {
- return 1;
- }
-
- atu_err = atu_uninitialize_region(&ATU_DEV_S,
- RSS_ATU_REGION_INPUT_IMAGE_SLOT_1);
- if (atu_err != ATU_ERR_NONE) {
- return 1;
- }
-
- atu_err = atu_uninitialize_region(&ATU_DEV_S,
- RSS_ATU_REGION_OUTPUT_IMAGE_SLOT);
- if (atu_err != ATU_ERR_NONE) {
- return 1;
- }
-
- return 0;
-}
diff --git a/platform/ext/target/arm/rss/tc/bl2/host_flash_atu.h b/platform/ext/target/arm/rss/tc/bl2/host_flash_atu.h
deleted file mode 100644
index 102e1b7..0000000
--- a/platform/ext/target/arm/rss/tc/bl2/host_flash_atu.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#ifndef __HOST_FLASH_ATU_H__
-#define __HOST_FLASH_ATU_H__
-
-#include <stdint.h>
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief Performs ATU setup so that the given image can be
- * accessed within the host flash.
- *
- * \param[in] image_id The image id to setup the ATU regions for.
- *
- * \return 0 if The regions have been setup successfully.
- */
-int host_flash_atu_pre_load(uint32_t image_id);
-
-/**
- * \brief Performs ATU teardown to disable the regions setup
- * for the particular image.
- *
- * \param[in] image_id The image id to teardown the ATU regions for.
- *
- * \return 0 if The regions have been disabled successfully.
- */
-int host_flash_atu_post_load(uint32_t image_id);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __HOST_FLASH_ATU_H__ */
diff --git a/platform/ext/target/arm/rss/tc/bl2/sic_boot.c b/platform/ext/target/arm/rss/tc/bl2/sic_boot.c
index 8da41f8..be0d786 100644
--- a/platform/ext/target/arm/rss/tc/bl2/sic_boot.c
+++ b/platform/ext/target/arm/rss/tc/bl2/sic_boot.c
@@ -11,6 +11,10 @@
#include "bl2_image_id.h"
#include "region_defs.h"
#include "tfm_plat_otp.h"
+#include "host_flash_atu.h"
+#include "plat_def_fip_uuid.h"
+
+#include <string.h>
#define RSS_ATU_S_IMAGE_XIP_REGION 0
#define RSS_ATU_NS_IMAGE_XIP_REGION 1
@@ -20,6 +24,9 @@
#define FLASH_SIC_HTR_SIZE 0x800
+uint32_t s_image_offset;
+uint32_t ns_image_offset;
+
struct rss_xip_htr_table {
uint32_t fw_revision;
uint32_t nonce[2];
@@ -51,7 +58,6 @@
{
enum sic_error_t sic_err;
struct rss_xip_htr_table *table;
- enum atu_error_t atu_err;
uint32_t key[8];
enum tfm_plat_err_t plat_err;
size_t sic_page_size;
@@ -59,31 +65,40 @@
uint32_t decrypt_region;
uint32_t xip_region_base_addr;
uint32_t xip_region_size;
+ uint64_t fip_offsets[2];
+ bool fip_found[2];
+ uint64_t fip_offset;
+ uint32_t atu_region;
+ uuid_t image_uuid;
+ uint32_t *image_offset;
+
+ int rc;
sic_page_size = sic_page_size_get(&SIC_DEV_S);
+ rc = host_flash_atu_get_fip_offsets(fip_found, fip_offsets);
+ if (rc) {
+ return rc;
+ }
+
switch (image_id) {
case RSS_BL2_IMAGE_NS:
table = (struct rss_xip_htr_table*)(BL2_XIP_TABLES_START
+ FLASH_SIC_TABLE_SIZE
+ BL2_HEADER_SIZE);
- if (image_load_offset == FLASH_AREA_11_OFFSET) {
- atu_err = atu_initialize_region(&ATU_DEV_S,
- RSS_ATU_NS_IMAGE_XIP_REGION,
- RSS_RUNTIME_NS_XIP_BASE_S,
- HOST_FLASH0_BASE + FLASH_AREA_3_OFFSET,
- FLASH_AREA_3_SIZE);
- if (atu_err != ATU_ERR_NONE) {
+ if (image_load_offset >= FLASH_AREA_11_OFFSET
+ && image_load_offset < FLASH_AREA_11_OFFSET + FLASH_AREA_11_SIZE) {
+ if (fip_found[0]) {
+ fip_offset = fip_offsets[0];
+ } else {
return 1;
}
- } else if (image_load_offset == FLASH_AREA_13_OFFSET) {
- atu_err = atu_initialize_region(&ATU_DEV_S,
- RSS_ATU_NS_IMAGE_XIP_REGION,
- RSS_RUNTIME_NS_XIP_BASE_S,
- HOST_FLASH0_BASE + FLASH_AREA_5_OFFSET,
- FLASH_AREA_5_SIZE);
- if (atu_err != ATU_ERR_NONE) {
+ } else if (image_load_offset >= FLASH_AREA_13_OFFSET
+ && image_load_offset < FLASH_AREA_13_OFFSET + FLASH_AREA_13_SIZE) {
+ if (fip_found[1]) {
+ fip_offset = fip_offsets[1];
+ } else {
return 1;
}
} else {
@@ -91,40 +106,34 @@
}
decrypt_key_otp_id = PLAT_OTP_ID_KEY_NON_SECURE_ENCRYPTION;
+ atu_region = RSS_ATU_NS_IMAGE_XIP_REGION;
decrypt_region = RSS_SIC_NS_IMAGE_DECRYPT_REGION;
xip_region_base_addr = RSS_RUNTIME_NS_XIP_BASE_S;
xip_region_size = NS_CODE_SIZE;
+ image_uuid = UUID_RSS_FIRMWARE_NS;
+ image_offset = &ns_image_offset;
break;
case RSS_BL2_IMAGE_S:
table = (struct rss_xip_htr_table*)(BL2_XIP_TABLES_START + BL2_HEADER_SIZE);
- if (image_load_offset == FLASH_AREA_10_OFFSET) {
- atu_err = atu_initialize_region(&ATU_DEV_S,
- RSS_ATU_S_IMAGE_XIP_REGION,
- RSS_RUNTIME_S_XIP_BASE_S,
- HOST_FLASH0_BASE + FLASH_AREA_2_OFFSET,
- FLASH_AREA_2_SIZE);
- if (atu_err != ATU_ERR_NONE) {
- return 1;
- }
- } else if (image_load_offset == FLASH_AREA_12_OFFSET) {
- atu_err = atu_initialize_region(&ATU_DEV_S,
- RSS_ATU_S_IMAGE_XIP_REGION,
- RSS_RUNTIME_S_XIP_BASE_S,
- HOST_FLASH0_BASE + FLASH_AREA_4_OFFSET,
- FLASH_AREA_4_SIZE);
- if (atu_err != ATU_ERR_NONE) {
- return 1;
- }
+ if (image_load_offset >= FLASH_AREA_10_OFFSET
+ && image_load_offset < FLASH_AREA_10_OFFSET + FLASH_AREA_10_SIZE) {
+ fip_offset = fip_offsets[0];
+ } else if (image_load_offset >= FLASH_AREA_12_OFFSET
+ && image_load_offset < FLASH_AREA_12_OFFSET + FLASH_AREA_12_SIZE) {
+ fip_offset = fip_offsets[1];
} else {
return 1;
}
decrypt_key_otp_id = PLAT_OTP_ID_KEY_SECURE_ENCRYPTION;
+ atu_region = RSS_ATU_S_IMAGE_XIP_REGION;
decrypt_region = RSS_SIC_S_IMAGE_DECRYPT_REGION;
xip_region_base_addr = RSS_RUNTIME_S_XIP_BASE_S;
xip_region_size = S_CODE_SIZE;
+ image_uuid = UUID_RSS_FIRMWARE_S;
+ image_offset = &s_image_offset;
break;
@@ -135,6 +144,25 @@
return 1;
}
+ rc = host_flash_atu_setup_image_input_slots_from_fip(fip_offset,
+ atu_region,
+ xip_region_base_addr,
+ image_uuid,
+ image_offset);
+ if (rc) {
+ return rc;
+ }
+
+ /* RSS XIP images must be aligned to, at minimum, the SIC authentication
+ * page size and the SIC decrypt page size. Alignments that do not match
+ * the ATU page size cause problems in jumping to NS code, and seem to
+ * cause startup failure in some cases, so 8KiB alignment is required.
+ */
+ if (*image_offset % 0x1000 != 0) {
+ return 1;
+ }
+
+
sic_err = sic_auth_table_set(&SIC_DEV_S, (uint32_t*)(table->htr),
table->htr_size, (xip_region_base_addr
- SIC_HOST_BASE_S)
@@ -178,7 +206,7 @@
return 1;
}
- *vt_cpy = (struct boot_arm_vector_table *)RSS_RUNTIME_S_XIP_BASE_S;
+ *vt_cpy = (struct boot_arm_vector_table *)(RSS_RUNTIME_S_XIP_BASE_S + s_image_offset);
return 0;
}
diff --git a/platform/ext/target/arm/rss/tc/flash_layout.h b/platform/ext/target/arm/rss/tc/flash_layout.h
index 644cdf0..df3aec8 100644
--- a/platform/ext/target/arm/rss/tc/flash_layout.h
+++ b/platform/ext/target/arm/rss/tc/flash_layout.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2023, 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.
@@ -18,6 +18,7 @@
#define __FLASH_LAYOUT_H__
#include "host_base_address.h"
+#include "platform_base_address.h"
/* Flash layout on RSS with XIP mode disabled:
*
@@ -49,7 +50,6 @@
* with comment.
*/
-
/* Size of a Secure and of a Non-secure image */
#define FLASH_BL2_PARTITION_SIZE (0x10000) /* BL2 partition: 128 KiB */
#define FLASH_S_PARTITION_SIZE (0x60000) /* S partition: 384 KiB */
@@ -69,11 +69,14 @@
#endif /* RSS_XIP */
/* Sector size of the flash hardware; same as FLASH0_SECTOR_SIZE */
-#define FLASH_AREA_IMAGE_SECTOR_SIZE (0x1000) /* 4 KB */
+#define FLASH_AREA_IMAGE_SECTOR_SIZE (0x200) /* 1 KiB */
/* Same as FLASH0_SIZE */
#define FLASH_TOTAL_SIZE (0xFC00000) /* 252 MiB */
-#define FLASH_BASE_ADDRESS (HOST_FLASH0_BASE_S)
+/* Flash offsets are offsets in the host ATU mapping space, to allow host flash
+ * to be mapped at any point in the mapping space.
+ */
+#define FLASH_BASE_ADDRESS (HOST_ACCESS_BASE_S)
/* Offset and size definitions of the flash partitions that are handled by the
* bootloader. The image swapping is done between IMAGE_PRIMARY and
@@ -81,78 +84,77 @@
* swapping.
*/
+#ifndef RSS_GPT_SUPPORT
+#define FLASH_FIP_A_OFFSET 0x0
+#define FLASH_FIP_B_OFFSET (FLASH_FIP_A_OFFSET + 0x800000)
+#endif /* !RSS_GPT_SUPPORT */
+
/* BL2 primary slot */
#define FLASH_AREA_0_ID (1)
-#define FLASH_AREA_0_OFFSET (0)
+#define FLASH_AREA_0_OFFSET (HOST_FLASH0_IMAGE0_BASE_S - HOST_ACCESS_BASE_S)
#define FLASH_AREA_0_SIZE (FLASH_BL2_PARTITION_SIZE)
/* BL2 secondary slot */
#define FLASH_AREA_1_ID (FLASH_AREA_0_ID + 1)
-#define FLASH_AREA_1_OFFSET (FLASH_AREA_0_OFFSET + FLASH_AREA_0_SIZE)
+#define FLASH_AREA_1_OFFSET (HOST_FLASH0_IMAGE1_BASE_S - HOST_ACCESS_BASE_S)
#define FLASH_AREA_1_SIZE (FLASH_BL2_PARTITION_SIZE)
/* Secure image primary slot. */
#define FLASH_AREA_2_ID (FLASH_AREA_1_ID + 1)
-#define FLASH_AREA_2_OFFSET (FLASH_AREA_1_OFFSET + FLASH_AREA_1_SIZE)
+#define FLASH_AREA_2_OFFSET (HOST_FLASH0_IMAGE0_BASE_S - HOST_ACCESS_BASE_S)
#define FLASH_AREA_2_SIZE (FLASH_S_PARTITION_SIZE)
/* Non-secure image primary slot. */
#define FLASH_AREA_3_ID (FLASH_AREA_2_ID + 1)
-#define FLASH_AREA_3_OFFSET (FLASH_AREA_2_OFFSET + FLASH_AREA_2_SIZE)
+#define FLASH_AREA_3_OFFSET (HOST_FLASH0_IMAGE1_BASE_S - HOST_ACCESS_BASE_S)
#define FLASH_AREA_3_SIZE (FLASH_NS_PARTITION_SIZE)
/* Secure image secondary slot. */
#define FLASH_AREA_4_ID (FLASH_AREA_3_ID + 1)
-#define FLASH_AREA_4_OFFSET (FLASH_AREA_3_OFFSET + FLASH_AREA_3_SIZE)
+#define FLASH_AREA_4_OFFSET (HOST_FLASH0_IMAGE0_BASE_S - HOST_ACCESS_BASE_S)
#define FLASH_AREA_4_SIZE (FLASH_S_PARTITION_SIZE)
/* Non-secure image secondary slot. */
#define FLASH_AREA_5_ID (FLASH_AREA_4_ID + 1)
-#define FLASH_AREA_5_OFFSET (FLASH_AREA_4_OFFSET + FLASH_AREA_4_SIZE)
+#define FLASH_AREA_5_OFFSET (HOST_FLASH0_IMAGE1_BASE_S - HOST_ACCESS_BASE_S)
#define FLASH_AREA_5_SIZE (FLASH_NS_PARTITION_SIZE)
/* AP image primary slot */
#define FLASH_AREA_6_ID (FLASH_AREA_5_ID + 1)
-#define FLASH_AREA_6_OFFSET (FLASH_AREA_5_OFFSET + FLASH_AREA_5_SIZE)
+#define FLASH_AREA_6_OFFSET (HOST_FLASH0_IMAGE0_BASE_S - HOST_ACCESS_BASE_S)
#define FLASH_AREA_6_SIZE (FLASH_AP_PARTITION_SIZE)
/* SCP image primary slot */
#define FLASH_AREA_7_ID (FLASH_AREA_6_ID + 1)
-#define FLASH_AREA_7_OFFSET (FLASH_AREA_6_OFFSET + FLASH_AREA_6_SIZE)
+#define FLASH_AREA_7_OFFSET (HOST_FLASH0_IMAGE1_BASE_S - HOST_ACCESS_BASE_S)
#define FLASH_AREA_7_SIZE (FLASH_SCP_PARTITION_SIZE)
/* AP image secondary slot */
#define FLASH_AREA_8_ID (FLASH_AREA_7_ID + 1)
-#define FLASH_AREA_8_OFFSET (FLASH_AREA_7_OFFSET + FLASH_AREA_7_SIZE)
+#define FLASH_AREA_8_OFFSET (HOST_FLASH0_IMAGE0_BASE_S - HOST_ACCESS_BASE_S)
#define FLASH_AREA_8_SIZE (FLASH_AP_PARTITION_SIZE)
/* SCP image secondary slot */
#define FLASH_AREA_9_ID (FLASH_AREA_8_ID + 1)
-#define FLASH_AREA_9_OFFSET (FLASH_AREA_8_OFFSET + FLASH_AREA_8_SIZE)
+#define FLASH_AREA_9_OFFSET (HOST_FLASH0_IMAGE1_BASE_S - HOST_ACCESS_BASE_S)
#define FLASH_AREA_9_SIZE (FLASH_SCP_PARTITION_SIZE)
#ifdef RSS_XIP
/* Secure image SIC tables primary slot */
#define FLASH_AREA_10_ID (FLASH_AREA_9_ID + 1)
-#define FLASH_AREA_10_OFFSET (FLASH_AREA_9_OFFSET + FLASH_AREA_9_SIZE)
+#define FLASH_AREA_10_OFFSET (HOST_FLASH0_IMAGE0_BASE_S - HOST_ACCESS_BASE_S)
#define FLASH_AREA_10_SIZE (FLASH_SIC_TABLE_SIZE)
/* Non-secure image SIC tables primary slot */
#define FLASH_AREA_11_ID (FLASH_AREA_10_ID + 1)
-#define FLASH_AREA_11_OFFSET (FLASH_AREA_10_OFFSET + FLASH_AREA_10_SIZE)
+#define FLASH_AREA_11_OFFSET (HOST_FLASH0_IMAGE0_BASE_S - HOST_ACCESS_BASE_S)
#define FLASH_AREA_11_SIZE (FLASH_SIC_TABLE_SIZE)
/* Secure image SIC tables secondary slot */
#define FLASH_AREA_12_ID (FLASH_AREA_11_ID + 1)
-#define FLASH_AREA_12_OFFSET (FLASH_AREA_11_OFFSET + FLASH_AREA_11_SIZE)
+#define FLASH_AREA_12_OFFSET (HOST_FLASH0_IMAGE1_BASE_S - HOST_ACCESS_BASE_S)
#define FLASH_AREA_12_SIZE (FLASH_SIC_TABLE_SIZE)
/* Non-secure image SIC tables secondary slot */
#define FLASH_AREA_13_ID (FLASH_AREA_12_ID + 1)
-#define FLASH_AREA_13_OFFSET (FLASH_AREA_12_OFFSET + FLASH_AREA_12_SIZE)
+#define FLASH_AREA_13_OFFSET (HOST_FLASH0_IMAGE1_BASE_S - HOST_ACCESS_BASE_S)
#define FLASH_AREA_13_SIZE (FLASH_SIC_TABLE_SIZE)
#endif /* RSS_XIP */
-
/* Maximum number of image sectors supported by the bootloader. */
#define MCUBOOT_MAX_IMG_SECTORS (FLASH_MAX_PARTITION_SIZE / \
FLASH_AREA_IMAGE_SECTOR_SIZE)
-/* Check that all the images can fit in the Flash area. */
-#if (FLASH_AREA_9_OFFSET + FLASH_AREA_9_SIZE > FLASH_TOTAL_SIZE)
-#error "Out of Flash memory!"
-#endif
-
#ifdef RSS_XIP
#define FLASH_AREA_IMAGE_PRIMARY(x) (((x) == 0) ? FLASH_AREA_10_ID : \
((x) == 1) ? FLASH_AREA_11_ID : \
@@ -210,10 +212,8 @@
/* Flash device name used by BL2
* Name is defined in flash driver file: Driver_Flash.c
*/
-#ifndef TFM_BL1_MEMORY_MAPPED_FLASH
#define FLASH_DEV_NAME Driver_FLASH0
/* Smallest flash programmable unit in bytes */
#define TFM_HAL_FLASH_PROGRAM_UNIT (0x1)
-#endif /* !TFM_BL1_MEMORY_MAPPED_FLASH */
#endif /* __FLASH_LAYOUT_H__ */
diff --git a/platform/ext/target/arm/rss/tc/host_base_address.h b/platform/ext/target/arm/rss/tc/host_base_address.h
index 6243560..48c886b 100644
--- a/platform/ext/target/arm/rss/tc/host_base_address.h
+++ b/platform/ext/target/arm/rss/tc/host_base_address.h
@@ -32,15 +32,7 @@
#define HOST_UART_BASE 0x2A400000UL /* Host UART base address */
#define HOST_UART_SIZE 0x2000U /* 8KB */
-/* In future HOST_FLASH0_BASE should be set to the _actual_ base of the flash,
- * and we should implement some logic to locate the images (in a FIP, probably).
- * For now, define the base address at an offset large enough that it's not used
- * by the AP firmware images.
- */
-/* #define HOST_FLASH_BASE 0x08000000UL /1* Host flash base address *1/ */
-/* FIP size = 34 MB */
-/* Total boot flash size = 64 MB */
-#define HOST_FLASH0_BASE 0x0A200000UL /* Host flash base address */
-#define HOST_FLASH0_SIZE 0x1E00000 /* 30 MiB */
+#define HOST_FLASH0_BASE 0x08000000UL /* Host flash base address */
+#define HOST_FLASH0_SIZE 0x4000000 /* 64 MiB */
#endif /* __HOST_BASE_ADDRESS_H__ */
diff --git a/platform/ext/target/arm/rss/tc/plat_def_fip_uuid.h b/platform/ext/target/arm/rss/tc/plat_def_fip_uuid.h
new file mode 100644
index 0000000..b65feaa
--- /dev/null
+++ b/platform/ext/target/arm/rss/tc/plat_def_fip_uuid.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __PLAT_DEF_FIP_UUID__
+#define __PLAT_DEF_FIP_UUID__
+
+#include "uuid.h"
+
+#define UUID_RSS_FIRMWARE_BL1_2 \
+ ((uuid_t){{0x0a, 0xa5, 0xb1, 0xbe}, {0xe7, 0x84}, {0x41, 0xc5}, 0x81, 0xb8, {0x4a, 0x41, 0xcb, 0x4a, 0xd2, 0xdf}})
+#define UUID_RSS_FIRMWARE_BL2 \
+ ((uuid_t){{0xa3, 0xb3, 0xb3, 0x0d}, {0xeb, 0xc9}, {0x40, 0x48}, 0xb4, 0x80, {0x15, 0x53, 0x61, 0xc1, 0x70, 0x48}})
+#define UUID_RSS_FIRMWARE_SCP_BL1 \
+ ((uuid_t){{0xbf, 0xd5, 0x09, 0x8d}, {0xa7, 0x07}, {0x4f, 0x15}, 0x89, 0x1c, {0x37, 0x22, 0x10, 0xcb, 0x51, 0xe2}})
+#define UUID_RSS_FIRMWARE_AP_BL1 \
+ ((uuid_t){{0x12, 0x4c, 0x50, 0xe0}, {0xf2, 0xda}, {0x45, 0xe9}, 0x85, 0xc8, {0xda, 0xd9, 0x60, 0x9b, 0x7a, 0x11}})
+#define UUID_RSS_FIRMWARE_NS \
+ ((uuid_t){{0x8d, 0x95, 0x9f, 0x72}, {0xb8, 0xb1}, {0x42, 0x11}, 0x9a, 0xe6, {0x4b, 0x80, 0x97, 0x47, 0x5a, 0xd9}})
+#define UUID_RSS_FIRMWARE_S \
+ ((uuid_t){{0x22, 0xea, 0x33, 0x85}, {0xf8, 0x6e}, {0x47, 0x93}, 0x96, 0x8a, {0x2f, 0xe3, 0xdd, 0x50, 0x33, 0xcc}})
+#define UUID_RSS_SIC_TABLES_NS \
+ ((uuid_t){{0xd9, 0x10, 0x00, 0x72}, {0x6a, 0x28}, {0x4b, 0xec}, 0xb0, 0xd6, {0x8c, 0xed, 0xc4, 0x15, 0x7c, 0xe0}})
+#define UUID_RSS_SIC_TABLES_S \
+ ((uuid_t){{0xc7, 0x38, 0xd0, 0xde}, {0x8c, 0x26}, {0x48, 0x51}, 0x93, 0x36, {0xf3, 0xdb, 0xe2, 0x96, 0x65, 0x18}})
+
+#endif /* __PLAT_DEF_FIP_UUID__ */