summaryrefslogtreecommitdiffstats
path: root/plat/arm/board/tc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 17:43:51 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 17:43:51 +0000
commitbe58c81aff4cd4c0ccf43dbd7998da4a6a08c03b (patch)
tree779c248fb61c83f65d1f0dc867f2053d76b4e03a /plat/arm/board/tc
parentInitial commit. (diff)
downloadarm-trusted-firmware-be58c81aff4cd4c0ccf43dbd7998da4a6a08c03b.tar.xz
arm-trusted-firmware-be58c81aff4cd4c0ccf43dbd7998da4a6a08c03b.zip
Adding upstream version 2.10.0+dfsg.upstream/2.10.0+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'plat/arm/board/tc')
-rw-r--r--plat/arm/board/tc/fdts/tc_fw_config.dts33
-rw-r--r--plat/arm/board/tc/fdts/tc_spmc_manifest.dts132
-rw-r--r--plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts129
-rw-r--r--plat/arm/board/tc/fdts/tc_tb_fw_config.dts76
-rw-r--r--plat/arm/board/tc/include/plat_macros.S24
-rw-r--r--plat/arm/board/tc/include/platform_def.h325
-rw-r--r--plat/arm/board/tc/include/tc_helpers.S61
-rw-r--r--plat/arm/board/tc/include/tc_plat.h33
-rw-r--r--plat/arm/board/tc/nv_counter_test.c60
-rw-r--r--plat/arm/board/tc/plat_def_fip_uuid.h37
-rw-r--r--plat/arm/board/tc/plat_tc_mbedtls_config.h33
-rw-r--r--plat/arm/board/tc/platform.mk206
-rw-r--r--plat/arm/board/tc/platform_test.mk112
-rw-r--r--plat/arm/board/tc/region_defs.h12
-rw-r--r--plat/arm/board/tc/rotpk_test.c55
-rw-r--r--plat/arm/board/tc/rss_ap_test_stubs.c121
-rw-r--r--plat/arm/board/tc/rss_ap_tests.c103
-rw-r--r--plat/arm/board/tc/rss_ap_testsuites.c25
-rw-r--r--plat/arm/board/tc/rss_ap_testsuites.h16
-rw-r--r--plat/arm/board/tc/tc_bl1_measured_boot.c59
-rw-r--r--plat/arm/board/tc/tc_bl2_measured_boot.c58
-rw-r--r--plat/arm/board/tc/tc_bl2_setup.c47
-rw-r--r--plat/arm/board/tc/tc_bl31_setup.c133
-rw-r--r--plat/arm/board/tc/tc_common_measured_boot.c36
-rw-r--r--plat/arm/board/tc/tc_err.c17
-rw-r--r--plat/arm/board/tc/tc_interconnect.c35
-rw-r--r--plat/arm/board/tc/tc_plat.c161
-rw-r--r--plat/arm/board/tc/tc_security.c23
-rw-r--r--plat/arm/board/tc/tc_topology.c58
-rw-r--r--plat/arm/board/tc/tc_trusted_boot.c26
30 files changed, 2246 insertions, 0 deletions
diff --git a/plat/arm/board/tc/fdts/tc_fw_config.dts b/plat/arm/board/tc/fdts/tc_fw_config.dts
new file mode 100644
index 0000000..a84c7f8
--- /dev/null
+++ b/plat/arm/board/tc/fdts/tc_fw_config.dts
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "fconf,dyn_cfg-dtb_registry";
+
+ tb_fw-config {
+ load-address = <0x0 0x4001300>;
+ max-size = <0x400>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ tos_fw-config {
+ load-address = <0x0 0x04001700>;
+ max-size = <0x1000>;
+ id = <TOS_FW_CONFIG_ID>;
+ };
+
+ hw-config {
+ load-address = <0x0 0x83000000>;
+ max-size = <0x8000>;
+ id = <HW_CONFIG_ID>;
+ };
+ };
+};
diff --git a/plat/arm/board/tc/fdts/tc_spmc_manifest.dts b/plat/arm/board/tc/fdts/tc_spmc_manifest.dts
new file mode 100644
index 0000000..b64e076
--- /dev/null
+++ b/plat/arm/board/tc/fdts/tc_spmc_manifest.dts
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/dts-v1/;
+
+/ {
+ compatible = "arm,ffa-core-manifest-1.0";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ attribute {
+ spmc_id = <0x8000>;
+ maj_ver = <0x1>;
+ min_ver = <0x1>;
+ exec_state = <0x0>;
+ load_address = <0x0 0xfd000000>;
+ entrypoint = <0x0 0xfd000000>;
+ binary_size = <0x80000>;
+ };
+
+ hypervisor {
+ compatible = "hafnium,hafnium";
+ vm1 {
+ is_ffa_partition;
+ debug_name = "cactus-primary";
+ load_address = <0xfe000000>;
+ vcpu_count = <8>;
+ mem_size = <1048576>;
+ };
+ vm2 {
+ is_ffa_partition;
+ debug_name = "cactus-secondary";
+ load_address = <0xfe100000>;
+ vcpu_count = <8>;
+ mem_size = <1048576>;
+ };
+ vm3 {
+ is_ffa_partition;
+ debug_name = "cactus-tertiary";
+ load_address = <0xfe200000>;
+ vcpu_count = <1>;
+ mem_size = <1048576>;
+ };
+ vm4 {
+ is_ffa_partition;
+ debug_name = "ivy";
+ load_address = <0xfe600000>;
+ vcpu_count = <1>;
+ mem_size = <1048576>;
+ };
+ };
+
+ cpus {
+ #address-cells = <0x2>;
+ #size-cells = <0x0>;
+
+ CPU0:cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ };
+
+ /*
+ * SPMC (Hafnium) requires secondary cpu nodes are declared in
+ * descending order
+ */
+ CPU7:cpu@700 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x700>;
+ enable-method = "psci";
+ };
+
+ CPU6:cpu@600 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x600>;
+ enable-method = "psci";
+ };
+
+ CPU5:cpu@500 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x500>;
+ enable-method = "psci";
+ };
+
+ CPU4:cpu@400 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x400>;
+ enable-method = "psci";
+ };
+
+ CPU3:cpu@300 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x300>;
+ enable-method = "psci";
+ };
+
+ CPU2:cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x200>;
+ enable-method = "psci";
+ };
+
+ CPU1:cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x100>;
+ enable-method = "psci";
+ };
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0xfd000000 0x0 0x2000000>,
+ <0x0 0x7000000 0x0 0x1000000>,
+ <0x0 0xff000000 0x0 0x1000000>;
+ };
+
+ memory@1 {
+ device_type = "ns-memory";
+ reg = <0x00008800 0x80000000 0x0 0x7f000000>,
+ <0x0 0x88000000 0x1 0x00000000>;
+ };
+};
diff --git a/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts b/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts
new file mode 100644
index 0000000..382f0e1
--- /dev/null
+++ b/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/dts-v1/;
+
+/ {
+ compatible = "arm,ffa-core-manifest-1.0";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ attribute {
+ spmc_id = <0x8000>;
+ maj_ver = <0x1>;
+ min_ver = <0x1>;
+ exec_state = <0x0>;
+ load_address = <0x0 0xfd000000>;
+ entrypoint = <0x0 0xfd000000>;
+ binary_size = <0x80000>;
+ };
+
+ hypervisor {
+ compatible = "hafnium,hafnium";
+ vm1 {
+ is_ffa_partition;
+ debug_name = "op-tee";
+ load_address = <0xfd280000>;
+ vcpu_count = <8>;
+#ifdef TS_SP_FW_CONFIG
+ mem_size = <26738688>; /* 25MB TZC DRAM */
+#else
+ mem_size = <30928896>; /* 29MB TZC DRAM */
+#endif
+ };
+#ifdef TS_SP_FW_CONFIG
+ vm2 {
+ is_ffa_partition;
+ debug_name = "internal-trusted-storage";
+ load_address = <0xfee00000>;
+ vcpu_count = <1>;
+ mem_size = <2097152>; /* 2MB TZC DRAM */
+ };
+ vm3 {
+ is_ffa_partition;
+ debug_name = "crypto";
+ load_address = <0xfec00000>;
+ vcpu_count = <1>;
+ mem_size = <2097152>; /* 2MB TZC DRAM */
+ };
+#endif
+ };
+
+ cpus {
+ #address-cells = <0x2>;
+ #size-cells = <0x0>;
+
+ CPU0:cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ };
+
+ /*
+ * SPMC (Hafnium) requires secondary cpu nodes are declared in
+ * descending order
+ */
+ CPU7:cpu@700 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x700>;
+ enable-method = "psci";
+ };
+
+ CPU6:cpu@600 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x600>;
+ enable-method = "psci";
+ };
+
+ CPU5:cpu@500 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x500>;
+ enable-method = "psci";
+ };
+
+ CPU4:cpu@400 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x400>;
+ enable-method = "psci";
+ };
+
+ CPU3:cpu@300 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x300>;
+ enable-method = "psci";
+ };
+
+ CPU2:cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x200>;
+ enable-method = "psci";
+ };
+
+ CPU1:cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x100>;
+ enable-method = "psci";
+ };
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0xfd000000 0x0 0x2000000>;
+ };
+
+ memory@1 {
+ device_type = "ns-memory";
+ reg = <0x0 0x80000000 0x0 0x79000000>,
+ <0x80 0x80000000 0x1 0x80000000>;
+ };
+};
diff --git a/plat/arm/board/tc/fdts/tc_tb_fw_config.dts b/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
new file mode 100644
index 0000000..4c6ccef
--- /dev/null
+++ b/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/libc/cdefs.h>
+
+/dts-v1/;
+
+/ {
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+ /*
+ * The following two entries are placeholders for Mbed TLS
+ * heap information. The default values don't matter since
+ * they will be overwritten by BL1.
+ * In case of having shared Mbed TLS heap between BL1 and BL2,
+ * BL1 will populate these two properties with the respective
+ * info about the shared heap. This info will be available for
+ * BL2 in order to locate and re-use the heap.
+ */
+ mbedtls_heap_addr = <0x0 0x0>;
+ mbedtls_heap_size = <0x0>;
+ };
+
+ secure-partitions {
+ compatible = "arm,sp";
+#ifdef ARM_BL2_SP_LIST_DTS
+ #include __XSTRING(ARM_BL2_SP_LIST_DTS)
+#else
+#ifdef TS_SP_FW_CONFIG
+ internal-trusted-storage {
+ uuid = "dc1eef48-b17a-4ccf-ac8b-dfcff7711b14";
+ load-address = <0xfee00000>;
+ };
+ crypto {
+ uuid = "d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0";
+ load-address = <0xfec00000>;
+ };
+#endif
+#if OPTEE_SP_FW_CONFIG
+ op-tee {
+ uuid = "486178e0-e7f8-11e3-bc5e-0002a5d5c51b";
+ load-address = <0xfd280000>;
+ };
+#else
+ cactus-primary {
+ uuid = "b4b5671e-4a90-4fe1-b81f-fb13dae1dacb";
+ load-address = <0xfe000000>;
+ owner = "SiP";
+ };
+
+ cactus-secondary {
+ uuid = "d1582309-f023-47b9-827c-4464f5578fc8";
+ load-address = <0xfe100000>;
+ owner = "Plat";
+ };
+
+ cactus-tertiary {
+ uuid = "79b55c73-1d8c-44b9-8593-61e1770ad8d2";
+ load-address = <0xfe200000>;
+ };
+
+ ivy {
+ uuid = "eaba83d8-baaf-4eaf-8144-f7fdcbe544a7";
+ load-address = <0xfe600000>;
+ owner = "Plat";
+ };
+#endif
+#endif /* ARM_BL2_SP_LIST_DTS */
+ };
+};
diff --git a/plat/arm/board/tc/include/plat_macros.S b/plat/arm/board/tc/include/plat_macros.S
new file mode 100644
index 0000000..6006fa5
--- /dev/null
+++ b/plat/arm/board/tc/include/plat_macros.S
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#include <arm_macros.S>
+
+/* ---------------------------------------------
+ * The below required platform porting macro
+ * prints out relevant platform registers
+ * whenever an unhandled exception is taken in
+ * BL31.
+ *
+ * There are currently no platform specific regs
+ * to print.
+ * ---------------------------------------------
+ */
+ .macro plat_crash_print_regs
+ .endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
new file mode 100644
index 0000000..59fff6e
--- /dev/null
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+#include <plat/arm/board/common/board_css_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/common/arm_spm_def.h>
+#include <plat/arm/css/common/css_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
+#include <plat/common/common_def.h>
+
+#define PLATFORM_CORE_COUNT 8
+
+#define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00080000 /* 512 KB */
+
+/*
+ * The top 16MB of ARM_DRAM1 is configured as secure access only using the TZC,
+ * its base is ARM_AP_TZC_DRAM1_BASE.
+ *
+ * Reserve 96 MB below ARM_AP_TZC_DRAM1_BASE for:
+ * - BL32_BASE when SPD_spmd is enabled
+ * - Region to load secure partitions
+ *
+ *
+ * 0xF900_0000 ------------------ TC_TZC_DRAM1_BASE
+ * | |
+ * | SPMC |
+ * | SP |
+ * | (96MB) |
+ * 0xFF00_0000 ------------------ ARM_AP_TZC_DRAM1_BASE
+ * | AP |
+ * | EL3 Monitor |
+ * | SCP |
+ * | (16MB) |
+ * 0xFFFF_FFFF ------------------
+ *
+ *
+ */
+#define TC_TZC_DRAM1_BASE (ARM_AP_TZC_DRAM1_BASE - \
+ TC_TZC_DRAM1_SIZE)
+#define TC_TZC_DRAM1_SIZE 96 * SZ_1M /* 96 MB */
+#define TC_TZC_DRAM1_END (TC_TZC_DRAM1_BASE + \
+ TC_TZC_DRAM1_SIZE - 1)
+
+#define TC_NS_DRAM1_BASE ARM_DRAM1_BASE
+#define TC_NS_DRAM1_SIZE (ARM_DRAM1_SIZE - \
+ ARM_TZC_DRAM1_SIZE - \
+ TC_TZC_DRAM1_SIZE)
+#define TC_NS_DRAM1_END (TC_NS_DRAM1_BASE + \
+ TC_NS_DRAM1_SIZE - 1)
+
+/*
+ * Mappings for TC DRAM1 (non-secure) and TC TZC DRAM1 (secure)
+ */
+#define TC_MAP_NS_DRAM1 MAP_REGION_FLAT( \
+ TC_NS_DRAM1_BASE, \
+ TC_NS_DRAM1_SIZE, \
+ MT_MEMORY | MT_RW | MT_NS)
+
+
+#define TC_MAP_TZC_DRAM1 MAP_REGION_FLAT( \
+ TC_TZC_DRAM1_BASE, \
+ TC_TZC_DRAM1_SIZE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
+#define PLAT_HW_CONFIG_DTB_BASE ULL(0x83000000)
+#define PLAT_HW_CONFIG_DTB_SIZE ULL(0x8000)
+
+#define PLAT_DTB_DRAM_NS MAP_REGION_FLAT( \
+ PLAT_HW_CONFIG_DTB_BASE, \
+ PLAT_HW_CONFIG_DTB_SIZE, \
+ MT_MEMORY | MT_RO | MT_NS)
+/*
+ * Max size of SPMC is 2MB for tc. With SPMD enabled this value corresponds to
+ * max size of BL32 image.
+ */
+#if defined(SPD_spmd)
+#define TC_EL2SPMC_LOAD_ADDR (TC_TZC_DRAM1_BASE + 0x04000000)
+
+#define PLAT_ARM_SPMC_BASE TC_EL2SPMC_LOAD_ADDR
+#define PLAT_ARM_SPMC_SIZE UL(0x200000) /* 2 MB */
+#endif
+
+/*
+ * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
+ * plat_arm_mmap array defined for each BL stage.
+ */
+#if defined(IMAGE_BL31)
+# if SPM_MM
+# define PLAT_ARM_MMAP_ENTRIES 9
+# define MAX_XLAT_TABLES 7
+# define PLAT_SP_IMAGE_MMAP_REGIONS 7
+# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
+# else
+# define PLAT_ARM_MMAP_ENTRIES 8
+# define MAX_XLAT_TABLES 8
+# endif
+#elif defined(IMAGE_BL32)
+# define PLAT_ARM_MMAP_ENTRIES 8
+# define MAX_XLAT_TABLES 5
+#elif !USE_ROMLIB
+# define PLAT_ARM_MMAP_ENTRIES 11
+# define MAX_XLAT_TABLES 7
+#else
+# define PLAT_ARM_MMAP_ENTRIES 12
+# define MAX_XLAT_TABLES 6
+#endif
+
+/*
+ * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
+ * plus a little space for growth.
+ */
+#define PLAT_ARM_MAX_BL1_RW_SIZE 0x12000
+
+/*
+ * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
+ */
+
+#if USE_ROMLIB
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE 0x1000
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE 0xe000
+#else
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE 0
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE 0
+#endif
+
+/*
+ * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
+ * little space for growth. Current size is considering that TRUSTED_BOARD_BOOT
+ * and MEASURED_BOOT is enabled.
+ */
+# define PLAT_ARM_MAX_BL2_SIZE 0x26000
+
+
+/*
+ * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
+ * calculated using the current BL31 PROGBITS debug size plus the sizes of
+ * BL2 and BL1-RW. Current size is considering that TRUSTED_BOARD_BOOT and
+ * MEASURED_BOOT is enabled.
+ */
+#define PLAT_ARM_MAX_BL31_SIZE 0x60000
+
+/*
+ * Size of cacheable stacks
+ */
+#if defined(IMAGE_BL1)
+# if TRUSTED_BOARD_BOOT
+# define PLATFORM_STACK_SIZE 0x1000
+# else
+# define PLATFORM_STACK_SIZE 0x440
+# endif
+#elif defined(IMAGE_BL2)
+# if TRUSTED_BOARD_BOOT
+# define PLATFORM_STACK_SIZE 0x1000
+# else
+# define PLATFORM_STACK_SIZE 0x400
+# endif
+#elif defined(IMAGE_BL2U)
+# define PLATFORM_STACK_SIZE 0x400
+#elif defined(IMAGE_BL31)
+# if SPM_MM
+# define PLATFORM_STACK_SIZE 0x500
+# else
+# define PLATFORM_STACK_SIZE 0xa00
+# endif
+#elif defined(IMAGE_BL32)
+# define PLATFORM_STACK_SIZE 0x440
+#endif
+
+/*
+ * In the current implementation the RoT Service request that requires the
+ * biggest message buffer is the RSS_DELEGATED_ATTEST_GET_PLATFORM_TOKEN. The
+ * maximum required buffer size is calculated based on the platform-specific
+ * needs of this request.
+ */
+#define PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE 0x500
+
+#define TC_DEVICE_BASE 0x21000000
+#define TC_DEVICE_SIZE 0x5f000000
+
+// TC_MAP_DEVICE covers different peripherals
+// available to the platform
+#define TC_MAP_DEVICE MAP_REGION_FLAT( \
+ TC_DEVICE_BASE, \
+ TC_DEVICE_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+
+#define TC_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\
+ V2M_FLASH0_SIZE, \
+ MT_DEVICE | MT_RO | MT_SECURE)
+
+#define PLAT_ARM_NSTIMER_FRAME_ID 0
+
+#define PLAT_ARM_TRUSTED_ROM_BASE 0x0
+
+/* PLAT_ARM_TRUSTED_ROM_SIZE 512KB minus ROM base. */
+#define PLAT_ARM_TRUSTED_ROM_SIZE (0x00080000 - PLAT_ARM_TRUSTED_ROM_BASE)
+
+#define PLAT_ARM_NSRAM_BASE 0x06000000
+#define PLAT_ARM_NSRAM_SIZE 0x00080000 /* 512KB */
+
+#define PLAT_ARM_DRAM2_BASE ULL(0x8080000000)
+#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000)
+#define PLAT_ARM_DRAM2_END (PLAT_ARM_DRAM2_BASE + PLAT_ARM_DRAM2_SIZE - 1ULL)
+
+#define PLAT_ARM_G1S_IRQ_PROPS(grp) CSS_G1S_INT_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp), \
+ INTR_PROP_DESC(SBSA_SECURE_WDOG_INTID, \
+ GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+
+#define PLAT_ARM_SP_IMAGE_STACK_BASE (PLAT_SP_IMAGE_NS_BUF_BASE + \
+ PLAT_SP_IMAGE_NS_BUF_SIZE)
+
+/*******************************************************************************
+ * Memprotect definitions
+ ******************************************************************************/
+/* PSCI memory protect definitions:
+ * This variable is stored in a non-secure flash because some ARM reference
+ * platforms do not have secure NVRAM. Real systems that provided MEM_PROTECT
+ * support must use a secure NVRAM to store the PSCI MEM_PROTECT definitions.
+ */
+#define PLAT_ARM_MEM_PROT_ADDR (V2M_FLASH0_BASE + \
+ V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+/* Secure Watchdog Constants */
+#define SBSA_SECURE_WDOG_CONTROL_BASE UL(0x2A480000)
+#define SBSA_SECURE_WDOG_REFRESH_BASE UL(0x2A490000)
+#define SBSA_SECURE_WDOG_TIMEOUT UL(100)
+#define SBSA_SECURE_WDOG_INTID 86
+
+#define PLAT_ARM_SCMI_CHANNEL_COUNT 1
+
+#define PLAT_ARM_CLUSTER_COUNT U(1)
+#define PLAT_MAX_CPUS_PER_CLUSTER U(8)
+#define PLAT_MAX_PE_PER_CPU U(1)
+
+/* Message Handling Unit (MHU) base addresses */
+#define PLAT_CSS_MHU_BASE UL(0x45400000)
+#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
+
+/* TC2: AP<->RSS MHUs */
+#define PLAT_RSS_AP_SND_MHU_BASE UL(0x2A840000)
+#define PLAT_RSS_AP_RCV_MHU_BASE UL(0x2A850000)
+
+#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2
+#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
+
+/*
+ * Physical and virtual address space limits for MMU in AARCH64
+ */
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36)
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE UL(0x30000000)
+#define PLAT_ARM_GICC_BASE UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE UL(0x30080000)
+
+/*
+ * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current
+ * SCP_BL2 size plus a little space for growth.
+ */
+#define PLAT_CSS_MAX_SCP_BL2_SIZE 0x20000
+
+/*
+ * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current
+ * SCP_BL2U size plus a little space for growth.
+ */
+#define PLAT_CSS_MAX_SCP_BL2U_SIZE 0x20000
+
+/* TZC Related Constants */
+#define PLAT_ARM_TZC_BASE UL(0x25000000)
+#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0)
+
+#define TZC400_OFFSET UL(0x1000000)
+#define TZC400_COUNT 4
+
+#define TZC400_BASE(n) (PLAT_ARM_TZC_BASE + \
+ (n * TZC400_OFFSET))
+
+#define TZC_NSAID_DEFAULT U(0)
+
+#define PLAT_ARM_TZC_NS_DEV_ACCESS \
+ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_DEFAULT))
+
+/*
+ * The first region below, TC_TZC_DRAM1_BASE (0xf9000000) to
+ * ARM_SCP_TZC_DRAM1_END (0xffffffff) will mark the last 112 MB of DRAM as
+ * secure. The second and third regions gives non secure access to rest of DRAM.
+ */
+#define TC_TZC_REGIONS_DEF \
+ {TC_TZC_DRAM1_BASE, ARM_SCP_TZC_DRAM1_END, \
+ TZC_REGION_S_RDWR, PLAT_ARM_TZC_NS_DEV_ACCESS}, \
+ {TC_NS_DRAM1_BASE, TC_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \
+ PLAT_ARM_TZC_NS_DEV_ACCESS}, \
+ {PLAT_ARM_DRAM2_BASE, PLAT_ARM_DRAM2_END, \
+ ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS}
+
+/* virtual address used by dynamic mem_protect for chunk_base */
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000)
+
+#if ARM_GPT_SUPPORT
+/*
+ * This overrides the default PLAT_ARM_FIP_OFFSET_IN_GPT in board_css_def.h.
+ * Offset of the FIP in the GPT image. BL1 component uses this option
+ * as it does not load the partition table to get the FIP base
+ * address. At sector 48 for TC to align with ATU page size boundaries (8KiB)
+ * (i.e. after reserved sectors 0-47).
+ * Offset = 48 * 512 = 0x6000
+ */
+#undef PLAT_ARM_FIP_OFFSET_IN_GPT
+#define PLAT_ARM_FIP_OFFSET_IN_GPT 0x6000
+#endif /* ARM_GPT_SUPPORT */
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/tc/include/tc_helpers.S b/plat/arm/board/tc/include/tc_helpers.S
new file mode 100644
index 0000000..5f54856
--- /dev/null
+++ b/plat/arm/board/tc/include/tc_helpers.S
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+#include <cpu_macros.S>
+
+ .globl plat_arm_calc_core_pos
+ .globl plat_reset_handler
+
+ /* ---------------------------------------------------------------------
+ * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
+ *
+ * Function to calculate the core position on TC.
+ *
+ * (ClusterId * PLAT_MAX_CPUS_PER_CLUSTER * PLAT_MAX_PE_PER_CPU) +
+ * (CPUId * PLAT_MAX_PE_PER_CPU) +
+ * ThreadId
+ *
+ * which can be simplified as:
+ *
+ * ((ClusterId * PLAT_MAX_CPUS_PER_CLUSTER + CPUId) * PLAT_MAX_PE_PER_CPU)
+ * + ThreadId
+ * ---------------------------------------------------------------------
+ */
+func plat_arm_calc_core_pos
+ /*
+ * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
+ * look as if in a multi-threaded implementation.
+ */
+ tst x0, #MPIDR_MT_MASK
+ lsl x3, x0, #MPIDR_AFFINITY_BITS
+ csel x3, x3, x0, eq
+
+ /* Extract individual affinity fields from MPIDR */
+ ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+
+ /* Compute linear position */
+ mov x4, #PLAT_MAX_CPUS_PER_CLUSTER
+ madd x1, x2, x4, x1
+ mov x5, #PLAT_MAX_PE_PER_CPU
+ madd x0, x1, x5, x0
+ ret
+endfunc plat_arm_calc_core_pos
+
+ /* -----------------------------------------------------
+ * void plat_reset_handler(void);
+ *
+ * Determine the CPU MIDR and disable power down bit for
+ * that CPU.
+ * -----------------------------------------------------
+ */
+func plat_reset_handler
+ ret
+endfunc plat_reset_handler
diff --git a/plat/arm/board/tc/include/tc_plat.h b/plat/arm/board/tc/include/tc_plat.h
new file mode 100644
index 0000000..a6b2b0d
--- /dev/null
+++ b/plat/arm/board/tc/include/tc_plat.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TC_PLAT_H
+#define TC_PLAT_H
+
+#ifdef PLATFORM_TEST_ROTPK
+#include <rss_crypto_defs.h>
+#endif
+
+void tc_bl31_common_platform_setup(void);
+
+#ifdef PLATFORM_TEST_TFM_TESTSUITE
+int run_platform_tests(void);
+#endif
+
+#ifdef PLATFORM_TEST_NV_COUNTERS
+int nv_counter_test(void);
+#endif
+
+#ifdef PLATFORM_TEST_ROTPK
+struct key_id_info {
+ enum rss_key_id_builtin_t key_id;
+ const char *key_id_name;
+};
+
+int rotpk_test(void);
+#endif
+
+#endif /* TC_PLAT_H */
diff --git a/plat/arm/board/tc/nv_counter_test.c b/plat/arm/board/tc/nv_counter_test.c
new file mode 100644
index 0000000..179ec4b
--- /dev/null
+++ b/plat/arm/board/tc/nv_counter_test.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include <drivers/arm/rss_comms.h>
+#include <plat/common/platform.h>
+#include "rss_platform_api.h"
+
+#include <platform_def.h>
+
+int nv_counter_test(void)
+{
+ psa_status_t status;
+ uint32_t old_val;
+ uint32_t new_val;
+ uint32_t id;
+
+ status = rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE, PLAT_RSS_AP_RCV_MHU_BASE);
+ if (status != PSA_SUCCESS) {
+ printf("Failed to initialize RSS communication channel - psa_status = %d\n", status);
+ return -1;
+ }
+
+ for (id = 0; id < 3; id++) {
+ status = rss_platform_nv_counter_read(id, sizeof(old_val), (uint8_t *)&old_val);
+ if (status != PSA_SUCCESS) {
+ printf("Failed during first id=(%d) rss_platform_nv_counter_read - psa_status = %d\n",
+ id, status);
+ return -1;
+ }
+
+ status = rss_platform_nv_counter_increment(id);
+ if (status != PSA_SUCCESS) {
+ printf("Failed during id=(%d) rss_platform_nv_counter_increment - psa_status = %d\n",
+ id, status);
+ return -1;
+ }
+
+ status = rss_platform_nv_counter_read(id, sizeof(new_val), (uint8_t *)&new_val);
+ if (status != PSA_SUCCESS) {
+ printf("Failed during second id=(%d) rss_platform_nv_counter_read - psa_status = %d\n",
+ id, status);
+ return -1;
+ }
+
+ if (old_val + 1 != new_val) {
+ printf("Failed nv_counter_test: old_val (%d) + 1 != new_val (%d)\n",
+ old_val, new_val);
+ return -1;
+ }
+ }
+ printf("Passed nv_counter_test\n");
+
+ return 0;
+}
diff --git a/plat/arm/board/tc/plat_def_fip_uuid.h b/plat/arm/board/tc/plat_def_fip_uuid.h
new file mode 100644
index 0000000..631f7c9
--- /dev/null
+++ b/plat/arm/board/tc/plat_def_fip_uuid.h
@@ -0,0 +1,37 @@
+/*
+ * 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 \
+ {{0x0a, 0xa5, 0xb1, 0xbe}, {0xe7, 0x84}, {0x41, 0xc5}, 0x81, 0xb8, {0x4a, 0x41, 0xcb, 0x4a, 0xd2, 0xdf}}
+
+#define UUID_RSS_FIRMWARE_BL2 \
+ {{0xa3, 0xb3, 0xb3, 0x0d}, {0xeb, 0xc9}, {0x40, 0x48}, 0xb4, 0x80, {0x15, 0x53, 0x61, 0xc1, 0x70, 0x48}}
+
+#define UUID_RSS_FIRMWARE_SCP_BL1 \
+ {{0xbf, 0xd5, 0x09, 0x8d}, {0xa7, 0x07}, {0x4f, 0x15}, 0x89, 0x1c, {0x37, 0x22, 0x10, 0xcb, 0x51, 0xe2}}
+
+#define UUID_RSS_FIRMWARE_AP_BL1 \
+ {{0x12, 0x4c, 0x50, 0xe0}, {0xf2, 0xda}, {0x45, 0xe9}, 0x85, 0xc8, {0xda, 0xd9, 0x60, 0x9b, 0x7a, 0x11}}
+
+#define UUID_RSS_FIRMWARE_NS \
+ {{0x8d, 0x95, 0x9f, 0x72}, {0xb8, 0xb1}, {0x42, 0x11}, 0x9a, 0xe6, {0x4b, 0x80, 0x97, 0x47, 0x5a, 0xd9}}
+
+#define UUID_RSS_FIRMWARE_S \
+ {{0x22, 0xea, 0x33, 0x85}, {0xf8, 0x6e}, {0x47, 0x93}, 0x96, 0x8a, {0x2f, 0xe3, 0xdd, 0x50, 0x33, 0xcc}}
+
+#define UUID_RSS_SIC_TABLES_NS \
+ {{0xd9, 0x10, 0x00, 0x72}, {0x6a, 0x28}, {0x4b, 0xec}, 0xb0, 0xd6, {0x8c, 0xed, 0xc4, 0x15, 0x7c, 0xe0}}
+
+#define UUID_RSS_SIC_TABLES_S \
+ {{0xc7, 0x38, 0xd0, 0xde}, {0x8c, 0x26}, {0x48, 0x51}, 0x93, 0x36, {0xf3, 0xdb, 0xe2, 0x96, 0x65, 0x18}}
+
+#endif /* __PLAT_DEF_FIP_UUID__ */
diff --git a/plat/arm/board/tc/plat_tc_mbedtls_config.h b/plat/arm/board/tc/plat_tc_mbedtls_config.h
new file mode 100644
index 0000000..f0aa60b
--- /dev/null
+++ b/plat/arm/board/tc/plat_tc_mbedtls_config.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2022-2023, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_TC_MBEDTLS_CONFIG_H
+#define PLAT_TC_MBEDTLS_CONFIG_H
+
+#include <export/lib/utils_def_exp.h>
+#include <mbedtls_config-3.h>
+
+#ifndef TF_MBEDTLS_HEAP_SIZE
+#error TF_MBEDTLS_HEAP_SIZE is not defined
+#else
+#define PLATFORM_TEST_MIN_MBEDTLS_HEAP_SIZE (8 * 1024)
+/* Only change heap size if it is less then the minimum required. */
+#if TF_MBEDTLS_HEAP_SIZE < PLATFORM_TEST_MIN_MBEDTLS_HEAP_SIZE
+#undef TF_MBEDTLS_HEAP_SIZE
+#define TF_MBEDTLS_HEAP_SIZE PLATFORM_TEST_MIN_MBEDTLS_HEAP_SIZE
+#endif
+#endif
+
+#define MBEDTLS_PSA_CRYPTO_C
+#define MBEDTLS_HMAC_DRBG_C
+#define MBEDTLS_ENTROPY_C
+#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+#define MBEDTLS_NO_PLATFORM_ENTROPY
+#define MBEDTLS_TEST_NULL_ENTROPY
+#define MBEDTLS_ECP_C
+#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
+
+#endif /* PLAT_TC_MBEDTLS_CONFIG_H */
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
new file mode 100644
index 0000000..6874cfa
--- /dev/null
+++ b/plat/arm/board/tc/platform.mk
@@ -0,0 +1,206 @@
+# Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include common/fdt_wrappers.mk
+
+ifeq ($(TARGET_PLATFORM), 0)
+ $(error Platform ${PLAT}$(TARGET_PLATFORM) is deprecated.)
+endif
+
+ifeq ($(TARGET_PLATFORM), 1)
+ $(warning Platform ${PLAT}$(TARGET_PLATFORM) is deprecated. \
+ Some of the features might not work as expected)
+endif
+
+ifeq ($(shell expr $(TARGET_PLATFORM) \<= 2), 0)
+ $(error TARGET_PLATFORM must be less than or equal to 2)
+endif
+
+$(eval $(call add_define,TARGET_PLATFORM))
+
+CSS_LOAD_SCP_IMAGES := 1
+
+CSS_USE_SCMI_SDS_DRIVER := 1
+
+ENABLE_FEAT_RAS := 1
+
+SDEI_SUPPORT := 0
+
+EL3_EXCEPTION_HANDLING := 0
+
+HANDLE_EA_EL3_FIRST_NS := 0
+
+# System coherency is managed in hardware
+HW_ASSISTED_COHERENCY := 1
+
+# When building for systems with hardware-assisted coherency, there's no need to
+# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
+USE_COHERENT_MEM := 0
+
+GIC_ENABLE_V4_EXTN := 1
+
+# GIC-600 configuration
+GICV3_SUPPORT_GIC600 := 1
+
+# Enable SVE
+ENABLE_SVE_FOR_NS := 2
+ENABLE_SVE_FOR_SWD := 1
+
+# enable trace buffer control registers access to NS by default
+ENABLE_TRBE_FOR_NS := 1
+
+# enable trace system registers access to NS by default
+ENABLE_SYS_REG_TRACE_FOR_NS := 1
+
+# enable trace filter control registers access to NS by default
+ENABLE_TRF_FOR_NS := 1
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+ENT_GIC_SOURCES := ${GICV3_SOURCES} \
+ plat/common/plat_gicv3.c \
+ plat/arm/common/arm_gicv3.c
+
+override NEED_BL2U := no
+
+override ARM_PLAT_MT := 1
+
+TC_BASE = plat/arm/board/tc
+
+PLAT_INCLUDES += -I${TC_BASE}/include/
+
+# CPU libraries for TARGET_PLATFORM=1
+ifeq (${TARGET_PLATFORM}, 1)
+TC_CPU_SOURCES += lib/cpus/aarch64/cortex_a510.S \
+ lib/cpus/aarch64/cortex_a715.S \
+ lib/cpus/aarch64/cortex_x3.S
+endif
+
+# CPU libraries for TARGET_PLATFORM=2
+ifeq (${TARGET_PLATFORM}, 2)
+TC_CPU_SOURCES += lib/cpus/aarch64/cortex_a520.S \
+ lib/cpus/aarch64/cortex_a720.S \
+ lib/cpus/aarch64/cortex_x4.S
+endif
+
+INTERCONNECT_SOURCES := ${TC_BASE}/tc_interconnect.c
+
+PLAT_BL_COMMON_SOURCES += ${TC_BASE}/tc_plat.c \
+ ${TC_BASE}/include/tc_helpers.S
+
+BL1_SOURCES += ${INTERCONNECT_SOURCES} \
+ ${TC_CPU_SOURCES} \
+ ${TC_BASE}/tc_trusted_boot.c \
+ ${TC_BASE}/tc_err.c \
+ drivers/arm/sbsa/sbsa.c
+
+BL2_SOURCES += ${TC_BASE}/tc_security.c \
+ ${TC_BASE}/tc_err.c \
+ ${TC_BASE}/tc_trusted_boot.c \
+ ${TC_BASE}/tc_bl2_setup.c \
+ lib/utils/mem_region.c \
+ drivers/arm/tzc/tzc400.c \
+ plat/arm/common/arm_tzc400.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c
+
+BL31_SOURCES += ${INTERCONNECT_SOURCES} \
+ ${TC_CPU_SOURCES} \
+ ${ENT_GIC_SOURCES} \
+ ${TC_BASE}/tc_bl31_setup.c \
+ ${TC_BASE}/tc_topology.c \
+ lib/fconf/fconf.c \
+ lib/fconf/fconf_dyn_cfg_getter.c \
+ drivers/cfi/v2m/v2m_flash.c \
+ lib/utils/mem_region.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c \
+ drivers/arm/sbsa/sbsa.c
+
+BL31_SOURCES += ${FDT_WRAPPERS_SOURCES}
+
+# Add the FDT_SOURCES and options for Dynamic Config
+FDT_SOURCES += ${TC_BASE}/fdts/${PLAT}_fw_config.dts \
+ ${TC_BASE}/fdts/${PLAT}_tb_fw_config.dts
+FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
+TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
+
+ifeq (${SPD},spmd)
+ifeq ($(ARM_SPMC_MANIFEST_DTS),)
+ARM_SPMC_MANIFEST_DTS := ${TC_BASE}/fdts/${PLAT}_spmc_manifest.dts
+endif
+
+FDT_SOURCES += ${ARM_SPMC_MANIFEST_DTS}
+TC_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/$(notdir $(basename ${ARM_SPMC_MANIFEST_DTS})).dtb
+
+# Add the TOS_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TC_TOS_FW_CONFIG},--tos-fw-config,${TC_TOS_FW_CONFIG}))
+endif
+
+#Device tree
+TC_HW_CONFIG_DTS := fdts/tc.dts
+TC_HW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}.dtb
+FDT_SOURCES += ${TC_HW_CONFIG_DTS}
+$(eval TC_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(TC_HW_CONFIG_DTS)))
+
+# Add the HW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TC_HW_CONFIG},--hw-config,${TC_HW_CONFIG}))
+
+override CTX_INCLUDE_AARCH32_REGS := 0
+
+override CTX_INCLUDE_PAUTH_REGS := 1
+
+override ENABLE_SPE_FOR_NS := 0
+
+override ENABLE_FEAT_AMU := 1
+override ENABLE_AMU_AUXILIARY_COUNTERS := 1
+override ENABLE_AMU_FCONF := 1
+
+override ENABLE_MPMM := 1
+override ENABLE_MPMM_FCONF := 1
+
+# Include Measured Boot makefile before any Crypto library makefile.
+# Crypto library makefile may need default definitions of Measured Boot build
+# flags present in Measured Boot makefile.
+ifeq (${MEASURED_BOOT},1)
+ MEASURED_BOOT_MK := drivers/measured_boot/rss/rss_measured_boot.mk
+ $(info Including ${MEASURED_BOOT_MK})
+ include ${MEASURED_BOOT_MK}
+ $(info Including rss_comms.mk)
+ include drivers/arm/rss/rss_comms.mk
+
+ BL1_SOURCES += ${MEASURED_BOOT_SOURCES} \
+ plat/arm/board/tc/tc_common_measured_boot.c \
+ plat/arm/board/tc/tc_bl1_measured_boot.c \
+ lib/psa/measured_boot.c \
+ ${RSS_COMMS_SOURCES}
+
+ BL2_SOURCES += ${MEASURED_BOOT_SOURCES} \
+ plat/arm/board/tc/tc_common_measured_boot.c \
+ plat/arm/board/tc/tc_bl2_measured_boot.c \
+ lib/psa/measured_boot.c \
+ ${RSS_COMMS_SOURCES}
+
+PLAT_INCLUDES += -Iinclude/lib/psa
+
+endif
+
+ifneq (${PLATFORM_TEST},)
+ # Add this include as first, before arm_common.mk. This is necessary
+ # because arm_common.mk builds Mbed TLS, and platform_test.mk can
+ # change the list of Mbed TLS files that are to be compiled
+ # (LIBMBEDTLS_SRCS).
+ include plat/arm/board/tc/platform_test.mk
+endif
+
+
+include plat/arm/common/arm_common.mk
+include plat/arm/css/common/css_common.mk
+include plat/arm/soc/common/soc_css.mk
+include plat/arm/board/common/board_common.mk
diff --git a/plat/arm/board/tc/platform_test.mk b/plat/arm/board/tc/platform_test.mk
new file mode 100644
index 0000000..2fd5ea0
--- /dev/null
+++ b/plat/arm/board/tc/platform_test.mk
@@ -0,0 +1,112 @@
+# Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+$(eval $(call add_define,PLATFORM_TESTS))
+
+ifeq (${PLATFORM_TEST},rss-nv-counters)
+ include drivers/arm/rss/rss_comms.mk
+
+ # Test code.
+ BL31_SOURCES += plat/arm/board/tc/nv_counter_test.c
+
+ # Code under testing.
+ BL31_SOURCES += lib/psa/rss_platform.c \
+ drivers/arm/rss/rss_comms.c \
+ ${RSS_COMMS_SOURCES}
+
+ PLAT_INCLUDES += -Iinclude/lib/psa
+
+ $(eval $(call add_define,PLATFORM_TEST_NV_COUNTERS))
+else ifeq (${PLATFORM_TEST},rss-rotpk)
+ include drivers/arm/rss/rss_comms.mk
+
+ # Test code.
+ BL31_SOURCES += plat/arm/board/tc/rotpk_test.c
+
+ # Code under testing.
+ BL31_SOURCES += lib/psa/rss_platform.c \
+ drivers/arm/rss/rss_comms.c \
+ ${RSS_COMMS_SOURCES}
+
+ PLAT_INCLUDES += -Iinclude/lib/psa
+
+ $(eval $(call add_define,PLATFORM_TEST_ROTPK))
+else ifeq (${PLATFORM_TEST},tfm-testsuite)
+
+ # The variables need to be set to compile the platform test:
+ ifeq (${TF_M_TESTS_PATH},)
+ # Example: ../rss/tf-m-tests
+ $(error Error: TF_M_TESTS_PATH not set)
+ endif
+ ifeq (${TF_M_EXTRAS_PATH},)
+ # Example: ../rss/tf-m-extras
+ $(error Error: TF_M_EXTRAS_PATH not set)
+ endif
+ ifeq (${MEASUREMENT_VALUE_SIZE},)
+ MEASUREMENT_VALUE_SIZE := 32
+ endif
+ ifeq (${MEASURED_BOOT_HASH_ALG},)
+ MEASURED_BOOT_HASH_ALG := "PSA_ALG_SHA_256"
+ endif
+
+ DELEGATED_ATTEST_TESTS_PATH = $(TF_M_EXTRAS_PATH)/partitions/delegated_attestation/test
+ MEASURED_BOOT_TESTS_PATH = $(TF_M_EXTRAS_PATH)/partitions/measured_boot/test
+
+ MBEDTLS_CONFIG_FILE = "<plat_tc_mbedtls_config.h>"
+
+ LIBMBEDTLS_SRCS += $(addprefix ${MBEDTLS_DIR}/library/, \
+ entropy.c \
+ entropy_poll.c \
+ hmac_drbg.c \
+ psa_crypto.c \
+ psa_crypto_client.c \
+ psa_crypto_driver_wrappers.c \
+ psa_crypto_hash.c \
+ psa_crypto_rsa.c \
+ psa_crypto_ecp.c \
+ psa_crypto_slot_management.c \
+ )
+
+ BL31_SOURCES += ${RSS_COMMS_SOURCES} \
+ plat/arm/common/arm_dyn_cfg.c \
+ ${TC_BASE}/rss_ap_tests.c \
+ ${TC_BASE}/rss_ap_testsuites.c \
+ ${TC_BASE}/rss_ap_test_stubs.c \
+ $(TF_M_TESTS_PATH)/test/framework/test_framework.c \
+ $(MEASURED_BOOT_TESTS_PATH)/measured_boot_common.c \
+ $(MEASURED_BOOT_TESTS_PATH)/measured_boot_tests_common.c \
+ $(DELEGATED_ATTEST_TESTS_PATH)/delegated_attest_test.c \
+ drivers/auth/mbedtls/mbedtls_common.c \
+ lib/psa/measured_boot.c \
+ lib/psa/delegated_attestation.c
+
+ PLAT_INCLUDES += -I$(TF_M_EXTRAS_PATH)/partitions/measured_boot/interface/include \
+ -I$(TF_M_EXTRAS_PATH)/partitions/delegated_attestation/interface/include \
+ -I$(TF_M_TESTS_PATH)/test/framework \
+ -I$(TF_M_TESTS_PATH)/log \
+ -I$(TF_M_TESTS_PATH)/test/secure_fw/suites/extra \
+ -I$(MEASURED_BOOT_TESTS_PATH)/non_secure \
+ -I$(DELEGATED_ATTEST_TESTS_PATH) \
+ -I$(DELEGATED_ATTEST_TESTS_PATH)/non_secure \
+ -Iplat/arm/board/tc \
+ -Iinclude/drivers/auth/mbedtls \
+ -Iinclude/drivers/arm
+
+ # Some of the PSA functions are declared in multiple header files, that
+ # triggers this warning.
+ TF_CFLAGS += -Wno-error=redundant-decls
+
+ # TODO: Created patch for warning in tf-m-tests
+ TF_CFLAGS += -Wno-error=return-type
+
+ # Define macros that are used by the code coming from the tf-m-extras repo.
+ $(eval $(call add_define,MEASUREMENT_VALUE_SIZE))
+ $(eval $(call add_define,MEASURED_BOOT_HASH_ALG))
+ $(eval $(call add_define,DELEG_ATTEST_DUMP_TOKEN_AND_KEY))
+
+ $(eval $(call add_define,PLATFORM_TEST_TFM_TESTSUITE))
+else
+ $(error "Unsupported PLATFORM_TEST value")
+endif
diff --git a/plat/arm/board/tc/region_defs.h b/plat/arm/board/tc/region_defs.h
new file mode 100644
index 0000000..50ec2f1
--- /dev/null
+++ b/plat/arm/board/tc/region_defs.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef REGION_DEFS_H
+#define REGION_DEFS_H
+
+#define PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE 0x800
+
+#endif /* REGION_DEFS_H */
diff --git a/plat/arm/board/tc/rotpk_test.c b/plat/arm/board/tc/rotpk_test.c
new file mode 100644
index 0000000..ed56c31
--- /dev/null
+++ b/plat/arm/board/tc/rotpk_test.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include <drivers/arm/rss_comms.h>
+#include <plat/common/platform.h>
+#include <rss_platform_api.h>
+#include <tc_plat.h>
+
+static void print_hex(const char *key_id_name, size_t key_size, const uint8_t *key_buf)
+{
+ printf("%s = ", key_id_name);
+ for (int i = 0; i < key_size; i++) {
+ printf("%02x", key_buf[i]);
+ }
+ printf("\n\n");
+}
+
+int rotpk_test(void)
+{
+ psa_status_t status;
+ uint8_t key_buf[128];
+ size_t key_size;
+
+ struct key_id_info key_ids[3] = {
+ {.key_id = RSS_BUILTIN_KEY_ID_HOST_S_ROTPK, .key_id_name = "Secure-ROTPK"},
+ {.key_id = RSS_BUILTIN_KEY_ID_HOST_NS_ROTPK, .key_id_name = "NS-ROTPK"},
+ {.key_id = RSS_BUILTIN_KEY_ID_HOST_CCA_ROTPK, .key_id_name = "CCA-ROTPK"}
+ };
+
+ status = rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE, PLAT_RSS_AP_RCV_MHU_BASE);
+ if (status != PSA_SUCCESS) {
+ printf("Failed to initialize RSS communication channel - psa_status = %d\n", status);
+ return -1;
+ }
+
+ for (int i = 0; i < ARRAY_SIZE(key_ids); i++) {
+ status = rss_platform_key_read(key_ids[i].key_id, key_buf,
+ sizeof(key_buf), &key_size);
+ if (status != PSA_SUCCESS) {
+ printf("Failed to retrieve %s - psa_status = %d\n", key_ids[i].key_id_name, status);
+ return -1;
+ }
+ print_hex(key_ids[i].key_id_name, key_size, key_buf);
+ }
+
+ printf("Passed rotpk_test\n");
+
+ return 0;
+}
diff --git a/plat/arm/board/tc/rss_ap_test_stubs.c b/plat/arm/board/tc/rss_ap_test_stubs.c
new file mode 100644
index 0000000..aa97476
--- /dev/null
+++ b/plat/arm/board/tc/rss_ap_test_stubs.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <delegated_attestation.h>
+#include <measured_boot.h>
+#include <psa/error.h>
+
+
+psa_status_t
+tfm_measured_boot_extend_measurement(uint8_t index,
+ const uint8_t *signer_id,
+ size_t signer_id_size,
+ const uint8_t *version,
+ size_t version_size,
+ uint32_t measurement_algo,
+ const uint8_t *sw_type,
+ size_t sw_type_size,
+ const uint8_t *measurement_value,
+ size_t measurement_value_size,
+ bool lock_measurement)
+{
+ return rss_measured_boot_extend_measurement(index,
+ signer_id,
+ signer_id_size,
+ version,
+ version_size,
+ measurement_algo,
+ sw_type,
+ sw_type_size,
+ measurement_value,
+ measurement_value_size,
+ lock_measurement);
+}
+
+psa_status_t
+tfm_measured_boot_read_measurement(uint8_t index,
+ uint8_t *signer_id,
+ size_t signer_id_size,
+ size_t *signer_id_len,
+ uint8_t *version,
+ size_t version_size,
+ size_t *version_len,
+ uint32_t *measurement_algo,
+ uint8_t *sw_type,
+ size_t sw_type_size,
+ size_t *sw_type_len,
+ uint8_t *measurement_value,
+ size_t measurement_value_size,
+ size_t *measurement_value_len,
+ bool *is_locked)
+{
+ return rss_measured_boot_read_measurement(index,
+ signer_id,
+ signer_id_size,
+ signer_id_len,
+ version,
+ version_size,
+ version_len,
+ measurement_algo,
+ sw_type,
+ sw_type_size,
+ sw_type_len,
+ measurement_value,
+ measurement_value_size,
+ measurement_value_len,
+ is_locked);
+}
+
+psa_status_t
+tfm_delegated_attest_get_token(const uint8_t *dak_pub_hash,
+ size_t dak_pub_hash_size,
+ uint8_t *token_buf,
+ size_t token_buf_size,
+ size_t *token_size)
+{
+ return rss_delegated_attest_get_token(dak_pub_hash,
+ dak_pub_hash_size,
+ token_buf,
+ token_buf_size,
+ token_size);
+}
+
+psa_status_t
+tfm_delegated_attest_get_delegated_key(uint8_t ecc_curve,
+ uint32_t key_bits,
+ uint8_t *key_buf,
+ size_t key_buf_size,
+ size_t *key_size,
+ uint32_t hash_algo)
+{
+ return rss_delegated_attest_get_delegated_key(ecc_curve,
+ key_bits,
+ key_buf,
+ key_buf_size,
+ key_size,
+ hash_algo);
+}
+
+int tfm_log_printf(const char *fmt, ...)
+{
+ int count;
+ va_list ap;
+
+ va_start(ap, fmt);
+ count = vprintf(fmt, ap);
+ va_end(ap);
+
+ return count;
+}
+
+void printf_set_color(int color_id)
+{
+ (void)color_id;
+}
diff --git a/plat/arm/board/tc/rss_ap_tests.c b/plat/arm/board/tc/rss_ap_tests.c
new file mode 100644
index 0000000..ea90ac3
--- /dev/null
+++ b/plat/arm/board/tc/rss_ap_tests.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdio.h>
+
+#include <mbedtls_common.h>
+#include <plat/common/platform.h>
+#include <psa/crypto.h>
+#include <rss_comms.h>
+
+#include "rss_ap_testsuites.h"
+
+static struct test_suite_t test_suites[] = {
+ {.freg = register_testsuite_delegated_attest},
+ {.freg = register_testsuite_measured_boot},
+};
+
+/*
+ * Return 0 if we could run all tests.
+ * Note that this does not mean that all tests passed - only that they all run.
+ * One should then look at each individual test result inside the
+ * test_suites[].val field.
+ */
+static int run_tests(void)
+{
+ enum test_suite_err_t ret;
+ psa_status_t status;
+ size_t i;
+
+ /* Initialize test environment. */
+ rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE, PLAT_RSS_AP_RCV_MHU_BASE);
+ mbedtls_init();
+ status = psa_crypto_init();
+ if (status != PSA_SUCCESS) {
+ printf("\n\npsa_crypto_init failed (status = %d)\n", status);
+ return -1;
+ }
+
+ /* Run all tests. */
+ for (i = 0; i < ARRAY_SIZE(test_suites); ++i) {
+ struct test_suite_t *suite = &(test_suites[i]);
+
+ suite->freg(suite);
+ ret = run_testsuite(suite);
+ if (ret != TEST_SUITE_ERR_NO_ERROR) {
+ printf("\n\nError during executing testsuite '%s'.\n", suite->name);
+ return -1;
+ }
+ }
+ printf("\nAll tests are run.\n");
+
+ return 0;
+}
+
+int run_platform_tests(void)
+{
+ size_t i;
+ int ret;
+ int failures = 0;
+
+ ret = run_tests();
+ if (ret != 0) {
+ /* For some reason, we could not run all tests. */
+ return ret;
+ }
+
+ printf("\n\n");
+
+ /*
+ * Print a summary of all the tests that had been run.
+ * Also count the number of tests failure and report that back to the
+ * caller.
+ */
+ printf("SUMMARY:\n");
+ for (i = 0; i < ARRAY_SIZE(test_suites); ++i) {
+
+ struct test_suite_t *suite = &(test_suites[i]);
+
+ switch (suite->val) {
+ case TEST_PASSED:
+ printf(" %s PASSED.\n", suite->name);
+ break;
+ case TEST_FAILED:
+ failures++;
+ printf(" %s FAILED.\n", suite->name);
+ break;
+ case TEST_SKIPPED:
+ printf(" %s SKIPPED.\n", suite->name);
+ break;
+ default:
+ assert(false);
+ break;
+ }
+ }
+
+ printf("\n\n");
+
+ return failures;
+}
diff --git a/plat/arm/board/tc/rss_ap_testsuites.c b/plat/arm/board/tc/rss_ap_testsuites.c
new file mode 100644
index 0000000..aa47d4c
--- /dev/null
+++ b/plat/arm/board/tc/rss_ap_testsuites.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * `delegated_attest_ns_interface_testsuite.c` and
+ * `measured_boot_ns_interface_testsuite.c` are not added to the build directly.
+ * but are included in this file, and this file is added to the build. This is
+ * necessary because both files define the function `extra_tests_init`, so a
+ * linker error occurs when both are linked to BL31. This file defines a macro
+ * that renames the colliding function names to something unique.
+ * `plat/arm/board/tc/rss_ap_tests.c` can call the test init functions with
+ * their new name.
+ */
+
+#define register_testsuite_extra_ns_interface \
+ register_testsuite_delegated_attest
+#include <delegated_attest_ns_interface_testsuite.c>
+
+#undef register_testsuite_extra_ns_interface
+#define register_testsuite_extra_ns_interface \
+ register_testsuite_measured_boot
+#include <measured_boot_ns_interface_testsuite.c> \ No newline at end of file
diff --git a/plat/arm/board/tc/rss_ap_testsuites.h b/plat/arm/board/tc/rss_ap_testsuites.h
new file mode 100644
index 0000000..58502ab
--- /dev/null
+++ b/plat/arm/board/tc/rss_ap_testsuites.h
@@ -0,0 +1,16 @@
+
+/*
+ * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RSS_AP_TESTSUITES_H
+#define RSS_AP_TESTSUITES_H
+
+#include <test_framework.h>
+
+void register_testsuite_measured_boot(struct test_suite_t *p_test_suite);
+void register_testsuite_delegated_attest(struct test_suite_t *p_test_suite);
+
+#endif /* RSS_AP_TESTSUITES_H */
diff --git a/plat/arm/board/tc/tc_bl1_measured_boot.c b/plat/arm/board/tc/tc_bl1_measured_boot.c
new file mode 100644
index 0000000..6821a6a
--- /dev/null
+++ b/plat/arm/board/tc/tc_bl1_measured_boot.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <drivers/arm/rss_comms.h>
+#include <drivers/measured_boot/rss/rss_measured_boot.h>
+#include <lib/psa/measured_boot.h>
+#include <tools_share/zero_oid.h>
+
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+/* Table with platform specific image IDs and metadata. Intentionally not a
+ * const struct, some members might set by bootloaders during trusted boot.
+ */
+struct rss_mboot_metadata tc_rss_mboot_metadata[] = {
+ {
+ .id = FW_CONFIG_ID,
+ .slot = U(6),
+ .signer_id_size = SIGNER_ID_MIN_SIZE,
+ .sw_type = RSS_MBOOT_FW_CONFIG_STRING,
+ .pk_oid = ZERO_OID,
+ .lock_measurement = true },
+ {
+ .id = TB_FW_CONFIG_ID,
+ .slot = U(7),
+ .signer_id_size = SIGNER_ID_MIN_SIZE,
+ .sw_type = RSS_MBOOT_TB_FW_CONFIG_STRING,
+ .pk_oid = ZERO_OID,
+ .lock_measurement = true },
+ {
+ .id = BL2_IMAGE_ID,
+ .slot = U(8),
+ .signer_id_size = SIGNER_ID_MIN_SIZE,
+ .sw_type = RSS_MBOOT_BL2_STRING,
+ .pk_oid = ZERO_OID,
+ .lock_measurement = true },
+
+ {
+ .id = RSS_MBOOT_INVALID_ID }
+};
+
+void bl1_plat_mboot_init(void)
+{
+ /* Initialize the communication channel between AP and RSS */
+ (void)rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE,
+ PLAT_RSS_AP_RCV_MHU_BASE);
+
+ rss_measured_boot_init(tc_rss_mboot_metadata);
+}
+
+void bl1_plat_mboot_finish(void)
+{
+ /* Nothing to do. */
+}
diff --git a/plat/arm/board/tc/tc_bl2_measured_boot.c b/plat/arm/board/tc/tc_bl2_measured_boot.c
new file mode 100644
index 0000000..4b79170
--- /dev/null
+++ b/plat/arm/board/tc/tc_bl2_measured_boot.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <drivers/arm/rss_comms.h>
+#include <drivers/measured_boot/rss/rss_measured_boot.h>
+#include <lib/psa/measured_boot.h>
+#include <tools_share/tbbr_oid.h>
+
+#include <plat/common/common_def.h>
+#include <platform_def.h>
+
+/* TC specific table with image IDs and metadata. Intentionally not a
+ * const struct, some members might set by bootloaders during trusted boot.
+ */
+struct rss_mboot_metadata tc_rss_mboot_metadata[] = {
+ {
+ .id = BL31_IMAGE_ID,
+ .slot = U(9),
+ .signer_id_size = SIGNER_ID_MIN_SIZE,
+ .sw_type = RSS_MBOOT_BL31_STRING,
+ .pk_oid = BL31_IMAGE_KEY_OID,
+ .lock_measurement = true },
+ {
+ .id = HW_CONFIG_ID,
+ .slot = U(10),
+ .signer_id_size = SIGNER_ID_MIN_SIZE,
+ .sw_type = RSS_MBOOT_HW_CONFIG_STRING,
+ .pk_oid = HW_CONFIG_KEY_OID,
+ .lock_measurement = true },
+ {
+ .id = SOC_FW_CONFIG_ID,
+ .slot = U(11),
+ .signer_id_size = SIGNER_ID_MIN_SIZE,
+ .sw_type = RSS_MBOOT_SOC_FW_CONFIG_STRING,
+ .pk_oid = SOC_FW_CONFIG_KEY_OID,
+ .lock_measurement = true },
+ {
+ .id = RSS_MBOOT_INVALID_ID }
+};
+
+void bl2_plat_mboot_init(void)
+{
+ /* Initialize the communication channel between AP and RSS */
+ (void)rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE,
+ PLAT_RSS_AP_RCV_MHU_BASE);
+
+ rss_measured_boot_init(tc_rss_mboot_metadata);
+}
+
+void bl2_plat_mboot_finish(void)
+{
+ /* Nothing to do. */
+}
diff --git a/plat/arm/board/tc/tc_bl2_setup.c b/plat/arm/board/tc/tc_bl2_setup.c
new file mode 100644
index 0000000..74ef569
--- /dev/null
+++ b/plat/arm/board/tc/tc_bl2_setup.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2021, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/bl_common.h>
+#include <common/desc_image_load.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+
+#include <plat/arm/common/plat_arm.h>
+
+/*******************************************************************************
+ * This function returns the list of executable images
+ ******************************************************************************/
+struct bl_params *plat_get_next_bl_params(void)
+{
+ struct bl_params *arm_bl_params = arm_get_next_bl_params();
+
+ const struct dyn_cfg_dtb_info_t *fw_config_info;
+ bl_mem_params_node_t *param_node;
+ uintptr_t fw_config_base = 0U;
+ entry_point_info_t *ep_info;
+
+ /* Get BL31 image node */
+ param_node = get_bl_mem_params_node(BL31_IMAGE_ID);
+ assert(param_node != NULL);
+
+ /* Get fw_config load address */
+ fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
+ assert(fw_config_info != NULL);
+
+ fw_config_base = fw_config_info->config_addr;
+ assert(fw_config_base != 0U);
+
+ /*
+ * Get the entry point info of BL31 image and override
+ * arg1 of entry point info with fw_config base address
+ */
+ ep_info = &param_node->ep_info;
+ ep_info->args.arg1 = (uint32_t)fw_config_base;
+
+ return arm_bl_params;
+}
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
new file mode 100644
index 0000000..ff7809d
--- /dev/null
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <libfdt.h>
+#include <tc_plat.h>
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+#include <drivers/arm/sbsa.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
+static scmi_channel_plat_info_t tc_scmi_plat_info[] = {
+ {
+ .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+ .db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
+ .db_preserve_mask = 0xfffffffe,
+ .db_modify_mask = 0x1,
+ .ring_doorbell = &mhuv2_ring_doorbell,
+ }
+};
+
+void bl31_platform_setup(void)
+{
+ tc_bl31_common_platform_setup();
+}
+
+scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id)
+{
+
+ return &tc_scmi_plat_info[channel_id];
+
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+
+ /* Fill the properties struct with the info from the config dtb */
+ fconf_populate("FW_CONFIG", arg1);
+}
+
+#ifdef PLATFORM_TESTS
+static __dead2 void tc_run_platform_tests(void)
+{
+ int tests_failed;
+
+ printf("\nStarting platform tests...\n");
+
+#ifdef PLATFORM_TEST_NV_COUNTERS
+ tests_failed = nv_counter_test();
+#elif PLATFORM_TEST_ROTPK
+ tests_failed = rotpk_test();
+#elif PLATFORM_TEST_TFM_TESTSUITE
+ tests_failed = run_platform_tests();
+#endif
+
+ printf("Platform tests %s.\n",
+ (tests_failed != 0) ? "failed" : "succeeded");
+
+ /* Suspend booting, no matter the tests outcome. */
+ printf("Suspend booting...\n");
+ plat_error_handler(-1);
+}
+#endif
+
+void tc_bl31_common_platform_setup(void)
+{
+ arm_bl31_platform_setup();
+
+#ifdef PLATFORM_TESTS
+ tc_run_platform_tests();
+#endif
+}
+
+const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
+{
+ return css_scmi_override_pm_ops(ops);
+}
+
+void __init bl31_plat_arch_setup(void)
+{
+ arm_bl31_plat_arch_setup();
+
+ /* HW_CONFIG was also loaded by BL2 */
+ const struct dyn_cfg_dtb_info_t *hw_config_info;
+
+ hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
+ assert(hw_config_info != NULL);
+
+ fconf_populate("HW_CONFIG", hw_config_info->config_addr);
+}
+
+#if defined(SPD_spmd) && (SPMC_AT_EL3 == 0)
+void tc_bl31_plat_runtime_setup(void)
+{
+ arm_bl31_plat_runtime_setup();
+
+ /* Start secure watchdog timer. */
+ plat_arm_secure_wdt_start();
+}
+
+void bl31_plat_runtime_setup(void)
+{
+ tc_bl31_plat_runtime_setup();
+}
+
+/*
+ * Platform handler for Group0 secure interrupt.
+ */
+int plat_spmd_handle_group0_interrupt(uint32_t intid)
+{
+ /* Trusted Watchdog timer is the only source of Group0 interrupt now. */
+ if (intid == SBSA_SECURE_WDOG_INTID) {
+ /* Refresh the timer. */
+ plat_arm_secure_wdt_refresh();
+
+ return 0;
+ }
+
+ return -1;
+}
+#endif /*defined(SPD_spmd) && (SPMC_AT_EL3 == 0)*/
diff --git a/plat/arm/board/tc/tc_common_measured_boot.c b/plat/arm/board/tc/tc_common_measured_boot.c
new file mode 100644
index 0000000..925a411
--- /dev/null
+++ b/plat/arm/board/tc/tc_common_measured_boot.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <common/desc_image_load.h>
+#include <drivers/measured_boot/rss/rss_measured_boot.h>
+
+extern struct rss_mboot_metadata tc_rss_mboot_metadata[];
+
+int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
+{
+ int err;
+
+ /* Calculate image hash and record data in RSS */
+ err = rss_mboot_measure_and_record(tc_rss_mboot_metadata,
+ image_data->image_base,
+ image_data->image_size,
+ image_id);
+ if (err != 0) {
+ ERROR("%s%s image id %u (%i)\n",
+ "Failed to ", "record in RSS", image_id, err);
+ }
+
+ return err;
+}
+
+int plat_mboot_measure_key(void *pk_oid, void *pk_ptr, unsigned int pk_len)
+{
+ return rss_mboot_set_signer_id(tc_rss_mboot_metadata, pk_oid, pk_ptr,
+ pk_len);
+}
diff --git a/plat/arm/board/tc/tc_err.c b/plat/arm/board/tc/tc_err.c
new file mode 100644
index 0000000..9ed7e92
--- /dev/null
+++ b/plat/arm/board/tc/tc_err.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * tc error handler
+ */
+void __dead2 plat_arm_error_handler(int err)
+{
+ while (true) {
+ wfi();
+ }
+}
diff --git a/plat/arm/board/tc/tc_interconnect.c b/plat/arm/board/tc/tc_interconnect.c
new file mode 100644
index 0000000..e2fc4e1
--- /dev/null
+++ b/plat/arm/board/tc/tc_interconnect.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * For Total Compute we should not do anything in these interface functions.
+ * They are used to override the weak functions in cci drivers.
+ */
+
+/******************************************************************************
+ * Helper function to initialize ARM interconnect driver.
+ *****************************************************************************/
+void __init plat_arm_interconnect_init(void)
+{
+}
+
+/******************************************************************************
+ * Helper function to place current master into coherency
+ *****************************************************************************/
+void plat_arm_interconnect_enter_coherency(void)
+{
+}
+
+/******************************************************************************
+ * Helper function to remove current master from coherency
+ *****************************************************************************/
+void plat_arm_interconnect_exit_coherency(void)
+{
+}
diff --git a/plat/arm/board/tc/tc_plat.c b/plat/arm/board/tc/tc_plat.c
new file mode 100644
index 0000000..766bfb5
--- /dev/null
+++ b/plat/arm/board/tc/tc_plat.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <plat/common/platform.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/arm/ccn.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <drivers/arm/sbsa.h>
+
+#if SPM_MM
+#include <services/spm_mm_partition.h>
+#endif
+
+/*
+ * Table of regions for different BL stages to map using the MMU.
+ * This doesn't include Trusted RAM as the 'mem_layout' argument passed to
+ * arm_configure_mmu_elx() will give the available subset of that.
+ */
+#if IMAGE_BL1
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ TC_FLASH0_RO,
+ TC_MAP_DEVICE,
+ {0}
+};
+#endif
+#if IMAGE_BL2
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ TC_FLASH0_RO,
+ TC_MAP_DEVICE,
+ TC_MAP_NS_DRAM1,
+#if defined(SPD_spmd)
+ TC_MAP_TZC_DRAM1,
+#endif
+#if ARM_BL31_IN_DRAM
+ ARM_MAP_BL31_SEC_DRAM,
+#endif
+#if SPM_MM
+ ARM_SP_IMAGE_MMAP,
+#endif
+#if TRUSTED_BOARD_BOOT && !RESET_TO_BL2
+ ARM_MAP_BL1_RW,
+#endif
+#ifdef SPD_opteed
+ ARM_MAP_OPTEE_CORE_MEM,
+ ARM_OPTEE_PAGEABLE_LOAD_MEM,
+#endif
+ {0}
+};
+#endif
+#if IMAGE_BL31
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ V2M_MAP_IOFPGA,
+ TC_MAP_DEVICE,
+ PLAT_DTB_DRAM_NS,
+#if SPM_MM
+ ARM_SPM_BUF_EL3_MMAP,
+#endif
+ {0}
+};
+
+#if SPM_MM && defined(IMAGE_BL31)
+const mmap_region_t plat_arm_secure_partition_mmap[] = {
+ PLAT_ARM_SECURE_MAP_DEVICE,
+ ARM_SP_IMAGE_MMAP,
+ ARM_SP_IMAGE_NS_BUF_MMAP,
+ ARM_SP_CPER_BUF_MMAP,
+ ARM_SP_IMAGE_RW_MMAP,
+ ARM_SPM_BUF_EL0_MMAP,
+ {0}
+};
+#endif /* SPM_MM && defined(IMAGE_BL31) */
+#endif
+
+ARM_CASSERT_MMAP
+
+#if SPM_MM && defined(IMAGE_BL31)
+/*
+ * Boot information passed to a secure partition during initialisation. Linear
+ * indices in MP information will be filled at runtime.
+ */
+static spm_mm_mp_info_t sp_mp_info[] = {
+ [0] = {0x81000000, 0},
+ [1] = {0x81000100, 0},
+ [2] = {0x81000200, 0},
+ [3] = {0x81000300, 0},
+ [4] = {0x81010000, 0},
+ [5] = {0x81010100, 0},
+ [6] = {0x81010200, 0},
+ [7] = {0x81010300, 0},
+};
+
+const spm_mm_boot_info_t plat_arm_secure_partition_boot_info = {
+ .h.type = PARAM_SP_IMAGE_BOOT_INFO,
+ .h.version = VERSION_1,
+ .h.size = sizeof(spm_mm_boot_info_t),
+ .h.attr = 0,
+ .sp_mem_base = ARM_SP_IMAGE_BASE,
+ .sp_mem_limit = ARM_SP_IMAGE_LIMIT,
+ .sp_image_base = ARM_SP_IMAGE_BASE,
+ .sp_stack_base = PLAT_SP_IMAGE_STACK_BASE,
+ .sp_heap_base = ARM_SP_IMAGE_HEAP_BASE,
+ .sp_ns_comm_buf_base = PLAT_SP_IMAGE_NS_BUF_BASE,
+ .sp_shared_buf_base = PLAT_SPM_BUF_BASE,
+ .sp_image_size = ARM_SP_IMAGE_SIZE,
+ .sp_pcpu_stack_size = PLAT_SP_IMAGE_STACK_PCPU_SIZE,
+ .sp_heap_size = ARM_SP_IMAGE_HEAP_SIZE,
+ .sp_ns_comm_buf_size = PLAT_SP_IMAGE_NS_BUF_SIZE,
+ .sp_shared_buf_size = PLAT_SPM_BUF_SIZE,
+ .num_sp_mem_regions = ARM_SP_IMAGE_NUM_MEM_REGIONS,
+ .num_cpus = PLATFORM_CORE_COUNT,
+ .mp_info = &sp_mp_info[0],
+};
+
+const struct mmap_region *plat_get_secure_partition_mmap(void *cookie)
+{
+ return plat_arm_secure_partition_mmap;
+}
+
+const struct spm_mm_boot_info *plat_get_secure_partition_boot_info(
+ void *cookie)
+{
+ return &plat_arm_secure_partition_boot_info;
+}
+#endif /* SPM_MM && defined(IMAGE_BL31) */
+
+#if TRUSTED_BOARD_BOOT || MEASURED_BOOT
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+ assert(heap_addr != NULL);
+ assert(heap_size != NULL);
+
+ return arm_get_mbedtls_heap(heap_addr, heap_size);
+}
+#endif
+
+void plat_arm_secure_wdt_start(void)
+{
+ sbsa_wdog_start(SBSA_SECURE_WDOG_CONTROL_BASE, SBSA_SECURE_WDOG_TIMEOUT);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+ sbsa_wdog_stop(SBSA_SECURE_WDOG_CONTROL_BASE);
+}
+
+void plat_arm_secure_wdt_refresh(void)
+{
+ sbsa_wdog_refresh(SBSA_SECURE_WDOG_REFRESH_BASE);
+}
diff --git a/plat/arm/board/tc/tc_security.c b/plat/arm/board/tc/tc_security.c
new file mode 100644
index 0000000..6a34501
--- /dev/null
+++ b/plat/arm/board/tc/tc_security.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+static const arm_tzc_regions_info_t tzc_regions[] = {
+ TC_TZC_REGIONS_DEF,
+ {}
+};
+
+/* Initialize the secure environment */
+void plat_arm_security_setup(void)
+{
+ unsigned int i;
+
+ for (i = 0U; i < TZC400_COUNT; i++) {
+ arm_tzc400_setup(TZC400_BASE(i), tzc_regions);
+ }
+}
diff --git a/plat/arm/board/tc/tc_topology.c b/plat/arm/board/tc/tc_topology.c
new file mode 100644
index 0000000..9e18da6
--- /dev/null
+++ b/plat/arm/board/tc/tc_topology.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+
+/******************************************************************************
+ * The power domain tree descriptor.
+ ******************************************************************************/
+const unsigned char tc_pd_tree_desc[] = {
+ PLAT_ARM_CLUSTER_COUNT,
+ PLAT_MAX_CPUS_PER_CLUSTER,
+};
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return tc_pd_tree_desc;
+}
+
+/*******************************************************************************
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ ******************************************************************************/
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
+};
+
+/*******************************************************************************
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ ******************************************************************************/
+unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
+{
+ return PLAT_MAX_CPUS_PER_CLUSTER;
+}
+
+#if ARM_PLAT_MT
+/******************************************************************************
+ * Return the number of PE's supported by the CPU.
+ *****************************************************************************/
+unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr)
+{
+ return PLAT_MAX_PE_PER_CPU;
+}
+#endif
diff --git a/plat/arm/board/tc/tc_trusted_boot.c b/plat/arm/board/tc/tc_trusted_boot.c
new file mode 100644
index 0000000..614f7e2
--- /dev/null
+++ b/plat/arm/board/tc/tc_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
+}