aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile26
-rw-r--r--el3_payload/plat/tc0/platform.S49
-rw-r--r--el3_payload/plat/tc0/platform.h19
-rw-r--r--el3_payload/plat/tc0/platform.mk8
-rw-r--r--plat/arm/fvp/platform.mk2
-rw-r--r--plat/arm/tc0/aarch64/plat_helpers.S90
-rw-r--r--plat/arm/tc0/include/platform_def.h140
-rw-r--r--plat/arm/tc0/plat_setup.c28
-rw-r--r--plat/arm/tc0/platform.mk42
-rw-r--r--plat/arm/tc0/tc0_mem_prot.c20
-rw-r--r--plat/arm/tc0/tc0_pwr_state.c44
-rw-r--r--plat/arm/tc0/tc0_topology.c52
-rw-r--r--plat/arm/tc0/tests_to_skip.txt12
-rw-r--r--spm/cactus/cactus.mk32
-rw-r--r--spm/cactus/cactus_def.h2
-rw-r--r--spm/cactus/cactus_ffa_tests.c22
-rw-r--r--spm/cactus/cactus_main.c12
-rw-r--r--spm/cactus/plat/arm/fvp/fdts/cactus-secondary.dts (renamed from spm/cactus/cactus-secondary.dts)0
-rw-r--r--spm/cactus/plat/arm/fvp/fdts/cactus-tertiary.dts (renamed from spm/cactus/cactus-tertiary.dts)0
-rw-r--r--spm/cactus/plat/arm/fvp/fdts/cactus.dts (renamed from spm/cactus/cactus.dts)0
-rw-r--r--spm/cactus/plat/arm/fvp/include/cactus_platform_def.h24
-rw-r--r--spm/cactus/plat/arm/fvp/platform.mk17
-rw-r--r--spm/cactus/plat/arm/tc0/fdts/cactus-secondary.dts57
-rw-r--r--spm/cactus/plat/arm/tc0/fdts/cactus-tertiary.dts61
-rw-r--r--spm/cactus/plat/arm/tc0/fdts/cactus.dts57
-rw-r--r--spm/cactus/plat/arm/tc0/include/cactus_platform_def.h24
-rw-r--r--spm/cactus/plat/arm/tc0/platform.mk17
-rwxr-xr-xtools/generate_json/generate_json.sh13
28 files changed, 842 insertions, 28 deletions
diff --git a/Makefile b/Makefile
index f809e211..bccd45a8 100644
--- a/Makefile
+++ b/Makefile
@@ -107,10 +107,18 @@ include tftf/framework/framework.mk
include tftf/tests/tests.mk
include fwu/ns_bl1u/ns_bl1u.mk
include fwu/ns_bl2u/ns_bl2u.mk
+
+# Only platform fvp supports cactus_mm, ivy, quark
+ifeq (${ARCH}-${PLAT},aarch64-fvp)
include spm/cactus_mm/cactus_mm.mk
-include spm/cactus/cactus.mk
include spm/ivy/ivy.mk
include spm/quark/quark.mk
+endif
+
+# cactus is supported on platforms: fvp, tc0
+ifeq (${ARCH}-${PLAT},$(filter ${ARCH}-${PLAT},aarch64-fvp aarch64-tc0))
+include spm/cactus/cactus.mk
+endif
################################################################################
# Include libc
@@ -345,11 +353,6 @@ cactus_mm:
@echo "ERROR: $@ is supported only on AArch64 FVP."
@exit 1
-.PHONY: cactus
-cactus:
- @echo "ERROR: $@ is supported only on AArch64 FVP."
- @exit 1
-
.PHONY: ivy
ivy:
@echo "ERROR: $@ is supported only on AArch64 FVP."
@@ -361,6 +364,13 @@ quark:
@exit 1
endif
+ifneq (${ARCH}-${PLAT},$(filter ${ARCH}-${PLAT},aarch64-fvp aarch64-tc0))
+.PHONY: cactus
+cactus:
+ @echo "ERROR: $@ is supported only on AArch64 FVP or TC0."
+ @exit 1
+endif
+
MAKE_DEP = -Wp,-MD,$(DEP) -MT $$@
define MAKE_C
@@ -498,6 +508,10 @@ ifeq (${ARCH}-${PLAT},aarch64-fvp)
$(eval $(call MAKE_IMG,quark))
endif
+ifeq (${ARCH}-${PLAT},aarch64-tc0)
+ $(eval $(call MAKE_IMG,cactus))
+endif
+
# The EL3 test payload is only supported in AArch64. It has an independent build
# system.
.PHONY: el3_payload
diff --git a/el3_payload/plat/tc0/platform.S b/el3_payload/plat/tc0/platform.S
new file mode 100644
index 00000000..1fac2c4b
--- /dev/null
+++ b/el3_payload/plat/tc0/platform.S
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "arch.h"
+#include "asm_macros.S"
+#include "platform.h"
+
+ .globl platform_get_core_pos
+
+/*----------------------------------------------------------------------
+ * unsigned int platform_get_core_pos(unsigned long mpid)
+ *
+ * Function to calculate the core position on TC0 platforms.
+ *
+ * (ClusterId * TC0_MAX_CPUS_PER_CLUSTER * TC0_MAX_PE_PER_CPU) +
+ * (CPUId * TC0_MAX_PE_PER_CPU) +
+ * ThreadId
+ *
+ * which can be simplified as:
+ *
+ * ((ClusterId * TC0_MAX_CPUS_PER_CLUSTER + CPUId) * TC0_MAX_PE_PER_CPU)
+ * + ThreadId
+ *
+ * ---------------------------------------------------------------------
+ */
+func platform_get_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 x3, #TC0_MAX_CPUS_PER_CLUSTER
+ madd x1, x2, x3, x1
+ mov x3, #TC0_MAX_PE_PER_CPU
+ madd x0, x1, x3, x0
+ ret
+endfunc platform_get_core_pos
diff --git a/el3_payload/plat/tc0/platform.h b/el3_payload/plat/tc0/platform.h
new file mode 100644
index 00000000..b1919b5b
--- /dev/null
+++ b/el3_payload/plat/tc0/platform.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_H
+#define PLATFORM_H
+
+#define PRIMARY_CPU_MPID 0x0
+
+#define CPUS_COUNT 4
+
+#define UART_BASE 0x7ff80000
+
+#define TC0_MAX_CPUS_PER_CLUSTER 4
+#define TC0_MAX_PE_PER_CPU 1
+
+#endif /* PLATFORM_H */
diff --git a/el3_payload/plat/tc0/platform.mk b/el3_payload/plat/tc0/platform.mk
new file mode 100644
index 00000000..8ff1cda1
--- /dev/null
+++ b/el3_payload/plat/tc0/platform.mk
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+DRAM_BASE := 0x80000000
+DRAM_SIZE := 0x80000000
diff --git a/plat/arm/fvp/platform.mk b/plat/arm/fvp/platform.mk
index 3c4311ff..42779c72 100644
--- a/plat/arm/fvp/platform.mk
+++ b/plat/arm/fvp/platform.mk
@@ -68,7 +68,7 @@ $(eval $(call add_define,NS_BL2U_DEFINES,FVP_CLUSTER_COUNT))
$(eval $(call add_define,NS_BL2U_DEFINES,FVP_MAX_CPUS_PER_CLUSTER))
$(eval $(call add_define,NS_BL2U_DEFINES,FVP_MAX_PE_PER_CPU))
-PLAT_INCLUDES := -Iplat/arm/fvp/include/
+PLAT_INCLUDES += -Iplat/arm/fvp/include/
PLAT_SOURCES := drivers/arm/gic/arm_gic_v2v3.c \
drivers/arm/gic/gic_v2.c \
diff --git a/plat/arm/tc0/aarch64/plat_helpers.S b/plat/arm/tc0/aarch64/plat_helpers.S
new file mode 100644
index 00000000..863b378e
--- /dev/null
+++ b/plat/arm/tc0/aarch64/plat_helpers.S
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <drivers/arm/pl011.h>
+#include <platform_def.h>
+
+ .globl platform_get_core_pos
+ .globl plat_crash_console_init
+ .globl plat_crash_console_putc
+ .globl plat_crash_console_flush
+
+/*----------------------------------------------------------------------
+ * unsigned int platform_get_core_pos(unsigned long mpid)
+ *
+ * Function to calculate the core position on TC0 platforms.
+ *
+ * (ClusterId * TC0_MAX_CPUS_PER_CLUSTER * TC0_MAX_PE_PER_CPU) +
+ * (CPUId * TC0_MAX_PE_PER_CPU) +
+ * ThreadId
+ *
+ * which can be simplified as:
+ *
+ * ((ClusterId * TC0_MAX_CPUS_PER_CLUSTER + CPUId) * TC0_MAX_PE_PER_CPU)
+ * + ThreadId
+ * ---------------------------------------------------------------------
+ */
+func platform_get_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 x3, #TC0_MAX_CPUS_PER_CLUSTER
+ madd x1, x2, x3, x1
+ mov x3, #TC0_MAX_PE_PER_CPU
+ madd x0, x1, x3, x0
+ ret
+endfunc platform_get_core_pos
+
+/* ---------------------------------------------
+ * int plat_crash_console_init(void)
+ * Function to initialize the crash console
+ * without a C Runtime to print crash report.
+ * Clobber list : x0 - x4
+ * ---------------------------------------------
+ */
+func plat_crash_console_init
+ mov_imm x0, PLAT_ARM_UART_BASE
+ mov_imm x1, PLAT_ARM_UART_CLK_IN_HZ
+ mov_imm x2, PL011_BAUDRATE
+ b console_core_init
+endfunc plat_crash_console_init
+
+/* ---------------------------------------------
+ * int plat_crash_console_putc(int c)
+ * Function to print a character on the crash
+ * console without a C Runtime.
+ * Clobber list : x1, x2
+ * ---------------------------------------------
+ */
+func plat_crash_console_putc
+ mov_imm x1, PLAT_ARM_UART_BASE
+ b console_core_putc
+endfunc plat_crash_console_putc
+
+/* ---------------------------------------------
+ * int plat_crash_console_flush()
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * Out : return -1 on error else return 0.
+ * Clobber list : x0 - x1
+ * ---------------------------------------------
+ */
+func plat_crash_console_flush
+ mov_imm x1, PLAT_ARM_UART_BASE
+ b console_core_flush
+endfunc plat_crash_console_flush
diff --git a/plat/arm/tc0/include/platform_def.h b/plat/arm/tc0/include/platform_def.h
new file mode 100644
index 00000000..fbfc2309
--- /dev/null
+++ b/plat/arm/tc0/include/platform_def.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <arch.h>
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+/* Platform binary types for linking */
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH aarch64
+
+#define TC0_CLUSTER_COUNT 1
+#define TC0_MAX_CPUS_PER_CLUSTER 4
+#define TC0_MAX_PE_PER_CPU 1
+
+/*******************************************************************************
+ * Run-time address of the TFTF image.
+ * It has to match the location where the Trusted Firmware-A loads the BL33
+ * image.
+ ******************************************************************************/
+#define TFTF_BASE 0xE0000000
+
+#define TC0_DRAM1_BASE 0x80000000
+#define TC0_DRAM1_SIZE 0x80000000
+#define DRAM_BASE TC0_DRAM1_BASE
+
+/*
+ * TF-A reserves DRAM space 0xFD000000 - 0xFEFFFFFF for Trusted DRAM
+ * TF-A reserves DRAM space 0xFF000000 - 0xFFFFFFFF for TZC
+ */
+#define ARM_TZC_DRAM1_SIZE 0x01000000
+#define ARM_TRUSTED_DRAM1_SIZE 0x02000000
+
+#define DRAM_SIZE (TC0_DRAM1_SIZE - \
+ ARM_TRUSTED_DRAM1_SIZE - \
+ ARM_TZC_DRAM1_SIZE)
+
+/* REFCLK CNTControl, Generic Timer. Secure Access only. */
+#define SYS_CNT_CONTROL_BASE 0x2a430000
+/* REFCLK CNTRead, Generic Timer. */
+#define SYS_CNT_READ_BASE 0x2a800000
+/* AP_REFCLK CNTBase1, Generic Timer. */
+#define SYS_CNT_BASE1 0x2A830000
+
+/* Base address of non-trusted watchdog (SP805) */
+#define SP805_WDOG_BASE 0x1C0F0000
+
+/* Base address and size of external NVM flash */
+#define FLASH_BASE 0x08000000
+
+#define NOR_FLASH_BLOCK_SIZE 0x40000 /* 256KB */
+#define FLASH_SIZE 0x4000000 /* 64MB */
+
+/*
+ * If you want to use DRAM for non-volatile memory then the first 128MB
+ * can be used. However for tests that involve power resets this is not
+ * suitable since the state will be lost.
+ */
+#define TFTF_NVM_OFFSET 0x0
+#define TFTF_NVM_SIZE 0x8000000 /* 128 MB */
+
+/* Sub-system Peripherals */
+#define TC0_DEVICE0_BASE 0x21000000
+#define TC0_DEVICE0_SIZE 0x5f000000
+
+/* Following covers Peripherals and PCIe expansion area */
+#define TC0_DEVICE1_BASE 0x60000000
+#define TC0_DEVICE1_SIZE 0x20000000
+
+/* GIC-600 & interrupt handling related constants */
+#define TC0_GICD_BASE 0x30000000
+#define TC0_GICR_BASE 0x30140000
+#define TC0_GICC_BASE 0x2C000000
+
+/* SoC's PL011 UART0 related constants */
+#define PL011_UART0_BASE 0x7FF70000
+#define PL011_UART0_CLK_IN_HZ 7372800
+
+/* SoC's PL011 UART1 related constants */
+#define PL011_UART1_BASE 0x7FF80000
+#define PL011_UART1_CLK_IN_HZ 7372800
+
+#define PLAT_ARM_UART_BASE PL011_UART0_BASE
+#define PLAT_ARM_UART_CLK_IN_HZ PL011_UART0_CLK_IN_HZ
+
+/* Size of cacheable stacks */
+#define PLATFORM_STACK_SIZE 0x1400
+
+/* Size of coherent stacks */
+#define PCPU_DV_MEM_STACK_SIZE 0x600
+
+#define PLATFORM_CORE_COUNT (TC0_CLUSTER_COUNT * TC0_MAX_CPUS_PER_CLUSTER)
+#define PLATFORM_NUM_AFFS (TC0_CLUSTER_COUNT + PLATFORM_CORE_COUNT)
+#define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL1
+
+#define PLAT_MAX_PWR_LEVEL PLATFORM_MAX_AFFLVL
+#define PLAT_MAX_PWR_STATES_PER_LVL 2
+
+/* I/O Storage NOR flash device */
+#define MAX_IO_DEVICES 1
+#define MAX_IO_HANDLES 1
+
+/* Local state bit width for each level in the state-ID field of power state */
+#define PLAT_LOCAL_PSTATE_WIDTH 4
+
+/* Platform specific page table and MMU setup constants */
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 36)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 36)
+#define MAX_XLAT_TABLES 5
+#define MAX_MMAP_REGIONS 16
+
+/*******************************************************************************
+ * Used to align variables on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ ******************************************************************************/
+#define CACHE_WRITEBACK_SHIFT 6
+#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
+
+/* Non-Secure Software Generated Interupts IDs */
+#define IRQ_NS_SGI_0 0
+#define IRQ_NS_SGI_7 7
+
+/* AP UART1 interrupt is considered as the maximum SPI */
+#define PLAT_MAX_SPI_OFFSET_ID 64
+
+/* AP_REFCLK Generic Timer, Non-secure. */
+#define IRQ_CNTPSIRQ1 92
+
+/* Per-CPU Hypervisor Timer Interrupt ID */
+#define IRQ_PCPU_HP_TIMER 26
+
+/* Times(in ms) used by test code for completion of different events */
+#define PLAT_SUSPEND_ENTRY_TIME 15
+#define PLAT_SUSPEND_ENTRY_EXIT_TIME 30
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/tc0/plat_setup.c b/plat/arm/tc0/plat_setup.c
new file mode 100644
index 00000000..0294c910
--- /dev/null
+++ b/plat/arm/tc0/plat_setup.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/arm/arm_gic.h>
+#include <xlat_tables_v2.h>
+
+static const mmap_region_t mmap[] = {
+ MAP_REGION_FLAT(TC0_DEVICE0_BASE, TC0_DEVICE0_SIZE,
+ MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(TC0_DEVICE1_BASE, TC0_DEVICE1_SIZE,
+ MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(DRAM_BASE, TFTF_BASE - DRAM_BASE,
+ MT_MEMORY | MT_RW | MT_NS),
+ {0}
+};
+
+const mmap_region_t *tftf_platform_get_mmap(void)
+{
+ return mmap;
+}
+
+void plat_arm_gic_init(void)
+{
+ arm_gic_init(TC0_GICC_BASE, TC0_GICD_BASE, TC0_GICR_BASE);
+}
diff --git a/plat/arm/tc0/platform.mk b/plat/arm/tc0/platform.mk
new file mode 100644
index 00000000..faf0d195
--- /dev/null
+++ b/plat/arm/tc0/platform.mk
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Default number of threads per CPU on FVP
+TC0_MAX_PE_PER_CPU := 1
+
+# Check the PE per core count
+ifneq ($(TC0_MAX_PE_PER_CPU),$(filter $(TC0_MAX_PE_PER_CPU),1 2))
+$(error "Incorrect TC0_MAX_PE_PER_CPU specified for TC0 port")
+endif
+
+# Pass FVP_MAX_PE_PER_CPU to the build system
+$(eval $(call add_define,TFTF_DEFINES,TC0_MAX_PE_PER_CPU))
+$(eval $(call add_define,NS_BL1U_DEFINES,TC0_MAX_PE_PER_CPU))
+$(eval $(call add_define,NS_BL2U_DEFINES,TC0_MAX_PE_PER_CPU))
+
+PLAT_INCLUDES += -Iplat/arm/tc0/include/
+
+PLAT_SOURCES := drivers/arm/gic/arm_gic_v2v3.c \
+ drivers/arm/gic/gic_v2.c \
+ drivers/arm/gic/gic_v3.c \
+ drivers/arm/sp805/sp805.c \
+ drivers/arm/timer/private_timer.c \
+ drivers/arm/timer/system_timer.c \
+ plat/arm/tc0/${ARCH}/plat_helpers.S \
+ plat/arm/tc0/plat_setup.c \
+ plat/arm/tc0/tc0_mem_prot.c \
+ plat/arm/tc0/tc0_pwr_state.c \
+ plat/arm/tc0/tc0_topology.c
+
+CACTUS_SOURCES += plat/arm/tc0/${ARCH}/plat_helpers.S
+
+PLAT_TESTS_SKIP_LIST := plat/arm/tc0/tests_to_skip.txt
+
+ifeq (${USE_NVM},1)
+$(error "USE_NVM is not supported on TC0 platforms")
+endif
+
+include plat/arm/common/arm_common.mk
diff --git a/plat/arm/tc0/tc0_mem_prot.c b/plat/arm/tc0/tc0_mem_prot.c
new file mode 100644
index 00000000..06a333ec
--- /dev/null
+++ b/plat/arm/tc0/tc0_mem_prot.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform.h>
+
+#define TC0_DRAM1_NS_START (TFTF_BASE + 0x4000000)
+#define TC0_DRAM1_NS_SIZE 0x10000000
+
+static const mem_region_t tc0_ram_ranges[] = {
+ { TC0_DRAM1_NS_START, TC0_DRAM1_NS_SIZE }
+};
+
+const mem_region_t *plat_get_prot_regions(int *nelem)
+{
+ *nelem = ARRAY_SIZE(tc0_ram_ranges);
+ return tc0_ram_ranges;
+}
diff --git a/plat/arm/tc0/tc0_pwr_state.c b/plat/arm/tc0/tc0_pwr_state.c
new file mode 100644
index 00000000..17d3b39e
--- /dev/null
+++ b/plat/arm/tc0/tc0_pwr_state.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform.h>
+#include <psci.h>
+
+/* State IDs for local power states on SGI platforms. */
+#define TC0_PS_RUN_STATE_ID 0 /* Valid for CPUs and Clusters */
+#define TC0_PS_RETENTION_STATE_ID 1 /* Valid for only CPUs */
+#define TC0_PS_OFF_STATE_ID 2 /* Valid for CPUs and Clusters */
+
+/* Suspend depth definitions for each power state */
+#define TC0_PS_RUN_DEPTH 0
+#define TC0_PS_RETENTION_DEPTH 1
+#define TC0_PS_OFF_DEPTH 2
+
+/* The state property array with details of idle state possible for the core */
+static const plat_state_prop_t core_state_prop[] = {
+ {TC0_PS_RETENTION_DEPTH, TC0_PS_RETENTION_STATE_ID,
+ PSTATE_TYPE_STANDBY},
+ {TC0_PS_OFF_DEPTH, TC0_PS_OFF_STATE_ID, PSTATE_TYPE_POWERDOWN},
+ {0}
+};
+
+/* The state property array with details of idle state possible for the cluster */
+static const plat_state_prop_t cluster_state_prop[] = {
+ {TC0_PS_OFF_DEPTH, TC0_PS_OFF_STATE_ID, PSTATE_TYPE_POWERDOWN},
+ {0}
+};
+
+const plat_state_prop_t *plat_get_state_prop(unsigned int level)
+{
+ switch (level) {
+ case MPIDR_AFFLVL0:
+ return core_state_prop;
+ case MPIDR_AFFLVL1:
+ return cluster_state_prop;
+ default:
+ return NULL;
+ }
+}
diff --git a/plat/arm/tc0/tc0_topology.c b/plat/arm/tc0/tc0_topology.c
new file mode 100644
index 00000000..feb8727b
--- /dev/null
+++ b/plat/arm/tc0/tc0_topology.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <plat_topology.h>
+#include <tftf_lib.h>
+
+static const struct {
+ unsigned int cluster_id;
+ unsigned int cpu_id;
+} tc0_cores[] = {
+ /* Cluster0: 4 cores*/
+ { 0, 0 },
+ { 0, 1 },
+ { 0, 2 },
+ { 0, 3 }
+};
+
+/*
+ * The power domain tree descriptor. The cluster power domains are
+ * arranged so that when the PSCI generic code creates the power domain tree,
+ * the indices of the CPU power domain nodes it allocates match the linear
+ * indices returned by plat_core_pos_by_mpidr().
+ */
+const unsigned char tc0_pd_tree_desc[] = {
+ /* Number of root nodes */
+ TC0_CLUSTER_COUNT,
+ /* Number of children for the 1st node */
+ TC0_MAX_CPUS_PER_CLUSTER,
+ /* Number of children for the 2nd node */
+ TC0_MAX_CPUS_PER_CLUSTER
+};
+
+const unsigned char *tftf_plat_get_pwr_domain_tree_desc(void)
+{
+ return tc0_pd_tree_desc;
+}
+
+uint64_t tftf_plat_get_mpidr(unsigned int core_pos)
+{
+ uint64_t mpid;
+
+ assert(core_pos < PLATFORM_CORE_COUNT);
+
+ mpid = (uint64_t)make_mpid(tc0_cores[core_pos].cluster_id,
+ tc0_cores[core_pos].cpu_id);
+
+ return mpid;
+}
diff --git a/plat/arm/tc0/tests_to_skip.txt b/plat/arm/tc0/tests_to_skip.txt
new file mode 100644
index 00000000..f039eeda
--- /dev/null
+++ b/plat/arm/tc0/tests_to_skip.txt
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# System suspend is not supported as there are no wakeup sources in tc0 FVP
+
+# PSCI is enabled but not tested
+PSCI STAT/Stats test cases after system suspend
+PSCI System Suspend Validation
+PSCI NODE_HW_STATE
diff --git a/spm/cactus/cactus.mk b/spm/cactus/cactus.mk
index e6577c3c..779fd38a 100644
--- a/spm/cactus/cactus.mk
+++ b/spm/cactus/cactus.mk
@@ -7,6 +7,12 @@
include branch_protection.mk
include lib/xlat_tables_v2/xlat_tables.mk
+# Include cactus platform make file
+CACTUS_PLAT_PATH := $(shell find spm/cactus/plat -wholename '*/${PLAT}')
+ifneq (${CACTUS_PLAT_PATH},)
+ include ${CACTUS_PLAT_PATH}/platform.mk
+endif
+
CACTUS_DTB := $(BUILD_PLAT)/cactus.dtb
CACTUS_INCLUDES := \
@@ -69,16 +75,32 @@ $(eval $(call add_define,CACTUS_DEFINES,FVP_MAX_PE_PER_CPU))
$(eval $(call add_define,CACTUS_DEFINES,LOG_LEVEL))
$(eval $(call add_define,CACTUS_DEFINES,PLAT_${PLAT}))
-
$(CACTUS_DTB) : $(BUILD_PLAT)/cactus $(BUILD_PLAT)/cactus/cactus.elf
-$(CACTUS_DTB) : spm/cactus/cactus.dts
- @echo " DTBGEN spm/cactus/cactus.dts"
+$(CACTUS_DTB) : $(CACTUS_DTS)
+ @echo " DTBGEN $@"
${Q}tools/generate_dtb/generate_dtb.sh \
- cactus spm/cactus/cactus.dts $(BUILD_PLAT)
+ cactus ${CACTUS_DTS} $(BUILD_PLAT)
${Q}tools/generate_json/generate_json.sh \
- cactus $(PLAT) $(BUILD_TYPE)
+ cactus $(BUILD_PLAT)
@echo
@echo "Built $@ successfully"
@echo
cactus: $(CACTUS_DTB)
+
+# FDTS_CP copies flattened device tree sources
+# $(1) = output directory
+# $(2) = flattened device tree source file to copy
+define FDTS_CP
+ $(eval FDTS := $(addprefix $(1)/,$(notdir $(2))))
+FDTS_LIST += $(FDTS)
+$(FDTS): $(2) $(CACTUS_DTB)
+ @echo " CP $$<"
+ ${Q}cp $$< $$@
+endef
+
+ifdef FDTS_CP_LIST
+ $(eval files := $(filter %.dts,$(FDTS_CP_LIST)))
+ $(eval $(foreach file,$(files),$(call FDTS_CP,$(BUILD_PLAT),$(file))))
+cactus: $(FDTS_LIST)
+endif
diff --git a/spm/cactus/cactus_def.h b/spm/cactus/cactus_def.h
index be6f06ae..83be35f7 100644
--- a/spm/cactus/cactus_def.h
+++ b/spm/cactus/cactus_def.h
@@ -24,7 +24,7 @@
* RX/TX buffer used by VM's in SPM for memory sharing
* Each VM allocated 2 pages, one for RX and one for TX buffer.
*/
-#define CACTUS_RX_BASE ULL(0x7300000)
+#define CACTUS_RX_BASE PLAT_CACTUS_RX_BASE
#define CACTUS_TX_BASE CACTUS_RX_BASE + PAGE_SIZE
#define CACTUS_RX_TX_SIZE PAGE_SIZE * 2
diff --git a/spm/cactus/cactus_ffa_tests.c b/spm/cactus/cactus_ffa_tests.c
index a242e41a..81970f76 100644
--- a/spm/cactus/cactus_ffa_tests.c
+++ b/spm/cactus/cactus_ffa_tests.c
@@ -6,6 +6,7 @@
#include <assert.h>
#include <debug.h>
#include <errno.h>
+#include <cactus_platform_def.h>
#include <cactus_def.h>
#include <ffa_helpers.h>
#include <sp_helpers.h>
@@ -121,9 +122,24 @@ static void ffa_partition_info_get_test(struct mailbox_buffers *mb)
const char *test_all = "Get all partitions info";
const struct ffa_partition_info expected_info[] = {
- {.id = SPM_VM_ID_FIRST, .exec_context = 8U, .properties = 0U}, /* Primary partition info */
- {.id = SPM_VM_ID_FIRST + 1U, .exec_context = 8U, .properties = 0U}, /* Secondary partition info */
- {.id = SPM_VM_ID_FIRST + 2U, .exec_context = 8U, .properties = 0U} /* Tertiary partition info */
+ /* Primary partition info */
+ {
+ .id = SPM_VM_ID_FIRST,
+ .exec_context = CACTUS_PRIMARY_EC_COUNT,
+ .properties = 0U
+ },
+ /* Secondary partition info */
+ {
+ .id = SPM_VM_ID_FIRST + 1U,
+ .exec_context = CACTUS_SECONDARY_EC_COUNT,
+ .properties = 0U
+ },
+ /* Tertiary partition info */
+ {
+ .id = SPM_VM_ID_FIRST + 2U,
+ .exec_context = CACTUS_TERTIARY_EC_COUNT,
+ .properties = 0U
+ }
};
announce_test_section_start(test_partition_info);
diff --git a/spm/cactus/cactus_main.c b/spm/cactus/cactus_main.c
index 08097163..acbe2af6 100644
--- a/spm/cactus/cactus_main.c
+++ b/spm/cactus/cactus_main.c
@@ -9,6 +9,7 @@
#include "cactus.h"
#include "cactus_def.h"
+#include <cactus_platform_def.h>
#include "cactus_tests.h"
#include <debug.h>
#include <drivers/arm/pl011.h>
@@ -84,8 +85,9 @@ static void __dead2 message_loop(ffa_vm_id_t vm_id)
}
static const mmap_region_t cactus_mmap[] __attribute__((used)) = {
- /* DEVICE0 area includes UART2 necessary to console */
- MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW),
+ /* PLAT_ARM_DEVICE0 area includes UART2 necessary to console */
+ MAP_REGION_FLAT(PLAT_ARM_DEVICE0_BASE, PLAT_ARM_DEVICE0_SIZE,
+ MT_DEVICE | MT_RW),
{0}
};
@@ -179,9 +181,9 @@ void __dead2 cactus_main(void)
enable_mmu_el1(0);
if (ffa_id == SPM_VM_ID_FIRST) {
- console_init(PL011_UART2_BASE,
- PL011_UART2_CLK_IN_HZ,
- PL011_BAUDRATE);
+ console_init(CACTUS_PL011_UART_BASE,
+ CACTUS_PL011_UART_CLK_IN_HZ,
+ PL011_BAUDRATE);
set_putc_impl(PL011_AS_STDOUT);
diff --git a/spm/cactus/cactus-secondary.dts b/spm/cactus/plat/arm/fvp/fdts/cactus-secondary.dts
index 661684bd..661684bd 100644
--- a/spm/cactus/cactus-secondary.dts
+++ b/spm/cactus/plat/arm/fvp/fdts/cactus-secondary.dts
diff --git a/spm/cactus/cactus-tertiary.dts b/spm/cactus/plat/arm/fvp/fdts/cactus-tertiary.dts
index ea7d5d6f..ea7d5d6f 100644
--- a/spm/cactus/cactus-tertiary.dts
+++ b/spm/cactus/plat/arm/fvp/fdts/cactus-tertiary.dts
diff --git a/spm/cactus/cactus.dts b/spm/cactus/plat/arm/fvp/fdts/cactus.dts
index e64d3a8e..e64d3a8e 100644
--- a/spm/cactus/cactus.dts
+++ b/spm/cactus/plat/arm/fvp/fdts/cactus.dts
diff --git a/spm/cactus/plat/arm/fvp/include/cactus_platform_def.h b/spm/cactus/plat/arm/fvp/include/cactus_platform_def.h
new file mode 100644
index 00000000..e8790027
--- /dev/null
+++ b/spm/cactus/plat/arm/fvp/include/cactus_platform_def.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#ifndef CACTUS_PLATFORM_DEF_H
+#define CACTUS_PLATFORM_DEF_H
+
+#define PLAT_ARM_DEVICE0_BASE DEVICE0_BASE
+#define PLAT_ARM_DEVICE0_SIZE DEVICE0_SIZE
+
+#define CACTUS_PL011_UART_BASE PL011_UART2_BASE
+#define CACTUS_PL011_UART_CLK_IN_HZ PL011_UART2_CLK_IN_HZ
+
+#define PLAT_CACTUS_RX_BASE ULL(0x7300000)
+
+#define CACTUS_PRIMARY_EC_COUNT (8U)
+#define CACTUS_SECONDARY_EC_COUNT (8U)
+#define CACTUS_TERTIARY_EC_COUNT (8U)
+
+#endif /* CACTUS_PLATFORM_DEF_H */
diff --git a/spm/cactus/plat/arm/fvp/platform.mk b/spm/cactus/plat/arm/fvp/platform.mk
new file mode 100644
index 00000000..c7b01bbe
--- /dev/null
+++ b/spm/cactus/plat/arm/fvp/platform.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+FVP_CACTUS_BASE = spm/cactus/plat/arm/fvp
+
+PLAT_INCLUDES += -I${FVP_CACTUS_BASE}/include/
+
+# Add the FDT source
+CACTUS_DTS = ${FVP_CACTUS_BASE}/fdts/cactus.dts
+
+# List of FDTS to copy
+FDTS_CP_LIST = ${FVP_CACTUS_BASE}/fdts/cactus.dts
+FDTS_CP_LIST += ${FVP_CACTUS_BASE}/fdts/cactus-secondary.dts
+FDTS_CP_LIST += ${FVP_CACTUS_BASE}/fdts/cactus-tertiary.dts
diff --git a/spm/cactus/plat/arm/tc0/fdts/cactus-secondary.dts b/spm/cactus/plat/arm/tc0/fdts/cactus-secondary.dts
new file mode 100644
index 00000000..cc7715c3
--- /dev/null
+++ b/spm/cactus/plat/arm/tc0/fdts/cactus-secondary.dts
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is a Partition Manifest (PM) for a minimal Secure Partition (SP)
+ * that has additional optional properties defined.
+ *
+ */
+
+/dts-v1/;
+
+/ {
+ compatible = "arm,ffa-manifest-1.0";
+
+ /* Properties */
+ description = "cactus-2";
+ ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+ uuid = <0xd1582309 0xf02347b9 0x827c4464 0xf5578fc8>;
+ id = <2>;
+ execution-ctx-count = <4>;
+ exception-level = <2>; /* S-EL1 */
+ execution-state = <0>; /* AARCH64 */
+ load-address = <0xfe100000>;
+ entrypoint-offset = <0x00001000>;
+ xlat-granule = <0>; /* 4KiB */
+ boot-order = <0>;
+ messaging-method = <0>; /* Direct messaging only */
+ run-time-model = <1>; /* Run to completion */
+
+ /* Boot protocol */
+ gp-register-num = <0x0>;
+
+ rx_tx-info {
+ compatible = "arm,ffa-manifest-rx_tx-buffer";
+ rx-buffer = <&rxbuffer>;
+ tx-buffer = <&txbuffer>;
+ };
+
+ memory-regions {
+ compatible = "arm,ffa-manifest-memory-regions";
+
+ rxbuffer: rx-buffer {
+ description = "rx-buffer";
+ pages-count = <1>;
+ base-address = <0x00000000 0xfe302000>;
+ attributes = <0x1>; /* read-only */
+ };
+
+ txbuffer: tx-buffer {
+ description = "tx-buffer";
+ pages-count = <1>;
+ base-address = <0x00000000 0xfe303000>;
+ attributes = <0x3>; /* read-write */
+ };
+ };
+};
diff --git a/spm/cactus/plat/arm/tc0/fdts/cactus-tertiary.dts b/spm/cactus/plat/arm/tc0/fdts/cactus-tertiary.dts
new file mode 100644
index 00000000..8567e069
--- /dev/null
+++ b/spm/cactus/plat/arm/tc0/fdts/cactus-tertiary.dts
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is a Partition Manifest (PM) for a minimal Secure Partition (SP)
+ * that has additional optional properties defined.
+ *
+ */
+
+/dts-v1/;
+
+/ {
+ compatible = "arm,ffa-manifest-1.0";
+
+ /* Properties */
+ description = "cactus-3";
+ ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+ uuid = <0x79b55c73 0x1d8c44b9 0x859361e1 0x770ad8d2>;
+ id = <3>;
+ execution-ctx-count = <4>;
+ exception-level = <2>; /* S-EL1 */
+ execution-state = <0>; /* AARCH64 */
+ load-address = <0xfe200000>;
+ entrypoint-offset = <0x00001000>;
+ xlat-granule = <0>; /* 4KiB */
+ boot-order = <0>;
+ messaging-method = <0>; /* Direct messaging only */
+ run-time-model = <1>; /* Run to completion */
+
+ /* Boot protocol */
+ gp-register-num = <0x0>;
+
+ memory-regions {
+ compatible = "arm,ffa-manifest-memory-regions";
+
+ /* Without optional base-address */
+ test-memory {
+ description = "test-memory";
+ pages-count = <4>;
+ attributes = <0x7>; /* read-write-execute */
+ };
+ };
+
+ device-regions {
+ compatible = "arm,ffa-manifest-device-regions";
+
+ test-reg {
+ /* Dummy values */
+ base-address = <0x00000000 0x25000000>;
+ pages-count = <16>;
+ attributes = <0x3>; /* read-write */
+ reg = <0x10000008 0x00000001 1>;
+ smmu-id = <1>;
+ stream-ids = <0x0 0x1>;
+ interrupts = <0x2 0x3>,
+ <0x4 0x5>;
+ };
+ };
+
+};
diff --git a/spm/cactus/plat/arm/tc0/fdts/cactus.dts b/spm/cactus/plat/arm/tc0/fdts/cactus.dts
new file mode 100644
index 00000000..4b279595
--- /dev/null
+++ b/spm/cactus/plat/arm/tc0/fdts/cactus.dts
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is a Partition Manifest (PM) for a minimal Secure Partition (SP)
+ * that has additional optional properties defined.
+ *
+ */
+
+/dts-v1/;
+
+/ {
+ compatible = "arm,ffa-manifest-1.0";
+
+ /* Properties */
+ description = "cactus-1";
+ ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+ uuid = <0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>;
+ id = <1>;
+ execution-ctx-count = <4>;
+ exception-level = <2>; /* S-EL1 */
+ execution-state = <0>; /* AARCH64 */
+ load-address = <0xfe000000>;
+ entrypoint-offset = <0x00001000>;
+ xlat-granule = <0>; /* 4KiB */
+ boot-order = <0>;
+ messaging-method = <0>; /* Direct messaging only */
+ run-time-model = <1>; /* Run to completion */
+
+ /* Boot protocol */
+ gp-register-num = <0x0>;
+
+ rx_tx-info {
+ compatible = "arm,ffa-manifest-rx_tx-buffer";
+ rx-buffer = <&rxbuffer>;
+ tx-buffer = <&txbuffer>;
+ };
+
+ memory-regions {
+ compatible = "arm,ffa-manifest-memory-regions";
+
+ rxbuffer: rx-buffer {
+ description = "rx-buffer";
+ pages-count = <1>;
+ base-address = <0x00000000 0xfe300000>;
+ attributes = <0x1>; /* read-only */
+ };
+
+ txbuffer: tx-buffer {
+ description = "tx-buffer";
+ pages-count = <1>;
+ base-address = <0x00000000 0xfe301000>;
+ attributes = <0x3>; /* read-write */
+ };
+ };
+};
diff --git a/spm/cactus/plat/arm/tc0/include/cactus_platform_def.h b/spm/cactus/plat/arm/tc0/include/cactus_platform_def.h
new file mode 100644
index 00000000..ae4d4e82
--- /dev/null
+++ b/spm/cactus/plat/arm/tc0/include/cactus_platform_def.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#ifndef CACTUS_PLATFORM_DEF_H
+#define CACTUS_PLATFORM_DEF_H
+
+#define PLAT_ARM_DEVICE0_BASE TC0_DEVICE0_BASE
+#define PLAT_ARM_DEVICE0_SIZE TC0_DEVICE0_SIZE
+
+#define CACTUS_PL011_UART_BASE PL011_UART1_BASE
+#define CACTUS_PL011_UART_CLK_IN_HZ PL011_UART1_CLK_IN_HZ
+
+#define PLAT_CACTUS_RX_BASE ULL(0xfe300000)
+
+#define CACTUS_PRIMARY_EC_COUNT (4U)
+#define CACTUS_SECONDARY_EC_COUNT (4U)
+#define CACTUS_TERTIARY_EC_COUNT (4U)
+
+#endif /* CACTUS_PLATFORM_DEF_H */
diff --git a/spm/cactus/plat/arm/tc0/platform.mk b/spm/cactus/plat/arm/tc0/platform.mk
new file mode 100644
index 00000000..3bc245e7
--- /dev/null
+++ b/spm/cactus/plat/arm/tc0/platform.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+TC0_CACTUS_BASE = spm/cactus/plat/arm/tc0
+
+PLAT_INCLUDES += -I${TC0_CACTUS_BASE}/include/
+
+# Add the FDT source
+CACTUS_DTS = ${TC0_CACTUS_BASE}/fdts/cactus.dts
+
+# List of FDTS to copy
+FDTS_CP_LIST = ${TC0_CACTUS_BASE}/fdts/cactus.dts
+FDTS_CP_LIST += ${TC0_CACTUS_BASE}/fdts/cactus-secondary.dts
+FDTS_CP_LIST += ${TC0_CACTUS_BASE}/fdts/cactus-tertiary.dts
diff --git a/tools/generate_json/generate_json.sh b/tools/generate_json/generate_json.sh
index 449733ce..f46cf158 100755
--- a/tools/generate_json/generate_json.sh
+++ b/tools/generate_json/generate_json.sh
@@ -10,11 +10,10 @@
# Secure Partitions as part of FIP.
# $1 = Secure Partition (cactus)
-# $2 = Platform (fvp)
-# $3 = Build Type
-# Output = build/plat/<Build Type>/sp_layout.json
+# $2 = Platform built path
+# Output = $2/sp_layout.json
-GENERATED_JSON=build/$2/$3/sp_layout.json
+GENERATED_JSON=$2/sp_layout.json
# To demonstrate communication between SP's, two cactus S-EL1 instances used.
# To also test mapping of the RXTX region a third cactus S-EL1 instance is used.
@@ -23,13 +22,13 @@ GENERATED_JSON=build/$2/$3/sp_layout.json
if [ "$1" == "cactus" ]; then
echo -e "{\n\t\"$1-primary\" : {\n \
\t\"image\": \"$1.bin\",\n \
- \t\"pm\": \"../../../spm/$1/$1.dts\",\n \
+ \t\"pm\": \"$1.dts\",\n \
\t\"owner\": \"SiP\"\n\t},\n\n\t\"$1-secondary\" : {\n \
\t\"image\": \"$1.bin\",\n \
- \t\"pm\": \"../../../spm/$1/$1-secondary.dts\",\n \
+ \t\"pm\": \"$1-secondary.dts\",\n \
\t\"owner\": \"Plat\"\n\t},\n\n\t\"$1-tertiary\" : {\n \
\t\"image\": \"$1.bin\",\n \
- \t\"pm\": \"../../../spm/$1/$1-tertiary.dts\" \n \
+ \t\"pm\": \"$1-tertiary.dts\" \n \
}\n}" \
> "$GENERATED_JSON"
else