Merge changes Iaf21883b,I523c5d57,I57164923 into integration
* changes:
fix(ufs): read and write attribute based on spec
fix(ufs): disables controller if enabled
refactor(ufs): adds a function for fdeviceinit
diff --git a/.commitlintrc.js b/.commitlintrc.js
index ed971a3..cfafbed 100644
--- a/.commitlintrc.js
+++ b/.commitlintrc.js
@@ -68,7 +68,6 @@
"type-enum": [2, "always", types], /* Error */
"scope-case": [2, "always", "lower-case"], /* Error */
- "scope-empty": [2, "never"], /* Error */
"scope-enum": [1, "always", scopes] /* Warning */
},
};
diff --git a/.gitignore b/.gitignore
index f524658..b005fab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,8 +30,7 @@
tools/stm32image/*.o
tools/stm32image/stm32image
tools/stm32image/stm32image.exe
-tools/sptool/sptool
-tools/sptool/sptool.exe
+tools/sptool/__pycache__/
# GNU GLOBAL files
GPATH
diff --git a/Makefile b/Makefile
index da3e493..16c85bc 100644
--- a/Makefile
+++ b/Makefile
@@ -135,6 +135,10 @@
ifneq (${ENABLE_PIE},0)
$(error ENABLE_RME does not support PIE)
endif
+# RME doesn't support BRBE
+ifneq (${ENABLE_BRBE_FOR_NS},0)
+ $(error ENABLE_RME does not support BRBE.)
+endif
# RME requires AARCH64
ifneq (${ARCH},aarch64)
$(error ENABLE_RME requires AArch64)
@@ -263,24 +267,24 @@
# Determine if FEAT_SB is supported
ENABLE_FEAT_SB = $(if $(findstring sb,${arch-features}),1,0)
-ifneq ($(findstring armclang,$(notdir $(CC))),)
-TF_CFLAGS_aarch32 = -target arm-arm-none-eabi $(march32-directive)
-TF_CFLAGS_aarch64 = -target aarch64-arm-none-eabi $(march64-directive)
-LD = $(LINKER)
-AS = $(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH))
-CPP = $(CC) -E $(TF_CFLAGS_$(ARCH))
-PP = $(CC) -E $(TF_CFLAGS_$(ARCH))
-else ifneq ($(findstring clang,$(notdir $(CC))),)
-CLANG_CCDIR = $(if $(filter-out ./,$(dir $(CC))),$(dir $(CC)),)
-TF_CFLAGS_aarch32 = $(target32-directive) $(march32-directive)
-TF_CFLAGS_aarch64 = -target aarch64-elf $(march64-directive)
-LD = $(CLANG_CCDIR)ld.lld
-ifeq (, $(shell which $(LD)))
-$(error "No $(LD) in PATH, make sure it is installed or set LD to a different linker")
-endif
-AS = $(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH))
-CPP = $(CC) -E
-PP = $(CC) -E
+ifneq ($(findstring clang,$(notdir $(CC))),)
+ ifneq ($(findstring armclang,$(notdir $(CC))),)
+ TF_CFLAGS_aarch32 := -target arm-arm-none-eabi $(march32-directive)
+ TF_CFLAGS_aarch64 := -target aarch64-arm-none-eabi $(march64-directive)
+ LD := $(LINKER)
+ else
+ TF_CFLAGS_aarch32 := $(target32-directive) $(march32-directive)
+ TF_CFLAGS_aarch64 := -target aarch64-elf $(march64-directive)
+ LD := $(shell $(CC) --print-prog-name ld.lld)
+
+ AR := $(shell $(CC) --print-prog-name llvm-ar)
+ OD := $(shell $(CC) --print-prog-name llvm-objdump)
+ OC := $(shell $(CC) --print-prog-name llvm-objcopy)
+ endif
+
+ CPP := $(CC) -E $(TF_CFLAGS_$(ARCH))
+ PP := $(CC) -E $(TF_CFLAGS_$(ARCH))
+ AS := $(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH))
else ifneq ($(findstring gcc,$(notdir $(CC))),)
TF_CFLAGS_aarch32 = $(march32-directive)
TF_CFLAGS_aarch64 = $(march64-directive)
@@ -523,6 +527,9 @@
ifeq ($(CTX_INCLUDE_EL2_REGS),0)
$(error SPMD with SPM at S-EL2 requires CTX_INCLUDE_EL2_REGS option)
endif
+ ifeq ($(SPMC_AT_EL3),1)
+ $(error SPM cannot be enabled in both S-EL2 and EL3.)
+ endif
endif
ifeq ($(findstring optee_sp,$(ARM_SPMC_MANIFEST_DTS)),optee_sp)
@@ -573,6 +580,9 @@
ifneq (${ARCH},aarch64)
$(error ENABLE_RME requires AArch64)
endif
+ifeq ($(SPMC_AT_EL3),1)
+ $(error SPMC_AT_EL3 and ENABLE_RME cannot both be enabled.)
+endif
include services/std_svc/rmmd/rmmd.mk
$(warning "RME is an experimental feature")
endif
@@ -771,8 +781,10 @@
endif
endif
-# SME/SVE only supported on AArch64
+# Ensure that no Aarch64-only features are enabled in Aarch32 build
ifeq (${ARCH},aarch32)
+
+ # SME/SVE only supported on AArch64
ifeq (${ENABLE_SME_FOR_NS},1)
$(error "ENABLE_SME_FOR_NS cannot be used with ARCH=aarch32")
endif
@@ -780,6 +792,12 @@
# Warning instead of error due to CI dependency on this
$(error "ENABLE_SVE_FOR_NS cannot be used with ARCH=aarch32")
endif
+
+ # BRBE is not supported in Aarch32
+ ifeq (${ENABLE_BRBE_FOR_NS},1)
+ $(error "ENABLE_BRBE_FOR_NS cannot be used with ARCH=aarch32")
+ endif
+
endif
# Ensure ENABLE_RME is not used with SME
@@ -912,7 +930,7 @@
# Variables for use with sptool
SPTOOLPATH ?= tools/sptool
-SPTOOL ?= ${SPTOOLPATH}/sptool${BIN_EXT}
+SPTOOL ?= ${SPTOOLPATH}/sptool.py
SP_MK_GEN ?= ${SPTOOLPATH}/sp_mk_generator.py
# Variables for use with ROMLIB
@@ -996,12 +1014,14 @@
PROGRAMMABLE_RESET_ADDRESS \
PSCI_EXTENDED_STATE_ID \
RESET_TO_BL31 \
+ RESET_TO_BL31_WITH_PARAMS \
SAVE_KEYS \
SEPARATE_CODE_AND_RODATA \
SEPARATE_BL2_NOLOAD_REGION \
SEPARATE_NOBITS_REGION \
SPIN_ON_BL1_EXIT \
SPM_MM \
+ SPMC_AT_EL3 \
SPMD_SPM_AT_SEL2 \
TRUSTED_BOARD_BOOT \
CRYPTO_SUPPORT \
@@ -1024,6 +1044,7 @@
COT_DESC_IN_DTB \
USE_SP804_TIMER \
PSA_FWU_SUPPORT \
+ ENABLE_BRBE_FOR_NS \
ENABLE_TRBE_FOR_NS \
ENABLE_SYS_REG_TRACE_FOR_NS \
ENABLE_MPMM \
@@ -1061,6 +1082,8 @@
NR_OF_FW_BANKS \
NR_OF_IMAGES_IN_FW_BANK \
RAS_EXTENSION \
+ TWED_DELAY \
+ ENABLE_FEAT_TWED \
)))
ifdef KEY_SIZE
@@ -1127,6 +1150,7 @@
PSCI_EXTENDED_STATE_ID \
RAS_EXTENSION \
RESET_TO_BL31 \
+ RESET_TO_BL31_WITH_PARAMS \
SEPARATE_CODE_AND_RODATA \
SEPARATE_BL2_NOLOAD_REGION \
SEPARATE_NOBITS_REGION \
@@ -1134,6 +1158,7 @@
SPD_${SPD} \
SPIN_ON_BL1_EXIT \
SPM_MM \
+ SPMC_AT_EL3 \
SPMD_SPM_AT_SEL2 \
TRUSTED_BOARD_BOOT \
CRYPTO_SUPPORT \
@@ -1160,6 +1185,7 @@
NR_OF_FW_BANKS \
NR_OF_IMAGES_IN_FW_BANK \
PSA_FWU_SUPPORT \
+ ENABLE_BRBE_FOR_NS \
ENABLE_TRBE_FOR_NS \
ENABLE_SYS_REG_TRACE_FOR_NS \
ENABLE_TRF_FOR_NS \
@@ -1176,6 +1202,8 @@
ENABLE_FEAT_CSV2_2 \
ENABLE_FEAT_PAN \
FEATURE_DETECTION \
+ TWED_DELAY \
+ ENABLE_FEAT_TWED \
)))
ifeq (${SANITIZE_UB},trap)
@@ -1322,8 +1350,7 @@
ifeq (${NEED_SP_PKG},yes)
$(BUILD_PLAT)/sp_gen.mk: ${SP_MK_GEN} ${SP_LAYOUT_FILE} | ${BUILD_PLAT}
${Q}${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT) ${COT}
-sp: $(SPTOOL) $(DTBS) $(BUILD_PLAT)/sp_gen.mk
- ${Q}$(SPTOOL) $(SPTOOL_ARGS)
+sp: $(DTBS) $(BUILD_PLAT)/sp_gen.mk $(SP_PKGS)
@${ECHO_BLANK_LINE}
@echo "Built SP Images successfully"
@${ECHO_BLANK_LINE}
@@ -1363,7 +1390,6 @@
# to pass the gnumake flags to nmake.
${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) realclean
endif
- ${Q}${MAKE} --no-print-directory -C ${SPTOOLPATH} clean
${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} realclean
${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} realclean
${Q}${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
@@ -1457,10 +1483,6 @@
${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL))
endif
-sptool: ${SPTOOL}
-${SPTOOL}: FORCE
- ${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" SPTOOL=${SPTOOL} --no-print-directory -C ${SPTOOLPATH}
-
romlib.bin: libraries FORCE
${Q}${MAKE} PLAT_DIR=${PLAT_DIR} BUILD_PLAT=${BUILD_PLAT} ENABLE_BTI=${ENABLE_BTI} ARM_ARCH_MINOR=${ARM_ARCH_MINOR} INCLUDES='${INCLUDES}' DEFINES='${DEFINES}' --no-print-directory -C ${ROMLIBPATH} all
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index 6aa7afd..c95706c 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -17,12 +17,12 @@
RAM (rwx): ORIGIN = BL2_RW_BASE, LENGTH = BL2_RW_LIMIT - BL2_RW_BASE
#else
RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
+#endif
#if SEPARATE_BL2_NOLOAD_REGION
RAM_NOLOAD (rw!a): ORIGIN = BL2_NOLOAD_START, LENGTH = BL2_NOLOAD_LIMIT - BL2_NOLOAD_START
#else
#define RAM_NOLOAD RAM
#endif
-#endif
}
#if !BL2_IN_XIP_MEM
diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S
index ed05864..b0c46dc 100644
--- a/bl31/aarch64/bl31_entrypoint.S
+++ b/bl31/aarch64/bl31_entrypoint.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -67,6 +67,7 @@
_exception_vectors=runtime_exceptions \
_pie_fixup_size=BL31_LIMIT - BL31_BASE
+#if !RESET_TO_BL31_WITH_PARAMS
/* ---------------------------------------------------------------------
* For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
* there's no argument to relay from a previous bootloader. Zero the
@@ -77,6 +78,7 @@
mov x21, 0
mov x22, 0
mov x23, 0
+#endif /* RESET_TO_BL31_WITH_PARAMS */
#endif /* RESET_TO_BL31 */
/* --------------------------------------------------------------------
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 25c7964..3964469 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -18,12 +18,21 @@
$(error EL3_EXCEPTION_HANDLING must be 1 for SPM-MM support)
else
$(info Including SPM Management Mode (MM) makefile)
- include services/std_svc/spm_mm/spm_mm.mk
+ include services/std_svc/spm/common/spm.mk
+ include services/std_svc/spm/spm_mm/spm_mm.mk
endif
endif
include lib/extensions/amu/amu.mk
include lib/mpmm/mpmm.mk
+
+ifeq (${SPMC_AT_EL3},1)
+ $(warning "EL3 SPMC is an experimental feature")
+ $(info Including EL3 SPMC makefile)
+ include services/std_svc/spm/common/spm.mk
+ include services/std_svc/spm/el3_spmc/spmc.mk
+endif
+
include lib/psci/psci_lib.mk
BL31_SOURCES += bl31/bl31_main.c \
@@ -40,6 +49,8 @@
services/std_svc/std_svc_setup.c \
${PSCI_LIB_SOURCES} \
${SPMD_SOURCES} \
+ ${SPM_MM_SOURCES} \
+ ${SPMC_SOURCES} \
${SPM_SOURCES}
ifeq (${DISABLE_MTPMU},1)
@@ -104,6 +115,10 @@
BL31_SOURCES += lib/extensions/trbe/trbe.c
endif
+ifeq (${ENABLE_BRBE_FOR_NS},1)
+BL31_SOURCES += lib/extensions/brbe/brbe.c
+endif
+
ifeq (${ENABLE_SYS_REG_TRACE_FOR_NS},1)
BL31_SOURCES += lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c
endif
diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk
index 590b032..ab1287d 100644
--- a/bl32/sp_min/sp_min.mk
+++ b/bl32/sp_min/sp_min.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -35,6 +35,10 @@
ifeq (${WORKAROUND_CVE_2017_5715},1)
BL32_SOURCES += bl32/sp_min/wa_cve_2017_5715_bpiall.S \
bl32/sp_min/wa_cve_2017_5715_icache_inv.S
+else
+ifeq (${WORKAROUND_CVE_2022_23960},1)
+BL32_SOURCES += bl32/sp_min/wa_cve_2017_5715_icache_inv.S
+endif
endif
ifeq (${TRNG_SUPPORT},1)
diff --git a/common/fdt_fixup.c b/common/fdt_fixup.c
index de02b46..b1d628c 100644
--- a/common/fdt_fixup.c
+++ b/common/fdt_fixup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -394,6 +394,110 @@
return offs;
}
+/*******************************************************************************
+ * fdt_add_cpu_idle_states() - add PSCI CPU idle states to cpu nodes in the DT
+ * @dtb: pointer to the device tree blob in memory
+ * @states: array of idle state descriptions, ending with empty element
+ *
+ * Add information about CPU idle states to the devicetree. This function
+ * assumes that CPU idle states are not already present in the devicetree, and
+ * that all CPU states are equally applicable to all CPUs.
+ *
+ * See arm/idle-states.yaml and arm/psci.yaml in the (Linux kernel) DT binding
+ * documentation for more details.
+ *
+ * Return: 0 on success, a negative error value otherwise.
+ ******************************************************************************/
+int fdt_add_cpu_idle_states(void *dtb, const struct psci_cpu_idle_state *state)
+{
+ int cpu_node, cpus_node, idle_states_node, ret;
+ uint32_t count, phandle;
+
+ ret = fdt_find_max_phandle(dtb, &phandle);
+ phandle++;
+ if (ret < 0) {
+ return ret;
+ }
+
+ cpus_node = fdt_path_offset(dtb, "/cpus");
+ if (cpus_node < 0) {
+ return cpus_node;
+ }
+
+ /* Create the idle-states node and its child nodes. */
+ idle_states_node = fdt_add_subnode(dtb, cpus_node, "idle-states");
+ if (idle_states_node < 0) {
+ return idle_states_node;
+ }
+
+ ret = fdt_setprop_string(dtb, idle_states_node, "entry-method", "psci");
+ if (ret < 0) {
+ return ret;
+ }
+
+ for (count = 0U; state->name != NULL; count++, phandle++, state++) {
+ int idle_state_node;
+
+ idle_state_node = fdt_add_subnode(dtb, idle_states_node,
+ state->name);
+ if (idle_state_node < 0) {
+ return idle_state_node;
+ }
+
+ fdt_setprop_string(dtb, idle_state_node, "compatible",
+ "arm,idle-state");
+ fdt_setprop_u32(dtb, idle_state_node, "arm,psci-suspend-param",
+ state->power_state);
+ if (state->local_timer_stop) {
+ fdt_setprop_empty(dtb, idle_state_node,
+ "local-timer-stop");
+ }
+ fdt_setprop_u32(dtb, idle_state_node, "entry-latency-us",
+ state->entry_latency_us);
+ fdt_setprop_u32(dtb, idle_state_node, "exit-latency-us",
+ state->exit_latency_us);
+ fdt_setprop_u32(dtb, idle_state_node, "min-residency-us",
+ state->min_residency_us);
+ if (state->wakeup_latency_us) {
+ fdt_setprop_u32(dtb, idle_state_node,
+ "wakeup-latency-us",
+ state->wakeup_latency_us);
+ }
+ fdt_setprop_u32(dtb, idle_state_node, "phandle", phandle);
+ }
+
+ if (count == 0U) {
+ return 0;
+ }
+
+ /* Link each cpu node to the idle state nodes. */
+ fdt_for_each_subnode(cpu_node, dtb, cpus_node) {
+ const char *device_type;
+ fdt32_t *value;
+
+ /* Only process child nodes with device_type = "cpu". */
+ device_type = fdt_getprop(dtb, cpu_node, "device_type", NULL);
+ if (device_type == NULL || strcmp(device_type, "cpu") != 0) {
+ continue;
+ }
+
+ /* Allocate space for the list of phandles. */
+ ret = fdt_setprop_placeholder(dtb, cpu_node, "cpu-idle-states",
+ count * sizeof(phandle),
+ (void **)&value);
+ if (ret < 0) {
+ return ret;
+ }
+
+ /* Fill in the phandles of the idle state nodes. */
+ for (uint32_t i = 0U; i < count; ++i) {
+ value[i] = cpu_to_fdt32(phandle - count + i);
+ }
+ }
+
+ return 0;
+}
+
/**
* fdt_adjust_gic_redist() - Adjust GICv3 redistributor size
* @dtb: Pointer to the DT blob in memory
diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c
index 2a9673f..1b065b1 100644
--- a/common/fdt_wrappers.c
+++ b/common/fdt_wrappers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -618,3 +618,24 @@
return ret;
}
+
+/*
+ * Find a given node in device tree. If not present, add it.
+ * Returns offset of node found/added on success, and < 0 on error.
+ */
+int fdtw_find_or_add_subnode(void *fdt, int parentoffset, const char *name)
+{
+ int offset;
+
+ offset = fdt_subnode_offset(fdt, parentoffset, name);
+
+ if (offset == -FDT_ERR_NOTFOUND) {
+ offset = fdt_add_subnode(fdt, parentoffset, name);
+ }
+
+ if (offset < 0) {
+ ERROR("%s: %s: %s\n", __func__, name, fdt_strerror(offset));
+ }
+
+ return offset;
+}
diff --git a/common/feat_detect.c b/common/feat_detect.c
index ef09b86..8f98876 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -203,6 +203,16 @@
#endif
}
+/***********************************************************
+ * Feature : FEAT_TWED (Delayed Trapping of WFE Instruction)
+ **********************************************************/
+static void read_feat_twed(void)
+{
+#if (ENABLE_FEAT_TWED == FEAT_STATE_1)
+ feat_detect_panic(is_armv8_6_twed_present(), "TWED");
+#endif
+}
+
/******************************************************************
* Feature : FEAT_HCX (Extended Hypervisor Configuration Register)
*****************************************************************/
@@ -279,6 +289,7 @@
read_feat_amuv1p1();
read_feat_fgt();
read_feat_ecv();
+ read_feat_twed();
/* v8.7 features */
read_feat_hcx();
diff --git a/docs/about/contact.rst b/docs/about/contact.rst
index 4440a37..4f482bd 100644
--- a/docs/about/contact.rst
+++ b/docs/about/contact.rst
@@ -47,10 +47,10 @@
via their partner managers.
.. _`issue tracker`: https://developer.trustedfirmware.org
-.. _`TF-A development`: https://lists.trustedfirmware.org/pipermail/tf-a/
-.. _`TF-A-Tests development`: https://lists.trustedfirmware.org/pipermail/tf-a-tests/
-.. _`summary of all the lists`: https://lists.trustedfirmware.org
+.. _`TF-A development`: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
+.. _`TF-A-Tests development`: https://lists.trustedfirmware.org/mailman3/lists/tf-a-tests.lists.trustedfirmware.org/
+.. _`summary of all the lists`: https://lists.trustedfirmware.org/mailman3/lists/
--------------
-*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index b58ea71..af8161a 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -315,9 +315,21 @@
:|G|: `AlexeiFedorov`_
:|M|: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
:|G|: `javieralso-arm`_
+:|M|: Sandrine Bailleux <sandrine.bailleux@arm.com>
+:|G|: `sandrine-bailleux-arm`_
:|F|: drivers/measured_boot
:|F|: include/drivers/measured_boot
-:|F|: plat/arm/board/fvp/fvp_measured_boot.c
+:|F|: docs/components/measured_boot
+:|F|: plat/arm/board/fvp/fvp\*_measured_boot.c
+
+PSA Firmware Update
+^^^^^^^^^^^^^^^^^^^
+:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
+:|G|: `ManishVB-Arm`_
+:|M|: Sandrine Bailleux <sandrine.bailleux@arm.com>
+:|G|: `sandrine-bailleux-arm`_
+:|F|: drivers/fwu
+:|F|: include/drivers/fwu
System Control and Management Interface (SCMI) Server
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -469,11 +481,11 @@
Intel SocFPGA platform ports
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Tien Hock Loh <tien.hock.loh@intel.com>
-:|G|: `thloh85-intel`_
-:|M|: Hadi Asyrafi <muhammad.hadi.asyrafi.abdul.halim@intel.com>
-:|G|: mabdulha
-:|F|: plat/intel/soc
+:|M|: Sieu Mun Tang <sieu.mun.tang@intel.com>
+:|G|: `sieumunt`_
+:|M|: Benjamin Jit Loon Lim <jit.loon.lim@intel.com>
+:|G|: `BenjaminLimJL`_
+:|F|: plat/intel/soc/
:|F|: drivers/intel/soc/
MediaTek platform ports
@@ -828,7 +840,8 @@
.. _soby-mathew: https://github.com/soby-mathew
.. _sreekare: https://github.com/sreekare
.. _stephan-gh: https://github.com/stephan-gh
-.. _thloh85-intel: https://github.com/thloh85-intel
+.. _sieumunt: https://github.com/sieumunt
+.. _BenjaminLimJL: https://github.com/BenjaminLimJL
.. _thomas-arm: https://github.com/thomas-arm
.. _TonyXie06: https://github.com/TonyXie06
.. _TravMurav: https://github.com/TravMurav
diff --git a/docs/components/fconf/fconf_properties.rst b/docs/components/fconf/fconf_properties.rst
index 5c28a7a..20cc758 100644
--- a/docs/components/fconf/fconf_properties.rst
+++ b/docs/components/fconf/fconf_properties.rst
@@ -30,3 +30,10 @@
- value type: <u32>
- Image ID of the configuration.
+- ns-load-address [optional]
+ - value type: <u64>
+ - Physical loading base address of the configuration in the non-secure
+ memory.
+ Only needed by those configuration files which require being loaded
+ in secure memory (at load-address) as well as in non-secure memory
+ e.g. HW_CONFIG
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index af298e3..2eaae75 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -127,14 +127,18 @@
This section explains the TF-A build options involved in building with
support for an FF-A based SPM where the SPMD is located at EL3 and the
-SPMC located at S-EL1 or S-EL2:
+SPMC located at S-EL1, S-EL2 or EL3:
- **SPD=spmd**: this option selects the SPMD component to relay the FF-A
protocol from NWd to SWd back and forth. It is not possible to
enable another Secure Payload Dispatcher when this option is chosen.
- **SPMD_SPM_AT_SEL2**: this option adjusts the SPMC exception
- level to being S-EL1 or S-EL2. It defaults to enabled (value 1) when
+ level to being at S-EL2. It defaults to enabled (value 1) when
SPD=spmd is chosen.
+- **SPMC_AT_EL3**: this option adjusts the SPMC exception level to being
+ at EL3.
+- If neither **SPMD_SPM_AT_SEL2** or **SPMC_AT_EL3** are enabled the SPMC
+ exception level is set to S-EL1.
- **CTX_INCLUDE_EL2_REGS**: this option permits saving (resp.
restoring) the EL2 system register context before entering (resp.
after leaving) the SPMC. It is mandatorily enabled when
@@ -146,14 +150,16 @@
is required when ``SPMD_SPM_AT_SEL2`` is enabled hence when multiple
secure partitions are to be loaded on behalf of the SPMC.
-+---------------+----------------------+------------------+
-| | CTX_INCLUDE_EL2_REGS | SPMD_SPM_AT_SEL2 |
-+---------------+----------------------+------------------+
-| SPMC at S-EL1 | 0 | 0 |
-+---------------+----------------------+------------------+
-| SPMC at S-EL2 | 1 | 1 (default when |
-| | | SPD=spmd) |
-+---------------+----------------------+------------------+
++---------------+----------------------+------------------+-------------+
+| | CTX_INCLUDE_EL2_REGS | SPMD_SPM_AT_SEL2 | SPMC_AT_EL3 |
++---------------+----------------------+------------------+-------------+
+| SPMC at S-EL1 | 0 | 0 | 0 |
++---------------+----------------------+------------------+-------------+
+| SPMC at S-EL2 | 1 | 1 (default when | 0 |
+| | | SPD=spmd) | |
++---------------+----------------------+------------------+-------------+
+| SPMC at EL3 | 0 | 0 | 1 |
++---------------+----------------------+------------------+-------------+
Other combinations of such build options either break the build or are not
supported.
@@ -229,6 +235,20 @@
GENERATE_COT=1 \
all fip
+Sample TF-A build command line when SPMC is located at EL3:
+
+.. code:: shell
+
+ make \
+ CROSS_COMPILE=aarch64-none-elf- \
+ SPD=spmd \
+ SPMD_SPM_AT_SEL2=0 \
+ SPMC_AT_EL3=1 \
+ BL32=<path-to-tee-binary> \
+ BL33=<path-to-bl33-binary> \
+ PLAT=fvp \
+ all fip
+
FVP model invocation
====================
@@ -1280,7 +1300,7 @@
.. _[8]:
-[8] https://lists.trustedfirmware.org/pipermail/tf-a/2020-February/000296.html
+[8] https://lists.trustedfirmware.org/archives/list/tf-a@lists.trustedfirmware.org/thread/CFQFGU6H2D5GZYMUYGTGUSXIU3OYZP6U/
.. _[9]:
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index af0e769..3029458 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -490,6 +490,10 @@
Cortex-X2 CPU. This needs to be enabled only for revisions r0p0, r1p0 and
r2p0 of the CPU, it is fixed in r2p1.
+- ``ERRATA_X2_2147715``: This applies errata 2147715 workaround to
+ Cortex-X2 CPU. This needs to be enabled only for revision r2p0 of the CPU,
+ it is fixed in r2p1.
+
For Cortex-A510, the following errata build flags are defined :
- ``ERRATA_A510_1922240``: This applies errata 1922240 workaround to
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 0831dc0..71fdfcb 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -131,6 +131,9 @@
- For other BL3x images, if the firmware configuration file is loaded by
BL2, then its address is passed in ``arg0`` and if HW_CONFIG is loaded
then its address is passed in ``arg1``.
+ - In case of the Arm FVP platform, FW_CONFIG address passed in ``arg1`` to
+ BL31/SP_MIN, and the SOC_FW_CONFIG and HW_CONFIG details are retrieved
+ from FW_CONFIG device tree.
BL1
~~~
@@ -1757,12 +1760,20 @@
DRAM
0xffffffff +----------+
: :
- |----------|
+ 0x82100000 |----------|
|HW_CONFIG |
- 0x83000000 |----------| (non-secure)
+ 0x82000000 |----------| (non-secure)
| |
0x80000000 +----------+
+ Trusted DRAM
+ 0x08000000 +----------+
+ |HW_CONFIG |
+ 0x07f00000 |----------|
+ : :
+ | |
+ 0x06000000 +----------+
+
Trusted SRAM
0x04040000 +----------+ loaded by BL2 +----------------+
| BL1 (rw) | <<<<<<<<<<<<< | |
@@ -1790,15 +1801,18 @@
DRAM
0xffffffff +--------------+
: :
- |--------------|
+ 0x82100000 |--------------|
| HW_CONFIG |
- 0x83000000 |--------------| (non-secure)
+ 0x82000000 |--------------| (non-secure)
| |
0x80000000 +--------------+
- Trusted DRAM
+ Trusted DRAM
0x08000000 +--------------+
- | BL32 |
+ | HW_CONFIG |
+ 0x07f00000 |--------------|
+ : :
+ | BL32 |
0x06000000 +--------------+
Trusted SRAM
@@ -1829,12 +1843,20 @@
| BL32 | (secure)
0xff000000 +----------+
| |
- |----------|
+ 0x82100000 |----------|
|HW_CONFIG |
- 0x83000000 |----------| (non-secure)
+ 0x82000000 |----------| (non-secure)
| |
0x80000000 +----------+
+ Trusted DRAM
+ 0x08000000 +----------+
+ |HW_CONFIG |
+ 0x7f000000 |----------|
+ : :
+ | |
+ 0x06000000 +----------+
+
Trusted SRAM
0x04040000 +----------+ loaded by BL2 +----------------+
| BL1 (rw) | <<<<<<<<<<<<< | |
@@ -2729,7 +2751,7 @@
--------------
-*Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.*
.. _Power State Coordination Interface PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
.. _SMCCC: https://developer.arm.com/docs/den0028/latest
diff --git a/docs/design/reset-design.rst b/docs/design/reset-design.rst
index 7b10c95..666ee4f 100644
--- a/docs/design/reset-design.rst
+++ b/docs/design/reset-design.rst
@@ -141,19 +141,26 @@
Platform initialization
~~~~~~~~~~~~~~~~~~~~~~~
-In this configuration, when the CPU resets to BL31 there are no parameters that
-can be passed in registers by previous boot stages. Instead, the platform code
-in BL31 needs to know, or be able to determine, the location of the BL32 (if
-required) and BL33 images and provide this information in response to the
+In this configuration, when the CPU resets to BL31 there should be no parameters
+that can be passed in registers by previous boot stages. Instead, the platform
+code in BL31 needs to know, or be able to determine, the location of the BL32
+(if required) and BL33 images and provide this information in response to the
``bl31_plat_get_next_image_ep_info()`` function.
+.. note::
+ Some platforms that configure ``RESET_TO_BL31`` might still be able to
+ receive parameters in registers depending on their actual boot sequence. On
+ those occasions, and in addition to ``RESET_TO_BL31``, these platforms should
+ set ``RESET_TO_BL31_WITH_PARAMS`` to avoid the input registers from being
+ zeroed before entering BL31.
+
Additionally, platform software is responsible for carrying out any security
initialisation, for example programming a TrustZone address space controller.
This might be done by the Trusted Boot Firmware or by platform code in BL31.
--------------
-*Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.*
.. |Default reset code flow| image:: ../resources/diagrams/default_reset_code.png
.. |Reset code flow with programmable reset address| image:: ../resources/diagrams/reset_code_no_boot_type_check.png
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 4dbf5cb..d2cda4d 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -327,6 +327,14 @@
This flag can take values 0 to 2, to align with the ``FEATURE_DETECTION``
mechanism. Default is ``0``.
+- ``ENABLE_FEAT_TWED``: Numeric value to enable the ``FEAT_TWED`` (Delayed
+ trapping of WFE Instruction) extension. ``FEAT_TWED`` is a optional feature
+ available on Arm v8.6. This flag can take values 0 to 2, to align with the
+ ``FEATURE_DETECTION`` mechanism. Default is ``0``.
+
+ When ``ENABLE_FEAT_TWED`` is set to ``1``, WFE instruction trapping gets
+ delayed by the amount of value in ``TWED_DELAY``.
+
- ``ENABLE_FEAT_VHE``: Numeric value to enable the ``FEAT_VHE`` (Virtualization
Host Extensions) extension. It allows access to CONTEXTIDR_EL2 register
during EL2 context save/restore operations.``FEAT_VHE`` is a mandatory
@@ -709,6 +717,11 @@
entrypoint) or 1 (CPU reset to BL31 entrypoint).
The default value is 0.
+- ``RESET_TO_BL31_WITH_PARAMS``: If ``RESET_TO_BL31`` has been enabled, setting
+ this additional option guarantees that the input registers are not cleared
+ therefore allowing parameters to be passed to the BL31 entrypoint.
+ The default value is 0.
+
- ``RESET_TO_SP_MIN``: SP_MIN is the minimal AArch32 Secure Payload provided
in TF-A. This flag configures SP_MIN entrypoint as the CPU reset vector
instead of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
@@ -780,13 +793,20 @@
firmware images have been loaded in memory, and the MMU and caches are
turned off. Refer to the "Debugging options" section for more details.
+- ``SPMC_AT_EL3`` : This boolean option is used jointly with the SPM
+ Dispatcher option (``SPD=spmd``). When enabled (1) it indicates the SPMC
+ component runs at the EL3 exception level. The default value is ``0`` (
+ disabled). This configuration supports pre-Armv8.4 platforms (aka not
+ implementing the ``FEAT_SEL2`` extension). This is an experimental feature.
+
- ``SPMD_SPM_AT_SEL2`` : This boolean option is used jointly with the SPM
Dispatcher option (``SPD=spmd``). When enabled (1) it indicates the SPMC
- component runs at the S-EL2 execution state provided by the Armv8.4-SecEL2
+ component runs at the S-EL2 exception level provided by the ``FEAT_SEL2``
extension. This is the default when enabling the SPM Dispatcher. When
disabled (0) it indicates the SPMC component runs at the S-EL1 execution
- state. This latter configuration supports pre-Armv8.4 platforms (aka not
- implementing the Armv8.4-SecEL2 extension).
+ state or at EL3 if ``SPMC_AT_EL3`` is enabled. The latter configurations
+ support pre-Armv8.4 platforms (aka not implementing the ``FEAT_SEL2``
+ extension).
- ``SPM_MM`` : Boolean option to enable the Management Mode (MM)-based Secure
Partition Manager (SPM) implementation. The default value is ``0``
@@ -838,6 +858,12 @@
When ``EL3_EXCEPTION_HANDLING`` is ``1``, ``TSP_NS_INTR_ASYNC_PREEMPT``
must also be set to ``1``.
+- ``TWED_DELAY``: Numeric value to be set in order to delay the trapping of
+ WFE instruction. ``ENABLE_FEAT_TWED`` build option must be enabled to set
+ this delay. It can take values in the range (0-15). Default value is ``0``
+ and based on this value, 2^(TWED_DELAY + 8) cycles will be delayed.
+ Platforms need to explicitly update this value based on their requirements.
+
- ``USE_ARM_LINK``: This flag determines whether to enable support for ARM
linker. When the ``LINKER`` build variable points to the armlink linker,
this flag is enabled automatically. To enable support for armlink, platforms
@@ -947,6 +973,11 @@
functions that wait for an arbitrary time length (udelay and mdelay). The
default value is 0.
+- ``ENABLE_BRBE_FOR_NS``: This flag enables access to the branch record buffer
+ registers from NS ELs when FEAT_BRBE is implemented. BRBE is an optional
+ architectural feature for AArch64. The default is 0 and it is automatically
+ disabled when the target architecture is AArch32.
+
- ``ENABLE_TRBE_FOR_NS``: This flag is used to enable access of trace buffer
control registers from NS ELs, NS-EL2 or NS-EL1(when NS-EL2 is implemented
but unused) when FEAT_TRBE is implemented. TRBE is an optional architectural
diff --git a/docs/getting_started/initial-build.rst b/docs/getting_started/initial-build.rst
index d4a8f01..62f1941 100644
--- a/docs/getting_started/initial-build.rst
+++ b/docs/getting_started/initial-build.rst
@@ -18,16 +18,12 @@
It is possible to build TF-A using Clang or Arm Compiler 6. To do so
``CC`` needs to point to the clang or armclang binary, which will
- also select the clang or armclang assembler. Be aware that for Arm Compiler,
- the GNU linker is used by default. However for Clang LLVM linker (LLD)
- is used by default. In case of being needed the linker can be overridden
- using the ``LD`` variable. LLVM linker (LLD) version 9 is
- known to work with TF-A.
-
- In both cases ``CROSS_COMPILE`` should be set as described above.
-
- Arm Compiler 6 will be selected when the base name of the path assigned
- to ``CC`` matches the string 'armclang'.
+ also select the clang or armclang assembler. Arm Compiler 6 will be selected
+ when the base name of the path assigned to ``CC`` matches the string
+ 'armclang'. GNU binutils are required since the TF-A build system doesn't
+ currently support Arm Scatter files. Meaning the GNU linker is used by
+ default for Arm Compiler 6. Because of this dependency, ``CROSS_COMPILE``
+ should be set as described above.
For AArch64 using Arm Compiler 6:
@@ -36,6 +32,11 @@
export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf-
make CC=<path-to-armclang>/bin/armclang PLAT=<platform> all
+ On the other hand, Clang uses LLVM linker (LLD) and other LLVM binutils by
+ default instead of GNU utilities (LLVM linker (LLD) 14.0.0 is known to
+ work with TF-A). ``CROSS_COMPILE`` need not be set for Clang. Please note,
+ that the default linker may be manually overridden using the ``LD`` variable.
+
Clang will be selected when the base name of the path assigned to ``CC``
contains the string 'clang'. This is to allow both clang and clang-X.Y
to work.
@@ -44,7 +45,6 @@
.. code:: shell
- export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf-
make CC=<path-to-clang>/bin/clang PLAT=<platform> all
- Change to the root directory of the TF-A source tree and build.
@@ -115,4 +115,4 @@
--------------
-*Copyright (c) 2020, Arm Limited. All rights reserved.*
+*Copyright (c) 2020-2022, Arm Limited. All rights reserved.*
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index 3d3b2e3..2c6a005 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -2118,21 +2118,6 @@
of the system counter, which is retrieved from the first entry in the frequency
modes table.
-Function : plat_arm_set_twedel_scr_el3() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : uint32_t
-
-This function is used in v8.6+ systems to set the WFE trap delay value in
-SCR_EL3. If this function returns TWED_DISABLED or is left unimplemented, this
-feature is not enabled. The only hook provided is to set the TWED fields in
-SCR_EL3, there are similar fields in HCR_EL2, SCTLR_EL2, and SCTLR_EL1 to adjust
-the WFE trap delays in lower ELs and these fields should be set by the
-appropriate EL2 or EL1 code depending on the platform configuration.
-
#define : PLAT_PERCPU_BAKERY_LOCK_SIZE [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index ee30128..3a54e69 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -26,9 +26,9 @@
|TF-A| can be built with any of the following *cross-compiler* toolchains that
target the Armv7-A or Armv8-A architectures:
-- GCC >= 10.3-2021.07 (from the `Arm Developer website`_)
-- Clang >= 4.0
-- Arm Compiler >= 6.0
+- GCC >= 11.2-2022.02 (from the `Arm Developer website`_)
+- Clang >= 14.0.0
+- Arm Compiler >= 6.18
In addition, a native compiler is required to build the supporting tools.
@@ -58,9 +58,10 @@
Required to build the cert_create tool.
-The following libraries are required for Trusted Board Boot support:
+The following libraries are required for Trusted Board Boot and Measured Boot
+support:
-- mbed TLS == 2.26.0 (tag: ``mbedtls-2.26.0``)
+- mbed TLS == 2.28.0 (tag: ``mbedtls-2.28.0``)
These tools are optional:
@@ -159,9 +160,9 @@
--------------
-*Copyright (c) 2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
-.. _Arm Developer website: https://developer.arm.com/open-source/gnu-toolchain/gnu-a/downloads
+.. _Arm Developer website: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads
.. _Gerrit Code Review: https://www.gerritcodereview.com/
.. _Linaro Release Notes: https://community.arm.com/dev-platforms/w/docs/226/old-release-notes
.. _Linaro instructions: https://community.arm.com/dev-platforms/w/docs/304/arm-reference-platforms-deliverables
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
index 2aaf195..9280f7b 100644
--- a/docs/plat/arm/fvp/index.rst
+++ b/docs/plat/arm/fvp/index.rst
@@ -392,7 +392,8 @@
- BL1 is loaded at the start of the Trusted ROM.
- The Firmware Image Package is loaded at the start of NOR FLASH0.
- The firmware loads the FDT packaged in FIP to the DRAM. The FDT load address
- is specified via the ``hw_config_addr`` property in `TB_FW_CONFIG for FVP`_.
+ is specified via the ``load-address`` property in the ``hw-config`` node of
+ `FW_CONFIG for FVP`_.
- The default use-case for the Foundation FVP is to use the ``--gicv3`` option
and enable the GICv3 device in the model. Note that without this option,
the Foundation FVP defaults to legacy (Versatile Express) memory map which
@@ -643,9 +644,9 @@
--------------
-*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
-.. _TB_FW_CONFIG for FVP: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+.. _FW_CONFIG for FVP: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/arm/board/fvp/fdts/fvp_fw_config.dts
.. _Arm's website: `FVP models`_
.. _FVP models: https://developer.arm.com/products/system-design/fixed-virtual-platforms
.. _Linaro Release 20.01: http://releases.linaro.org/members/arm/platforms/20.01
diff --git a/docs/plat/xilinx-versal.rst b/docs/plat/xilinx-versal.rst
index d65b048..91ad6f1 100644
--- a/docs/plat/xilinx-versal.rst
+++ b/docs/plat/xilinx-versal.rst
@@ -43,6 +43,8 @@
* `VERSAL_PLATFORM`: Select the platform. Options:
- `versal_virt` : Versal Virtual platform
+ - `spp_itr6` : SPP ITR6
+ - `emu_it6` : EMU ITR6
# PLM->TF-A Parameter Passing
------------------------------
diff --git a/docs/plat/xilinx-zynqmp.rst b/docs/plat/xilinx-zynqmp.rst
index 79c2535..af1cb22 100644
--- a/docs/plat/xilinx-zynqmp.rst
+++ b/docs/plat/xilinx-zynqmp.rst
@@ -14,13 +14,13 @@
.. code:: bash
- make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp bl31
+ make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp RESET_TO_BL31=1 bl31
To build bl32 TSP you have to rebuild bl31 too:
.. code:: bash
- make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp SPD=tspd bl31 bl32
+ make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp SPD=tspd RESET_TO_BL31=1 bl31 bl32
To build TF-A for JTAG DCC console:
diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst
index f80389d..ef9ebd3 100644
--- a/docs/process/contributing.rst
+++ b/docs/process/contributing.rst
@@ -299,6 +299,6 @@
.. _TF-A Tests: https://trustedfirmware-a-tests.readthedocs.io
.. _Trusted Firmware binary repository: https://review.trustedfirmware.org/admin/repos/tf-binaries
.. _tf-binaries-readme: https://git.trustedfirmware.org/tf-binaries.git/tree/readme.rst
-.. _TF-A mailing list: https://lists.trustedfirmware.org/mailman/listinfo/tf-a
+.. _TF-A mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
.. _tf-a-ci-scripts repository: https://git.trustedfirmware.org/ci/tf-a-ci-scripts.git/
.. _tf-cov-make: https://git.trustedfirmware.org/ci/tf-a-ci-scripts.git/tree/script/tf-coverity/tf-cov-make
diff --git a/docs/process/platform-compatibility-policy.rst b/docs/process/platform-compatibility-policy.rst
index be1f9ba..a10236c 100644
--- a/docs/process/platform-compatibility-policy.rst
+++ b/docs/process/platform-compatibility-policy.rst
@@ -31,6 +31,6 @@
--------------
-*Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.*
-.. _TF-A public mailing list: https://lists.trustedfirmware.org/mailman/listinfo/tf-a
+.. _TF-A public mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
diff --git a/docs/process/security.rst b/docs/process/security.rst
index a3b9971..e15783b 100644
--- a/docs/process/security.rst
+++ b/docs/process/security.rst
@@ -71,7 +71,7 @@
+-----------+------------------------------------------------------------------+
.. _issue tracker: https://developer.trustedfirmware.org/project/board/1/
-.. _mailing list: https://lists.trustedfirmware.org/mailman/listinfo/tf-a
+.. _mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
.. |TFV-1| replace:: :ref:`Advisory TFV-1 (CVE-2016-10319)`
.. |TFV-2| replace:: :ref:`Advisory TFV-2 (CVE-2017-7564)`
@@ -86,4 +86,4 @@
--------------
-*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
diff --git a/drivers/arm/smmu/smmu_v3.c b/drivers/arm/smmu/smmu_v3.c
index a082a81..45f6df9 100644
--- a/drivers/arm/smmu/smmu_v3.c
+++ b/drivers/arm/smmu/smmu_v3.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +9,7 @@
#include <drivers/arm/smmu_v3.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
+#include <arch_features.h>
/* SMMU poll number of retries */
#define SMMU_POLL_TIMEOUT_US U(1000)
@@ -79,14 +80,74 @@
if (smmuv3_security_init(smmu_base) != 0)
return -1;
- /* Check if the SMMU supports secure state */
- if ((mmio_read_32(smmu_base + SMMU_S_IDR1) &
- SMMU_S_IDR1_SECURE_IMPL) == 0U)
- return 0;
+#if ENABLE_RME
+
+ if (get_armv9_2_feat_rme_support() != 0U) {
+ if ((mmio_read_32(smmu_base + SMMU_ROOT_IDR0) &
+ SMMU_ROOT_IDR0_ROOT_IMPL) == 0U) {
+ WARN("Skip SMMU GPC configuration.\n");
+ } else {
+ uint64_t gpccr_el3 = read_gpccr_el3();
+ uint64_t gptbr_el3 = read_gptbr_el3();
+
+ /* SMMU_ROOT_GPT_BASE_CFG[16] is RES0. */
+ gpccr_el3 &= ~(1UL << 16);
+
+ /*
+ * TODO: SMMU_ROOT_GPT_BASE_CFG is 64b in the spec,
+ * but SMMU model only accepts 32b access.
+ */
+ mmio_write_32(smmu_base + SMMU_ROOT_GPT_BASE_CFG,
+ gpccr_el3);
+
+ /*
+ * pa_gpt_table_base[51:12] maps to GPTBR_EL3[39:0]
+ * whereas it maps to SMMU_ROOT_GPT_BASE[51:12]
+ * hence needs a 12 bit left shit.
+ */
+ mmio_write_64(smmu_base + SMMU_ROOT_GPT_BASE,
+ gptbr_el3 << 12);
+
+ /*
+ * ACCESSEN=1: SMMU- and client-originated accesses are
+ * not terminated by this mechanism.
+ * GPCEN=1: All clients and SMMU-originated accesses,
+ * except GPT-walks, are subject to GPC.
+ */
+ mmio_setbits_32(smmu_base + SMMU_ROOT_CR0,
+ SMMU_ROOT_CR0_GPCEN |
+ SMMU_ROOT_CR0_ACCESSEN);
+
+ /* Poll for ACCESSEN and GPCEN ack bits. */
+ if (smmuv3_poll(smmu_base + SMMU_ROOT_CR0ACK,
+ SMMU_ROOT_CR0_GPCEN |
+ SMMU_ROOT_CR0_ACCESSEN,
+ SMMU_ROOT_CR0_GPCEN |
+ SMMU_ROOT_CR0_ACCESSEN) != 0) {
+ WARN("Failed enabling SMMU GPC.\n");
+
+ /*
+ * Do not return in error, but fall back to
+ * invalidating all entries through the secure
+ * register file.
+ */
+ }
+ }
+ }
+
+#endif /* ENABLE_RME */
+
/*
* Initiate invalidation of secure caches and TLBs if the SMMU
* supports secure state. If not, it's implementation defined
* as to how SMMU_S_INIT register is accessed.
+ * Arm SMMU Arch RME supplement, section 3.4: all SMMU registers
+ * specified to be accessible only in secure physical address space are
+ * additionally accessible in root physical address space in an SMMU
+ * with RME.
+ * Section 3.3: as GPT information is permitted to be cached in a TLB,
+ * the SMMU_S_INIT.INV_ALL mechanism also invalidates GPT information
+ * cached in TLBs.
*/
mmio_write_32(smmu_base + SMMU_S_INIT, SMMU_S_INIT_INV_ALL);
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index 0a4775d..3eb4161 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -48,6 +48,7 @@
rsa_internal.c \
x509.c \
x509_crt.c \
+ constant_time.c \
)
# The platform may define the variable 'TF_MBEDTLS_KEY_ALG' to select the key
diff --git a/drivers/st/clk/clk-stm32-core.c b/drivers/st/clk/clk-stm32-core.c
index 355c9da..e1b6940 100644
--- a/drivers/st/clk/clk-stm32-core.c
+++ b/drivers/st/clk/clk-stm32-core.c
@@ -327,6 +327,9 @@
}
old_parent = _clk_stm32_get_parent(priv, clk);
+ if (old_parent < 0) {
+ return old_parent;
+ }
if (old_parent == clkp) {
return 0;
}
@@ -415,7 +418,7 @@
sel = clk_mux_get_parent(priv, mux_id);
}
- if (sel < parent->num_parents) {
+ if ((sel >= 0) && (sel < parent->num_parents)) {
return parent->id_parents[sel];
}
@@ -488,6 +491,9 @@
}
parent = _clk_stm32_get_parent(priv, id);
+ if (parent < 0) {
+ return 0UL;
+ }
if (clk->ops->recalc_rate != NULL) {
unsigned long prate = 0UL;
@@ -517,6 +523,10 @@
{
int parent_id = _clk_stm32_get_parent(priv, id);
+ if (parent_id < 0) {
+ return 0UL;
+ }
+
return _clk_stm32_get_rate(priv, parent_id);
}
@@ -552,6 +562,9 @@
if (priv->gate_refcounts[id] == 0U) {
parent = _clk_stm32_get_parent(priv, id);
+ if (parent < 0) {
+ return parent;
+ }
if (parent != CLK_IS_ROOT) {
ret = _clk_stm32_enable_core(priv, parent);
if (ret) {
@@ -616,7 +629,7 @@
clk_stm32_disable_call_ops(priv, id);
parent = _clk_stm32_get_parent(priv, id);
- if (parent != CLK_IS_ROOT) {
+ if ((parent >= 0) && (parent != CLK_IS_ROOT)) {
_clk_stm32_disable_core(priv, parent);
}
}
@@ -1060,12 +1073,15 @@
uint32_t i;
cell = fdt_getprop(fdt, node, name, &len);
- if (cell != NULL) {
- for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
- uint32_t val = fdt32_to_cpu(cell[i]);
+ if (cell == NULL) {
+ *nb = 0U;
+ return 0;
+ }
- tab[i] = val;
- }
+ for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
+ uint32_t val = fdt32_to_cpu(cell[i]);
+
+ tab[i] = val;
}
*nb = (uint32_t)len / sizeof(uint32_t);
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index c71ff5a..7db6c0b 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -388,7 +388,6 @@
hd->prdto = (utrd->size_upiu + utrd->size_resp_upiu) >> 2;
}
- flush_dcache_range((uintptr_t)utrd, sizeof(utp_utrd_t));
flush_dcache_range((uintptr_t)utrd->header, UFS_DESC_SIZE);
return 0;
}
@@ -447,7 +446,6 @@
assert(0);
break;
}
- flush_dcache_range((uintptr_t)utrd, sizeof(utp_utrd_t));
flush_dcache_range((uintptr_t)utrd->header, UFS_DESC_SIZE);
return 0;
}
@@ -471,7 +469,6 @@
nop_out->trans_type = 0;
nop_out->task_tag = utrd->task_tag;
- flush_dcache_range((uintptr_t)utrd, sizeof(utp_utrd_t));
flush_dcache_range((uintptr_t)utrd->header, UFS_DESC_SIZE);
}
@@ -505,7 +502,6 @@
hd = (utrd_header_t *)utrd->header;
resp = (resp_upiu_t *)utrd->resp_upiu;
- inv_dcache_range((uintptr_t)hd, UFS_DESC_SIZE);
do {
data = mmio_read_32(ufs_params.reg_base + IS);
if ((data & ~(UFS_INT_UCCS | UFS_INT_UTRCS)) != 0)
@@ -515,6 +511,12 @@
data = mmio_read_32(ufs_params.reg_base + UTRLDBR);
assert((data & (1 << slot)) == 0);
+ /*
+ * Invalidate the header after DMA read operation has
+ * completed to avoid cpu referring to the prefetched
+ * data brought in before DMA completion.
+ */
+ inv_dcache_range((uintptr_t)hd, UFS_DESC_SIZE);
assert(hd->ocs == OCS_SUCCESS);
assert((resp->trans_type & TRANS_TYPE_CODE_MASK) == trans_type);
(void)resp;
@@ -690,7 +692,6 @@
sense_data_t *sense;
unsigned char data[CACHE_WRITEBACK_GRANULE << 1];
uintptr_t buf;
- int result;
int retry;
assert((ufs_params.reg_base != 0) &&
@@ -702,8 +703,6 @@
buf = (uintptr_t)data;
buf = (buf + CACHE_WRITEBACK_GRANULE - 1) &
~(CACHE_WRITEBACK_GRANULE - 1);
- memset((void *)buf, 0, CACHE_WRITEBACK_GRANULE);
- flush_dcache_range(buf, CACHE_WRITEBACK_GRANULE);
do {
ufs_send_cmd(&utrd, CDBCMD_READ_CAPACITY_10, lun, 0,
buf, READ_CAPACITY_LENGTH);
@@ -727,14 +726,12 @@
/* logical block length in bytes */
*size = be32toh(*(unsigned int *)(buf + 4));
} while (retry);
- (void)result;
}
size_t ufs_read_blocks(int lun, int lba, uintptr_t buf, size_t size)
{
utp_utrd_t utrd;
resp_upiu_t *resp;
- int result;
assert((ufs_params.reg_base != 0) &&
(ufs_params.desc_base != 0) &&
@@ -744,8 +741,12 @@
#ifdef UFS_RESP_DEBUG
dump_upiu(&utrd);
#endif
+ /*
+ * Invalidate prefetched cache contents before cpu
+ * accesses the buf.
+ */
+ inv_dcache_range(buf, size);
resp = (resp_upiu_t *)utrd.resp_upiu;
- (void)result;
return size - resp->res_trans_cnt;
}
@@ -753,7 +754,6 @@
{
utp_utrd_t utrd;
resp_upiu_t *resp;
- int result;
assert((ufs_params.reg_base != 0) &&
(ufs_params.desc_base != 0) &&
@@ -764,7 +764,6 @@
dump_upiu(&utrd);
#endif
resp = (resp_upiu_t *)utrd.resp_upiu;
- (void)result;
return size - resp->res_trans_cnt;
}
diff --git a/fdts/stm32mp131.dtsi b/fdts/stm32mp131.dtsi
index dff1b33..adf7a91 100644
--- a/fdts/stm32mp131.dtsi
+++ b/fdts/stm32mp131.dtsi
@@ -26,26 +26,6 @@
};
};
- nvmem_layout: nvmem_layout@0 {
- compatible = "st,stm32-nvmem-layout";
-
- nvmem-cells = <&cfg0_otp>,
- <&part_number_otp>,
- <&monotonic_otp>,
- <&nand_otp>,
- <&nand2_otp>,
- <&uid_otp>,
- <&hw2_otp>;
-
- nvmem-cell-names = "cfg0_otp",
- "part_number_otp",
- "monotonic_otp",
- "nand_otp",
- "nand2_otp",
- "uid_otp",
- "hw2_otp";
- };
-
clocks {
clk_csi: clk-csi {
#clock-cells = <0>;
diff --git a/fdts/stm32mp135f-dk.dts b/fdts/stm32mp135f-dk.dts
index 0fa064b..6240381 100644
--- a/fdts/stm32mp135f-dk.dts
+++ b/fdts/stm32mp135f-dk.dts
@@ -175,28 +175,6 @@
status = "okay";
};
-&nvmem_layout {
- nvmem-cells = <&cfg0_otp>,
- <&part_number_otp>,
- <&monotonic_otp>,
- <&nand_otp>,
- <&nand2_otp>,
- <&uid_otp>,
- <&hw2_otp>,
- <&pkh_otp>,
- <&board_id>;
-
- nvmem-cell-names = "cfg0_otp",
- "part_number_otp",
- "monotonic_otp",
- "nand_otp",
- "nand2_otp",
- "uid_otp",
- "hw2_otp",
- "pkh_otp",
- "board_id";
-};
-
&pka {
secure-status = "okay";
};
diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi
index 454e124..63cc917 100644
--- a/fdts/stm32mp151.dtsi
+++ b/fdts/stm32mp151.dtsi
@@ -24,26 +24,6 @@
};
};
- nvmem_layout: nvmem_layout@0 {
- compatible = "st,stm32-nvmem-layout";
-
- nvmem-cells = <&cfg0_otp>,
- <&part_number_otp>,
- <&monotonic_otp>,
- <&nand_otp>,
- <&uid_otp>,
- <&package_otp>,
- <&hw2_otp>;
-
- nvmem-cell-names = "cfg0_otp",
- "part_number_otp",
- "monotonic_otp",
- "nand_otp",
- "uid_otp",
- "package_otp",
- "hw2_otp";
- };
-
psci {
compatible = "arm,psci-1.0";
method = "smc";
diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts
index 44c7016..659e8bf 100644
--- a/fdts/stm32mp157c-ed1.dts
+++ b/fdts/stm32mp157c-ed1.dts
@@ -195,26 +195,6 @@
status = "okay";
};
-&nvmem_layout {
- nvmem-cells = <&cfg0_otp>,
- <&part_number_otp>,
- <&monotonic_otp>,
- <&nand_otp>,
- <&uid_otp>,
- <&package_otp>,
- <&hw2_otp>,
- <&board_id>;
-
- nvmem-cell-names = "cfg0_otp",
- "part_number_otp",
- "monotonic_otp",
- "nand_otp",
- "uid_otp",
- "package_otp",
- "hw2_otp",
- "board_id";
-};
-
&pwr_regulators {
vdd-supply = <&vdd>;
vdd_3v3_usbfs-supply = <&vdd_usb>;
diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi
index 2eb3a57..05eb46a 100644
--- a/fdts/stm32mp15xx-dkx.dtsi
+++ b/fdts/stm32mp15xx-dkx.dtsi
@@ -183,26 +183,6 @@
secure-status = "okay";
};
-&nvmem_layout {
- nvmem-cells = <&cfg0_otp>,
- <&part_number_otp>,
- <&monotonic_otp>,
- <&nand_otp>,
- <&uid_otp>,
- <&package_otp>,
- <&hw2_otp>,
- <&board_id>;
-
- nvmem-cell-names = "cfg0_otp",
- "part_number_otp",
- "monotonic_otp",
- "nand_otp",
- "uid_otp",
- "package_otp",
- "hw2_otp",
- "board_id";
-};
-
&pwr_regulators {
vdd-supply = <&vdd>;
vdd_3v3_usbfs-supply = <&vdd_usb>;
diff --git a/fdts/tc.dts b/fdts/tc.dts
index 7c0e842..2099229 100644
--- a/fdts/tc.dts
+++ b/fdts/tc.dts
@@ -261,6 +261,12 @@
arm,mhuv2-protocols = <0 1>;
};
+ cmn-pmu {
+ compatible = "arm,ci-700";
+ reg = <0x0 0x50000000 0x0 0x10000000>;
+ interrupts = <0x0 460 0x4>;
+ };
+
scmi {
compatible = "arm,scmi";
mbox-names = "tx", "rx";
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index b4608ae..bbbc77a 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -234,6 +234,11 @@
#define ID_AA64DFR0_MTPMU_MASK ULL(0xf)
#define ID_AA64DFR0_MTPMU_SUPPORTED ULL(1)
+/* ID_AA64DFR0_EL1.BRBE definitions */
+#define ID_AA64DFR0_BRBE_SHIFT U(52)
+#define ID_AA64DFR0_BRBE_MASK ULL(0xf)
+#define ID_AA64DFR0_BRBE_SUPPORTED ULL(1)
+
/* ID_AA64ISAR0_EL1 definitions */
#define ID_AA64ISAR0_RNDR_SHIFT U(60)
#define ID_AA64ISAR0_RNDR_MASK ULL(0xf)
@@ -512,6 +517,8 @@
#define MDCR_EnPMSN_BIT (ULL(1) << 36)
#define MDCR_MPMX_BIT (ULL(1) << 35)
#define MDCR_MCCD_BIT (ULL(1) << 34)
+#define MDCR_SBRBE_SHIFT U(32)
+#define MDCR_SBRBE_MASK ULL(0x3)
#define MDCR_NSTB(x) ((x) << 24)
#define MDCR_NSTB_EL1 ULL(0x3)
#define MDCR_NSTBE (ULL(1) << 26)
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index 8cb4990..3a06cfb 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -81,6 +81,10 @@
#define __RODATA_END__ Load$$__RODATA_EPILOGUE__$$Base
#define __RT_SVC_DESCS_START__ Load$$__RT_SVC_DESCS__$$Base
#define __RT_SVC_DESCS_END__ Load$$__RT_SVC_DESCS__$$Limit
+#if SPMC_AT_EL3
+#define __EL3_LP_DESCS_START__ Load$$__EL3_LP_DESCS__$$Base
+#define __EL3_LP_DESCS_END__ Load$$__EL3_LP_DESCS__$$Limit
+#endif
#define __RW_START__ Load$$LR$$LR_RW_DATA$$Base
#define __RW_END__ Load$$LR$$LR_END$$Base
#define __SPM_SHIM_EXCEPTIONS_START__ Load$$__SPM_SHIM_EXCEPTIONS__$$Base
diff --git a/include/common/bl_common.ld.h b/include/common/bl_common.ld.h
index 9888a3c..080e331 100644
--- a/include/common/bl_common.ld.h
+++ b/include/common/bl_common.ld.h
@@ -39,6 +39,16 @@
KEEP(*(rt_svc_descs)) \
__RT_SVC_DESCS_END__ = .;
+#if SPMC_AT_EL3
+#define EL3_LP_DESCS \
+ . = ALIGN(STRUCT_ALIGN); \
+ __EL3_LP_DESCS_START__ = .; \
+ KEEP(*(el3_lp_descs)) \
+ __EL3_LP_DESCS_END__ = .;
+#else
+#define EL3_LP_DESCS
+#endif
+
#define PMF_SVC_DESCS \
. = ALIGN(STRUCT_ALIGN); \
__PMF_SVC_DESCS_START__ = .; \
@@ -89,7 +99,8 @@
PARSER_LIB_DESCS \
CPU_OPS \
GOT \
- BASE_XLAT_TABLE_RO
+ BASE_XLAT_TABLE_RO \
+ EL3_LP_DESCS
/*
* .data must be placed at a lower address than the stacks if the stack
diff --git a/include/common/fdt_fixup.h b/include/common/fdt_fixup.h
index 7a590b2..c35e9be 100644
--- a/include/common/fdt_fixup.h
+++ b/include/common/fdt_fixup.h
@@ -7,14 +7,29 @@
#ifndef FDT_FIXUP_H
#define FDT_FIXUP_H
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
#define INVALID_BASE_ADDR ((uintptr_t)~0UL)
+struct psci_cpu_idle_state {
+ const char *name;
+ uint32_t power_state;
+ bool local_timer_stop;
+ uint32_t entry_latency_us;
+ uint32_t exit_latency_us;
+ uint32_t min_residency_us;
+ uint32_t wakeup_latency_us;
+};
+
int dt_add_psci_node(void *fdt);
int dt_add_psci_cpu_enable_methods(void *fdt);
int fdt_add_reserved_memory(void *dtb, const char *node_name,
uintptr_t base, size_t size);
int fdt_add_cpus_node(void *dtb, unsigned int afflv0,
unsigned int afflv1, unsigned int afflv2);
+int fdt_add_cpu_idle_states(void *dtb, const struct psci_cpu_idle_state *state);
int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores, uintptr_t gicr_base,
unsigned int gicr_frame_size);
diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h
index 9c7180c..2929fc2 100644
--- a/include/common/fdt_wrappers.h
+++ b/include/common/fdt_wrappers.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -44,6 +44,8 @@
int fdtw_for_each_cpu(const void *fdt,
int (*callback)(const void *dtb, int node, uintptr_t mpidr));
+int fdtw_find_or_add_subnode(void *fdt, int parentoffset, const char *name);
+
static inline uint32_t fdt_blob_size(const void *dtb)
{
const uint32_t *dtb_header = dtb;
diff --git a/include/drivers/arm/smmu_v3.h b/include/drivers/arm/smmu_v3.h
index a820a44..e60c754 100644
--- a/include/drivers/arm/smmu_v3.h
+++ b/include/drivers/arm/smmu_v3.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +9,7 @@
#include <stdint.h>
#include <lib/utils_def.h>
+#include <platform_def.h>
/* SMMUv3 register offsets from device base */
#define SMMU_GBPA U(0x0044)
@@ -16,6 +17,26 @@
#define SMMU_S_INIT U(0x803c)
#define SMMU_S_GBPA U(0x8044)
+/*
+ * TODO: SMMU_ROOT_PAGE_OFFSET is platform specific.
+ * Currently defined as a command line model parameter.
+ */
+#if ENABLE_RME
+
+#define SMMU_ROOT_PAGE_OFFSET (PLAT_ARM_SMMUV3_ROOT_REG_OFFSET)
+#define SMMU_ROOT_IDR0 U(SMMU_ROOT_PAGE_OFFSET + 0x0000)
+#define SMMU_ROOT_IIDR U(SMMU_ROOT_PAGE_OFFSET + 0x0008)
+#define SMMU_ROOT_CR0 U(SMMU_ROOT_PAGE_OFFSET + 0x0020)
+#define SMMU_ROOT_CR0ACK U(SMMU_ROOT_PAGE_OFFSET + 0x0024)
+#define SMMU_ROOT_GPT_BASE U(SMMU_ROOT_PAGE_OFFSET + 0x0028)
+#define SMMU_ROOT_GPT_BASE_CFG U(SMMU_ROOT_PAGE_OFFSET + 0x0030)
+#define SMMU_ROOT_GPF_FAR U(SMMU_ROOT_PAGE_OFFSET + 0x0038)
+#define SMMU_ROOT_GPT_CFG_FAR U(SMMU_ROOT_PAGE_OFFSET + 0x0040)
+#define SMMU_ROOT_TLBI U(SMMU_ROOT_PAGE_OFFSET + 0x0050)
+#define SMMU_ROOT_TLBI_CTRL U(SMMU_ROOT_PAGE_OFFSET + 0x0058)
+
+#endif /* ENABLE_RME */
+
/* SMMU_GBPA register fields */
#define SMMU_GBPA_UPDATE (1UL << 31)
#define SMMU_GBPA_ABORT (1UL << 20)
@@ -30,6 +51,13 @@
#define SMMU_S_GBPA_UPDATE (1UL << 31)
#define SMMU_S_GBPA_ABORT (1UL << 20)
+/* SMMU_ROOT_IDR0 register fields */
+#define SMMU_ROOT_IDR0_ROOT_IMPL (1UL << 0)
+
+/* SMMU_ROOT_CR0 register fields */
+#define SMMU_ROOT_CR0_GPCEN (1UL << 1)
+#define SMMU_ROOT_CR0_ACCESSEN (1UL << 0)
+
int smmuv3_init(uintptr_t smmu_base);
int smmuv3_security_init(uintptr_t smmu_base);
diff --git a/include/lib/cpus/aarch64/cortex_x2.h b/include/lib/cpus/aarch64/cortex_x2.h
index 62530e2..92140b1 100644
--- a/include/lib/cpus/aarch64/cortex_x2.h
+++ b/include/lib/cpus/aarch64/cortex_x2.h
@@ -34,6 +34,12 @@
#define CORTEX_X2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1)
/*******************************************************************************
+ * CPU Auxiliary Control Register definitions
+ ******************************************************************************/
+#define CORTEX_X2_CPUACTLR_EL1 S3_0_C15_C1_0
+#define CORTEX_X2_CPUACTLR_EL1_BIT_22 (ULL(1) << 22)
+
+/*******************************************************************************
* CPU Auxiliary Control Register 5 definitions
******************************************************************************/
#define CORTEX_X2_CPUACTLR5_EL1 S3_0_C15_C8_0
diff --git a/include/lib/extensions/brbe.h b/include/lib/extensions/brbe.h
new file mode 100644
index 0000000..aac1ace
--- /dev/null
+++ b/include/lib/extensions/brbe.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BRBE_H
+#define BRBE_H
+
+void brbe_enable(void);
+
+#endif /* BRBE_H */
diff --git a/include/lib/extensions/twed.h b/include/lib/extensions/twed.h
deleted file mode 100644
index eac4aa3..0000000
--- a/include/lib/extensions/twed.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef TWED_H
-#define TWED_H
-
-#include <stdint.h>
-
-#define TWED_DISABLED U(0xFFFFFFFF)
-
-uint32_t plat_arm_set_twedel_scr_el3(void);
-
-#endif /* TWEDE_H */
diff --git a/include/lib/fconf/fconf_dyn_cfg_getter.h b/include/lib/fconf/fconf_dyn_cfg_getter.h
index ff51c6c..43f298e 100644
--- a/include/lib/fconf/fconf_dyn_cfg_getter.h
+++ b/include/lib/fconf/fconf_dyn_cfg_getter.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,6 +18,13 @@
uintptr_t config_addr;
uint32_t config_max_size;
unsigned int config_id;
+ /*
+ * Load address in non-secure memory. Only needed by those
+ * configuration files which require being loaded in secure
+ * memory (at config_addr) as well as in non-secure memory
+ * - e.g. HW_CONFIG
+ */
+ uintptr_t ns_config_addr;
};
unsigned int dyn_cfg_dtb_info_get_index(unsigned int config_id);
@@ -25,7 +32,8 @@
int fconf_populate_dtb_registry(uintptr_t config);
/* Set config information in global DTB array */
-void set_config_info(uintptr_t config_addr, uint32_t config_max_size,
- unsigned int config_id);
+void set_config_info(uintptr_t config_addr, uintptr_t ns_config_addr,
+ uint32_t config_max_size,
+ unsigned int config_id);
#endif /* FCONF_DYN_CFG_GETTER_H */
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 2af8c11..a8211bd 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -284,12 +284,10 @@
ARM_EL3_TZC_DRAM1_SIZE, \
MT_MEMORY | MT_RW | EL3_PAS)
-#if defined(SPD_spmd)
#define ARM_MAP_TRUSTED_DRAM MAP_REGION_FLAT( \
PLAT_ARM_TRUSTED_DRAM_BASE, \
PLAT_ARM_TRUSTED_DRAM_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
-#endif
#if ENABLE_RME
#define ARM_MAP_RMM_DRAM MAP_REGION_FLAT( \
@@ -620,7 +618,7 @@
* Trusted DRAM (if available) or the DRAM region secured by the TrustZone
* controller.
*/
-# if SPM_MM
+# if SPM_MM || SPMC_AT_EL3
# define TSP_SEC_MEM_BASE (ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
# define TSP_SEC_MEM_SIZE (ARM_AP_TZC_DRAM1_SIZE - ULL(0x200000))
# define BL32_BASE (ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
@@ -666,12 +664,13 @@
/*
* BL32 is mandatory in AArch32. In AArch64, undefine BL32_BASE if there is no
- * SPD and no SPM-MM, as they are the only ones that can be used as BL32.
+ * SPD and no SPM-MM and no SPMC-AT-EL3, as they are the only ones that can be
+ * used as BL32.
*/
#if defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME
-# if defined(SPD_none) && !SPM_MM
+# if defined(SPD_none) && !SPM_MM && !SPMC_AT_EL3
# undef BL32_BASE
-# endif /* defined(SPD_none) && !SPM_MM */
+# endif /* defined(SPD_none) && !SPM_MM || !SPMC_AT_EL3 */
#endif /* defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME */
/*******************************************************************************
diff --git a/include/services/el3_spmc_logical_sp.h b/include/services/el3_spmc_logical_sp.h
new file mode 100644
index 0000000..7ec9958
--- /dev/null
+++ b/include/services/el3_spmc_logical_sp.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef EL3_SP_H
+#define EL3_SP_H
+
+#include <common/bl_common.h>
+#include <lib/cassert.h>
+
+/*******************************************************************************
+ * Structure definition, typedefs & constants for the Logical SPs.
+ ******************************************************************************/
+
+typedef uint64_t (*direct_msg_handler)(uint32_t smc_fid, bool secure_origin,
+ uint64_t x1, uint64_t x2, uint64_t x3,
+ uint64_t x4, void *cookie, void *handle,
+ uint64_t flags);
+
+/* Prototype for logical partition initializing function. */
+typedef int32_t (*ffa_partition_init_t)(void);
+
+/* Logical Partition Descriptor. */
+struct el3_lp_desc {
+ ffa_partition_init_t init;
+ uint16_t sp_id;
+ uint32_t properties;
+ uint32_t uuid[4]; /* Little Endian. */
+ direct_msg_handler direct_req;
+ const char *debug_name;
+};
+
+/* Convenience macro to declare a logical partition descriptor. */
+#define DECLARE_LOGICAL_PARTITION(_name, _init, _sp_id, _uuid, _properties, \
+ _direct_req) \
+ static const struct el3_lp_desc __partition_desc_ ## _name \
+ __section("el3_lp_descs") __used = { \
+ .debug_name = #_name, \
+ .init = (_init), \
+ .sp_id = (_sp_id), \
+ .uuid = _uuid, \
+ .properties = (_properties), \
+ .direct_req = (_direct_req), \
+ }
+
+
+/*******************************************************************************
+ * Function & variable prototypes.
+ ******************************************************************************/
+int el3_sp_desc_validate(void);
+uintptr_t handle_el3_sp(uint32_t smc_fid, void *cookie, void *handle,
+ unsigned int flags);
+IMPORT_SYM(uintptr_t, __EL3_LP_DESCS_START__, EL3_LP_DESCS_START);
+IMPORT_SYM(uintptr_t, __EL3_LP_DESCS_END__, EL3_LP_DESCS_END);
+
+#define EL3_LP_DESCS_COUNT ((EL3_LP_DESCS_END - EL3_LP_DESCS_START) \
+ / sizeof(struct el3_lp_desc))
+
+#endif /* EL3_SP_H */
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
index 9a7c489..2b4a377 100644
--- a/include/services/ffa_svc.h
+++ b/include/services/ffa_svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +7,8 @@
#ifndef FFA_SVC_H
#define FFA_SVC_H
+#include <stdbool.h>
+
#include <lib/smccc.h>
#include <lib/utils_def.h>
#include <tools_share/uuid.h>
@@ -107,6 +109,7 @@
#define FFA_VERSION FFA_FID(SMC_32, FFA_FNUM_VERSION)
#define FFA_FEATURES FFA_FID(SMC_32, FFA_FNUM_FEATURES)
#define FFA_RX_RELEASE FFA_FID(SMC_32, FFA_FNUM_RX_RELEASE)
+#define FFA_RX_ACQUIRE FFA_FID(SMC_32, FFA_FNUM_RX_ACQUIRE)
#define FFA_RXTX_MAP_SMC32 FFA_FID(SMC_32, FFA_FNUM_RXTX_MAP)
#define FFA_RXTX_UNMAP FFA_FID(SMC_32, FFA_FNUM_RXTX_UNMAP)
#define FFA_PARTITION_INFO_GET FFA_FID(SMC_32, FFA_FNUM_PARTITION_INFO_GET)
@@ -161,6 +164,13 @@
FFA_FID(SMC_64, FFA_FNUM_NOTIFICATION_INFO_GET)
/*
+ * FF-A partition properties values.
+ */
+#define FFA_PARTITION_DIRECT_REQ_RECV U(1 << 0)
+#define FFA_PARTITION_DIRECT_REQ_SEND U(1 << 1)
+#define FFA_PARTITION_INDIRECT_MSG U(1 << 2)
+
+/*
* Reserve a special value for traffic targeted to the Hypervisor or SPM.
*/
#define FFA_TARGET_INFO_MBZ U(0x0)
@@ -176,6 +186,15 @@
#define FFA_ENDPOINT_ID_MAX U(1 << 16)
/*
+ * Reserve endpoint id for the SPMD.
+ */
+#define SPMD_DIRECT_MSG_ENDPOINT_ID U(FFA_ENDPOINT_ID_MAX - 1)
+
+/* Mask and shift to check valid secure FF-A Endpoint ID. */
+#define SPMC_SECURE_ID_MASK U(1)
+#define SPMC_SECURE_ID_SHIFT U(15)
+
+/*
* Mask for source and destination endpoint id in
* a direct message request/response.
*/
@@ -209,4 +228,24 @@
FFA_DIRECT_MSG_ENDPOINT_ID_MASK;
}
+/******************************************************************************
+ * FF-A helper functions to determine partition ID world.
+ *****************************************************************************/
+
+/*
+ * Determine if provided ID is in the secure world.
+ */
+static inline bool ffa_is_secure_world_id(uint16_t id)
+{
+ return ((id >> SPMC_SECURE_ID_SHIFT) & SPMC_SECURE_ID_MASK) == 1;
+}
+
+/*
+ * Determine if provided ID is in the normal world.
+ */
+static inline bool ffa_is_normal_world_id(uint16_t id)
+{
+ return !ffa_is_secure_world_id(id);
+}
+
#endif /* FFA_SVC_H */
diff --git a/include/services/spmc_svc.h b/include/services/spmc_svc.h
new file mode 100644
index 0000000..8ee61e9
--- /dev/null
+++ b/include/services/spmc_svc.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPMC_SVC_H
+#define SPMC_SVC_H
+
+#ifndef __ASSEMBLER__
+#include <stdint.h>
+
+#include <lib/utils_def.h>
+#include <services/ffa_svc.h>
+#include <services/spm_core_manifest.h>
+
+int spmc_setup(void);
+void spmc_populate_attrs(spmc_manifest_attribute_t *spmc_attrs);
+void *spmc_get_config_addr(void);
+
+void spmc_set_config_addr(uintptr_t soc_fw_config);
+
+uint64_t spmc_smc_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags);
+
+static inline bool is_spmc_at_el3(void)
+{
+ return SPMC_AT_EL3 == 1;
+}
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* SPMC_SVC_H */
diff --git a/include/services/spmd_svc.h b/include/services/spmd_svc.h
index 1e7e6aa..29dfdad 100644
--- a/include/services/spmd_svc.h
+++ b/include/services/spmd_svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,6 +12,14 @@
#include <stdint.h>
int spmd_setup(void);
+uint64_t spmd_ffa_smc_handler(uint32_t smc_fid,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags);
uint64_t spmd_smc_handler(uint32_t smc_fid,
uint64_t x1,
uint64_t x2,
@@ -20,6 +28,13 @@
void *cookie,
void *handle,
uint64_t flags);
+uint64_t spmd_smc_switch_state(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *handle);
#endif /* __ASSEMBLER__ */
#endif /* SPMD_SVC_H */
diff --git a/include/tools_share/sptool.h b/include/tools_share/sptool.h
deleted file mode 100644
index 53668e0..0000000
--- a/include/tools_share/sptool.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPTOOL_H
-#define SPTOOL_H
-
-#include <stdint.h>
-
-/* 4 Byte magic name "SPKG" */
-#define SECURE_PARTITION_MAGIC 0x474B5053
-
-/* Header for a secure partition package. */
-struct sp_pkg_header {
- uint32_t magic;
- uint32_t version;
- uint32_t pm_offset;
- uint32_t pm_size;
- uint32_t img_offset;
- uint32_t img_size;
-};
-
-#endif /* SPTOOL_H */
diff --git a/lib/cpus/aarch32/cortex_a15.S b/lib/cpus/aarch32/cortex_a15.S
index ab136ad..1143e9b 100644
--- a/lib/cpus/aarch32/cortex_a15.S
+++ b/lib/cpus/aarch32/cortex_a15.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -100,6 +100,15 @@
bx lr
endfunc check_errata_cve_2017_5715
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+ mov r0, #ERRATA_APPLIES
+#else
+ mov r0, #ERRATA_MISSING
+#endif
+ bx lr
+endfunc check_errata_cve_2022_23960
+
#if REPORT_ERRATA
/*
* Errata printing function for Cortex A15. Must follow AAPCS.
@@ -117,6 +126,7 @@
report_errata ERRATA_A15_816470, cortex_a15, 816470
report_errata ERRATA_A15_827671, cortex_a15, 827671
report_errata WORKAROUND_CVE_2017_5715, cortex_a15, cve_2017_5715
+ report_errata WORKAROUND_CVE_2022_23960, cortex_a15, cve_2022_23960
pop {r12, lr}
bx lr
@@ -131,11 +141,11 @@
bl errata_a15_827671_wa
#endif
-#if IMAGE_BL32 && WORKAROUND_CVE_2017_5715
+#if IMAGE_BL32 && (WORKAROUND_CVE_2017_5715 || WORKAROUND_CVE_2022_23960)
ldcopr r0, ACTLR
orr r0, #CORTEX_A15_ACTLR_INV_BTB_BIT
stcopr r0, ACTLR
- ldr r0, =workaround_icache_inv_runtime_exceptions
+ ldr r0, =wa_cve_2017_5715_icache_inv_vbar
stcopr r0, VBAR
stcopr r0, MVBAR
/* isb will be applied in the course of the reset func */
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index 9586a5b..90a906b 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -237,6 +237,36 @@
ret
endfunc check_errata_cve_2022_23960
+ /* ---------------------------------------------------------
+ * Errata Workaround for Cortex-X2 Errata 2147715.
+ * This applies only to revisions r2p0 and is fixed in r2p1.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0, x1, x17
+ * ---------------------------------------------------------
+ */
+func errata_x2_2147715_wa
+ /* Compare x0 against revision r2p0 */
+ mov x17, x30
+ bl check_errata_2147715
+ cbz x0, 1f
+
+ /* Apply the workaround by setting bit 22 in CPUACTLR_EL1. */
+ mrs x1, CORTEX_X2_CPUACTLR_EL1
+ orr x1, x1, CORTEX_X2_CPUACTLR_EL1_BIT_22
+ msr CORTEX_X2_CPUACTLR_EL1, x1
+
+1:
+ ret x17
+endfunc errata_x2_2147715_wa
+
+func check_errata_2147715
+ /* Applies to r2p0 */
+ mov x1, #0x20
+ mov x2, #0x20
+ b cpu_rev_var_range
+endfunc check_errata_2147715
+
/* ----------------------------------------------------
* HW will do the cache maintenance while powering down
* ----------------------------------------------------
@@ -268,10 +298,11 @@
* checking functions of each errata.
*/
report_errata ERRATA_X2_2002765, cortex_x2, 2002765
- report_errata ERRATA_X2_2058056, cortex_x2, 2058056
- report_errata ERRATA_X2_2083908, cortex_x2, 2083908
report_errata ERRATA_X2_2017096, cortex_x2, 2017096
+ report_errata ERRATA_X2_2058056, cortex_x2, 2058056
report_errata ERRATA_X2_2081180, cortex_x2, 2081180
+ report_errata ERRATA_X2_2083908, cortex_x2, 2083908
+ report_errata ERRATA_X2_2147715, cortex_x2, 2147715
report_errata ERRATA_X2_2216384, cortex_x2, 2216384
report_errata WORKAROUND_CVE_2022_23960, cortex_x2, cve_2022_23960
@@ -321,6 +352,11 @@
bl errata_x2_2216384_wa
#endif
+#if ERRATA_X2_2147715
+ mov x0, x18
+ bl errata_x2_2147715_wa
+#endif
+
#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
/*
* The Cortex-X2 generic vectors are overridden to apply errata
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 8840f8e..462ca9d 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -547,6 +547,10 @@
# r2p1.
ERRATA_X2_2216384 ?=0
+# Flag to apply erratum 2147715 workaround during reset. This erratum applies
+# only to revision r2p0 of the Cortex-X2 cpu, it is fixed in r2p1.
+ERRATA_X2_2147715 ?=0
+
# Flag to apply erratum 1922240 workaround during reset. This erratum applies
# to revision r0p0 of the Cortex-A510 cpu and is fixed in r0p1.
ERRATA_A510_1922240 ?=0
@@ -1046,6 +1050,10 @@
$(eval $(call assert_boolean,ERRATA_X2_2216384))
$(eval $(call add_define,ERRATA_X2_2216384))
+# Process ERRATA_X2_2147715 flag
+$(eval $(call assert_boolean,ERRATA_X2_2147715))
+$(eval $(call add_define,ERRATA_X2_2147715))
+
# Process ERRATA_A510_1922240 flag
$(eval $(call assert_boolean,ERRATA_A510_1922240))
$(eval $(call add_define,ERRATA_A510_1922240))
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 459ca2c..449f120 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -20,6 +20,7 @@
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/el3_runtime/pubsub_events.h>
#include <lib/extensions/amu.h>
+#include <lib/extensions/brbe.h>
#include <lib/extensions/mpam.h>
#include <lib/extensions/sme.h>
#include <lib/extensions/spe.h>
@@ -27,11 +28,14 @@
#include <lib/extensions/sys_reg_trace.h>
#include <lib/extensions/trbe.h>
#include <lib/extensions/trf.h>
-#include <lib/extensions/twed.h>
#include <lib/utils.h>
-static void manage_extensions_secure(cpu_context_t *ctx);
+#if ENABLE_FEAT_TWED
+/* Make sure delay value fits within the range(0-15) */
+CASSERT(((TWED_DELAY & ~SCR_TWEDEL_MASK) == 0U), assert_twed_delay_value_check);
+#endif /* ENABLE_FEAT_TWED */
+static void manage_extensions_secure(cpu_context_t *ctx);
/******************************************************************************
* This function performs initializations that are specific to SECURE state
* and updates the cpu context specified by 'ctx'.
@@ -329,23 +333,16 @@
sctlr_elx |= SCTLR_IESB_BIT;
#endif
+#if ENABLE_FEAT_TWED
/* Enable WFE trap delay in SCR_EL3 if supported and configured */
- if (is_armv8_6_twed_present()) {
- uint32_t delay = plat_arm_set_twedel_scr_el3();
+ /* Set delay in SCR_EL3 */
+ scr_el3 &= ~(SCR_TWEDEL_MASK << SCR_TWEDEL_SHIFT);
+ scr_el3 |= ((TWED_DELAY & SCR_TWEDEL_MASK)
+ << SCR_TWEDEL_SHIFT);
- if (delay != TWED_DISABLED) {
- /* Make sure delay value fits */
- assert((delay & ~SCR_TWEDEL_MASK) == 0U);
-
- /* Set delay in SCR_EL3 */
- scr_el3 &= ~(SCR_TWEDEL_MASK << SCR_TWEDEL_SHIFT);
- scr_el3 |= ((delay & SCR_TWEDEL_MASK)
- << SCR_TWEDEL_SHIFT);
-
- /* Enable WFE delay */
- scr_el3 |= SCR_TWEDEn_BIT;
- }
- }
+ /* Enable WFE delay */
+ scr_el3 |= SCR_TWEDEn_BIT;
+#endif /* ENABLE_FEAT_TWED */
/*
* Store the initialised SCTLR_EL1 value in the cpu_context - SCTLR_EL2
@@ -473,6 +470,10 @@
trbe_enable();
#endif /* ENABLE_TRBE_FOR_NS */
+#if ENABLE_BRBE_FOR_NS
+ brbe_enable();
+#endif /* ENABLE_BRBE_FOR_NS */
+
#if ENABLE_SYS_REG_TRACE_FOR_NS
sys_reg_trace_enable(ctx);
#endif /* ENABLE_SYS_REG_TRACE_FOR_NS */
diff --git a/lib/extensions/brbe/brbe.c b/lib/extensions/brbe/brbe.c
new file mode 100644
index 0000000..6975b04
--- /dev/null
+++ b/lib/extensions/brbe/brbe.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+
+static bool brbe_supported(void)
+{
+ uint64_t features;
+
+ features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_BRBE_SHIFT;
+ return ((features & ID_AA64DFR0_BRBE_MASK) ==
+ ID_AA64DFR0_BRBE_SUPPORTED);
+}
+
+void brbe_enable(void)
+{
+ uint64_t val;
+
+ if (brbe_supported()) {
+ /*
+ * MDCR_EL3.SBRBE = 0b01
+ *
+ * Allows BRBE usage in non-secure world and prohibited in
+ * secure world.
+ */
+ val = read_mdcr_el3();
+ val &= ~(MDCR_SBRBE_MASK << MDCR_SBRBE_SHIFT);
+ val |= (0x1UL << MDCR_SBRBE_SHIFT);
+ write_mdcr_el3(val);
+ }
+}
diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c
index 34623fb..3038c09 100644
--- a/lib/fconf/fconf_dyn_cfg_getter.c
+++ b/lib/fconf/fconf_dyn_cfg_getter.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -29,13 +29,15 @@
* This function is used to alloc memory for config information from
* global pool and set the configuration information.
*/
-void set_config_info(uintptr_t config_addr, uint32_t config_max_size,
- unsigned int config_id)
+void set_config_info(uintptr_t config_addr, uintptr_t ns_config_addr,
+ uint32_t config_max_size,
+ unsigned int config_id)
{
struct dyn_cfg_dtb_info_t *dtb_info;
dtb_info = pool_alloc(&dtb_info_pool);
dtb_info->config_addr = config_addr;
+ dtb_info->ns_config_addr = ns_config_addr;
dtb_info->config_max_size = config_max_size;
dtb_info->config_id = config_id;
}
@@ -88,7 +90,7 @@
*/
if (dtb_infos[0].config_id == 0U) {
uint32_t config_max_size = fdt_totalsize(dtb);
- set_config_info(config, config_max_size, FW_CONFIG_ID);
+ set_config_info(config, ~0UL, config_max_size, FW_CONFIG_ID);
}
/* Find the node offset point to "fconf,dyn_cfg-dtb_registry" compatible property */
@@ -102,6 +104,7 @@
fdt_for_each_subnode(child, dtb, node) {
uint32_t config_max_size, config_id;
uintptr_t config_addr;
+ uintptr_t ns_config_addr = ~0UL;
uint64_t val64;
/* Read configuration dtb information */
@@ -129,7 +132,14 @@
VERBOSE("\tmax-size = 0x%x\n", config_max_size);
VERBOSE("\tconfig-id = %u\n", config_id);
- set_config_info(config_addr, config_max_size, config_id);
+ rc = fdt_read_uint64(dtb, child, "ns-load-address", &val64);
+ if (rc == 0) {
+ ns_config_addr = (uintptr_t)val64;
+ VERBOSE("\tns-load-address = %lx\n", ns_config_addr);
+ }
+
+ set_config_info(config_addr, ns_config_addr, config_max_size,
+ config_id);
}
if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) {
diff --git a/lib/locks/bakery/bakery_lock_normal.c b/lib/locks/bakery/bakery_lock_normal.c
index 7d35dea..faea6c5 100644
--- a/lib/locks/bakery/bakery_lock_normal.c
+++ b/lib/locks/bakery/bakery_lock_normal.c
@@ -83,7 +83,7 @@
}
/* Helper function to check if the lock is acquired */
-static inline bool is_lock_acquired(const bakery_info_t *my_bakery_info,
+static inline __unused bool is_lock_acquired(const bakery_info_t *my_bakery_info,
bool is_cached)
{
/*
diff --git a/lib/xlat_tables_v2/ro_xlat_tables.mk b/lib/xlat_tables_v2/ro_xlat_tables.mk
index 7991e1a..fb8a426 100644
--- a/lib/xlat_tables_v2/ro_xlat_tables.mk
+++ b/lib/xlat_tables_v2/ro_xlat_tables.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2020, ARM Limited. All rights reserved.
+# Copyright (c) 2020-2022, ARM Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -34,4 +34,8 @@
attributes, which is not possible once the translation tables \
have been made read-only.")
endif
+ ifeq (${SPMC_AT_EL3},1)
+ $(error "EL3 SPMC requires functionality from the dynamic translation \
+ library and is incompatible with ALLOW_RO_XLAT_TABLES.")
+ endif
endif
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 12aaee6..a58caf5 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -489,6 +489,10 @@
$(ELF): romlib.bin
endif
+# MODULE_OBJS can be assigned by vendors with different compiled
+# object file path, and prebuilt object file path.
+$(eval OBJS += $(MODULE_OBJS))
+
$(ELF): $(OBJS) $(LINKERFILE) | $(1)_dirs libraries $(BL_LIBS)
$$(ECHO) " LD $$@"
ifdef MAKE_BUILD_STRINGS
@@ -507,7 +511,7 @@
$(BUILD_DIR)/build_message.o $(OBJS)
else ifneq ($(findstring gcc,$(notdir $(LD))),)
$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Wl,-Map=$(MAPFILE) \
- -Wl,-T$(LINKERFILE) $(BUILD_DIR)/build_message.o \
+ -Wl,-dT $(LINKERFILE) $(EXTRA_LINKERFILE) $(BUILD_DIR)/build_message.o \
$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
else
$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Map=$(MAPFILE) \
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 99f44a4..6e57237 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -169,6 +169,9 @@
# Flag to enable Virtualization Host Extensions
ENABLE_FEAT_VHE := 0
+# Flag to enable delayed trapping of WFE instruction (FEAT_TWED)
+ENABLE_FEAT_TWED := 0
+
# By default BL31 encryption disabled
ENCRYPT_BL31 := 0
@@ -254,6 +257,9 @@
# By default, BL1 acts as the reset handler, not BL31
RESET_TO_BL31 := 0
+# By default, clear the input registers when RESET_TO_BL31 is enabled
+RESET_TO_BL31_WITH_PARAMS := 0
+
# For Chain of Trust
SAVE_KEYS := 0
@@ -288,6 +294,9 @@
# Enable the Management Mode (MM)-based Secure Partition Manager implementation
SPM_MM := 0
+# Use the FF-A SPMC implementation in EL3.
+SPMC_AT_EL3 := 0
+
# Use SPM at S-EL2 as a default config for SPMD
SPMD_SPM_AT_SEL2 := 1
@@ -431,6 +440,11 @@
override ENABLE_TRBE_FOR_NS := 0
endif
+# By default, disable access to branch record buffer control registers from NS
+# lower ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused
+# if FEAT_BRBE is implemented.
+ENABLE_BRBE_FOR_NS := 0
+
# By default, disable access of trace system registers from NS lower
# ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused if
# system register trace is implemented.
@@ -440,3 +454,9 @@
# lower ELs, i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused
# if FEAT_TRF is implemented.
ENABLE_TRF_FOR_NS := 0
+
+# In v8.6+ platforms with delayed trapping of WFE being supported
+# via FEAT_TWED, this flag takes the delay value to be set in the
+# SCR_EL3.TWEDEL(4bit) field, when FEAT_TWED is implemented.
+# By default it takes 0, and need to be updated by the platforms.
+TWED_DELAY := 0
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
index 34fdaf6..61c1dbe 100644
--- a/plat/allwinner/common/allwinner-common.mk
+++ b/plat/allwinner/common/allwinner-common.mk
@@ -27,6 +27,7 @@
plat/common/plat_gicv2.c \
plat/common/plat_psci_common.c \
${AW_PLAT}/common/sunxi_bl31_setup.c \
+ ${AW_PLAT}/${PLAT}/sunxi_idle_states.c \
${AW_PLAT}/common/sunxi_pm.c \
${AW_PLAT}/${PLAT}/sunxi_power.c \
${AW_PLAT}/common/sunxi_security.c \
@@ -65,6 +66,23 @@
$(eval $(call assert_boolean,SUNXI_SETUP_REGULATORS))
$(eval $(call add_define,SUNXI_SETUP_REGULATORS))
+SUNXI_BL31_IN_DRAM ?= 0
+$(eval $(call assert_boolean,SUNXI_BL31_IN_DRAM))
+
+ifeq (${SUNXI_BL31_IN_DRAM},1)
+SUNXI_AMEND_DTB := 1
+$(eval $(call add_define,SUNXI_BL31_IN_DRAM))
+endif
+
+SUNXI_AMEND_DTB ?= 0
+$(eval $(call assert_boolean,SUNXI_AMEND_DTB))
+$(eval $(call add_define,SUNXI_AMEND_DTB))
+
+ifeq (${SUNXI_AMEND_DTB},1)
+BL31_SOURCES += common/fdt_fixup.c \
+ ${AW_PLAT}/common/sunxi_prepare_dtb.c
+endif
+
# The bootloader is guaranteed to only run on CPU 0 by the boot ROM.
COLD_BOOT_SINGLE_CPU := 1
diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h
index 49951e0..c9d075a 100644
--- a/plat/allwinner/common/include/platform_def.h
+++ b/plat/allwinner/common/include/platform_def.h
@@ -57,9 +57,10 @@
#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE \
(SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE - 0x200)
-#define PLAT_MAX_PWR_LVL_STATES U(2)
+/* These states are used directly for SCPI communication. */
+#define PLAT_MAX_PWR_LVL_STATES U(3)
#define PLAT_MAX_RET_STATE U(1)
-#define PLAT_MAX_OFF_STATE U(2)
+#define PLAT_MAX_OFF_STATE U(3)
#define PLAT_MAX_PWR_LVL U(2)
#define PLAT_NUM_PWR_DOMAINS (U(1) + \
diff --git a/plat/allwinner/common/include/sunxi_def.h b/plat/allwinner/common/include/sunxi_def.h
index ec50887..c17ef95 100644
--- a/plat/allwinner/common/include/sunxi_def.h
+++ b/plat/allwinner/common/include/sunxi_def.h
@@ -20,4 +20,7 @@
#define SUNXI_SOC_H616 0x1823
#define SUNXI_SOC_R329 0x1851
+#define JEDEC_ALLWINNER_BKID 9U
+#define JEDEC_ALLWINNER_MFID 0x9eU
+
#endif /* SUNXI_DEF_H */
diff --git a/plat/allwinner/common/include/sunxi_private.h b/plat/allwinner/common/include/sunxi_private.h
index 6cf4670..6a38657 100644
--- a/plat/allwinner/common/include/sunxi_private.h
+++ b/plat/allwinner/common/include/sunxi_private.h
@@ -7,8 +7,12 @@
#ifndef SUNXI_PRIVATE_H
#define SUNXI_PRIVATE_H
+#include <common/fdt_fixup.h>
+
#include <lib/psci/psci.h>
+extern const struct psci_cpu_idle_state sunxi_idle_states[];
+
void sunxi_configure_mmu_el3(int flags);
void sunxi_cpu_on(u_register_t mpidr);
@@ -24,8 +28,13 @@
}
#endif
#if SUNXI_PSCI_USE_SCPI
+bool sunxi_psci_is_scpi(void);
int sunxi_set_scpi_psci_ops(const plat_psci_ops_t **psci_ops);
#else
+static inline bool sunxi_psci_is_scpi(void)
+{
+ return false;
+}
static inline int sunxi_set_scpi_psci_ops(const plat_psci_ops_t **psci_ops)
{
return -1;
@@ -41,7 +50,7 @@
int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb);
void sunxi_execute_arisc_code(uint32_t *code, size_t size, uint16_t param);
-#ifdef SUNXI_BL31_IN_DRAM
+#if SUNXI_AMEND_DTB
void sunxi_prepare_dtb(void *fdt);
#else
static inline void sunxi_prepare_dtb(void *fdt)
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
index 14049e8..a32124a 100644
--- a/plat/allwinner/common/sunxi_bl31_setup.c
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -32,6 +32,8 @@
static console_t console;
+static void *fdt;
+
static const gicv2_driver_data_t sunxi_gic_data = {
.gicd_base = SUNXI_GICD_BASE,
.gicc_base = SUNXI_GICC_BASE,
@@ -49,7 +51,7 @@
* entry point to find the load address, which should be followed by the
* size. Adding those together gives us the address of the DTB.
*/
-static void *sunxi_find_dtb(void)
+static void sunxi_find_dtb(void)
{
uint64_t *u_boot_base;
int i;
@@ -57,7 +59,7 @@
u_boot_base = (void *)SUNXI_BL33_VIRT_BASE;
for (i = 0; i < 2048 / sizeof(uint64_t); i++) {
- uint32_t *dtb_base;
+ void *dtb_base;
if (u_boot_base[i] != PRELOADED_BL33_BASE)
continue;
@@ -67,15 +69,13 @@
continue;
/* end of the image: base address + size */
- dtb_base = (void *)((char *)u_boot_base + u_boot_base[i + 1]);
-
- if (fdt_check_header(dtb_base) != 0)
- continue;
+ dtb_base = (char *)u_boot_base + u_boot_base[i + 1];
- return dtb_base;
+ if (fdt_check_header(dtb_base) == 0) {
+ fdt = dtb_base;
+ return;
+ }
}
-
- return NULL;
}
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
@@ -113,7 +113,6 @@
{
const char *soc_name;
uint16_t soc_id = sunxi_read_soc_id();
- void *fdt;
switch (soc_id) {
case SUNXI_SOC_A64:
@@ -139,7 +138,7 @@
generic_delay_timer_init();
- fdt = sunxi_find_dtb();
+ sunxi_find_dtb();
if (fdt) {
const char *model;
int length;
@@ -180,9 +179,15 @@
sunxi_pmic_setup(soc_id, fdt);
+ INFO("BL31: Platform setup done\n");
+}
+
+void bl31_plat_runtime_setup(void)
+{
+ /* Change the DTB if the configuration requires so. */
sunxi_prepare_dtb(fdt);
- INFO("BL31: Platform setup done\n");
+ console_switch_state(CONSOLE_FLAG_RUNTIME);
}
entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
index 82410b1..092659c 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -8,7 +8,9 @@
#include <common/debug.h>
#include <lib/mmio.h>
+#include <lib/smccc.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <services/arm_arch_svc.h>
#include <sunxi_def.h>
#include <sunxi_mmap.h>
@@ -157,3 +159,29 @@
return 0;
}
+
+int32_t plat_is_smccc_feature_available(u_register_t fid)
+{
+ switch (fid) {
+ case SMCCC_ARCH_SOC_ID:
+ return SMC_ARCH_CALL_SUCCESS;
+ default:
+ return SMC_ARCH_CALL_NOT_SUPPORTED;
+ }
+}
+
+int32_t plat_get_soc_version(void)
+{
+ int32_t ret;
+
+ ret = SOC_ID_SET_JEP_106(JEDEC_ALLWINNER_BKID, JEDEC_ALLWINNER_MFID);
+
+ return ret | (sunxi_read_soc_id() & SOC_ID_IMPL_DEF_MASK);
+}
+
+int32_t plat_get_soc_revision(void)
+{
+ uint32_t reg = mmio_read_32(SRAM_VER_REG);
+
+ return reg & GENMASK_32(7, 0);
+}
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
index eb1b7e7..3772b4a 100644
--- a/plat/allwinner/common/sunxi_pm.c
+++ b/plat/allwinner/common/sunxi_pm.c
@@ -9,12 +9,22 @@
#include <platform_def.h>
#include <common/debug.h>
+#include <common/fdt_fixup.h>
#include <lib/mmio.h>
#include <lib/psci/psci.h>
#include <sunxi_cpucfg.h>
#include <sunxi_private.h>
+static bool psci_is_scpi;
+
+#if SUNXI_PSCI_USE_SCPI
+bool sunxi_psci_is_scpi(void)
+{
+ return psci_is_scpi;
+}
+#endif
+
int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint)
{
/* The non-secure entry point must be in DRAM */
@@ -40,6 +50,7 @@
if (sunxi_set_scpi_psci_ops(psci_ops) == 0) {
INFO("PSCI: Suspend is available via SCPI\n");
+ psci_is_scpi = true;
} else {
INFO("PSCI: Suspend is unavailable\n");
sunxi_set_native_psci_ops(psci_ops);
diff --git a/plat/allwinner/sun50i_h616/prepare_dtb.c b/plat/allwinner/common/sunxi_prepare_dtb.c
similarity index 69%
rename from plat/allwinner/sun50i_h616/prepare_dtb.c
rename to plat/allwinner/common/sunxi_prepare_dtb.c
index e94b0b4..66af35a 100644
--- a/plat/allwinner/sun50i_h616/prepare_dtb.c
+++ b/plat/allwinner/common/sunxi_prepare_dtb.c
@@ -19,25 +19,34 @@
if (fdt == NULL || fdt_check_header(fdt) != 0) {
return;
}
- ret = fdt_open_into(fdt, fdt, 0x100000);
+
+ ret = fdt_open_into(fdt, fdt, 0x10000);
if (ret < 0) {
ERROR("Preparing devicetree at %p: error %d\n", fdt, ret);
return;
}
+#ifdef SUNXI_BL31_IN_DRAM
/* Reserve memory used by Trusted Firmware. */
if (fdt_add_reserved_memory(fdt, "tf-a@40000000", BL31_BASE,
BL31_LIMIT - BL31_BASE)) {
WARN("Failed to add reserved memory nodes to DT.\n");
- return;
}
+#endif
+
+ if (sunxi_psci_is_scpi()) {
+ ret = fdt_add_cpu_idle_states(fdt, sunxi_idle_states);
+ if (ret < 0) {
+ WARN("Failed to add idle states to DT: %d\n", ret);
+ }
+ }
ret = fdt_pack(fdt);
if (ret < 0) {
ERROR("Failed to pack devicetree at %p: error %d\n",
fdt, ret);
- } else {
- clean_dcache_range((uintptr_t)fdt, fdt_blob_size(fdt));
- INFO("Changed devicetree to reserve BL31 memory.\n");
}
+
+ clean_dcache_range((uintptr_t)fdt, fdt_blob_size(fdt));
+ INFO("Changed devicetree.\n");
}
diff --git a/plat/allwinner/common/sunxi_scpi_pm.c b/plat/allwinner/common/sunxi_scpi_pm.c
index eb37daa..41dc563 100644
--- a/plat/allwinner/common/sunxi_scpi_pm.c
+++ b/plat/allwinner/common/sunxi_scpi_pm.c
@@ -33,6 +33,9 @@
*/
#define SCP_FIRMWARE_MAGIC 0xb4400012
+#define PLAT_LOCAL_PSTATE_WIDTH U(4)
+#define PLAT_LOCAL_PSTATE_MASK ((U(1) << PLAT_LOCAL_PSTATE_WIDTH) - 1)
+
#define CPU_PWR_LVL MPIDR_AFFLVL0
#define CLUSTER_PWR_LVL MPIDR_AFFLVL1
#define SYSTEM_PWR_LVL MPIDR_AFFLVL2
@@ -44,17 +47,6 @@
#define SYSTEM_PWR_STATE(state) \
((state)->pwr_domain_state[SYSTEM_PWR_LVL])
-static inline scpi_power_state_t scpi_map_state(plat_local_state_t psci_state)
-{
- if (is_local_state_run(psci_state)) {
- return scpi_power_on;
- }
- if (is_local_state_retn(psci_state)) {
- return scpi_power_retention;
- }
- return scpi_power_off;
-}
-
static void sunxi_cpu_standby(plat_local_state_t cpu_state)
{
u_register_t scr = read_scr_el3();
@@ -87,9 +79,9 @@
}
scpi_set_css_power_state(read_mpidr(),
- scpi_map_state(cpu_pwr_state),
- scpi_map_state(cluster_pwr_state),
- scpi_map_state(system_pwr_state));
+ cpu_pwr_state,
+ cluster_pwr_state,
+ system_pwr_state);
}
static void sunxi_pwr_domain_on_finish(const psci_power_state_t *target_state)
@@ -137,7 +129,9 @@
psci_power_state_t *req_state)
{
unsigned int power_level = psci_get_pstate_pwrlvl(power_state);
+ unsigned int state_id = psci_get_pstate_id(power_state);
unsigned int type = psci_get_pstate_type(power_state);
+ unsigned int i;
assert(req_state != NULL);
@@ -146,28 +140,19 @@
}
if (type == PSTATE_TYPE_STANDBY) {
- /* Only one retention power state is supported. */
- if (psci_get_pstate_id(power_state) > 0) {
- return PSCI_E_INVALID_PARAMS;
- }
- /* The SoC cannot be suspended without losing state */
- if (power_level == SYSTEM_PWR_LVL) {
- return PSCI_E_INVALID_PARAMS;
- }
- for (unsigned int i = 0; i <= power_level; ++i) {
- req_state->pwr_domain_state[i] = PLAT_MAX_RET_STATE;
- }
- } else {
- /* Only one off power state is supported. */
- if (psci_get_pstate_id(power_state) > 0) {
- return PSCI_E_INVALID_PARAMS;
- }
- for (unsigned int i = 0; i <= power_level; ++i) {
- req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
- }
+ return PSCI_E_INVALID_PARAMS;
}
+
+ /* Pass through the requested PSCI state as-is. */
+ for (i = 0; i <= power_level; ++i) {
+ unsigned int local_pstate = state_id & PLAT_LOCAL_PSTATE_MASK;
+
+ req_state->pwr_domain_state[i] = local_pstate;
+ state_id >>= PLAT_LOCAL_PSTATE_WIDTH;
+ }
+
/* Higher power domain levels should all remain running */
- for (unsigned int i = power_level + 1; i <= PLAT_MAX_PWR_LVL; ++i) {
+ for (; i <= PLAT_MAX_PWR_LVL; ++i) {
req_state->pwr_domain_state[i] = PSCI_LOCAL_STATE_RUN;
}
diff --git a/plat/allwinner/sun50i_a64/sunxi_idle_states.c b/plat/allwinner/sun50i_a64/sunxi_idle_states.c
new file mode 100644
index 0000000..2918bb7
--- /dev/null
+++ b/plat/allwinner/sun50i_a64/sunxi_idle_states.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <sunxi_private.h>
+
+const struct psci_cpu_idle_state sunxi_idle_states[] = {
+ {
+ .name = "cpu-sleep",
+ .power_state = 0x00010003,
+ .local_timer_stop = true,
+ .entry_latency_us = 800,
+ .exit_latency_us = 1500,
+ .min_residency_us = 25000
+ },
+ {
+ .name = "cluster-sleep",
+ .power_state = 0x01010013,
+ .local_timer_stop = true,
+ .entry_latency_us = 850,
+ .exit_latency_us = 1500,
+ .min_residency_us = 50000
+ },
+ {}
+};
diff --git a/plat/allwinner/sun50i_h6/sunxi_idle_states.c b/plat/allwinner/sun50i_h6/sunxi_idle_states.c
new file mode 100644
index 0000000..4339bcd
--- /dev/null
+++ b/plat/allwinner/sun50i_h6/sunxi_idle_states.c
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <sunxi_private.h>
+
+const struct psci_cpu_idle_state sunxi_idle_states[] = {
+ {}
+};
diff --git a/plat/allwinner/sun50i_h616/platform.mk b/plat/allwinner/sun50i_h616/platform.mk
index fc09af7..de494a2 100644
--- a/plat/allwinner/sun50i_h616/platform.mk
+++ b/plat/allwinner/sun50i_h616/platform.mk
@@ -4,6 +4,8 @@
# SPDX-License-Identifier: BSD-3-Clause
#
+SUNXI_BL31_IN_DRAM := 1
+
# Without a management processor there is no SCPI support.
SUNXI_PSCI_USE_SCPI := 0
SUNXI_PSCI_USE_NATIVE := 1
@@ -18,7 +20,3 @@
BL31_SOURCES += drivers/allwinner/axp/axp805.c \
drivers/allwinner/sunxi_rsb.c \
- common/fdt_fixup.c \
- ${AW_PLAT}/${PLAT}/prepare_dtb.c
-
-$(eval $(call add_define,SUNXI_BL31_IN_DRAM))
diff --git a/plat/allwinner/sun50i_h616/sunxi_idle_states.c b/plat/allwinner/sun50i_h616/sunxi_idle_states.c
new file mode 100644
index 0000000..4339bcd
--- /dev/null
+++ b/plat/allwinner/sun50i_h616/sunxi_idle_states.c
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <sunxi_private.h>
+
+const struct psci_cpu_idle_state sunxi_idle_states[] = {
+ {}
+};
diff --git a/plat/allwinner/sun50i_r329/sunxi_idle_states.c b/plat/allwinner/sun50i_r329/sunxi_idle_states.c
new file mode 100644
index 0000000..4339bcd
--- /dev/null
+++ b/plat/allwinner/sun50i_r329/sunxi_idle_states.c
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <sunxi_private.h>
+
+const struct psci_cpu_idle_state sunxi_idle_states[] = {
+ {}
+};
diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
index c26b519..577ac74 100644
--- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,9 +19,10 @@
};
hw-config {
- load-address = <0x0 0x82000000>;
- max-size = <0x01000000>;
+ load-address = <0x0 0x07f00000>;
+ max-size = <0x00100000>;
id = <HW_CONFIG_ID>;
+ ns-load-address = <0x0 0x82000000>;
};
/*
diff --git a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
index b803340..27f4724 100644
--- a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
+++ b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -22,7 +22,7 @@
exception-level = <2>; /* S-EL1 */
execution-state = <0>; /* AARCH64 */
load-address = <0x6280000>;
- entrypoint-offset = <0x1000>;
+ entrypoint-offset = <0x4000>;
xlat-granule = <0>; /* 4KiB */
boot-order = <0>;
messaging-method = <0x3>; /* Direct request/response supported. */
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index 5a17a0d..74e5d72 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -40,17 +40,23 @@
struct bl_params *plat_get_next_bl_params(void)
{
struct bl_params *arm_bl_params;
+ const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
+ bl_mem_params_node_t *param_node __unused;
arm_bl_params = arm_get_next_bl_params();
-#if __aarch64__ && !BL2_AT_EL3
+#if !BL2_AT_EL3 && !EL3_PAYLOAD_BASE
const struct dyn_cfg_dtb_info_t *fw_config_info;
- bl_mem_params_node_t *param_node;
- uintptr_t fw_config_base = 0U;
+ uintptr_t fw_config_base = 0UL;
entry_point_info_t *ep_info;
+#if __aarch64__
/* Get BL31 image node */
param_node = get_bl_mem_params_node(BL31_IMAGE_ID);
+#else /* aarch32 */
+ /* Get SP_MIN image node */
+ param_node = get_bl_mem_params_node(BL32_IMAGE_ID);
+#endif /* __aarch64__ */
assert(param_node != NULL);
/* get fw_config load address */
@@ -58,15 +64,42 @@
assert(fw_config_info != NULL);
fw_config_base = fw_config_info->config_addr;
- assert(fw_config_base != 0U);
+ assert(fw_config_base != 0UL);
/*
- * Get the entry point info of BL31 image and override
+ * Get the entry point info of next executable image and override
* arg1 of entry point info with fw_config base address
*/
ep_info = ¶m_node->ep_info;
ep_info->args.arg1 = (uint32_t)fw_config_base;
-#endif /* __aarch64__ && !BL2_AT_EL3 */
+
+ /* grab NS HW config address */
+ hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
+ assert(hw_config_info != NULL);
+
+ /* To retrieve actual size of the HW_CONFIG */
+ param_node = get_bl_mem_params_node(HW_CONFIG_ID);
+ assert(param_node != NULL);
+
+ /* Copy HW config from Secure address to NS address */
+ memcpy((void *)hw_config_info->ns_config_addr,
+ (void *)hw_config_info->config_addr,
+ (size_t)param_node->image_info.image_size);
+
+ /*
+ * Ensure HW-config device tree committed to memory, as there is
+ * a possibility to use HW-config without cache and MMU enabled
+ * at BL33
+ */
+ flush_dcache_range(hw_config_info->ns_config_addr,
+ param_node->image_info.image_size);
+
+ param_node = get_bl_mem_params_node(BL33_IMAGE_ID);
+ assert(param_node != NULL);
+
+ /* Update BL33's ep info with NS HW config address */
+ param_node->ep_info.args.arg1 = hw_config_info->ns_config_addr;
+#endif /* !BL2_AT_EL3 && !EL3_PAYLOAD_BASE */
return arm_bl_params;
}
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index a94a4f4..dd90965 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.c
@@ -17,6 +17,8 @@
#include "fvp_private.h"
+static const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
+
void __init bl31_early_platform_setup2(u_register_t arg0,
u_register_t arg1, u_register_t arg2, u_register_t arg3)
{
@@ -34,6 +36,17 @@
if (soc_fw_config_info != NULL) {
arg1 = soc_fw_config_info->config_addr;
}
+
+ /*
+ * arg2 is currently holding the 'secure' address of HW_CONFIG.
+ * But arm_bl31_early_platform_setup() below expects the 'non-secure'
+ * address of HW_CONFIG (which it will pass to BL33).
+ * This why we need to override arg2 here.
+ */
+ hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
+ assert(hw_config_info != NULL);
+ assert(hw_config_info->ns_config_addr != 0UL);
+ arg2 = hw_config_info->ns_config_addr;
#endif /* !RESET_TO_BL31 && !BL2_AT_EL3 */
arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
@@ -66,22 +79,57 @@
void __init bl31_plat_arch_setup(void)
{
+ int rc __unused;
+ uintptr_t hw_config_base_align __unused;
+ size_t mapped_size_align __unused;
+
arm_bl31_plat_arch_setup();
/*
* For RESET_TO_BL31 systems, BL31 is the first bootloader to run.
* So there is no BL2 to load the HW_CONFIG dtb into memory before
- * control is passed to BL31.
+ * control is passed to BL31. The code below relies on dynamic mapping
+ * capability, which is not supported by xlat tables lib V1.
+ * TODO: remove the ARM_XLAT_TABLES_LIB_V1 check when its support
+ * gets deprecated.
*/
-#if !RESET_TO_BL31 && !BL2_AT_EL3
- /* 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);
+#if !RESET_TO_BL31 && !BL2_AT_EL3 && !ARM_XLAT_TABLES_LIB_V1
assert(hw_config_info != NULL);
+ assert(hw_config_info->config_addr != 0UL);
+ /* Page aligned address and size if necessary */
+ hw_config_base_align = page_align(hw_config_info->config_addr, DOWN);
+ mapped_size_align = page_align(hw_config_info->config_max_size, UP);
+
+ if ((hw_config_info->config_addr != hw_config_base_align) &&
+ (hw_config_info->config_max_size == mapped_size_align)) {
+ mapped_size_align += PAGE_SIZE;
+ }
+
+ /*
+ * map dynamically HW config region with its aligned base address and
+ * size
+ */
+ rc = mmap_add_dynamic_region((unsigned long long)hw_config_base_align,
+ hw_config_base_align,
+ mapped_size_align,
+ MT_RO_DATA);
+ if (rc != 0) {
+ ERROR("Error while mapping HW_CONFIG device tree (%d).\n", rc);
+ panic();
+ }
+
+ /* Populate HW_CONFIG device tree with the mapped address */
fconf_populate("HW_CONFIG", hw_config_info->config_addr);
-#endif
+
+ /* unmap the HW_CONFIG memory region */
+ rc = mmap_remove_dynamic_region(hw_config_base_align, mapped_size_align);
+ if (rc != 0) {
+ ERROR("Error while unmapping HW_CONFIG device tree (%d).\n",
+ rc);
+ panic();
+ }
+#endif /* !RESET_TO_BL31 && !BL2_AT_EL3 && !ARM_XLAT_TABLES_LIB_V1 */
}
unsigned int plat_get_syscnt_freq2(void)
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index d8d19de..a7028f6 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -104,9 +104,10 @@
#ifdef __aarch64__
ARM_MAP_DRAM2,
#endif
-#if defined(SPD_spmd)
+ /*
+ * Required to load HW_CONFIG, SPMC and SPs to trusted DRAM.
+ */
ARM_MAP_TRUSTED_DRAM,
-#endif
#if ENABLE_RME
ARM_MAP_RMM_DRAM,
ARM_MAP_GPT_L1_DRAM,
@@ -126,7 +127,7 @@
*/
ARM_MAP_BL1_RW,
#endif /* CRYPTO_SUPPORT && !BL2_AT_EL3 */
-#if SPM_MM
+#if SPM_MM || SPMC_AT_EL3
ARM_SP_IMAGE_MMAP,
#endif
#if ARM_BL31_IN_DRAM
@@ -166,8 +167,6 @@
#if SPM_MM
ARM_SPM_BUF_EL3_MMAP,
#endif
- /* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */
- ARM_DTB_DRAM_NS,
#if ENABLE_RME
ARM_MAP_GPT_L1_DRAM,
#endif
@@ -197,8 +196,6 @@
V2M_MAP_IOFPGA,
MAP_DEVICE0,
MAP_DEVICE1,
- /* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */
- ARM_DTB_DRAM_NS,
{0}
};
#endif
diff --git a/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c b/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c
new file mode 100644
index 0000000..b9e4f86
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <services/el3_spmc_logical_sp.h>
+#include <services/ffa_svc.h>
+#include <smccc_helpers.h>
+
+#define LP_PARTITION_ID 0xC001
+#define LP_UUID {0x47a3bf57, 0xe98e43ad, 0xb7db524f, 0x1588f4e3}
+
+/* Our Logical SP currently only supports receipt of direct messaging. */
+#define PARTITION_PROPERTIES FFA_PARTITION_DIRECT_REQ_RECV
+
+static int32_t sp_init(void)
+{
+ INFO("LSP: Init function called.\n");
+ return 0;
+}
+
+static uint64_t handle_ffa_direct_request(uint32_t smc_fid, bool secure_origin,
+ uint64_t x1, uint64_t x2, uint64_t x3,
+ uint64_t x4, void *cookie,
+ void *handle, uint64_t flags)
+{
+ uint64_t ret;
+
+ /* Determine if we have a 64 or 32 direct request. */
+ if (smc_fid == FFA_MSG_SEND_DIRECT_REQ_SMC32) {
+ ret = FFA_MSG_SEND_DIRECT_RESP_SMC32;
+ } else if (smc_fid == FFA_MSG_SEND_DIRECT_REQ_SMC64) {
+ ret = FFA_MSG_SEND_DIRECT_RESP_SMC64;
+ } else {
+ panic(); /* Unknown SMC. */
+ }
+ /*
+ * Handle the incoming request. For testing purposes we echo the
+ * incoming message.
+ */
+ INFO("Logical Partition: Received Direct Request from %s world!\n",
+ secure_origin ? "Secure" : "Normal");
+
+ /*
+ * Logical SP's must always send a direct response so we can populate
+ * our response directly.
+ */
+ SMC_RET8(handle, ret, 0, 0, x4, 0, 0, 0, 0);
+}
+
+/* Register logical partition */
+DECLARE_LOGICAL_PARTITION(
+ my_logical_partition,
+ sp_init, /* Init Function */
+ LP_PARTITION_ID, /* FF-A Partition ID */
+ LP_UUID, /* UUID */
+ PARTITION_PROPERTIES, /* Partition Properties. */
+ handle_ffa_direct_request /* Callback for direct requests. */
+);
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 5e5ddce..82bd7c8 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -90,6 +90,31 @@
FVP_DTB_DRAM_MAP_START, \
FVP_DTB_DRAM_MAP_SIZE, \
MT_MEMORY | MT_RO | MT_NS)
+
+#if SPMC_AT_EL3
+/*
+ * Number of Secure Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of supported
+ * secure partitions.
+ */
+#define SECURE_PARTITION_COUNT 1
+
+/*
+ * Number of Normal World Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of supported
+ * NWd partitions.
+ */
+#define NS_PARTITION_COUNT 1
+
+/*
+ * Number of Logical Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of supported
+ * logical partitions.
+ */
+#define MAX_EL3_LP_DESCS_COUNT 1
+
+#endif /* SPMC_AT_EL3 */
+
/*
* Load address of BL33 for this platform port
*/
@@ -106,9 +131,12 @@
# define MAX_XLAT_TABLES 11
# else
# define MAX_XLAT_TABLES 9
-# endif
+# endif
# define PLAT_SP_IMAGE_MMAP_REGIONS 30
# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
+# elif SPMC_AT_EL3
+# define PLAT_ARM_MMAP_ENTRIES 13
+# define MAX_XLAT_TABLES 11
# else
# define PLAT_ARM_MMAP_ENTRIES 9
# if USE_DEBUGFS
@@ -126,8 +154,13 @@
# endif
# endif
#elif defined(IMAGE_BL32)
-# define PLAT_ARM_MMAP_ENTRIES 9
-# define MAX_XLAT_TABLES 6
+# if SPMC_AT_EL3
+# define PLAT_ARM_MMAP_ENTRIES 270
+# define MAX_XLAT_TABLES 10
+# else
+# define PLAT_ARM_MMAP_ENTRIES 9
+# define MAX_XLAT_TABLES 6
+# endif
#elif !USE_ROMLIB
# define PLAT_ARM_MMAP_ENTRIES 11
# define MAX_XLAT_TABLES 5
@@ -261,6 +294,7 @@
#define PLAT_ARM_TRP_UART_CLK_IN_HZ V2M_IOFPGA_UART3_CLK_IN_HZ
#define PLAT_FVP_SMMUV3_BASE UL(0x2b400000)
+#define PLAT_ARM_SMMUV3_ROOT_REG_OFFSET UL(0x20000)
/* CCI related constants */
#define PLAT_FVP_CCI400_BASE UL(0x2c090000)
diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i
index b72bdab..85e6e3a 100644
--- a/plat/arm/board/fvp/jmptbl.i
+++ b/plat/arm/board/fvp/jmptbl.i
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -35,6 +35,8 @@
fdt fdt_get_name
fdt fdt_get_alias
fdt fdt_node_offset_by_phandle
+fdt fdt_subnode_offset
+fdt fdt_add_subnode
mbedtls mbedtls_asn1_get_alg
mbedtls mbedtls_asn1_get_alg_null
mbedtls mbedtls_asn1_get_bitstring_null
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index c9f5551..d89e91f 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -333,15 +333,10 @@
endif
# Enable the dynamic translation tables library.
-ifeq (${ARCH},aarch32)
- ifeq (${RESET_TO_SP_MIN},1)
+ifeq ($(filter 1,${BL2_AT_EL3} ${ARM_XLAT_TABLES_LIB_V1}),)
+ ifeq (${ARCH},aarch32)
BL32_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
- endif
-else # AArch64
- ifeq (${RESET_TO_BL31},1)
- BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
- endif
- ifeq (${SPD},trusty)
+ else # AArch64
BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
endif
endif
@@ -394,6 +389,15 @@
# enable trace buffer control registers access to NS by default
ENABLE_TRBE_FOR_NS := 1
+# enable branch record buffer control registers access in NS by default
+# only enable for aarch64
+# do not enable when ENABLE_RME=1
+ifeq (${ARCH}, aarch64)
+ifeq (${ENABLE_RME},0)
+ ENABLE_BRBE_FOR_NS := 1
+endif
+endif
+
# enable trace system registers access to NS by default
ENABLE_SYS_REG_TRACE_FOR_NS := 1
diff --git a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
index 763b42a..9ab36a6 100644
--- a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
+++ b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,15 +9,31 @@
#include <bl32/sp_min/platform_sp_min.h>
#include <common/debug.h>
#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
#include <plat/arm/common/plat_arm.h>
#include "../fvp_private.h"
-uintptr_t hw_config_dtb;
-
void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
+ const struct dyn_cfg_dtb_info_t *tos_fw_config_info __unused;
+
+ /* Initialize the console to provide early debug support */
+ arm_console_boot_init();
+
+#if !RESET_TO_SP_MIN && !BL2_AT_EL3
+
+ INFO("SP_MIN FCONF: FW_CONFIG address = %lx\n", (uintptr_t)arg1);
+ /* Fill the properties struct with the info from the config dtb */
+ fconf_populate("FW_CONFIG", arg1);
+
+ tos_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TOS_FW_CONFIG_ID);
+ if (tos_fw_config_info != NULL) {
+ arg1 = tos_fw_config_info->config_addr;
+ }
+#endif /* !RESET_TO_SP_MIN && !BL2_AT_EL3 */
+
arm_sp_min_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
/* Initialize the platform config for future decision making */
@@ -37,12 +53,15 @@
* FVP PSCI code will enable coherency for other clusters.
*/
fvp_interconnect_enable();
-
- hw_config_dtb = arg2;
}
void sp_min_plat_arch_setup(void)
{
+ int rc __unused;
+ const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
+ uintptr_t hw_config_base_align __unused;
+ size_t mapped_size_align __unused;
+
arm_sp_min_plat_arch_setup();
/*
@@ -50,11 +69,53 @@
* to run. So there is no BL2 to load the HW_CONFIG dtb into memory
* before control is passed to SP_MIN.
* Also, BL2 skips loading HW_CONFIG dtb for BL2_AT_EL3 builds.
+ * The code below relies on dynamic mapping capability, which is not
+ * supported by xlat tables lib V1.
+ * TODO: remove the ARM_XLAT_TABLES_LIB_V1 check when its support
+ * gets deprecated.
*/
-#if !RESET_TO_SP_MIN && !BL2_AT_EL3
- assert(hw_config_dtb != 0U);
+#if !RESET_TO_SP_MIN && !BL2_AT_EL3 && !ARM_XLAT_TABLES_LIB_V1
+ hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
+ assert(hw_config_info != NULL);
+ assert(hw_config_info->config_addr != 0UL);
+
+ INFO("SP_MIN FCONF: HW_CONFIG address = %p\n",
+ (void *)hw_config_info->config_addr);
+
+ /*
+ * Preferrably we expect this address and size are page aligned,
+ * but if they are not then align it.
+ */
+ hw_config_base_align = page_align(hw_config_info->config_addr, DOWN);
+ mapped_size_align = page_align(hw_config_info->config_max_size, UP);
+
+ if ((hw_config_info->config_addr != hw_config_base_align) &&
+ (hw_config_info->config_max_size == mapped_size_align)) {
+ mapped_size_align += PAGE_SIZE;
+ }
+
+ /*
+ * map dynamically HW config region with its aligned base address and
+ * size
+ */
+ rc = mmap_add_dynamic_region((unsigned long long)hw_config_base_align,
+ hw_config_base_align,
+ mapped_size_align,
+ MT_RO_DATA);
+ if (rc != 0) {
+ ERROR("Error while mapping HW_CONFIG device tree (%d).\n", rc);
+ panic();
+ }
+
+ /* Populate HW_CONFIG device tree with the mapped address */
+ fconf_populate("HW_CONFIG", hw_config_info->config_addr);
- INFO("SP_MIN FCONF: HW_CONFIG address = %p\n", (void *)hw_config_dtb);
- fconf_populate("HW_CONFIG", hw_config_dtb);
-#endif
+ /* unmap the HW_CONFIG memory region */
+ rc = mmap_remove_dynamic_region(hw_config_base_align, mapped_size_align);
+ if (rc != 0) {
+ ERROR("Error while unmapping HW_CONFIG device tree (%d).\n",
+ rc);
+ panic();
+ }
+#endif /* !RESET_TO_SP_MIN && !BL2_AT_EL3 && !ARM_XLAT_TABLES_LIB_V1 */
}
diff --git a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
index 0d8cca5..183d802 100644
--- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
+++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -25,7 +25,8 @@
# Added separately from the above list for better readability
ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_SP_MIN}),)
BL32_SOURCES += lib/fconf/fconf.c \
- plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
+ lib/fconf/fconf_dyn_cfg_getter.c \
+ plat/arm/board/fvp/fconf/fconf_hw_config_getter.c \
BL32_SOURCES += ${FDT_WRAPPERS_SOURCES}
diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
index 68872c1..1ac0a9c 100644
--- a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
+++ b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
@@ -154,7 +154,8 @@
/* Set global DTB info for fixed fw_config information */
fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE;
- set_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size, FW_CONFIG_ID);
+ set_config_info(ARM_FW_CONFIG_BASE, ~0UL, fw_config_max_size,
+ FW_CONFIG_ID);
assert(bl1_plat_get_image_desc(BL33_IMAGE_ID) != NULL);
diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i
index 393a648..8932aa0 100644
--- a/plat/arm/board/juno/jmptbl.i
+++ b/plat/arm/board/juno/jmptbl.i
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -34,6 +34,8 @@
fdt fdt_get_name
fdt fdt_get_alias
fdt fdt_node_offset_by_phandle
+fdt fdt_subnode_offset
+fdt fdt_add_subnode
mbedtls mbedtls_asn1_get_alg
mbedtls mbedtls_asn1_get_alg_null
mbedtls mbedtls_asn1_get_bitstring_null
diff --git a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts
deleted file mode 100644
index 5d478e9..0000000
--- a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. 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 = <0x200>;
- id = <TB_FW_CONFIG_ID>;
- };
- };
-};
diff --git a/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts
deleted file mode 100644
index 49eda27..0000000
--- a/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/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>;
- };
-};
diff --git a/plat/arm/board/sgm775/include/platform_def.h b/plat/arm/board/sgm775/include/platform_def.h
deleted file mode 100644
index e83cd57..0000000
--- a/plat/arm/board/sgm775/include/platform_def.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLATFORM_DEF_H
-#define PLATFORM_DEF_H
-
-#include <sgm_base_platform_def.h>
-
-#define PLAT_MAX_CPUS_PER_CLUSTER U(8)
-#define PLAT_MAX_PE_PER_CPU U(1)
-
-#define PLAT_ARM_DRAM2_BASE ULL(0x880000000)
-#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000)
-
-/*
- * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
- */
-#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36)
-#else
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
-#endif
-
-#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk
deleted file mode 100644
index f8df1a7..0000000
--- a/plat/arm/board/sgm775/platform.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-$(warning Platform ${PLAT} is deprecated. Some of the features might not work as expected)
-
-include plat/arm/css/sgm/sgm-common.mk
-
-SGM775_BASE= plat/arm/board/sgm775
-
-# Add the FDT_SOURCES and options for Dynamic Config
-FDT_SOURCES += ${SGM775_BASE}/fdts/${PLAT}_fw_config.dts \
- ${SGM775_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}))
-
-PLAT_INCLUDES +=-I${SGM775_BASE}/include/
-
-BL1_SOURCES += ${SGM775_BASE}/sgm775_err.c
-
-BL2_SOURCES += lib/utils/mem_region.c \
- ${SGM775_BASE}/sgm775_err.c \
- plat/arm/common/arm_nor_psci_mem_protect.c
-
-BL31_SOURCES += drivers/cfi/v2m/v2m_flash.c \
- lib/utils/mem_region.c \
- plat/arm/common/arm_nor_psci_mem_protect.c
-
-ifeq (${TRUSTED_BOARD_BOOT}, 1)
-BL1_SOURCES += ${SGM775_BASE}/sgm775_trusted_boot.c
-BL2_SOURCES += ${SGM775_BASE}/sgm775_trusted_boot.c
-endif
diff --git a/plat/arm/board/sgm775/sgm775_err.c b/plat/arm/board/sgm775/sgm775_err.c
deleted file mode 100644
index dc114f0..0000000
--- a/plat/arm/board/sgm775/sgm775_err.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-/*
- * sgm775 error handler
- */
-void __dead2 plat_arm_error_handler(int err)
-{
- while (true) {
- wfi();
- }
-}
diff --git a/plat/arm/board/sgm775/sgm775_trusted_boot.c b/plat/arm/board/sgm775/sgm775_trusted_boot.c
deleted file mode 100644
index 4592b8f..0000000
--- a/plat/arm/board/sgm775/sgm775_trusted_boot.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2020, Arm Limited. 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);
-}
diff --git a/plat/arm/board/sgm775/tsp/tsp-sgm775.mk b/plat/arm/board/sgm775/tsp/tsp-sgm775.mk
deleted file mode 100644
index 129b586..0000000
--- a/plat/arm/board/sgm775/tsp/tsp-sgm775.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-include plat/arm/css/sgm/tsp/tsp-sgm.mk
\ No newline at end of file
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index 73338cb..7a9e04d 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -166,7 +166,7 @@
/* Set global DTB info for fixed fw_config information */
fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE;
- set_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size, FW_CONFIG_ID);
+ set_config_info(ARM_FW_CONFIG_BASE, ~0UL, fw_config_max_size, FW_CONFIG_ID);
/* Fill the device tree information struct with the info from the config dtb */
err = fconf_load_config(FW_CONFIG_ID);
diff --git a/plat/arm/css/sgm/aarch64/css_sgm_helpers.S b/plat/arm/css/sgm/aarch64/css_sgm_helpers.S
deleted file mode 100644
index 32ca1bb..0000000
--- a/plat/arm/css/sgm/aarch64/css_sgm_helpers.S
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2018, 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 <cortex_a75.h>
-#include <cortex_a55.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 FVP.
- *
- * (ClusterId * MAX_CPUS_PER_CLUSTER * MAX_PE_PER_CPU) +
- * (CPUId * MAX_PE_PER_CPU) +
- * ThreadId
- *
- * which can be simplified as:
- *
- * ((ClusterId * MAX_CPUS_PER_CLUSTER + CPUId) * 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
- lsr 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
- jump_if_cpu_midr CORTEX_A75_MIDR, A75
- jump_if_cpu_midr CORTEX_A55_MIDR, A55
- ret
-
- /* -----------------------------------------------------
- * Disable CPU power down bit in power control register
- * -----------------------------------------------------
- */
-A75:
- mrs x0, CORTEX_A75_CPUPWRCTLR_EL1
- bic x0, x0, #CORTEX_A75_CORE_PWRDN_EN_MASK
- msr CORTEX_A75_CPUPWRCTLR_EL1, x0
- isb
- ret
-A55:
- mrs x0, CORTEX_A55_CPUPWRCTLR_EL1
- bic x0, x0, #CORTEX_A55_CORE_PWRDN_EN_MASK
- msr CORTEX_A55_CPUPWRCTLR_EL1, x0
- isb
- ret
-endfunc plat_reset_handler
diff --git a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts
deleted file mode 100644
index 54b2423..0000000
--- a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-
-/ {
- /* Platform Config */
- tb_fw-config {
- compatible = "arm,tb_fw";
- hw_config_addr = <0x0 0x83000000>;
- hw_config_max_size = <0x01000000>;
- /*
- * 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>;
- };
-};
diff --git a/plat/arm/css/sgm/include/plat_macros.S b/plat/arm/css/sgm/include/plat_macros.S
deleted file mode 100644
index 715ded2..0000000
--- a/plat/arm/css/sgm/include/plat_macros.S
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#ifndef PLAT_MACROS_S
-#define PLAT_MACROS_S
-
-#include <cci_macros.S>
-#include <css_macros.S>
-
-/* ---------------------------------------------
- * The below required platform porting macro
- * prints out relevant platform registers
- * whenever an unhandled exception is taken in
- * BL31.
- * ---------------------------------------------
- */
-.macro plat_crash_print_regs
-css_print_gic_regs
-print_cci_regs
-.endm
-
-#endif /* PLAT_MACROS_S */
diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h
deleted file mode 100644
index 2d8e677..0000000
--- a/plat/arm/css/sgm/include/sgm_base_platform_def.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGM_BASE_PLATFORM_DEF_H
-#define SGM_BASE_PLATFORM_DEF_H
-
-#include <drivers/arm/tzc400.h>
-#include <drivers/arm/tzc_common.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/css/common/css_def.h>
-#include <plat/arm/soc/common/soc_css_def.h>
-#include <plat/common/common_def.h>
-
-/* CPU topology */
-#define PLAT_ARM_CLUSTER_COUNT U(1)
-#define PLAT_ARM_CLUSTER_CORE_COUNT U(8)
-#define PLATFORM_CORE_COUNT PLAT_ARM_CLUSTER_CORE_COUNT
-
-#define PLAT_MAX_PWR_LVL ARM_PWR_LVL2
-#define PLAT_NUM_PWR_DOMAINS (ARM_SYSTEM_COUNT + \
- PLAT_ARM_CLUSTER_COUNT + \
- PLATFORM_CORE_COUNT)
-
-/*
- * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
- * terminology. On a GICv2 system or mode, the lists will be merged and treated
- * as Group 0 interrupts.
- */
-#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
- CSS_G1S_IRQ_PROPS(grp), \
- ARM_G1S_IRQ_PROPS(grp)
-
-#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp)
-
-/* GIC related constants */
-#define PLAT_ARM_GICD_BASE 0x30000000
-#define PLAT_ARM_GICR_BASE 0x300C0000
-#define PLAT_ARM_GICC_BASE 0x2c000000
-
-#define CSS_GIC_SIZE 0x00200000
-
-#define CSS_MAP_GIC_DEVICE MAP_REGION_FLAT( \
- PLAT_ARM_GICD_BASE, \
- CSS_GIC_SIZE, \
- MT_DEVICE | MT_RW | MT_SECURE)
-
-/* Platform ID address */
-#define SSC_VERSION (SSC_REG_BASE + SSC_VERSION_OFFSET)
-#ifndef __ASSEMBLER__
-/* SSC_VERSION related accessors */
-/* Returns the part number of the platform */
-#define GET_PLAT_PART_NUM \
- GET_SSC_VERSION_PART_NUM(mmio_read_32(SSC_VERSION))
-/* Returns the configuration number of the platform */
-#define GET_PLAT_CONFIG_NUM \
- GET_SSC_VERSION_CONFIG(mmio_read_32(SSC_VERSION))
-#endif /* __ASSEMBLER__ */
-
-
-/*************************************************************************
- * Definitions common to all SGM CSS based platforms
- *************************************************************************/
-
-/* TZC-400 related constants */
-#define PLAT_ARM_TZC_BASE 0x2a500000
-#define TZC_NSAID_ALL_AP 0 /* Note: Same as default NSAID!! */
-#define TZC_NSAID_HDLCD0 2
-#define TZC_NSAID_HDLCD1 3
-#define TZC_NSAID_GPU 9
-#define TZC_NSAID_VIDEO 10
-#define TZC_NSAID_DISP0 11
-#define TZC_NSAID_DISP1 12
-
-
-/*************************************************************************
- * Required platform porting definitions common to all SGM CSS based
- * platforms
- *************************************************************************/
-
-#define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00040000 /* 256 KB */
-
-/* MHU related constants */
-#define PLAT_CSS_MHU_BASE 0x2b1f0000
-
-#define PLAT_ARM_TRUSTED_ROM_BASE 0x00000000
-#define PLAT_ARM_TRUSTED_ROM_SIZE 0x00080000
-
-#define PLAT_ARM_CCI_BASE 0x2a000000
-
-/* Cluster to CCI slave mapping */
-#define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX 6
-#define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX 5
-
-/* System timer related constants */
-#define PLAT_ARM_NSTIMER_FRAME_ID 0
-
-/* TZC related constants */
-#define PLAT_ARM_TZC_NS_DEV_ACCESS ( \
- TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP) | \
- TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0) | \
- TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD1) | \
- TZC_REGION_ACCESS_RDWR(TZC_NSAID_GPU) | \
- TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIDEO) | \
- TZC_REGION_ACCESS_RDWR(TZC_NSAID_DISP0) | \
- TZC_REGION_ACCESS_RDWR(TZC_NSAID_DISP1))
-
-/* Display Processor register definitions to setup the NSAIDs */
-#define MALI_DP_BASE 0x2cc00000
-#define DP_NPROT_NSAID_OFFSET 0x1000c
-#define W_NPROT_NSAID_SHIFT 24
-#define LS_NPORT_NSAID_SHIFT 12
-
-/*
- * Base address of the first memory region used for communication between AP
- * and SCP. Used by the BootOverMHU and SCPI protocols.
- */
-#if !CSS_USE_SCMI_SDS_DRIVER
-/*
- * Note that this is located at the same address as SCP_BOOT_CFG_ADDR, which
- * means the SCP/AP configuration data gets overwritten when the AP initiates
- * communication with the SCP. The configuration data is expected to be a
- * 32-bit word on all CSS platforms. Part of this configuration is
- * which CPU is the primary, according to the shift and mask definitions below.
- */
-#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE (ARM_TRUSTED_SRAM_BASE + 0x80)
-#define PLAT_CSS_PRIMARY_CPU_SHIFT 8
-#define PLAT_CSS_PRIMARY_CPU_BIT_WIDTH 4
-#endif
-
-/*
- * SCP_BL2 uses up whatever remaining space is available as it is loaded before
- * anything else in this memory region and is handed over to the SCP before
- * BL31 is loaded over the top.
- */
-#define PLAT_CSS_MAX_SCP_BL2_SIZE \
- ((SCP_BL2_LIMIT - ARM_FW_CONFIG_LIMIT) & ~PAGE_SIZE_MASK)
-
-#define PLAT_CSS_MAX_SCP_BL2U_SIZE PLAT_CSS_MAX_SCP_BL2_SIZE
-
-/*
- * Most platform porting definitions provided by included headers
- */
-
-/*
- * 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)
-# define PLAT_ARM_MMAP_ENTRIES 8
-# define MAX_XLAT_TABLES 5
-#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 5
-#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 0xB000
-
-/*
- * 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.
- */
-#if TRUSTED_BOARD_BOOT
-# define PLAT_ARM_MAX_BL2_SIZE 0x1D000
-#else
-# define PLAT_ARM_MAX_BL2_SIZE 0x12000
-#endif
-
-/*
- * 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
- */
-#define PLAT_ARM_MAX_BL31_SIZE 0x3B000
-
-/*
- * 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)
-# define PLATFORM_STACK_SIZE 0x400
-#elif defined(IMAGE_BL32)
-# define PLATFORM_STACK_SIZE 0x440
-#endif
-
-/*******************************************************************************
- * 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)
-
-/* System power domain level */
-#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2
-
-/* Number of SCMI channels on the platform */
-#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1)
-
-#endif /* SGM_BASE_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgm/include/sgm_plat_config.h b/plat/arm/css/sgm/include/sgm_plat_config.h
deleted file mode 100644
index 29b98d4..0000000
--- a/plat/arm/css/sgm/include/sgm_plat_config.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGM_PLAT_CONFIG_H
-#define SGM_PLAT_CONFIG_H
-
-#include <drivers/arm/ccn.h>
-#include <drivers/arm/gicv3.h>
-
-/* The type of interconnect */
-typedef enum {
- ARM_CCI = 0,
- ARM_CCN,
- ARM_CMN
-} css_inteconn_type_t;
-
-typedef ccn_desc_t inteconn_desc_t;
-
-/* Interconnect configurations */
-typedef struct css_inteconn_config {
- css_inteconn_type_t ip_type;
- const inteconn_desc_t *plat_inteconn_desc;
-} css_inteconn_config_t;
-
-/* Topology configurations */
-typedef struct css_topology {
- const unsigned char *power_tree;
- unsigned int plat_cluster_core_count;
-} css_topology_t;
-
-typedef struct css_plat_config {
- const gicv3_driver_data_t *gic_data;
- const css_inteconn_config_t *inteconn;
- const css_topology_t *topology;
-} css_plat_config_t;
-
-void plat_config_init(void);
-css_plat_config_t *get_plat_config(void);
-
-#endif /* SGM_PLAT_CONFIG_H */
diff --git a/plat/arm/css/sgm/include/sgm_variant.h b/plat/arm/css/sgm/include/sgm_variant.h
deleted file mode 100644
index 859ddb5..0000000
--- a/plat/arm/css/sgm/include/sgm_variant.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGM_VARIANT_H
-#define SGM_VARIANT_H
-
-/* SSC_VERSION values for sgm */
-#define SGM775_SSC_VER_PART_NUM 0x0790
-
-/* DMC configuration for sgm */
-#define SGM_DMC_SIZE 0x40000
-#define SGM775_DMC_COUNT 4
-
-#endif /* SGM_VARIANT_H */
diff --git a/plat/arm/css/sgm/sgm-common.mk b/plat/arm/css/sgm/sgm-common.mk
deleted file mode 100644
index 5b954f8..0000000
--- a/plat/arm/css/sgm/sgm-common.mk
+++ /dev/null
@@ -1,76 +0,0 @@
-#
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-CSS_USE_SCMI_SDS_DRIVER := 1
-
-CSS_SGM_BASE := plat/arm/css/sgm
-
-PLAT_INCLUDES := -I${CSS_SGM_BASE}/include
-
-PLAT_BL_COMMON_SOURCES := ${CSS_SGM_BASE}/sgm_mmap_config.c \
- ${CSS_SGM_BASE}/aarch64/css_sgm_helpers.S
-
-SECURITY_SOURCES := drivers/arm/tzc/tzc_dmc500.c \
- plat/arm/common/arm_tzc_dmc500.c \
- ${CSS_SGM_BASE}/sgm_security.c
-
-SGM_CPU_SOURCES := lib/cpus/aarch64/cortex_a55.S \
- lib/cpus/aarch64/cortex_a75.S
-
-INTERCONNECT_SOURCES := ${CSS_SGM_BASE}/sgm_interconnect.c
-
-# GIC-600 configuration
-GICV3_SUPPORT_GIC600 := 1
-
-# Include GICv3 driver files
-include drivers/arm/gic/v3/gicv3.mk
-
-SGM_GIC_SOURCES := ${GICV3_SOURCES} \
- plat/common/plat_gicv3.c \
- plat/arm/common/arm_gicv3.c
-
-BL1_SOURCES += $(SGM_CPU_SOURCES) \
- ${INTERCONNECT_SOURCES} \
- ${CSS_SGM_BASE}/sgm_bl1_setup.c \
- ${CSS_SGM_BASE}/sgm_plat_config.c \
- drivers/arm/sp805/sp805.c
-
-BL2_SOURCES += ${SECURITY_SOURCES} \
- ${CSS_SGM_BASE}/sgm_plat_config.c
-
-BL2U_SOURCES += ${SECURITY_SOURCES}
-
-BL31_SOURCES += $(SGM_CPU_SOURCES) \
- ${INTERCONNECT_SOURCES} \
- ${SECURITY_SOURCES} \
- ${SGM_GIC_SOURCES} \
- ${CSS_SGM_BASE}/sgm_topology.c \
- ${CSS_SGM_BASE}/sgm_bl31_setup.c \
- ${CSS_SGM_BASE}/sgm_plat_config.c
-
-ifneq (${RESET_TO_BL31},0)
- $(error "Using BL31 as the reset vector is not supported on ${PLAT} platform. \
- Please set RESET_TO_BL31 to 0.")
-endif
-
-# sgm uses CCI-500 as Cache Coherent Interconnect
-ARM_CCI_PRODUCT_ID := 500
-
-# 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
-
-override ARM_PLAT_MT := 1
-
-$(eval $(call add_define,SGM_PLAT))
-
-include plat/arm/common/arm_common.mk
-include plat/arm/board/common/board_common.mk
-include plat/arm/css/common/css_common.mk
-include plat/arm/soc/common/soc_css.mk
diff --git a/plat/arm/css/sgm/sgm_bl1_setup.c b/plat/arm/css/sgm/sgm_bl1_setup.c
deleted file mode 100644
index 5fd9655..0000000
--- a/plat/arm/css/sgm/sgm_bl1_setup.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/bl_common.h>
-#include <common/debug.h>
-#include <plat/arm/common/plat_arm.h>
-#include <plat/arm/soc/common/soc_css.h>
-#include <plat/arm/common/arm_def.h>
-#include <drivers/arm/sp805.h>
-#include <sgm_plat_config.h>
-
-void bl1_early_platform_setup(void)
-{
-
- /* Initialize the console before anything else */
- arm_bl1_early_platform_setup();
-
- /* Initialize the platform configuration structure */
- plat_config_init();
-
-#if !HW_ASSISTED_COHERENCY
- /*
- * Initialize Interconnect for this cluster during cold boot.
- * No need for locks as no other CPU is active.
- */
- plat_arm_interconnect_init();
- /*
- * Enable Interconnect coherency for the primary CPU's cluster.
- */
- plat_arm_interconnect_enter_coherency();
-#endif
-}
-
-void plat_arm_secure_wdt_start(void)
-{
- sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
-}
-
-void plat_arm_secure_wdt_stop(void)
-{
- sp805_stop(ARM_SP805_TWDG_BASE);
-}
diff --git a/plat/arm/css/sgm/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c
deleted file mode 100644
index 907e9fd..0000000
--- a/plat/arm/css/sgm/sgm_bl31_setup.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/bl_common.h>
-#include <common/debug.h>
-#include <drivers/arm/css/css_mhu_doorbell.h>
-#include <drivers/arm/css/scmi.h>
-#include <plat/arm/common/plat_arm.h>
-
-#include <sgm_plat_config.h>
-
-static scmi_channel_plat_info_t sgm775_scmi_plat_info = {
- .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
- .db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
- .db_preserve_mask = 0xfffffffe,
- .db_modify_mask = 0x1,
- .ring_doorbell = &mhu_ring_doorbell,
-};
-
-scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
-{
- return &sgm775_scmi_plat_info;
-}
-
-void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
- u_register_t arg2, u_register_t arg3)
-{
- uint32_t plat_version;
- bl_params_node_t *bl_params;
-
- bl_params = ((bl_params_t *)arg0)->head;
-
- /* Initialize the platform configuration structure */
- plat_config_init();
-
- while (bl_params) {
- if (bl_params->image_id == BL33_IMAGE_ID) {
- plat_version = mmio_read_32(SSC_VERSION);
- bl_params->ep_info->args.arg2 = plat_version;
- break;
- }
-
- bl_params = bl_params->next_params_info;
- }
-
- arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
-}
-
-const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
-{
- return css_scmi_override_pm_ops(ops);
-}
diff --git a/plat/arm/css/sgm/sgm_interconnect.c b/plat/arm/css/sgm/sgm_interconnect.c
deleted file mode 100644
index 5b45341..0000000
--- a/plat/arm/css/sgm/sgm_interconnect.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <cdefs.h>
-
-/*
- * As the SGM platform supports FCM (with automatic interconnect
- * enter/exit), 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/css/sgm/sgm_mmap_config.c b/plat/arm/css/sgm/sgm_mmap_config.c
deleted file mode 100644
index e5b4b03..0000000
--- a/plat/arm/css/sgm/sgm_mmap_config.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <common/bl_common.h>
-#include <common/debug.h>
-#include <plat/arm/common/plat_arm.h>
-
-#include <sgm_variant.h>
-
-/*
- * 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,
- V2M_MAP_FLASH0_RO,
- V2M_MAP_IOFPGA,
- CSS_MAP_DEVICE,
- CSS_MAP_GIC_DEVICE,
- SOC_CSS_MAP_DEVICE,
-#if TRUSTED_BOARD_BOOT
- ARM_MAP_NS_DRAM1,
-#endif
- {0}
-};
-#endif
-#if IMAGE_BL2
-const mmap_region_t plat_arm_mmap[] = {
- ARM_MAP_SHARED_RAM,
- V2M_MAP_FLASH0_RO,
- V2M_MAP_IOFPGA,
- CSS_MAP_DEVICE,
- CSS_MAP_GIC_DEVICE,
- SOC_CSS_MAP_DEVICE,
- ARM_MAP_NS_DRAM1,
-#ifdef SPD_tspd
- ARM_MAP_TSP_SEC_MEM,
-#endif
-#ifdef SPD_opteed
- ARM_OPTEE_PAGEABLE_LOAD_MEM,
-#endif
-#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
- ARM_MAP_BL1_RW,
-#endif
- {0}
-};
-#endif
-#if IMAGE_BL2U
-const mmap_region_t plat_arm_mmap[] = {
- ARM_MAP_SHARED_RAM,
- CSS_MAP_DEVICE,
- CSS_MAP_GIC_DEVICE,
- SOC_CSS_MAP_DEVICE,
- {0}
-};
-#endif
-#if IMAGE_BL31
-const mmap_region_t plat_arm_mmap[] = {
- ARM_MAP_SHARED_RAM,
- V2M_MAP_IOFPGA,
- CSS_MAP_DEVICE,
- CSS_MAP_GIC_DEVICE,
- SOC_CSS_MAP_DEVICE,
- {0}
-};
-#endif
-#if IMAGE_BL32
-const mmap_region_t plat_arm_mmap[] = {
- V2M_MAP_IOFPGA,
- CSS_MAP_DEVICE,
- CSS_MAP_GIC_DEVICE,
- SOC_CSS_MAP_DEVICE,
- {0}
-};
-#endif
-
-ARM_CASSERT_MMAP
-
-const mmap_region_t *plat_arm_get_mmap(void)
-{
- return plat_arm_mmap;
-}
diff --git a/plat/arm/css/sgm/sgm_plat_config.c b/plat/arm/css/sgm/sgm_plat_config.c
deleted file mode 100644
index eed3631..0000000
--- a/plat/arm/css/sgm/sgm_plat_config.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <platform_def.h>
-
-#include <common/debug.h>
-#include <plat/common/platform.h>
-#include <plat/arm/common/plat_arm.h>
-
-#include <sgm_plat_config.h>
-#include <sgm_variant.h>
-
-static css_plat_config_t *css_plat_info;
-
-/* Interconnect */
-const css_inteconn_config_t sgm_inteconn = {
- .ip_type = ARM_CCI,
- .plat_inteconn_desc = NULL
-};
-
-/* Special definition for SGM775 */
-/* Topology configuration for SGM775 */
-const unsigned char sgm775_power_domain_tree_desc[] = {
- /* No of root nodes */
- ARM_SYSTEM_COUNT,
- /* No of children for the root node */
- PLAT_ARM_CLUSTER_COUNT,
- /* No of children for the first cluster node */
- PLAT_ARM_CLUSTER_CORE_COUNT,
-};
-
-const css_topology_t sgm775_topology = {
- .power_tree = sgm775_power_domain_tree_desc,
- .plat_cluster_core_count = PLAT_ARM_CLUSTER_CORE_COUNT
-};
-
-/* Configuration structure for SGM775 */
-css_plat_config_t sgm775_config = {
- .inteconn = &sgm_inteconn,
- .topology = &sgm775_topology
-};
-
-/*******************************************************************************
- * This function initializes the platform structure.
- ******************************************************************************/
-void plat_config_init(void)
-{
- /* Get the platform configurations */
- switch (GET_PLAT_PART_NUM) {
- case SGM775_SSC_VER_PART_NUM:
- css_plat_info = &sgm775_config;
-
- break;
- default:
- ERROR("Not a valid sgm variant!\n");
- panic();
- }
-}
-
-/*******************************************************************************
- * This function returns the platform structure pointer.
- ******************************************************************************/
-css_plat_config_t *get_plat_config(void)
-{
- assert(css_plat_info != NULL);
- return css_plat_info;
-}
-
-#if TRUSTED_BOARD_BOOT
-int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
-{
- return get_mbedtls_heap_helper(heap_addr, heap_size);
-}
-#endif
diff --git a/plat/arm/css/sgm/sgm_security.c b/plat/arm/css/sgm/sgm_security.c
deleted file mode 100644
index 21d5306..0000000
--- a/plat/arm/css/sgm/sgm_security.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/debug.h>
-#include <drivers/arm/tzc_dmc500.h>
-#include <plat/arm/common/plat_arm.h>
-#include <plat/arm/soc/common/soc_css.h>
-
-#include <sgm_variant.h>
-
-/* Is populated with the DMC-500 controllers base addresses */
-static tzc_dmc500_driver_data_t plat_driver_data;
-
-void plat_sgm_dp_security_setup(void)
-{
- unsigned int nprot_nsaid;
-
- /*
- * At reset the Mali display processors start with NSAIDs set to zero
- * so the firmware must set them up to the expected values for ARM sgm
- * platforms.
- */
-
- nprot_nsaid = mmio_read_32(MALI_DP_BASE + DP_NPROT_NSAID_OFFSET);
- nprot_nsaid &= ~((0xF << W_NPROT_NSAID_SHIFT) |
- (0xF << LS_NPORT_NSAID_SHIFT));
- nprot_nsaid |= ((TZC_NSAID_DISP1 << W_NPROT_NSAID_SHIFT) |
- (TZC_NSAID_DISP0 << LS_NPORT_NSAID_SHIFT));
- mmio_write_32(MALI_DP_BASE + DP_NPROT_NSAID_OFFSET, nprot_nsaid);
-}
-
-void plat_arm_security_setup(void)
-{
- unsigned int i;
- unsigned int part_num = GET_PLAT_PART_NUM;
-
- INFO("part_num: 0x%x\n", part_num);
-
- /*
- * Initialise plat_driver_data with platform specific DMC_BASE
- * addresses
- */
- switch (part_num) {
- case SGM775_SSC_VER_PART_NUM:
- for (i = 0; i < SGM775_DMC_COUNT; i++)
- plat_driver_data.dmc_base[i] = PLAT_ARM_TZC_BASE
- + SGM_DMC_SIZE * i;
- plat_driver_data.dmc_count = SGM775_DMC_COUNT;
- break;
- default:
- /* Unexpected platform */
- ERROR("Unexpected platform\n");
- panic();
- }
- /* Initialize the TrustZone Controller in DMC-500 */
- arm_tzc_dmc500_setup(&plat_driver_data, NULL);
-
- /* Do DP NSAID setup */
- plat_sgm_dp_security_setup();
- /* Do ARM CSS SoC security setup */
- soc_css_security_setup();
-}
diff --git a/plat/arm/css/sgm/sgm_topology.c b/plat/arm/css/sgm/sgm_topology.c
deleted file mode 100644
index 2d9552d..0000000
--- a/plat/arm/css/sgm/sgm_topology.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-#include <sgm_plat_config.h>
-
-/*******************************************************************************
- * This function returns the topology tree information.
- ******************************************************************************/
-const unsigned char *plat_get_power_domain_tree_desc(void)
-{
- return get_plat_config()->topology->power_tree;
-}
-
-/*******************************************************************************
- * 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 get_plat_config()->topology->plat_cluster_core_count;
-}
-
-/*
- * 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[PLATFORM_CORE_COUNT] = {
- 0, 1, 2, 3, 4, 5, 6, 7 };
diff --git a/plat/arm/css/sgm/tsp/sgm_tsp_setup.c b/plat/arm/css/sgm/tsp/sgm_tsp_setup.c
deleted file mode 100644
index 5f40c4c..0000000
--- a/plat/arm/css/sgm/tsp/sgm_tsp_setup.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-#include <sgm_plat_config.h>
-
-void tsp_early_platform_setup(void)
-{
- /* Initialize the platform configuration structure */
- plat_config_init();
-
- arm_tsp_early_platform_setup();
-}
diff --git a/plat/arm/css/sgm/tsp/tsp-sgm.mk b/plat/arm/css/sgm/tsp/tsp-sgm.mk
deleted file mode 100644
index de5e5b7..0000000
--- a/plat/arm/css/sgm/tsp/tsp-sgm.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-BL32_SOURCES += ${SGM_GIC_SOURCES} \
- ${CSS_SGM_BASE}/sgm_plat_config.c \
- plat/arm/css/sgm/tsp/sgm_tsp_setup.c
-
-include plat/arm/common/tsp/arm_tsp.mk
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index 38a5786..e807660 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,7 +13,6 @@
#if RAS_EXTENSION
#include <lib/extensions/ras.h>
#endif
-#include <lib/extensions/twed.h>
#include <lib/xlat_tables/xlat_mmu_helpers.h>
#include <plat/common/platform.h>
@@ -23,7 +22,6 @@
* platforms but may also be overridden by a platform if required.
*/
#pragma weak bl31_plat_runtime_setup
-#pragma weak plat_arm_set_twedel_scr_el3
#if SDEI_SUPPORT
#pragma weak plat_sdei_handle_masked_trigger
@@ -105,16 +103,3 @@
#endif
panic();
}
-
-/*******************************************************************************
- * In v8.6+ platforms with delayed trapping of WFE this hook sets the delay. It
- * is a weak function definition so can be overridden depending on the
- * requirements of a platform. The only hook provided is for the TWED fields
- * in SCR_EL3, the TWED fields in HCR_EL2, SCTLR_EL2, and SCTLR_EL1 should be
- * configured as needed in lower exception levels.
- ******************************************************************************/
-
-uint32_t plat_arm_set_twedel_scr_el3(void)
-{
- return TWED_DISABLED;
-}
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index 6e67502..03adcf3 100644
--- a/plat/intel/soc/agilex/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex/bl2_plat_setup.c
@@ -71,8 +71,8 @@
watchdog_init(get_wdt_clk());
- console_16550_register(PLAT_UART0_BASE, get_uart_clk(), PLAT_BAUDRATE,
- &console);
+ console_16550_register(PLAT_INTEL_UART_BASE, get_uart_clk(),
+ PLAT_BAUDRATE, &console);
socfpga_delay_timer_init();
init_ncore_ccu();
diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c
index 168236b..b1b9514 100644
--- a/plat/intel/soc/agilex/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex/bl31_plat_setup.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,6 +14,7 @@
#include <lib/mmio.h>
#include <lib/xlat_tables/xlat_tables.h>
+#include "ccu/ncore_ccu.h"
#include "socfpga_mailbox.h"
#include "socfpga_private.h"
@@ -41,8 +42,8 @@
mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
- console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE,
- &console);
+ console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
+ PLAT_BAUDRATE, &console);
/*
* Check params passed from BL31 should not be NULL,
*/
@@ -114,6 +115,8 @@
(uint64_t)plat_secondary_cpus_bl31_entry);
mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
+
+ ncore_enable_ocram_firewall();
}
const mmap_region_t plat_agilex_mmap[] = {
diff --git a/plat/intel/soc/agilex/include/agilex_noc.h b/plat/intel/soc/agilex/include/agilex_noc.h
index 22db3e2..9aba3c3 100644
--- a/plat/intel/soc/agilex/include/agilex_noc.h
+++ b/plat/intel/soc/agilex/include/agilex_noc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h
index 9c87e45..6a5cf9b 100644
--- a/plat/intel/soc/agilex/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h
@@ -19,6 +19,8 @@
#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 0x2000000
/* Register Mapping */
+#define SOCFPGA_CCU_NOC_REG_BASE 0xf7000000
+
#define SOCFPGA_MMC_REG_BASE 0xff808000
#define SOCFPGA_RSTMGR_REG_BASE 0xffd11000
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index 10a3eec..89df46a 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -26,6 +26,7 @@
lib/xlat_tables/xlat_tables_common.c \
plat/intel/soc/common/aarch64/platform_common.c \
plat/intel/soc/common/aarch64/plat_helpers.S \
+ plat/intel/soc/common/drivers/ccu/ncore_ccu.c \
plat/intel/soc/common/socfpga_delay_timer.c
BL2_SOURCES += \
@@ -48,13 +49,12 @@
plat/intel/soc/common/socfpga_image_load.c \
plat/intel/soc/common/socfpga_storage.c \
plat/intel/soc/common/soc/socfpga_emac.c \
+ plat/intel/soc/common/soc/socfpga_firewall.c \
plat/intel/soc/common/soc/socfpga_handoff.c \
plat/intel/soc/common/soc/socfpga_mailbox.c \
plat/intel/soc/common/soc/socfpga_reset_manager.c \
- plat/intel/soc/common/soc/socfpga_system_manager.c \
plat/intel/soc/common/drivers/qspi/cadence_qspi.c \
- plat/intel/soc/common/drivers/wdt/watchdog.c \
- plat/intel/soc/common/drivers/ccu/ncore_ccu.c
+ plat/intel/soc/common/drivers/wdt/watchdog.c
BL31_SOURCES += \
drivers/arm/cci/cci.c \
diff --git a/plat/intel/soc/common/aarch64/plat_helpers.S b/plat/intel/soc/common/aarch64/plat_helpers.S
index 5cb9b69..213fd3c 100644
--- a/plat/intel/soc/common/aarch64/plat_helpers.S
+++ b/plat/intel/soc/common/aarch64/plat_helpers.S
@@ -102,7 +102,7 @@
* ---------------------------------------------
*/
func plat_crash_console_init
- mov_imm x0, PLAT_UART0_BASE
+ mov_imm x0, CRASH_CONSOLE_BASE
mov_imm x1, PLAT_UART_CLOCK
mov_imm x2, PLAT_BAUDRATE
b console_16550_core_init
@@ -116,7 +116,7 @@
* ---------------------------------------------
*/
func plat_crash_console_putc
- mov_imm x1, PLAT_UART0_BASE
+ mov_imm x1, CRASH_CONSOLE_BASE
b console_16550_core_putc
endfunc plat_crash_console_putc
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
index d4716cf..d9a238e 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
@@ -118,6 +118,7 @@
mmio_setbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF4),
OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
}
+
uint32_t init_ncore_ccu(void)
{
uint32_t status;
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index 7859493..d37904b 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -168,6 +168,7 @@
#define PLAT_UART1_BASE (0xFFC02100)
#define CRASH_CONSOLE_BASE PLAT_UART0_BASE
+#define PLAT_INTEL_UART_BASE PLAT_UART0_BASE
#ifndef SIMICS_BUILD
#define PLAT_BAUDRATE (115200)
diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h
index ff10d36..d3b7141 100644
--- a/plat/intel/soc/common/include/socfpga_fcs.h
+++ b/plat/intel/soc/common/include/socfpga_fcs.h
@@ -11,9 +11,11 @@
#define FCS_RANDOM_WORD_SIZE 8U
#define FCS_PROV_DATA_WORD_SIZE 44U
+#define FCS_SHA384_WORD_SIZE 12U
#define FCS_RANDOM_BYTE_SIZE (FCS_RANDOM_WORD_SIZE * 4U)
#define FCS_PROV_DATA_BYTE_SIZE (FCS_PROV_DATA_WORD_SIZE * 4U)
+#define FCS_SHA384_BYTE_SIZE (FCS_SHA384_WORD_SIZE * 4U)
#define FCS_CRYPTION_DATA_0 0x10100
@@ -38,4 +40,7 @@
uint32_t src_size, uint32_t dst_addr,
uint32_t dst_size, uint32_t *send_id);
+uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
+ uint32_t *mbox_error);
+
#endif /* SOCFPGA_FCS_H */
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index 6b7e0fc..b260a62 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -42,6 +42,7 @@
#define MBOX_CMD_CANCEL 0x03
#define MBOX_CMD_VAB_SRC_CERT 0x0B
#define MBOX_CMD_GET_IDCODE 0x10
+#define MBOX_CMD_GET_USERCODE 0x13
#define MBOX_CMD_REBOOT_HPS 0x47
/* Reconfiguration Commands */
@@ -50,6 +51,11 @@
#define MBOX_RECONFIG_DATA 0x08
#define MBOX_RECONFIG_STATUS 0x09
+/* HWMON Commands */
+#define MBOX_HWMON_READVOLT 0x18
+#define MBOX_HWMON_READTEMP 0x19
+
+
/* QSPI Commands */
#define MBOX_CMD_QSPI_OPEN 0x32
#define MBOX_CMD_QSPI_CLOSE 0x33
@@ -67,6 +73,8 @@
#define MBOX_FCS_ENCRYPT_REQ 0x7E
#define MBOX_FCS_DECRYPT_REQ 0x7F
#define MBOX_FCS_RANDOM_GEN 0x80
+/* Miscellaneous commands */
+#define MBOX_GET_ROM_PATCH_SHA384 0x1B0
/* Mailbox Definitions */
@@ -143,6 +151,10 @@
#define RSU_VERSION_ACMF BIT(8)
#define RSU_VERSION_ACMF_MASK 0xff00
+/* Config Status Macros */
+#define CONFIG_STATUS_WORD_SIZE 16U
+#define CONFIG_STATUS_FW_VER_OFFSET 1
+#define CONFIG_STATUS_FW_VER_MASK 0x00FFFFFF
/* Mailbox Function Definitions */
@@ -171,5 +183,7 @@
int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len);
int mailbox_rsu_update(uint32_t *flash_offset);
int mailbox_hps_stage_notify(uint32_t execution_stage);
+int mailbox_hwmon_readtemp(uint32_t chan, uint32_t *resp_buf);
+int mailbox_hwmon_readvolt(uint32_t chan, uint32_t *resp_buf);
#endif /* SOCFPGA_MBOX_H */
diff --git a/plat/intel/soc/common/include/socfpga_noc.h b/plat/intel/soc/common/include/socfpga_noc.h
new file mode 100644
index 0000000..e3c0f73
--- /dev/null
+++ b/plat/intel/soc/common/include/socfpga_noc.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_NOC_H
+#define SOCFPGA_NOC_H
+
+/* Macros */
+#define SCR_AXI_AP_MASK BIT(24)
+#define SCR_FPGA2SOC_MASK BIT(16)
+#define SCR_MPU_MASK BIT(0)
+#define DISABLE_L4_FIREWALL (SCR_AXI_AP_MASK | SCR_FPGA2SOC_MASK \
+ | SCR_MPU_MASK)
+#define DISABLE_BRIDGE_FIREWALL 0x0ffe0101
+
+#define SOCFPGA_CCU_NOC(_ctrl, _dev) (SOCFPGA_CCU_NOC_REG_BASE \
+ + (SOCFPGA_CCU_NOC_##_ctrl##_##_dev))
+
+#define SOCFPGA_L4_PER_SCR(_reg) (SOCFPGA_L4_PER_SCR_REG_BASE \
+ + (SOCFPGA_NOC_FW_L4_PER_SCR_##_reg))
+
+#define SOCFPGA_L4_SYS_SCR(_reg) (SOCFPGA_L4_SYS_SCR_REG_BASE \
+ + (SOCFPGA_NOC_FW_L4_SYS_SCR_##_reg))
+
+/* L3 Interconnect Register Map */
+#define SOCFPGA_NOC_FW_L4_PER_SCR_NAND_REGISTER 0x0000
+#define SOCFPGA_NOC_FW_L4_PER_SCR_NAND_DATA 0x0004
+#define SOCFPGA_NOC_FW_L4_PER_SCR_USB0_REGISTER 0x000c
+#define SOCFPGA_NOC_FW_L4_PER_SCR_USB1_REGISTER 0x0010
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_MASTER0 0x001c
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_MASTER1 0x0020
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_SLAVE0 0x0024
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_SLAVE1 0x0028
+#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC0 0x002c
+#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC1 0x0030
+#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC2 0x0034
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SDMMC 0x0040
+#define SOCFPGA_NOC_FW_L4_PER_SCR_GPIO0 0x0044
+#define SOCFPGA_NOC_FW_L4_PER_SCR_GPIO1 0x0048
+#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C0 0x0050
+#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C1 0x0054
+#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C2 0x0058
+#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C3 0x005c
+#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C4 0x0060
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SP_TIMER0 0x0064
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SP_TIMER1 0x0068
+#define SOCFPGA_NOC_FW_L4_PER_SCR_UART0 0x006c
+#define SOCFPGA_NOC_FW_L4_PER_SCR_UART1 0x0070
+
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_DMA_ECC 0x0008
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC0RX_ECC 0x000c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC0TX_ECC 0x0010
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC1RX_ECC 0x0014
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC1TX_ECC 0x0018
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC2RX_ECC 0x001c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC2TX_ECC 0x0020
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_ECC 0x002c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_READ_ECC 0x0030
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_WRITE_ECC 0x0034
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_OCRAM_ECC 0x0038
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_SDMMC_ECC 0x0040
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB0_ECC 0x0044
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB1_ECC 0x0048
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_CLK_MGR 0x004c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_IO_MGR 0x0054
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_RST_MGR 0x0058
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_SYS_MGR 0x005c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_OSC0_TIMER 0x0060
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_OSC1_TIMER 0x0064
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG0 0x0068
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG1 0x006c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG2 0x0070
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG3 0x0074
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_DAP 0x0078
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_PROBES 0x0090
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_QOS 0x0094
+
+/* CCU NOC Register Map */
+
+#define SOCFPGA_CCU_NOC_CPU0_RAM0 0x04688
+#define SOCFPGA_CCU_NOC_IOM_RAM0 0x18628
+
+#define SOCFPGA_CCU_NOC_ADMASK_P_MASK BIT(0)
+#define SOCFPGA_CCU_NOC_ADMASK_NS_MASK BIT(1)
+
+/* Function Definitions */
+
+void enable_ns_peripheral_access(void);
+void enable_ns_bridge_access(void);
+void enable_ns_ocram_access(void);
+void enable_ocram_firewall(void);
+
+#endif
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index 0db71e2..43f3dc4 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -27,6 +27,12 @@
#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE 0xC2000004
#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM 0xC2000005
+/* FPGA Bitstream Flag */
+#define FLAG_PARTIAL_CONFIG BIT(0)
+#define FLAG_AUTHENTICATION BIT(1)
+#define CONFIG_TEST_FLAG(_flag, _type) (((flag) & FLAG_##_type) \
+ == FLAG_##_type)
+
/* Secure Register Access */
#define INTEL_SIP_SMC_REG_READ 0xC2000007
#define INTEL_SIP_SMC_REG_WRITE 0xC2000008
@@ -39,31 +45,50 @@
#define INTEL_SIP_SMC_RSU_RETRY_COUNTER 0xC200000F
#define INTEL_SIP_SMC_RSU_DCMF_VERSION 0xC2000010
#define INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION 0xC2000011
+#define INTEL_SIP_SMC_RSU_MAX_RETRY 0xC2000012
+#define INTEL_SIP_SMC_RSU_COPY_MAX_RETRY 0xC2000013
+#define INTEL_SIP_SMC_RSU_DCMF_STATUS 0xC2000014
+#define INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS 0xC2000015
+/* Hardware monitor */
+#define INTEL_SIP_SMC_HWMON_READTEMP 0xC2000020
+#define INTEL_SIP_SMC_HWMON_READVOLT 0xC2000021
+#define TEMP_CHANNEL_MAX (1 << 15)
+#define VOLT_CHANNEL_MAX (1 << 15)
/* ECC */
#define INTEL_SIP_SMC_ECC_DBE 0xC200000D
+/* Generic Command */
+#define INTEL_SIP_SMC_GET_ROM_PATCH_SHA384 0xC2000040
+
/* Send Mailbox Command */
#define INTEL_SIP_SMC_MBOX_SEND_CMD 0xC200001E
+#define INTEL_SIP_SMC_FIRMWARE_VERSION 0xC200001F
+#define INTEL_SIP_SMC_HPS_SET_BRIDGES 0xC2000032
+/* Mailbox Command */
+#define INTEL_SIP_SMC_GET_USERCODE 0xC200003D
/* SiP Definitions */
/* ECC DBE */
#define WARM_RESET_WFI_FLAG BIT(31)
-#define SYSMGR_ECC_DBE_COLD_RST_MASK (SYSMGR_ECC_OCRAM_MASK |\
+#define SYSMGR_ECC_DBE_COLD_RST_MASK (SYSMGR_ECC_OCRAM_MASK |\
SYSMGR_ECC_DDR0_MASK |\
SYSMGR_ECC_DDR1_MASK)
+/* Non-mailbox SMC Call */
+#define INTEL_SIP_SMC_SVC_VERSION 0xC2000200
+
/* SMC function IDs for SiP Service queries */
-#define SIP_SVC_CALL_COUNT 0x8200ff00
-#define SIP_SVC_UID 0x8200ff01
-#define SIP_SVC_VERSION 0x8200ff03
+#define SIP_SVC_CALL_COUNT 0x8200ff00
+#define SIP_SVC_UID 0x8200ff01
+#define SIP_SVC_VERSION 0x8200ff03
/* SiP Service Calls version numbers */
-#define SIP_SVC_VERSION_MAJOR 0
-#define SIP_SVC_VERSION_MINOR 1
+#define SIP_SVC_VERSION_MAJOR 1
+#define SIP_SVC_VERSION_MINOR 0
/* Structure Definitions */
diff --git a/plat/intel/soc/common/include/socfpga_system_manager.h b/plat/intel/soc/common/include/socfpga_system_manager.h
index 2b13f1f..a77734d 100644
--- a/plat/intel/soc/common/include/socfpga_system_manager.h
+++ b/plat/intel/soc/common/include/socfpga_system_manager.h
@@ -42,13 +42,6 @@
#define IDLE_DATA_SOC2FPGA BIT(4)
#define IDLE_DATA_MASK (IDLE_DATA_LWSOC2FPGA | IDLE_DATA_SOC2FPGA)
-#define SCR_AXI_AP_MASK BIT(24)
-#define SCR_FPGA2SOC_MASK BIT(16)
-#define SCR_MPU_MASK BIT(0)
-#define DISABLE_L4_FIREWALL (SCR_AXI_AP_MASK | SCR_FPGA2SOC_MASK \
- | SCR_MPU_MASK)
-#define DISABLE_BRIDGE_FIREWALL 0x0ffe0101
-
#define SYSMGR_ECC_OCRAM_MASK BIT(1)
#define SYSMGR_ECC_DDR0_MASK BIT(16)
#define SYSMGR_ECC_DDR1_MASK BIT(17)
@@ -58,69 +51,4 @@
#define SOCFPGA_SYSMGR(_reg) (SOCFPGA_SYSMGR_REG_BASE \
+ (SOCFPGA_SYSMGR_##_reg))
-#define SOCFPGA_L4_PER_SCR(_reg) (SOCFPGA_L4_PER_SCR_REG_BASE \
- + (SOCFPGA_NOC_FW_L4_PER_SCR_##_reg))
-
-#define SOCFPGA_L4_SYS_SCR(_reg) (SOCFPGA_L4_SYS_SCR_REG_BASE \
- + (SOCFPGA_NOC_FW_L4_SYS_SCR_##_reg))
-
-/* L3 Interconnect Register Map */
-#define SOCFPGA_NOC_FW_L4_PER_SCR_NAND_REGISTER 0x0000
-#define SOCFPGA_NOC_FW_L4_PER_SCR_NAND_DATA 0x0004
-#define SOCFPGA_NOC_FW_L4_PER_SCR_USB0_REGISTER 0x000c
-#define SOCFPGA_NOC_FW_L4_PER_SCR_USB1_REGISTER 0x0010
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_MASTER0 0x001c
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_MASTER1 0x0020
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_SLAVE0 0x0024
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_SLAVE1 0x0028
-#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC0 0x002c
-#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC1 0x0030
-#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC2 0x0034
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SDMMC 0x0040
-#define SOCFPGA_NOC_FW_L4_PER_SCR_GPIO0 0x0044
-#define SOCFPGA_NOC_FW_L4_PER_SCR_GPIO1 0x0048
-#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C0 0x0050
-#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C1 0x0054
-#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C2 0x0058
-#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C3 0x005c
-#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C4 0x0060
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SP_TIMER0 0x0064
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SP_TIMER1 0x0068
-#define SOCFPGA_NOC_FW_L4_PER_SCR_UART0 0x006c
-#define SOCFPGA_NOC_FW_L4_PER_SCR_UART1 0x0070
-
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_DMA_ECC 0x0008
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC0RX_ECC 0x000c
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC0TX_ECC 0x0010
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC1RX_ECC 0x0014
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC1TX_ECC 0x0018
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC2RX_ECC 0x001c
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC2TX_ECC 0x0020
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_ECC 0x002c
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_READ_ECC 0x0030
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_WRITE_ECC 0x0034
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_OCRAM_ECC 0x0038
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_SDMMC_ECC 0x0040
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB0_ECC 0x0044
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB1_ECC 0x0048
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_CLK_MGR 0x004c
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_IO_MGR 0x0054
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_RST_MGR 0x0058
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_SYS_MGR 0x005c
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_OSC0_TIMER 0x0060
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_OSC1_TIMER 0x0064
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG0 0x0068
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG1 0x006c
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG2 0x0070
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG3 0x0074
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_DAP 0x0078
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_PROBES 0x0090
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_QOS 0x0094
-
-#define SOCFPGA_CCU_NOC_CPU0_RAMSPACE0_0 0xf7004688
-#define SOCFPGA_CCU_NOC_IOM_RAMSPACE0_0 0xf7018628
-
-void enable_ns_peripheral_access(void);
-void enable_ns_bridge_access(void);
-
#endif /* SOCFPGA_SYSTEMMANAGER_H */
diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
index fe5461b..85551a4 100644
--- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c
+++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
@@ -11,6 +11,15 @@
#include "socfpga_mailbox.h"
#include "socfpga_sip_svc.h"
+static bool is_size_4_bytes_aligned(uint32_t size)
+{
+ if ((size % MBOX_WORD_BYTE) != 0U) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
uint32_t *mbox_error)
{
@@ -57,6 +66,10 @@
return INTEL_SIP_SMC_STATUS_REJECTED;
}
+ if (!is_size_4_bytes_aligned(size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
(uint32_t *)addr, size / MBOX_WORD_BYTE,
CMD_DIRECT);
@@ -89,11 +102,6 @@
int status;
uint32_t cmd;
- if (!is_address_in_ddr_range(src_addr, src_size) ||
- !is_address_in_ddr_range(dst_addr, dst_size)) {
- return INTEL_SIP_SMC_STATUS_REJECTED;
- }
-
fcs_crypt_payload payload = {
FCS_CRYPTION_DATA_0,
src_addr,
@@ -101,6 +109,15 @@
dst_addr,
dst_size };
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_size_4_bytes_aligned(sizeof(fcs_crypt_payload))) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
if (mode != 0U) {
cmd = MBOX_FCS_ENCRYPT_REQ;
} else {
@@ -118,3 +135,33 @@
return INTEL_SIP_SMC_STATUS_OK;
}
+
+uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
+ uint32_t *mbox_error)
+{
+ int status;
+ unsigned int resp_len = FCS_SHA384_WORD_SIZE;
+
+ if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
+ CMD_CASUAL, (uint32_t *) addr, &resp_len);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ if (resp_len != FCS_SHA384_WORD_SIZE) {
+ *mbox_error = GENERIC_RESPONSE_ERROR;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *ret_size = FCS_SHA384_BYTE_SIZE;
+
+ flush_dcache_range(addr, *ret_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
diff --git a/plat/intel/soc/common/soc/socfpga_system_manager.c b/plat/intel/soc/common/soc/socfpga_firewall.c
similarity index 84%
rename from plat/intel/soc/common/soc/socfpga_system_manager.c
rename to plat/intel/soc/common/soc/socfpga_firewall.c
index a64053c..515784b 100644
--- a/plat/intel/soc/common/soc/socfpga_system_manager.c
+++ b/plat/intel/soc/common/soc/socfpga_firewall.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +7,8 @@
#include <lib/mmio.h>
#include <lib/utils_def.h>
+#include "socfpga_noc.h"
+#include "socfpga_plat_def.h"
#include "socfpga_system_manager.h"
void enable_nonsecure_access(void)
@@ -92,12 +94,18 @@
mmio_write_32(SOCFPGA_L4_SYS_SCR(L4_NOC_QOS), DISABLE_L4_FIREWALL);
#if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
- mmio_clrbits_32(SOCFPGA_CCU_NOC_CPU0_RAMSPACE0_0, 0x03);
- mmio_clrbits_32(SOCFPGA_CCU_NOC_IOM_RAMSPACE0_0, 0x03);
-
+ enable_ns_ocram_access();
mmio_write_32(SOCFPGA_SYSMGR(SDMMC), SYSMGR_SDMMC_DRVSEL(3));
#endif
+}
+
+void enable_ns_ocram_access(void)
+{
+ mmio_clrbits_32(SOCFPGA_CCU_NOC(CPU0, RAM0),
+ SOCFPGA_CCU_NOC_ADMASK_P_MASK | SOCFPGA_CCU_NOC_ADMASK_NS_MASK);
+ mmio_clrbits_32(SOCFPGA_CCU_NOC(IOM, RAM0),
+ SOCFPGA_CCU_NOC_ADMASK_P_MASK | SOCFPGA_CCU_NOC_ADMASK_NS_MASK);
}
void enable_ns_bridge_access(void)
@@ -105,3 +113,11 @@
mmio_write_32(SOCFPGA_SOC2FPGA_SCR_REG_BASE, DISABLE_BRIDGE_FIREWALL);
mmio_write_32(SOCFPGA_LWSOC2FPGA_SCR_REG_BASE, DISABLE_BRIDGE_FIREWALL);
}
+
+void enable_ocram_firewall(void)
+{
+ mmio_setbits_32(SOCFPGA_CCU_NOC(CPU0, RAM0),
+ SOCFPGA_CCU_NOC_ADMASK_P_MASK | SOCFPGA_CCU_NOC_ADMASK_NS_MASK);
+ mmio_setbits_32(SOCFPGA_CCU_NOC(IOM, RAM0),
+ SOCFPGA_CCU_NOC_ADMASK_P_MASK | SOCFPGA_CCU_NOC_ADMASK_NS_MASK);
+}
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index be900c9..8ecd6db 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -507,11 +507,13 @@
return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
}
- if ((res & SOFTFUNC_STATUS_CONF_DONE) == 0U)
+ if ((res & SOFTFUNC_STATUS_CONF_DONE) == 0U) {
return MBOX_CFGSTAT_STATE_CONFIG;
+ }
- if (init_done && (res & SOFTFUNC_STATUS_INIT_DONE) == 0U)
+ if (init_done && (res & SOFTFUNC_STATUS_INIT_DONE) == 0U) {
return MBOX_CFGSTAT_STATE_CONFIG;
+ }
return MBOX_RET_OK;
}
@@ -527,3 +529,22 @@
return ret;
}
+
+int mailbox_hwmon_readtemp(uint32_t chan, uint32_t *resp_buf)
+{
+ unsigned int resp_len = sizeof(resp_buf);
+
+ return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HWMON_READTEMP, &chan, 1U,
+ CMD_CASUAL, resp_buf,
+ &resp_len);
+
+}
+
+int mailbox_hwmon_readvolt(uint32_t chan, uint32_t *resp_buf)
+{
+ unsigned int resp_len = sizeof(resp_buf);
+
+ return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HWMON_READVOLT, &chan, 1U,
+ CMD_CASUAL, resp_buf,
+ &resp_len);
+}
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index 14cd9e0..f22c2ee 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -20,10 +20,17 @@
#define FPGA_CONFIG_BUFFER_SIZE 4
static int current_block, current_buffer;
-static int read_block, max_blocks, is_partial_reconfig;
+static int read_block, max_blocks;
static uint32_t send_id, rcv_id;
static uint32_t bytes_per_block, blocks_submitted;
+static bool bridge_disable;
+/* RSU static variables */
+static uint32_t rsu_dcmf_ver[4] = {0};
+
+/* RSU Max Retry */
+static uint32_t rsu_max_retry;
+static uint16_t rsu_dcmf_stat[4] = {0};
/* SiP Service UUID */
DEFINE_SVC_UUID2(intl_svc_uid,
@@ -83,22 +90,23 @@
{
uint32_t ret;
- if (query_type == 1)
+ if (query_type == 1U) {
ret = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS, false);
- else
+ } else {
ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS, true);
+ }
- if (ret) {
- if (ret == MBOX_CFGSTAT_STATE_CONFIG)
+ if (ret != 0U) {
+ if (ret == MBOX_CFGSTAT_STATE_CONFIG) {
return INTEL_SIP_SMC_STATUS_BUSY;
- else
+ } else {
return INTEL_SIP_SMC_STATUS_ERROR;
+ }
}
- if (query_type != 1) {
- /* full reconfiguration */
- if (!is_partial_reconfig)
- socfpga_bridges_enable(); /* Enable bridge */
+ if (bridge_disable) {
+ socfpga_bridges_enable(); /* Enable bridge */
+ bridge_disable = false;
}
return INTEL_SIP_SMC_STATUS_OK;
@@ -184,7 +192,7 @@
return status;
}
-static int intel_fpga_config_start(uint32_t config_type)
+static int intel_fpga_config_start(uint32_t flag)
{
uint32_t argument = 0x1;
uint32_t response[3];
@@ -192,7 +200,14 @@
unsigned int size = 0;
unsigned int resp_len = ARRAY_SIZE(response);
+ if (!CONFIG_TEST_FLAG(flag, PARTIAL_CONFIG)) {
+ bridge_disable = true;
+ }
+
- is_partial_reconfig = config_type;
+ if (CONFIG_TEST_FLAG(flag, AUTHENTICATION)) {
+ size = 1;
+ bridge_disable = false;
+ }
mailbox_clear_response();
@@ -202,8 +217,10 @@
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RECONFIG, &argument, size,
CMD_CASUAL, response, &resp_len);
- if (status < 0)
- return status;
+ if (status < 0) {
+ bridge_disable = false;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
max_blocks = response[0];
bytes_per_block = response[1];
@@ -222,13 +239,12 @@
read_block = 0;
current_buffer = 0;
- /* full reconfiguration */
- if (!is_partial_reconfig) {
- /* Disable bridge */
+ /* Disable bridge on full reconfiguration */
+ if (bridge_disable) {
socfpga_bridges_disable();
}
- return 0;
+ return INTEL_SIP_SMC_STATUS_OK;
}
static bool is_fpga_config_buffer_full(void)
@@ -261,8 +277,9 @@
intel_fpga_sdm_write_all();
if (!is_address_in_ddr_range(mem, size) ||
- is_fpga_config_buffer_full())
+ is_fpga_config_buffer_full()) {
return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
int j = (i + current_buffer) % FPGA_CONFIG_BUFFER_SIZE;
@@ -279,14 +296,19 @@
}
}
- if (is_fpga_config_buffer_full())
+ if (is_fpga_config_buffer_full()) {
return INTEL_SIP_SMC_STATUS_BUSY;
+ }
return INTEL_SIP_SMC_STATUS_OK;
}
static int is_out_of_sec_range(uint64_t reg_addr)
{
+#if DEBUG
+ return 0;
+#endif
+
switch (reg_addr) {
case(0xF8011100): /* ECCCTRL1 */
case(0xF8011104): /* ECCCTRL2 */
@@ -393,7 +415,77 @@
return INTEL_SIP_SMC_STATUS_OK;
}
+static uint32_t intel_rsu_copy_dcmf_version(uint64_t dcmf_ver_1_0,
+ uint64_t dcmf_ver_3_2)
+{
+ rsu_dcmf_ver[0] = dcmf_ver_1_0;
+ rsu_dcmf_ver[1] = dcmf_ver_1_0 >> 32;
+ rsu_dcmf_ver[2] = dcmf_ver_3_2;
+ rsu_dcmf_ver[3] = dcmf_ver_3_2 >> 32;
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static uint32_t intel_rsu_copy_dcmf_status(uint64_t dcmf_stat)
+{
+ rsu_dcmf_stat[0] = 0xFFFF & (dcmf_stat >> (0 * 16));
+ rsu_dcmf_stat[1] = 0xFFFF & (dcmf_stat >> (1 * 16));
+ rsu_dcmf_stat[2] = 0xFFFF & (dcmf_stat >> (2 * 16));
+ rsu_dcmf_stat[3] = 0xFFFF & (dcmf_stat >> (3 * 16));
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+/* Intel HWMON services */
+static uint32_t intel_hwmon_readtemp(uint32_t chan, uint32_t *retval)
+{
+ if (chan > TEMP_CHANNEL_MAX) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ if (mailbox_hwmon_readtemp(chan, retval) < 0) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static uint32_t intel_hwmon_readvolt(uint32_t chan, uint32_t *retval)
+{
+ if (chan > VOLT_CHANNEL_MAX) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ if (mailbox_hwmon_readvolt(chan, retval) < 0) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
/* Mailbox services */
+static uint32_t intel_smc_fw_version(uint32_t *fw_version)
+{
+ int status;
+ unsigned int resp_len = CONFIG_STATUS_WORD_SIZE;
+ uint32_t resp_data[CONFIG_STATUS_WORD_SIZE] = {0U};
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CONFIG_STATUS, NULL, 0U,
+ CMD_CASUAL, resp_data, &resp_len);
+
+ if (status < 0) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ if (resp_len <= CONFIG_STATUS_FW_VER_OFFSET) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *fw_version = resp_data[CONFIG_STATUS_FW_VER_OFFSET] & CONFIG_STATUS_FW_VER_MASK;
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args,
unsigned int len,
uint32_t urgent, uint32_t *response,
@@ -419,6 +511,33 @@
return INTEL_SIP_SMC_STATUS_OK;
}
+static int intel_smc_get_usercode(uint32_t *user_code)
+{
+ int status;
+ unsigned int resp_len = sizeof(user_code) / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_USERCODE, NULL,
+ 0U, CMD_CASUAL, user_code, &resp_len);
+
+ if (status < 0) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+/* Miscellaneous HPS services */
+static uint32_t intel_hps_set_bridges(uint64_t enable)
+{
+ if (enable != 0U) {
+ socfpga_bridges_enable();
+ } else {
+ socfpga_bridges_disable();
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
/*
* This function is responsible for handling all SiP calls from the NS world
*/
@@ -433,8 +552,9 @@
u_register_t flags)
{
uint32_t retval = 0;
+ uint32_t mbox_error = 0;
uint32_t completed_addr[3];
- uint64_t rsu_respbuf[9];
+ uint64_t retval64, rsu_respbuf[9];
int status = INTEL_SIP_SMC_STATUS_OK;
int mbox_status;
unsigned int len_in_resp;
@@ -530,10 +650,41 @@
SMC_RET2(handle, status, retval);
}
+ case INTEL_SIP_SMC_RSU_DCMF_VERSION:
+ SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK,
+ ((uint64_t)rsu_dcmf_ver[1] << 32) | rsu_dcmf_ver[0],
+ ((uint64_t)rsu_dcmf_ver[3] << 32) | rsu_dcmf_ver[2]);
+
+ case INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION:
+ status = intel_rsu_copy_dcmf_version(x1, x2);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_RSU_DCMF_STATUS:
+ SMC_RET2(handle, INTEL_SIP_SMC_STATUS_OK,
+ ((uint64_t)rsu_dcmf_stat[3] << 48) |
+ ((uint64_t)rsu_dcmf_stat[2] << 32) |
+ ((uint64_t)rsu_dcmf_stat[1] << 16) |
+ rsu_dcmf_stat[0]);
+
+ case INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS:
+ status = intel_rsu_copy_dcmf_status(x1);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_RSU_MAX_RETRY:
+ SMC_RET2(handle, INTEL_SIP_SMC_STATUS_OK, rsu_max_retry);
+
+ case INTEL_SIP_SMC_RSU_COPY_MAX_RETRY:
+ rsu_max_retry = x1;
+ SMC_RET1(handle, INTEL_SIP_SMC_STATUS_OK);
+
case INTEL_SIP_SMC_ECC_DBE:
status = intel_ecc_dbe_notification(x1);
SMC_RET1(handle, status);
+ case INTEL_SIP_SMC_FIRMWARE_VERSION:
+ status = intel_smc_fw_version(&retval);
+ SMC_RET2(handle, status, retval);
+
case INTEL_SIP_SMC_MBOX_SEND_CMD:
x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
@@ -542,6 +693,32 @@
&len_in_resp);
SMC_RET3(handle, status, mbox_status, len_in_resp);
+ case INTEL_SIP_SMC_GET_USERCODE:
+ status = intel_smc_get_usercode(&retval);
+ SMC_RET2(handle, status, retval);
+
+ case INTEL_SIP_SMC_GET_ROM_PATCH_SHA384:
+ status = intel_fcs_get_rom_patch_sha384(x1, &retval64,
+ &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x1, retval64);
+
+ case INTEL_SIP_SMC_SVC_VERSION:
+ SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK,
+ SIP_SVC_VERSION_MAJOR,
+ SIP_SVC_VERSION_MINOR);
+
+ case INTEL_SIP_SMC_HPS_SET_BRIDGES:
+ status = intel_hps_set_bridges(x1);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_HWMON_READTEMP:
+ status = intel_hwmon_readtemp(x1, &retval);
+ SMC_RET2(handle, status, retval);
+
+ case INTEL_SIP_SMC_HWMON_READVOLT:
+ status = intel_hwmon_readvolt(x1, &retval);
+ SMC_RET2(handle, status, retval);
+
default:
return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
cookie, handle, flags);
diff --git a/plat/intel/soc/n5x/bl31_plat_setup.c b/plat/intel/soc/n5x/bl31_plat_setup.c
index 2a8daa6..5ca1a71 100644
--- a/plat/intel/soc/n5x/bl31_plat_setup.c
+++ b/plat/intel/soc/n5x/bl31_plat_setup.c
@@ -42,8 +42,8 @@
mmio_write_64(PLAT_SEC_ENTRY, 0);
- console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE,
- &console);
+ console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
+ PLAT_BAUDRATE, &console);
/*
* Check params passed from BL31 should not be NULL,
*/
diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c
index a8026ea..faff898 100644
--- a/plat/intel/soc/stratix10/bl2_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl2_plat_setup.c
@@ -69,8 +69,8 @@
watchdog_init(get_wdt_clk());
- console_16550_register(PLAT_UART0_BASE, get_uart_clk(), PLAT_BAUDRATE,
- &console);
+ console_16550_register(PLAT_INTEL_UART_BASE, get_uart_clk(),
+ PLAT_BAUDRATE, &console);
socfpga_emac_init();
socfpga_delay_timer_init();
diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c
index 128a808..be0fae5 100644
--- a/plat/intel/soc/stratix10/bl31_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl31_plat_setup.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,6 +17,7 @@
#include <platform_def.h>
#include "socfpga_mailbox.h"
+#include "socfpga_noc.h"
#include "socfpga_private.h"
#include "socfpga_reset_manager.h"
#include "socfpga_system_manager.h"
@@ -49,8 +50,8 @@
mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
- console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE,
- &console);
+ console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
+ PLAT_BAUDRATE, &console);
/*
* Check params passed from BL31 should not be NULL,
*/
@@ -122,6 +123,8 @@
(uint64_t)plat_secondary_cpus_bl31_entry);
mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
+
+ enable_ocram_firewall();
}
const mmap_region_t plat_stratix10_mmap[] = {
diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
index b84a567..2defeb9 100644
--- a/plat/intel/soc/stratix10/include/socfpga_plat_def.h
+++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
@@ -1,6 +1,5 @@
/*
* Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,6 +18,8 @@
#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 0x1000000
/* Register Mapping */
+#define SOCFPGA_CCU_NOC_REG_BASE 0xf7000000
+
#define SOCFPGA_MMC_REG_BASE 0xff808000
#define SOCFPGA_RSTMGR_REG_BASE 0xffd11000
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index d9d88d4..b7808ae 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -26,7 +26,8 @@
lib/xlat_tables/xlat_tables_common.c \
plat/intel/soc/common/aarch64/platform_common.c \
plat/intel/soc/common/aarch64/plat_helpers.S \
- plat/intel/soc/common/socfpga_delay_timer.c
+ plat/intel/soc/common/socfpga_delay_timer.c \
+ plat/intel/soc/common/soc/socfpga_firewall.c
BL2_SOURCES += \
common/desc_image_load.c \
@@ -50,7 +51,6 @@
plat/intel/soc/common/soc/socfpga_handoff.c \
plat/intel/soc/common/soc/socfpga_mailbox.c \
plat/intel/soc/common/soc/socfpga_reset_manager.c \
- plat/intel/soc/common/soc/socfpga_system_manager.c \
plat/intel/soc/common/drivers/qspi/cadence_qspi.c \
plat/intel/soc/common/drivers/wdt/watchdog.c
diff --git a/plat/mediatek/build_helpers/conditional_eval_options.mk b/plat/mediatek/build_helpers/conditional_eval_options.mk
new file mode 100644
index 0000000..6bb3b4e
--- /dev/null
+++ b/plat/mediatek/build_helpers/conditional_eval_options.mk
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Conditional makefile variable assignment
+
+# Options depend on BUILD_TYPE variable
+ifeq ($(BUILD_TYPE),release)
+MTK_DEBUGSYS_LOCK := 1
+MTK_GET_PERM_DIS := 1
+ERRATA_KLEIN_2218950 := 0
+ERRATA_KLEIN_2184257 := 0
+ERRATA_KLEIN_BOOKER := 0
+ERRATA_MTH_BOOKER := 0
+ERRATA_MTHELP_BOOKER := 0
+CRASH_REPORTING := 1
+CONFIG_MTK_BL31_RAMDUMP := 0
+endif
+
+ifeq ($(BUILD_TYPE),debug)
+MTK_PTP3_PROC_DEBUG := 1
+MTK_SRAMRC_DEBUG := 1
+MTK_IOMMU_DEBUG := 1
+MTK_DCM_DEBUG := 1
+MTK_EMI_MPU_DEBUG := 1
+endif
+
+ifeq (${SPD},none)
+SPD_NONE:=1
+$(eval $(call add_define,SPD_NONE))
+endif
+
+# TEE OS config
+ifeq ($(SPD), tbase)
+CONFIG_TBASE := y
+endif
+
+# MICROTRUST OS config
+ifeq ($(SPD), teeid)
+CONFIG_MICROTRUST_TEEI := y
+endif
+
+ifeq (${CONFIG_ARCH_ARM_V8_2},y)
+ARCH_VERSION := armv8_2
+endif
+
+ifeq (${CONFIG_ARCH_ARM_V9},y)
+ARCH_VERSION := armv9
+endif
diff --git a/plat/mediatek/build_helpers/mtk_build_helpers.mk b/plat/mediatek/build_helpers/mtk_build_helpers.mk
new file mode 100644
index 0000000..47d96fa
--- /dev/null
+++ b/plat/mediatek/build_helpers/mtk_build_helpers.mk
@@ -0,0 +1,139 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Get local directory path
+define GET_LOCAL_DIR
+$(patsubst %/,%,$(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))))
+endef
+
+# Clear module source variable
+define CLEAR_LOCAL_SRCS
+$(eval $(1) :=)
+endef
+
+define EXPAND_SUB_MAKEFILE
+include $(S)
+endef
+
+# Expand sub rules.mk
+define INCLUDE_MAKEFILE
+$(eval MODULES_SUB_MAKEFILE := $(patsubst %,%/rules.mk,$(1)))
+$(foreach S,$(MODULES_SUB_MAKEFILE),$(eval $(EXPAND_SUB_MAKEFILE)))
+endef
+
+# Determine option variable is defined or not then define it
+define add_defined_option
+ifdef $(1)
+ifeq ($(findstring $(value $(1)), $(uppercase_table)),)
+DEFINES += -D$(1)$(if $(value $(1)),=$(value $(1)),)
+else
+ifeq ($(strip $(value $(1))),y)
+DEFINES += -D$(1)$(if $(value $(1)),=1,)
+endif
+endif
+endif
+endef
+
+define EXPAND_RULES_MAKEFILE
+LOCAL_SRCS-y :=
+MODULE :=
+SUB_RULES-y :=
+include $(S)
+endef
+
+# INCLUDE_MODULES macro expand included modules rules.mk
+# Arguments:
+# $(1) = MODULES variables
+define INCLUDE_MODULES
+$(eval MODULES_TEMP := $(1))
+$(eval MODULES_MAKEFILE := $(patsubst %,%/rules.mk,$(MODULES_TEMP)))
+$(foreach S,$(MODULES_MAKEFILE),$(eval $(EXPAND_RULES_MAKEFILE)))
+endef
+
+# MAKE_LOCALS expand module source file variable to BL${BL}_SOURCES
+# Arguments:
+# $(1) = source file
+# $(2) = BL stage (1, 2, 2u, 31, 32)
+define MAKE_LOCALS
+$(eval $(call uppercase,$(2))_SOURCES += $(1))
+endef
+
+# MAKE_LINKERFILE change linker script source file name to
+# target linker script
+# $(1) = linker script source file
+# $(2) = BL stage
+define MAKE_LINKERFILE
+$(eval EXTRA_GENERATED_LINKER_SCRIPT += $(BUILD_PLAT)/$(2)/$(patsubst %.ld.S,%.ld,$(notdir $(1))))
+endef
+
+# MAKE_LINKERFILE_ITER call MAKE_LINKERFILE iteratively
+# $(1) = linker script source file
+# $(2) = BL stage
+define MAKE_LINKERFILE_ITER
+$(eval $(foreach link_src,$(1),$(call MAKE_LINKERFILE,$(link_src),$(2))))
+endef
+
+# MAKE_LD_ITER generate the linker scripts using the C preprocessor iteratively
+# $(1) = output linker script
+# $(2) = input template
+# $(3) = BL stage (1, 2, 2u, 31, 32)
+define MAKE_LD_ITER
+$(eval index_list=$(shell seq $(words $(1))))
+$(eval $(foreach i, $(index_list), \
+$(call MAKE_LD,$(word $(i), $(1)), $(word $(i), $(2)),$(3))))
+endef
+
+# MAKE_MODULE reference MAKE_OBJS.
+# Create module folder under out/bl$(BL)/$(module)
+# Arguments:
+# $(1) = module name
+# $(2) = source file
+# $(3) = BL stage
+define MAKE_MODULE
+ $(eval MODULE := $(strip $(1)))
+ $(eval BUILD_DIR := ${BUILD_PLAT}/${3})
+ $(eval SOURCES := $(2))
+ $(eval OBJS_TEMP := $(addprefix $(BUILD_DIR)/$(MODULE)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
+ $(eval MODULE_OBJS += $(OBJS_TEMP))
+ # We use sort only to get a list of unique object directory names.
+ # ordering is not relevant but sort removes duplicates.
+ $(eval TEMP_OBJ_DIRS := $(sort $(dir ${OBJS_TEMP} ${LINKERFILE})))
+ # The $(dir ) function leaves a trailing / on the directory names
+ # Rip off the / to match directory names with make rule targets.
+ $(eval OBJ_DIRS := $(patsubst %/,%,$(TEMP_OBJ_DIRS)))
+
+$(eval $(foreach objd,${OBJ_DIRS},$(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
+${3}_dirs: | ${OBJ_DIRS}
+
+$(eval $(call MAKE_OBJS,$(BUILD_DIR)/$(MODULE),$(SOURCES),${3}))
+
+libraries: $(OBJS_TEMP)
+endef
+
+# Include MTK configuration files
+
+# MTK makefile variables
+MTK_PLAT := plat/mediatek
+MTK_PLAT_SOC := ${MTK_PLAT}/${MTK_SOC}
+MTK_COMMON_CFG := $(MTK_PLAT)/common/common_config.mk
+MTK_PLAT_CFG := $(MTK_PLAT_SOC)/plat_config.mk
+MTK_PROJECT_CFG := $(MTK_PLAT)/project/$(PLAT)/project_config.mk
+MTK_OPTIONS := $(MTK_PLAT)/build_helpers/options.mk
+MTK_COND_EVAL := $(MTK_PLAT)/build_helpers/conditional_eval_options.mk
+
+# Indicate which BL should be built in command line
+ifeq (${NEED_BL31},yes)
+MTK_BL := bl31
+endif
+ifeq (${NEED_BL32},yes)
+MTK_BL := bl32
+endif
+# Include common, platform, board level config
+include $(MTK_COMMON_CFG)
+include $(MTK_PLAT_CFG)
+-include $(MTK_PROJECT_CFG)
+include $(MTK_COND_EVAL)
+include $(MTK_OPTIONS)
diff --git a/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk b/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
new file mode 100644
index 0000000..22a546c
--- /dev/null
+++ b/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Expand include modules
+$(eval $(call INCLUDE_MODULES,$(MODULES-y)))
+
+# Make next section align to page size
+ifneq ($(MTK_EXTRA_LINKERFILE),)
+$(eval $(call MAKE_LINKERFILE_ITER,$(MTK_LINKERFILE_SOURCE),bl31))
+
+# EXTRA_GENERATED_LINKER_SCRIPT is a global variable of derived linker
+# script list(from MTK_LINKERFILE_SOURCE) after MAKE_LINKERFILE_ITER
+# function call
+EXTRA_LINKERFILE += ${EXTRA_GENERATED_LINKER_SCRIPT}
+
+# Expand derived linker script as build target
+$(eval $(call MAKE_LD_ITER, $(EXTRA_GENERATED_LINKER_SCRIPT),$(MTK_LINKERFILE_SOURCE),bl31))
+
+# mtk_align.ld MUST BE THE LAST LINKER SCRIPT!
+EXTRA_LINKERFILE += ${MTK_PLAT}/include/mtk_align.ld
+
+# bl31.ld should depend on EXTRA_LINKERFILE
+$(eval ${BUILD_PLAT}/bl31/bl31.ld: ${EXTRA_LINKERFILE})
+EXTRA_LINKERFILE := $(addprefix -T,$(EXTRA_LINKERFILE))
+else
+EXTRA_LINKERFILE :=
+endif
diff --git a/plat/mediatek/build_helpers/options.mk b/plat/mediatek/build_helpers/options.mk
new file mode 100644
index 0000000..394a605
--- /dev/null
+++ b/plat/mediatek/build_helpers/options.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# call add_defined_option to evaluate MTK defined value
+$(eval $(call add_defined_option,MTK_SIP_KERNEL_BOOT_ENABLE))
+$(eval $(call add_defined_option,PLAT_EXTRA_LD_SCRIPT))
+$(eval $(call add_defined_option,MTK_EXTRA_LINKERFILE))
+$(eval $(call add_defined_option,MTK_BL31_AS_BL2))
+$(eval $(call add_defined_option,MTK_BL33_IS_64BIT))
+$(eval $(call add_defined_option,PLAT_XLAT_TABLES_DYNAMIC))
+$(eval $(call add_defined_option,MTK_ADAPTED))
+$(eval $(call add_defined_option,MTK_SOC))
+$(eval $(call add_defined_option,UART_CLOCK))
+$(eval $(call add_defined_option,UART_BAUDRATE))
diff --git a/plat/mediatek/mt6795/aarch64/plat_helpers.S b/plat/mediatek/mt6795/aarch64/plat_helpers.S
deleted file mode 100644
index aaddb2b..0000000
--- a/plat/mediatek/mt6795/aarch64/plat_helpers.S
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2016-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>
-
- .globl plat_secondary_cold_boot_setup
- .globl plat_report_exception
- .globl platform_is_primary_cpu
- .globl plat_crash_console_init
- .globl plat_crash_console_putc
- .globl plat_crash_console_flush
- .globl platform_mem_init
-
-
- .macro crash_ram_log
- /*
- * Check teearg->atf_log_buf_size.
- * Exit if atf_log_buf_size equals 0
- */
- adr x2, ptr_atf_crash_flag
- ldr x2, [x2]
- /* exit if ptr_atf_crash_flag equals NULL */
- cbz x2, exit_putc
-
- /*
- * set atf crash magic number
- */
-1:
- adr x2, ptr_atf_crash_flag
- ldr x2, [x2]
- mov_imm x1, 0xdead1abf
- /* p_atf_log_ctrl->atf_crash_flag = 0xdead1abf */
- str w1, [x2]
- /* can't use w3 return addr, w4, start of buffer addr */
- ldr w2, [x2]
- cmp w2, w1
- b.ne 1b
-
- /*
- * get cpu id
- */
- mrs x1, mpidr_el1
- /* refer to platform_get_core_pos */
- and x2, x1, #MPIDR_CPU_MASK
- and x1, x1, #MPIDR_CLUSTER_MASK
- /* x1 = cpu id (cpu id = aff0 + aff1*4 ) */
- add x1, x2, x1, LSR #6
-
- adr x2, ptr_atf_except_write_pos_per_cpu
- ldr x2, [x2]
- /*
- * plus (cpu_id * 8)-->
- * &p_atf_log_ctrl->atf_except_write_pos_per_cpu[cpu_id]
- * x2 = &p_atf_log_ctrl->atf_except_write_pos_per_cpu[cpu_id];
- */
- add x2, x2, x1, LSL # 3
- /* log write */
- /* w1 = p_atf_log_ctrl->atf_except_write_pos_per_cpu[cpu_id] */
- ldr x1, [x2]
- /* *x1 = w0-->
- * *(p_atf_log_ctrl->atf_except_write_pos_per_cpu[cpu_id]) = c)
- */
- strb w0, [x1]
- /* w1++ */
- add x1, x1, #1
- /* p_atf_log_ctrl->atf_except_write_pos_per_cpu[cpu_id] = w1 */
- str x1, [x2]
-exit_putc:
- .endm
-
- /* -----------------------------------------------------
- * void plat_secondary_cold_boot_setup (void);
- *
- * This function performs any platform specific actions
- * needed for a secondary cpu after a cold reset e.g
- * mark the cpu's presence, mechanism to place it in a
- * holding pen etc.
- * -----------------------------------------------------
- */
-func plat_secondary_cold_boot_setup
- /* Do not do cold boot for secondary CPU */
-cb_panic:
- b cb_panic
-endfunc plat_secondary_cold_boot_setup
-
-func platform_is_primary_cpu
- and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
- cmp x0, #PLAT_PRIMARY_CPU
- cset x0, eq
- ret
-endfunc platform_is_primary_cpu
-
- /* ---------------------------------------------
- * int plat_crash_console_init(void)
- * Function to initialize the crash console
- * without a C Runtime to print crash report.
- * Clobber list : x0, x1, x2
- * ---------------------------------------------
- */
-func plat_crash_console_init
- mov_imm x0, UART0_BASE
- mov_imm x1, UART_CLOCK
- mov_imm x2, UART_BAUDRATE
- b console_init
- ret
-endfunc plat_crash_console_init
-
- /* ---------------------------------------------
- * int plat_crash_console_putc(void)
- * 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, UART0_BASE
- b console_core_putc
- ret
-endfunc plat_crash_console_putc
-
- /* ---------------------------------------------
- * void plat_crash_console_flush(int c)
- * Function to force a write of all buffered
- * data that hasn't been output.
- * Out : void.
- * Clobber list : x0, x1
- * ---------------------------------------------
- */
-func plat_crash_console_flush
- mov_imm x0, UART0_BASE
- b console_core_flush
-endfunc plat_crash_console_flush
-
- /* --------------------------------------------------------
- * void platform_mem_init (void);
- *
- * Any memory init, relocation to be done before the
- * platform boots. Called very early in the boot process.
- * --------------------------------------------------------
- */
-func platform_mem_init
- ret
-endfunc platform_mem_init
-
diff --git a/plat/mediatek/mt6795/bl31.ld.S b/plat/mediatek/mt6795/bl31.ld.S
deleted file mode 100644
index 3d881fc..0000000
--- a/plat/mediatek/mt6795/bl31.ld.S
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/bl_common.ld.h>
-#include <lib/xlat_tables/xlat_tables_defs.h>
-
-OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
-OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
-ENTRY(bl31_entrypoint)
-
-
-MEMORY {
- RAM (rwx): ORIGIN = BL31_BASE, LENGTH = BL31_TZRAM_SIZE
- RAM2 (rwx): ORIGIN = TZRAM2_BASE, LENGTH = TZRAM2_SIZE
-}
-
-
-SECTIONS
-{
- . = BL31_BASE;
-
- ASSERT(. == ALIGN(2048),
- "vector base is not aligned on a 2K boundary.")
-
- __RO_START__ = .;
- vector . : {
- *(.vectors)
- } >RAM
-
- ASSERT(. == ALIGN(PAGE_SIZE),
- "BL31_BASE address is not aligned on a page boundary.")
-
- ro . : {
- *bl31_entrypoint.o(.text*)
- *(.text*)
- *(.rodata*)
-
- RODATA_COMMON
-
- __RO_END_UNALIGNED__ = .;
- /*
- * Memory page(s) mapped to this section will be marked as read-only,
- * executable. No RW data from the next section must creep in.
- * Ensure the rest of the current memory page is unused.
- */
- . = ALIGN(PAGE_SIZE);
- __RO_END__ = .;
- } >RAM
-
- ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
- "cpu_ops not defined for this platform.")
-
- /*
- * Define a linker symbol to mark start of the RW memory area for this
- * image.
- */
- __RW_START__ = . ;
-
- DATA_SECTION >RAM
-
-#ifdef BL31_PROGBITS_LIMIT
- ASSERT(. <= BL31_PROGBITS_LIMIT, "BL3-1 progbits has exceeded its limit.")
-#endif
-
- STACK_SECTION >RAM
- BSS_SECTION >RAM
- __RW_END__ = __BSS_END__;
-
- ASSERT(. <= BL31_LIMIT, "BL3-1 image has exceeded its limit.")
-
- XLAT_TABLE_SECTION >RAM2
-
-#if USE_COHERENT_MEM
- /*
- * The base address of the coherent memory section must be page-aligned (4K)
- * to guarantee that the coherent data are stored on their own pages and
- * are not mixed with normal data. This is required to set up the correct
- * memory attributes for the coherent data page tables.
- */
- coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
- __COHERENT_RAM_START__ = .;
- /*
- * Bakery locks are stored in coherent memory
- *
- * Each lock's data is contiguous and fully allocated by the compiler
- */
- *(bakery_lock)
- *(tzfw_coherent_mem)
- __COHERENT_RAM_END_UNALIGNED__ = .;
- /*
- * Memory page(s) mapped to this section will be marked
- * as device memory. No other unexpected data must creep in.
- * Ensure the rest of the current memory page is unused.
- */
- . = ALIGN(PAGE_SIZE);
- __COHERENT_RAM_END__ = .;
- } >RAM2
-#endif
-
- /*
- * Define a linker symbol to mark end of the RW memory area for this
- * image.
- */
- __BL31_END__ = .;
-
- __BSS_SIZE__ = SIZEOF(.bss);
-#if USE_COHERENT_MEM
- __COHERENT_RAM_UNALIGNED_SIZE__ =
- __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
-
- ASSERT(. <= TZRAM2_LIMIT, "TZRAM2 image has exceeded its limit.")
-}
diff --git a/plat/mediatek/mt6795/bl31_plat_setup.c b/plat/mediatek/mt6795/bl31_plat_setup.c
deleted file mode 100644
index 2051fe7..0000000
--- a/plat/mediatek/mt6795/bl31_plat_setup.c
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <arch_helpers.h>
-#include <common/bl_common.h>
-#include <common/debug.h>
-#include <drivers/arm/cci.h>
-#include <drivers/console.h>
-#include <drivers/generic_delay_timer.h>
-#include <lib/el3_runtime/context_mgmt.h>
-#include <lib/mmio.h>
-#include <lib/utils_def.h>
-#include <lib/xlat_tables/xlat_tables.h>
-#include <plat/common/common_def.h>
-#include <plat/common/platform.h>
-
-#include <mcucfg.h>
-#include <mt_cpuxgpt.h>
-#include <mtk_plat_common.h>
-#include <mtk_sip_svc.h>
-#include <plat_private.h>
-
-/*******************************************************************************
- * Declarations of linker defined symbols which will help us find the layout
- * of trusted SRAM
- ******************************************************************************/
-/*
- * The next 2 constants identify the extents of the code & RO data region.
- * These addresses are used by the MMU setup code and therefore they must be
- * page-aligned. It is the responsibility of the linker script to ensure that
- * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
- */
-IMPORT_SYM(unsigned long, __RO_START__, BL31_RO_BASE);
-IMPORT_SYM(unsigned long, __RO_END__, BL31_RO_LIMIT);
-
-/*
- * Placeholder variables for copying the arguments that have been passed to
- * BL3-1 from BL2.
- */
-static entry_point_info_t bl32_image_ep_info;
-static entry_point_info_t bl33_image_ep_info;
-
-static const int cci_map[] = {
- PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX,
- PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX
-};
-
-static uint32_t cci_map_length = ARRAY_SIZE(cci_map);
-
-/* Table of regions to map using the MMU. */
-static const mmap_region_t plat_mmap[] = {
- /* for TF text, RO, RW */
- MAP_REGION_FLAT(MTK_DEV_RNG0_BASE, MTK_DEV_RNG0_SIZE,
- MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(MTK_DEV_RNG1_BASE, MTK_DEV_RNG1_SIZE,
- MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(RAM_CONSOLE_BASE & ~(PAGE_SIZE_MASK), RAM_CONSOLE_SIZE,
- MT_DEVICE | MT_RW | MT_NS),
- { 0 }
-
-};
-
-/*******************************************************************************
- * Macro generating the code for the function setting up the pagetables as per
- * the platform memory map & initialize the mmu, for the given exception level
- ******************************************************************************/
-#define DEFINE_CONFIGURE_MMU_EL(_el) \
- void plat_configure_mmu_el ## _el(unsigned long total_base, \
- unsigned long total_size, \
- unsigned long ro_start, \
- unsigned long ro_limit, \
- unsigned long coh_start, \
- unsigned long coh_limit) \
- { \
- mmap_add_region(total_base, total_base, \
- total_size, \
- MT_MEMORY | MT_RW | MT_SECURE); \
- mmap_add_region(ro_start, ro_start, \
- ro_limit - ro_start, \
- MT_MEMORY | MT_RO | MT_SECURE); \
- mmap_add_region(coh_start, coh_start, \
- coh_limit - coh_start, \
- MT_DEVICE | MT_RW | MT_SECURE); \
- mmap_add(plat_mmap); \
- init_xlat_tables(); \
- \
- enable_mmu_el ## _el(0); \
- }
-
-/* Define EL3 variants of the function initialising the MMU */
-DEFINE_CONFIGURE_MMU_EL(3)
-
-unsigned int plat_get_syscnt_freq2(void)
-{
- return SYS_COUNTER_FREQ_IN_TICKS;
-}
-
-void plat_cci_init(void)
-{
- /* Initialize CCI driver */
- cci_init(PLAT_MT_CCI_BASE, cci_map, cci_map_length);
-}
-
-void plat_cci_enable(void)
-{
- /*
- * Enable CCI coherency for this cluster.
- * No need for locks as no other cpu is active at the moment.
- */
- cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr()));
-}
-
-void plat_cci_disable(void)
-{
- cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr()));
-}
-
-
-static void platform_setup_cpu(void)
-{
- /* setup big cores */
- mmio_write_32((uintptr_t)&mt6795_mcucfg->mp1_config_res,
- MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK |
- MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK |
- MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK |
- MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK |
- MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK);
- mmio_setbits_32((uintptr_t)&mt6795_mcucfg->mp1_miscdbg, MP1_AINACTS);
- mmio_setbits_32((uintptr_t)&mt6795_mcucfg->mp1_clkenm_div,
- MP1_SW_CG_GEN);
- mmio_clrbits_32((uintptr_t)&mt6795_mcucfg->mp1_rst_ctl,
- MP1_L2RSTDISABLE);
-
- /* set big cores arm64 boot mode */
- mmio_setbits_32((uintptr_t)&mt6795_mcucfg->mp1_cpucfg,
- MP1_CPUCFG_64BIT);
-
- /* set LITTLE cores arm64 boot mode */
- mmio_setbits_32((uintptr_t)&mt6795_mcucfg->mp0_rv_addr[0].rv_addr_hw,
- MP0_CPUCFG_64BIT);
-}
-
-/*******************************************************************************
- * Return a pointer to the 'entry_point_info' structure of the next image for
- * the security state specified. BL33 corresponds to the non-secure image type
- * while BL32 corresponds to the secure image type. A NULL pointer is returned
- * if the image does not exist.
- ******************************************************************************/
-entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
-{
- entry_point_info_t *next_image_info;
-
- next_image_info = (type == NON_SECURE) ?
- &bl33_image_ep_info : &bl32_image_ep_info;
-
- /* None of the images on this platform can have 0x0 as the entrypoint */
- if (next_image_info->pc)
- return next_image_info;
- else
- return NULL;
-}
-
-/*******************************************************************************
- * Perform any BL3-1 early platform setup. Here is an opportunity to copy
- * parameters passed by the calling EL (S-EL1 in BL2 & EL3 in BL1) before they
- * are lost (potentially). This needs to be done before the MMU is initialized
- * so that the memory layout can be used while creating page tables.
- * BL2 has flushed this information to memory, so we are guaranteed to pick up
- * good data.
- ******************************************************************************/
-void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
- u_register_t arg2, u_register_t arg3)
-{
- struct mtk_bl_param_t *pmtk_bl_param = (struct mtk_bl_param_t *)arg0;
- struct atf_arg_t *teearg;
- unsigned long long normal_base;
- unsigned long long atf_base;
-
- assert(pmtk_bl_param != NULL);
- /*
- * Mediatek preloader(i.e, BL2) is in 32 bit state, high 32bits
- * of 64 bit GP registers are UNKNOWN if CPU warm reset from 32 bit
- * to 64 bit state. So we need to clear high 32bit,
- * which may be random value.
- */
- pmtk_bl_param =
- (struct mtk_bl_param_t *)((uint64_t)pmtk_bl_param & 0x00000000ffffffff);
-
- teearg = (struct atf_arg_t *)pmtk_bl_param->tee_info_addr;
-
- console_init(teearg->atf_log_port, UART_CLOCK, UART_BAUDRATE);
- memcpy((void *)>eearg, (void *)teearg, sizeof(struct atf_arg_t));
-
- normal_base = 0;
- /* in ATF boot time, timer for cntpct_el0 is not initialized
- * so it will not count now.
- */
- atf_base = read_cntpct_el0();
- sched_clock_init(normal_base, atf_base);
-
- VERBOSE("bl31_setup\n");
-
- /* Populate entry point information for BL3-2 and BL3-3 */
- SET_PARAM_HEAD(&bl32_image_ep_info,
- PARAM_EP,
- VERSION_1,
- 0);
- SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
- bl32_image_ep_info.pc = BL32_BASE;
-
- SET_PARAM_HEAD(&bl33_image_ep_info,
- PARAM_EP,
- VERSION_1,
- 0);
- /*
- * Tell BL3-1 where the non-trusted software image
- * is located and the entry state information
- */
- /* BL33_START_ADDRESS */
- bl33_image_ep_info.pc = pmtk_bl_param->bl33_start_addr;
- bl33_image_ep_info.spsr = plat_get_spsr_for_bl33_entry();
- bl33_image_ep_info.args.arg4 = pmtk_bl_param->bootarg_loc;
- bl33_image_ep_info.args.arg5 = pmtk_bl_param->bootarg_size;
- SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
-}
-/*******************************************************************************
- * Perform any BL3-1 platform setup code
- ******************************************************************************/
-
-void bl31_platform_setup(void)
-{
- platform_setup_cpu();
-
- generic_delay_timer_init();
-
- plat_mt_gic_driver_init();
- /* Initialize the gic cpu and distributor interfaces */
- plat_mt_gic_init();
-
- /* Topologies are best known to the platform. */
- mt_setup_topology();
-}
-/*******************************************************************************
- * Perform the very early platform specific architectural setup here. At the
- * moment this is only intializes the mmu in a quick and dirty way.
- * Init MTK propiartary log buffer control field.
- ******************************************************************************/
-void bl31_plat_arch_setup(void)
-{
- /* Enable non-secure access to CCI-400 registers */
- mmio_write_32(CCI400_BASE + CCI_SEC_ACCESS_OFFSET, 0x1);
-
- plat_cci_init();
- plat_cci_enable();
-
- if (gteearg.atf_log_buf_size != 0) {
- INFO("mmap atf buffer : 0x%x, 0x%x\n\r",
- gteearg.atf_log_buf_start,
- gteearg.atf_log_buf_size);
-
- mmap_add_region(
- gteearg.atf_log_buf_start &
- ~(PAGE_SIZE_2MB_MASK),
- gteearg.atf_log_buf_start &
- ~(PAGE_SIZE_2MB_MASK),
- PAGE_SIZE_2MB,
- MT_DEVICE | MT_RW | MT_NS);
-
- INFO("mmap atf buffer (force 2MB aligned):0x%x, 0x%x\n",
- (gteearg.atf_log_buf_start & ~(PAGE_SIZE_2MB_MASK)),
- PAGE_SIZE_2MB);
- }
- /*
- * add TZRAM_BASE to memory map
- * then set RO and COHERENT to different attribute
- */
- plat_configure_mmu_el3(
- (TZRAM_BASE & ~(PAGE_SIZE_MASK)),
- (TZRAM_SIZE & ~(PAGE_SIZE_MASK)),
- (BL31_RO_BASE & ~(PAGE_SIZE_MASK)),
- BL31_RO_LIMIT,
- BL_COHERENT_RAM_BASE,
- BL_COHERENT_RAM_END);
- /* Initialize for ATF log buffer */
- if (gteearg.atf_log_buf_size != 0) {
- gteearg.atf_aee_debug_buf_size = ATF_AEE_BUFFER_SIZE;
- gteearg.atf_aee_debug_buf_start =
- gteearg.atf_log_buf_start +
- gteearg.atf_log_buf_size - ATF_AEE_BUFFER_SIZE;
- INFO("ATF log service is registered (0x%x, aee:0x%x)\n",
- gteearg.atf_log_buf_start,
- gteearg.atf_aee_debug_buf_start);
- } else{
- gteearg.atf_aee_debug_buf_size = 0;
- gteearg.atf_aee_debug_buf_start = 0;
- }
-
- /* Platform code before bl31_main */
- /* compatible to the earlier chipset */
-
- /* Show to ATF log buffer & UART */
- INFO("BL3-1: %s\n", version_string);
- INFO("BL3-1: %s\n", build_message);
-
-}
-#if 0
-/* MTK Define */
-#define ACTLR_CPUECTLR_BIT (1 << 1)
-
-void enable_ns_access_to_cpuectlr(void)
-{
- unsigned int next_actlr;
-
-
- /* ACTLR_EL1 do not implement CUPECTLR */
- next_actlr = read_actlr_el2();
- next_actlr |= ACTLR_CPUECTLR_BIT;
- write_actlr_el2(next_actlr);
-
- next_actlr = read_actlr_el3();
- next_actlr |= ACTLR_CPUECTLR_BIT;
- write_actlr_el3(next_actlr);
-}
-#endif
-/*******************************************************************************
- * This function prepare boot argument for 64 bit kernel entry
- ******************************************************************************/
-static entry_point_info_t *bl31_plat_get_next_kernel64_ep_info(void)
-{
- entry_point_info_t *next_image_info;
- unsigned int mode;
-
- mode = 0;
-
- /* Kernel image is always non-secured */
- next_image_info = &bl33_image_ep_info;
-
- /* Figure out what mode we enter the non-secure world in */
- if (el_implemented(2) != EL_IMPL_NONE) {
- INFO("Kernel_EL2\n");
- mode = MODE_EL2;
- } else{
- INFO("Kernel_EL1\n");
- mode = MODE_EL1;
- }
-
- INFO("Kernel is 64Bit\n");
- next_image_info->spsr =
- SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
- next_image_info->pc = get_kernel_info_pc();
- next_image_info->args.arg0 = get_kernel_info_r0();
- next_image_info->args.arg1 = get_kernel_info_r1();
-
- INFO("pc=0x%lx, r0=0x%lx, r1=0x%lx\n",
- next_image_info->pc,
- next_image_info->args.arg0,
- next_image_info->args.arg1);
-
-
- SET_SECURITY_STATE(next_image_info->h.attr, NON_SECURE);
-
- /* None of the images on this platform can have 0x0 as the entrypoint */
- if (next_image_info->pc)
- return next_image_info;
- else
- return NULL;
-}
-
-/*******************************************************************************
- * This function prepare boot argument for 32 bit kernel entry
- ******************************************************************************/
-static entry_point_info_t *bl31_plat_get_next_kernel32_ep_info(void)
-{
- entry_point_info_t *next_image_info;
- unsigned int mode;
-
- mode = 0;
-
- /* Kernel image is always non-secured */
- next_image_info = &bl33_image_ep_info;
-
- /* Figure out what mode we enter the non-secure world in */
- mode = MODE32_hyp;
- /*
- * TODO: Consider the possibility of specifying the SPSR in
- * the FIP ToC and allowing the platform to have a say as
- * well.
- */
-
- INFO("Kernel is 32Bit\n");
- next_image_info->spsr =
- SPSR_MODE32(mode, SPSR_T_ARM, SPSR_E_LITTLE,
- (DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT));
- next_image_info->pc = get_kernel_info_pc();
- next_image_info->args.arg0 = get_kernel_info_r0();
- next_image_info->args.arg1 = get_kernel_info_r1();
- next_image_info->args.arg2 = get_kernel_info_r2();
-
- INFO("pc=0x%lx, r0=0x%lx, r1=0x%lx, r2=0x%lx\n",
- next_image_info->pc,
- next_image_info->args.arg0,
- next_image_info->args.arg1,
- next_image_info->args.arg2);
-
-
- SET_SECURITY_STATE(next_image_info->h.attr, NON_SECURE);
-
- /* None of the images on this platform can have 0x0 as the entrypoint */
- if (next_image_info->pc)
- return next_image_info;
- else
- return NULL;
-}
-
-/*******************************************************************************
- * This function prepare boot argument for kernel entrypoint
- ******************************************************************************/
-void bl31_prepare_kernel_entry(uint64_t k32_64)
-{
- entry_point_info_t *next_image_info;
- uint32_t image_type;
-
- /* Determine which image to execute next */
- /* image_type = bl31_get_next_image_type(); */
- image_type = NON_SECURE;
-
- /* Program EL3 registers to enable entry into the next EL */
- if (k32_64 == 0)
- next_image_info = bl31_plat_get_next_kernel32_ep_info();
- else
- next_image_info = bl31_plat_get_next_kernel64_ep_info();
-
- assert(next_image_info);
- assert(image_type == GET_SECURITY_STATE(next_image_info->h.attr));
-
- INFO("BL3-1: Preparing for EL3 exit to %s world, Kernel\n",
- (image_type == SECURE) ? "secure" : "normal");
- INFO("BL3-1: Next image address = 0x%llx\n",
- (unsigned long long) next_image_info->pc);
- INFO("BL3-1: Next image spsr = 0x%x\n", next_image_info->spsr);
- cm_init_my_context(next_image_info);
- cm_prepare_el3_exit(image_type);
-}
diff --git a/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.c b/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.c
deleted file mode 100644
index 3696f8e..0000000
--- a/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stdint.h>
-
-#include <arch_helpers.h>
-#include <common/debug.h>
-#include <lib/mmio.h>
-#include <plat/common/platform.h>
-
-#include <mt_cpuxgpt.h>
-
-#define CPUXGPT_BASE 0x10200000
-#define INDEX_BASE (CPUXGPT_BASE+0x0674)
-#define CTL_BASE (CPUXGPT_BASE+0x0670)
-
-uint64_t normal_time_base;
-uint64_t atf_time_base;
-
-void sched_clock_init(uint64_t normal_base, uint64_t atf_base)
-{
- normal_time_base = normal_base;
- atf_time_base = atf_base;
-}
-
-uint64_t sched_clock(void)
-{
- uint64_t cval;
-
- cval = (((read_cntpct_el0() - atf_time_base)*1000)/
- SYS_COUNTER_FREQ_IN_MHZ) + normal_time_base;
- return cval;
-}
-
-/*
- * Return: 0 - Trying to disable the CPUXGPT control bit,
- * and not allowed to disable it.
- * Return: 1 - reg_addr is not realted to disable the control bit.
- */
-unsigned char check_cpuxgpt_write_permission(unsigned int reg_addr,
- unsigned int reg_value)
-{
- unsigned int idx;
- unsigned int ctl_val;
-
- if (reg_addr == CTL_BASE) {
- idx = mmio_read_32(INDEX_BASE);
-
- /* idx 0: CPUXGPT system control */
- if (idx == 0) {
- ctl_val = mmio_read_32(CTL_BASE);
- if (ctl_val & 1) {
- /*
- * if enable bit already set,
- * then bit 0 is not allow to set as 0
- */
- if (!(reg_value & 1))
- return 0;
- }
- }
- }
- return 1;
-}
-
diff --git a/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.h b/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.h
deleted file mode 100644
index 84df081..0000000
--- a/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef MT_CPUXGPT_H
-#define MT_CPUXGPT_H
-
-/* REG */
-#define INDEX_CTL_REG 0x000
-#define INDEX_STA_REG 0x004
-#define INDEX_CNT_L_INIT 0x008
-#define INDEX_CNT_H_INIT 0x00C
-
-/* CTL_REG SET */
-#define EN_CPUXGPT 0x01
-#define EN_AHLT_DEBUG 0x02
-#define CLK_DIV1 (0x1 << 8)
-#define CLK_DIV2 (0x2 << 8)
-#define CLK_DIV4 (0x4 << 8)
-#define CLK_DIV_MASK (~(0x7<<8))
-
-void generic_timer_backup(void);
-void sched_clock_init(uint64_t normal_base, uint64_t atf_base);
-uint64_t sched_clock(void);
-
-#endif /* MT_CPUXGPT_H */
diff --git a/plat/mediatek/mt6795/include/mcucfg.h b/plat/mediatek/mt6795/include/mcucfg.h
deleted file mode 100644
index 21c5394..0000000
--- a/plat/mediatek/mt6795/include/mcucfg.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef MCUCFG_H
-#define MCUCFG_H
-
-#include <stdint.h>
-
-#include <platform_def.h>
-
-struct mt6795_mcucfg_regs {
- uint32_t mp0_ca7l_cache_config;
- struct {
- uint32_t mem_delsel0;
- uint32_t mem_delsel1;
- } mp0_cpu[4];
- uint32_t mp0_cache_mem_delsel0;
- uint32_t mp0_cache_mem_delsel1;
- uint32_t mp0_axi_config;
- uint32_t mp0_misc_config[2];
- struct {
- uint32_t rv_addr_lw;
- uint32_t rv_addr_hw;
- } mp0_rv_addr[4];
- uint32_t mp0_ca7l_cfg_dis;
- uint32_t mp0_ca7l_clken_ctrl;
- uint32_t mp0_ca7l_rst_ctrl;
- uint32_t mp0_ca7l_misc_config;
- uint32_t mp0_ca7l_dbg_pwr_ctrl;
- uint32_t mp0_rw_rsvd0;
- uint32_t mp0_rw_rsvd1;
- uint32_t mp0_ro_rsvd;
- uint32_t reserved0_0[100];
- uint32_t mp1_cpucfg;
- uint32_t mp1_miscdbg;
- uint32_t reserved0_1[13];
- uint32_t mp1_rst_ctl;
- uint32_t mp1_clkenm_div;
- uint32_t reserved0_2[7];
- uint32_t mp1_config_res;
- uint32_t reserved0_3[13];
- struct {
- uint32_t rv_addr_lw;
- uint32_t rv_addr_hw;
- } mp1_rv_addr[2];
- uint32_t reserved0_4[84];
- uint32_t mp0_rst_status; /* 0x400 */
- uint32_t mp0_dbg_ctrl;
- uint32_t mp0_dbg_flag;
- uint32_t mp0_ca7l_ir_mon;
- struct {
- uint32_t pc_lw;
- uint32_t pc_hw;
- uint32_t fp_arch32;
- uint32_t sp_arch32;
- uint32_t fp_arch64_lw;
- uint32_t fp_arch64_hw;
- uint32_t sp_arch64_lw;
- uint32_t sp_arch64_hw;
- } mp0_dbg_core[4];
- uint32_t dfd_ctrl;
- uint32_t dfd_cnt_l;
- uint32_t dfd_cnt_h;
- uint32_t misccfg_mp0_rw_rsvd;
- uint32_t misccfg_sec_vio_status0;
- uint32_t misccfg_sec_vio_status1;
- uint32_t reserved1[22];
- uint32_t misccfg_rw_rsvd; /* 0x500 */
- uint32_t mcusys_dbg_mon_sel_a;
- uint32_t mcusys_dbg_mon;
- uint32_t reserved2[61];
- uint32_t mcusys_config_a; /* 0x600 */
- uint32_t mcusys_config1_a;
- uint32_t mcusys_gic_peribase_a;
- uint32_t reserved3;
- uint32_t sec_range0_start; /* 0x610 */
- uint32_t sec_range0_end;
- uint32_t sec_range_enable;
- uint32_t reserved4;
- uint32_t int_pol_ctl[8]; /* 0x620 */
- uint32_t aclken_div; /* 0x640 */
- uint32_t pclken_div;
- uint32_t l2c_sram_ctrl;
- uint32_t armpll_jit_ctrl;
- uint32_t cci_addrmap; /* 0x650 */
- uint32_t cci_config;
- uint32_t cci_periphbase;
- uint32_t cci_nevntcntovfl;
- uint32_t cci_clk_ctrl; /* 0x660 */
- uint32_t cci_acel_s1_ctrl;
- uint32_t bus_fabric_dcm_ctrl;
- uint32_t reserved5;
- uint32_t xgpt_ctl; /* 0x670 */
- uint32_t xgpt_idx;
- uint32_t ptpod2_ctl0;
- uint32_t ptpod2_ctl1;
- uint32_t mcusys_revid;
- uint32_t mcusys_rw_rsvd0;
- uint32_t mcusys_rw_rsvd1;
-};
-
-static struct mt6795_mcucfg_regs *const mt6795_mcucfg = (void *)MCUCFG_BASE;
-
-/* cpu boot mode */
-#define MP0_CPUCFG_64BIT_SHIFT 12
-#define MP1_CPUCFG_64BIT_SHIFT 28
-#define MP0_CPUCFG_64BIT (U(0xf) << MP0_CPUCFG_64BIT_SHIFT)
-#define MP1_CPUCFG_64BIT (U(0xf) << MP1_CPUCFG_64BIT_SHIFT)
-
-/* scu related */
-enum {
- MP0_ACINACTM_SHIFT = 4,
- MP1_ACINACTM_SHIFT = 0,
- MP0_ACINACTM = 1 << MP0_ACINACTM_SHIFT,
- MP1_ACINACTM = 1 << MP1_ACINACTM_SHIFT
-};
-
-enum {
- MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK_SHIFT = 0,
- MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK_SHIFT = 4,
- MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK_SHIFT = 8,
- MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK_SHIFT = 12,
- MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK_SHIFT = 16,
-
- MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK =
- 0xf << MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK_SHIFT,
- MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK =
- 0xf << MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK_SHIFT,
- MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK =
- 0xf << MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK_SHIFT,
- MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK =
- 0xf << MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK_SHIFT,
- MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK =
- 0xf << MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK_SHIFT
-};
-
-enum {
- MP1_AINACTS_SHIFT = 4,
- MP1_AINACTS = 1 << MP1_AINACTS_SHIFT
-};
-
-enum {
- MP1_SW_CG_GEN_SHIFT = 12,
- MP1_SW_CG_GEN = 1 << MP1_SW_CG_GEN_SHIFT
-};
-
-enum {
- MP1_L2RSTDISABLE_SHIFT = 14,
- MP1_L2RSTDISABLE = 1 << MP1_L2RSTDISABLE_SHIFT
-};
-
-#endif /* MCUCFG_H */
diff --git a/plat/mediatek/mt6795/include/plat_macros.S b/plat/mediatek/mt6795/include/plat_macros.S
deleted file mode 100644
index d198fdc..0000000
--- a/plat/mediatek/mt6795/include/plat_macros.S
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <drivers/arm/cci.h>
-#include <platform_def.h>
-
-.section .rodata.gic_reg_name, "aS"
-gicc_regs:
- .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
-gicd_pend_reg:
- .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n" \
- " Offset:\t\t\tvalue\n"
-newline:
- .asciz "\n"
-spacer:
- .asciz ":\t\t0x"
-
- /* ---------------------------------------------
- * The below macro prints out relevant GIC
- * registers whenever an unhandled exception is
- * taken in BL3-1.
- * Clobbers: x0 - x10, x16, x17, sp
- * ---------------------------------------------
- */
- .macro plat_crash_print_regs
- mov_imm x16, BASE_GICD_BASE
- mov_imm x17, BASE_GICC_BASE
- /* Load the gicc reg list to x6 */
- adr x6, gicc_regs
- /* Load the gicc regs to gp regs used by str_in_crash_buf_print */
- ldr w8, [x17, #GICC_HPPIR]
- ldr w9, [x17, #GICC_AHPPIR]
- ldr w10, [x17, #GICC_CTLR]
- /* Store to the crash buf and print to console */
- bl str_in_crash_buf_print
-
- /* Print the GICD_ISPENDR regs */
- add x7, x16, #GICD_ISPENDR
- adr x4, gicd_pend_reg
- bl asm_print_str
-gicd_ispendr_loop:
- sub x4, x7, x16
- cmp x4, #0x280
- b.eq exit_print_gic_regs
- bl asm_print_hex
-
- adr x4, spacer
- bl asm_print_str
-
- ldr x4, [x7], #8
- bl asm_print_hex
-
- adr x4, newline
- bl asm_print_str
- b gicd_ispendr_loop
-exit_print_gic_regs:
- .endm
-
-.section .rodata.cci_reg_name, "aS"
-cci_iface_regs:
- .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , ""
-
- /* ------------------------------------------------
- * The below macro prints out relevant interconnect
- * registers whenever an unhandled exception is
- * taken in BL3-1.
- * Clobbers: x0 - x9, sp
- * ------------------------------------------------
- */
- .macro plat_print_interconnect_regs
- adr x6, cci_iface_regs
- /* Store in x7 the base address of the first interface */
- mov_imm x7, (PLAT_MT_CCI_BASE + SLAVE_IFACE_OFFSET( \
- PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX))
- ldr w8, [x7, #SNOOP_CTRL_REG]
- /* Store in x7 the base address of the second interface */
- mov_imm x7, (PLAT_MT_CCI_BASE + SLAVE_IFACE_OFFSET( \
- PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX))
- ldr w9, [x7, #SNOOP_CTRL_REG]
- /* Store to the crash buf and print to console */
- bl str_in_crash_buf_print
- .endm
diff --git a/plat/mediatek/mt6795/include/plat_private.h b/plat/mediatek/mt6795/include/plat_private.h
deleted file mode 100644
index f7450ca..0000000
--- a/plat/mediatek/mt6795/include/plat_private.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLAT_PRIVATE_H
-#define PLAT_PRIVATE_H
-
-#include <stdint.h>
-
-#include <lib/xlat_tables/xlat_tables.h>
-
-void plat_configure_mmu_el3(unsigned long total_base,
- unsigned long total_size,
- unsigned long,
- unsigned long,
- unsigned long,
- unsigned long);
-
-void plat_cci_init(void);
-void plat_cci_enable(void);
-void plat_cci_disable(void);
-
-/* Declarations for plat_mt_gic.c */
-void plat_mt_gic_init(void);
-
-/* Declarations for plat_topology.c */
-int mt_setup_topology(void);
-void plat_delay_timer_init(void);
-
-void plat_mt_gic_driver_init(void);
-void plat_mt_gic_init(void);
-void plat_mt_gic_cpuif_enable(void);
-void plat_mt_gic_cpuif_disable(void);
-void plat_mt_gic_pcpu_init(void);
-
-#endif /* PLAT_PRIVATE_H */
diff --git a/plat/mediatek/mt6795/include/plat_sip_calls.h b/plat/mediatek/mt6795/include/plat_sip_calls.h
deleted file mode 100644
index b9a1363..0000000
--- a/plat/mediatek/mt6795/include/plat_sip_calls.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLAT_SIP_CALLS_H
-#define PLAT_SIP_CALLS_H
-
-/*******************************************************************************
- * Plat SiP function constants
- ******************************************************************************/
-#define MTK_PLAT_SIP_NUM_CALLS 0
-
-#endif /* PLAT_SIP_CALLS_H */
diff --git a/plat/mediatek/mt6795/include/platform_def.h b/plat/mediatek/mt6795/include/platform_def.h
deleted file mode 100644
index b353a3d..0000000
--- a/plat/mediatek/mt6795/include/platform_def.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLATFORM_DEF_H
-#define PLATFORM_DEF_H
-
-#include <lib/utils_def.h>
-
-#define PLAT_PRIMARY_CPU 0x0
-
-/* Special value used to verify platform parameters from BL2 to BL3-1 */
-#define MT_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL
-
-#define IO_PHYS (0x10000000)
-#define INFRACFG_AO_BASE (IO_PHYS + 0x1000)
-#define MCUCFG_BASE (IO_PHYS + 0x200000)
-#define PERI_BASE (IO_PHYS + 0x1000000)
-
-
-#define GPIO_BASE (IO_PHYS + 0x370000)
-#define SPM_BASE (IO_PHYS + 0x6000)
-#define RGU_BASE (MCUCFG_BASE + 0x11000)
-#define PMIC_WRAP_BASE (IO_PHYS + 0x10000)
-
-#define TRNG_base (MCUCFG_BASE + 0x230000)
-#define MT_GIC_BASE (0x10220000)
-#define MCU_SYS_SIZE (0x700000)
-#define PLAT_MT_CCI_BASE (IO_PHYS + 0x390000)
-
-/* Aggregate of all devices in the first GB */
-#define MTK_DEV_RNG0_BASE IO_PHYS
-#define MTK_DEV_RNG0_SIZE 0x400000
-#define MTK_DEV_RNG1_BASE (PERI_BASE)
-#define MTK_DEV_RNG1_SIZE 0x4000000
-
-/*******************************************************************************
- * UART related constants
- ******************************************************************************/
-#define UART0_BASE (PERI_BASE + 0x2000)
-
-#define UART_BAUDRATE (921600)
-#define UART_CLOCK (26000000)
-
-/*******************************************************************************
- * System counter frequency related constants
- ******************************************************************************/
-#define SYS_COUNTER_FREQ_IN_TICKS 13000000
-#define SYS_COUNTER_FREQ_IN_MHZ (SYS_COUNTER_FREQ_IN_TICKS/1000000)
-
-/*******************************************************************************
- * GIC-400 & interrupt handling related constants
- ******************************************************************************/
-
-/* Base MTK_platform compatible GIC memory map */
-#define BASE_GICD_BASE (MT_GIC_BASE+0x1000)
-#define BASE_GICC_BASE (MT_GIC_BASE + 0x2000)
-#define BASE_GICR_BASE (MT_GIC_BASE + 0x200000)
-#define BASE_GICH_BASE (MT_GIC_BASE + 0x4000)
-#define BASE_GICV_BASE (MT_GIC_BASE + 0x6000)
-
-#define INT_POL_CTL0 0x10200620
-#define GIC_PRIVATE_SIGNALS (32)
-
-/*******************************************************************************
- * CCI-400 related constants
- ******************************************************************************/
-#define PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX 4
-#define PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX 3
-
-/*******************************************************************************
- * WDT Registers
- ******************************************************************************/
-#define MTK_WDT_BASE (RGU_BASE)
-#define MTK_WDT_SIZE (0x1000)
-#define MTK_WDT_MODE (MTK_WDT_BASE+0x0000)
-#define MTK_WDT_LENGTH (MTK_WDT_BASE+0x0004)
-#define MTK_WDT_RESTART (MTK_WDT_BASE+0x0008)
-#define MTK_WDT_STATUS (MTK_WDT_BASE+0x000C)
-#define MTK_WDT_INTERVAL (MTK_WDT_BASE+0x0010)
-#define MTK_WDT_SWRST (MTK_WDT_BASE+0x0014)
-#define MTK_WDT_SWSYSRST (MTK_WDT_BASE+0x0018)
-#define MTK_WDT_NONRST_REG (MTK_WDT_BASE+0x0020)
-#define MTK_WDT_NONRST_REG2 (MTK_WDT_BASE+0x0024)
-#define MTK_WDT_REQ_MODE (MTK_WDT_BASE+0x0030)
-#define MTK_WDT_REQ_IRQ_EN (MTK_WDT_BASE+0x0034)
-#define MTK_WDT_DEBUG_CTL (MTK_WDT_BASE+0x0040)
-
-/*WDT_STATUS*/
-#define MTK_WDT_STATUS_HWWDT_RST (0x80000000)
-#define MTK_WDT_STATUS_SWWDT_RST (0x40000000)
-#define MTK_WDT_STATUS_IRQWDT_RST (0x20000000)
-#define MTK_WDT_STATUS_DEBUGWDT_RST (0x00080000)
-#define MTK_WDT_STATUS_SPMWDT_RST (0x0002)
-#define MTK_WDT_STATUS_SPM_THERMAL_RST (0x0001)
-#define MTK_WDT_STATUS_THERMAL_DIRECT_RST (1<<18)
-#define MTK_WDT_STATUS_SECURITY_RST (1<<28)
-
-#define MTK_WDT_MODE_DUAL_MODE 0x0040
-#define MTK_WDT_MODE_IRQ 0x0008
-#define MTK_WDT_MODE_KEY 0x22000000
-#define MTK_WDT_MODE_EXTEN 0x0004
-#define MTK_WDT_SWRST_KEY 0x1209
-#define MTK_WDT_RESTART_KEY (0x1971)
-
-/* FIQ platform related define */
-#define MT_IRQ_SEC_SGI_0 8
-#define MT_IRQ_SEC_SGI_1 9
-#define MT_IRQ_SEC_SGI_2 10
-#define MT_IRQ_SEC_SGI_3 11
-#define MT_IRQ_SEC_SGI_4 12
-#define MT_IRQ_SEC_SGI_5 13
-#define MT_IRQ_SEC_SGI_6 14
-#define MT_IRQ_SEC_SGI_7 15
-
-#define FIQ_SMP_CALL_SGI MT_IRQ_SEC_SGI_5
-
-/*******************************************************************************
- * Platform binary types for linking
- ******************************************************************************/
-#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
-#define PLATFORM_LINKER_ARCH aarch64
-
-/*******************************************************************************
- * Generic platform constants
- ******************************************************************************/
-
-/* Size of cacheable stacks */
-#if defined(IMAGE_BL1)
-#define PLATFORM_STACK_SIZE 0x440
-#elif defined(IMAGE_BL2)
-#define PLATFORM_STACK_SIZE 0x400
-#elif defined(IMAGE_BL31)
-#define PLATFORM_STACK_SIZE 0x800
-#elif defined(IMAGE_BL32)
-#define PLATFORM_STACK_SIZE 0x440
-#endif
-
-#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n"
-#define PLAT_MAX_PWR_LVL U(2) /* MPIDR_AFFLVL2 */
-
-#define PLAT_MAX_RET_STATE U(1)
-#define PLAT_MAX_OFF_STATE U(2)
-
-#define PLATFORM_CACHE_LINE_SIZE 64
-#define PLATFORM_SYSTEM_COUNT U(1)
-#define PLATFORM_CLUSTER_COUNT U(2)
-#define PLATFORM_CLUSTER0_CORE_COUNT U(4)
-#define PLATFORM_CLUSTER1_CORE_COUNT U(4)
-#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \
- PLATFORM_CLUSTER0_CORE_COUNT)
-#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4)
-#define PLATFORM_NUM_AFFS (PLATFORM_SYSTEM_COUNT + \
- PLATFORM_CLUSTER_COUNT + \
- PLATFORM_CORE_COUNT)
-
-/*******************************************************************************
- * Platform memory map related constants
- ******************************************************************************/
-/* ATF Argument */
-#define ATF_ARG_SIZE (0x800)
-
-/* TF txet, ro, rw, internal SRAM, Size: release: 80KB, debug: 92KB */
-#define TZRAM_BASE (0x110000)
-#if DEBUG
-#define TZRAM_SIZE (0x1C400)
-#else
-#define TZRAM_SIZE (0x1C400)
-#endif
-#define TZRAM2_BASE 0x00100000
-#define TZRAM2_SIZE 0xDC00
-#define TZRAM2_LIMIT (TZRAM2_BASE + TZRAM2_SIZE)
-
-#define RAM_CONSOLE_BASE 0x0012D000
-#define RAM_CONSOLE_SIZE 0x00001000
-/*******************************************************************************
- * BL31 specific defines.
- ******************************************************************************/
-/*
- * Put BL3-1 at the top of the Trusted SRAM (just below the shared memory, if
- * present). BL31_BASE is calculated using the current BL3-1 debug size plus a
- * little space for growth.
- */
-#define BL31_BASE (TZRAM_BASE + 0x1000)
-#define BL31_LIMIT (TZRAM_BASE + TZRAM_SIZE)
-#define BSS1_STACK_LIMIT (TZRAM_BASE + TZRAM_SIZE)
-#define BL31_TZRAM_SIZE (TZRAM_SIZE - ATF_ARG_SIZE)
-
-/*******************************************************************************
- * Platform specific page table and MMU setup constants
- ******************************************************************************/
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
-#define MAX_XLAT_TABLES 7
-#define MAX_MMAP_REGIONS 16
-
-
-/*******************************************************************************
- * CCI-400 related constants
- ******************************************************************************/
-#define CCI400_BASE 0x10390000
-#define CCI400_SL_IFACE_CLUSTER0 4
-#define CCI400_SL_IFACE_CLUSTER1 3
-#define CCI400_SL_IFACE_INDEX(mpidr) (mpidr & MPIDR_CLUSTER_MASK ? \
- CCI400_SL_IFACE_CLUSTER1 : \
- CCI400_SL_IFACE_CLUSTER0)
-#define CCI_SEC_ACCESS_OFFSET (0x8)
-
-
-/*******************************************************************************
- * Declarations and constants to access the mailboxes safely. Each mailbox is
- * aligned 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. Such alignment ensures that two maiboxes do not sit on the same cache
- * line at any cache level. They could belong to different cpus/clusters &
- * get written while being protected by different locks causing corruption of
- * a valid mailbox address.
- ******************************************************************************/
-#define CACHE_WRITEBACK_SHIFT 6
-#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
-
-#define BL32_BASE (0x0)
-
-/*
- * Load address of BL3-3 for this platform port
- */
-#define LK_SIZE_LIMIT (0x100000)
-#define PLAT_MTK_NS_IMAGE_OFFSET (0x41E00000)
-/* 16KB */
-#define ATF_AEE_BUFFER_SIZE (0x4000)
-#define PAGE_SIZE_2MB_MASK (PAGE_SIZE_2MB - 1)
-#define IS_PAGE_2MB_ALIGNED(addr) (((addr) & PAGE_SIZE_2MB_MASK) == 0)
-#define PAGE_SIZE_2MB (1 << PAGE_SIZE_2MB_SHIFT)
-#define PAGE_SIZE_2MB_SHIFT TWO_MB_SHIFT
-
-#endif /* PLATFORM_DEF_H */
diff --git a/plat/mediatek/mt6795/include/power_tracer.h b/plat/mediatek/mt6795/include/power_tracer.h
deleted file mode 100644
index 8c98dbd..0000000
--- a/plat/mediatek/mt6795/include/power_tracer.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef POWER_TRACER_H
-#define POWER_TRACER_H
-
-#define CPU_UP 0
-#define CPU_DOWN 1
-#define CPU_SUSPEND 2
-#define CLUSTER_UP 3
-#define CLUSTER_DOWN 4
-#define CLUSTER_SUSPEND 5
-
-void trace_power_flow(unsigned long mpidr, unsigned char mode);
-
-#endif /* POWER_TRACER_H */
diff --git a/plat/mediatek/mt6795/include/scu.h b/plat/mediatek/mt6795/include/scu.h
deleted file mode 100644
index 625418a..0000000
--- a/plat/mediatek/mt6795/include/scu.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SCU_H
-#define SCU_H
-
-void disable_scu(unsigned long mpidr);
-void enable_scu(unsigned long mpidr);
-
-#endif /* SCU_H */
diff --git a/plat/mediatek/mt6795/include/spm.h b/plat/mediatek/mt6795/include/spm.h
deleted file mode 100644
index 5227e1d..0000000
--- a/plat/mediatek/mt6795/include/spm.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPM_H
-#define SPM_H
-
-#define SPM_POWERON_CONFIG_SET (SPM_BASE + 0x000)
-#define SPM_POWER_ON_VAL0 (SPM_BASE + 0x010)
-#define SPM_POWER_ON_VAL1 (SPM_BASE + 0x014)
-#define SPM_CLK_SETTLE (SPM_BASE + 0x100)
-#define SPM_CA7_CPU1_PWR_CON (SPM_BASE + 0x218)
-#define SPM_CA7_CPU2_PWR_CON (SPM_BASE + 0x21c)
-#define SPM_CA7_CPU3_PWR_CON (SPM_BASE + 0x220)
-#define SPM_CA7_CPU1_L1_PDN (SPM_BASE + 0x264)
-#define SPM_CA7_CPU2_L1_PDN (SPM_BASE + 0x26c)
-#define SPM_CA7_CPU3_L1_PDN (SPM_BASE + 0x274)
-#define SPM_MD32_SRAM_CON (SPM_BASE + 0x2c8)
-#define SPM_PCM_CON0 (SPM_BASE + 0x310)
-#define SPM_PCM_CON1 (SPM_BASE + 0x314)
-#define SPM_PCM_IM_PTR (SPM_BASE + 0x318)
-#define SPM_PCM_IM_LEN (SPM_BASE + 0x31c)
-#define SPM_PCM_REG_DATA_INI (SPM_BASE + 0x320)
-#define SPM_PCM_EVENT_VECTOR0 (SPM_BASE + 0x340)
-#define SPM_PCM_EVENT_VECTOR1 (SPM_BASE + 0x344)
-#define SPM_PCM_EVENT_VECTOR2 (SPM_BASE + 0x348)
-#define SPM_PCM_EVENT_VECTOR3 (SPM_BASE + 0x34c)
-#define SPM_PCM_MAS_PAUSE_MASK (SPM_BASE + 0x354)
-#define SPM_PCM_PWR_IO_EN (SPM_BASE + 0x358)
-#define SPM_PCM_TIMER_VAL (SPM_BASE + 0x35c)
-#define SPM_PCM_TIMER_OUT (SPM_BASE + 0x360)
-#define SPM_PCM_REG0_DATA (SPM_BASE + 0x380)
-#define SPM_PCM_REG1_DATA (SPM_BASE + 0x384)
-#define SPM_PCM_REG2_DATA (SPM_BASE + 0x388)
-#define SPM_PCM_REG3_DATA (SPM_BASE + 0x38c)
-#define SPM_PCM_REG4_DATA (SPM_BASE + 0x390)
-#define SPM_PCM_REG5_DATA (SPM_BASE + 0x394)
-#define SPM_PCM_REG6_DATA (SPM_BASE + 0x398)
-#define SPM_PCM_REG7_DATA (SPM_BASE + 0x39c)
-#define SPM_PCM_REG8_DATA (SPM_BASE + 0x3a0)
-#define SPM_PCM_REG9_DATA (SPM_BASE + 0x3a4)
-#define SPM_PCM_REG10_DATA (SPM_BASE + 0x3a8)
-#define SPM_PCM_REG11_DATA (SPM_BASE + 0x3ac)
-#define SPM_PCM_REG12_DATA (SPM_BASE + 0x3b0)
-#define SPM_PCM_REG13_DATA (SPM_BASE + 0x3b4)
-#define SPM_PCM_REG14_DATA (SPM_BASE + 0x3b8)
-#define SPM_PCM_REG15_DATA (SPM_BASE + 0x3bc)
-#define SPM_PCM_EVENT_REG_STA (SPM_BASE + 0x3c0)
-#define SPM_PCM_FSM_STA (SPM_BASE + 0x3c4)
-#define SPM_PCM_IM_HOST_RW_PTR (SPM_BASE + 0x3c8)
-#define SPM_PCM_IM_HOST_RW_DAT (SPM_BASE + 0x3cc)
-#define SPM_PCM_EVENT_VECTOR4 (SPM_BASE + 0x3d0)
-#define SPM_PCM_EVENT_VECTOR5 (SPM_BASE + 0x3d4)
-#define SPM_PCM_EVENT_VECTOR6 (SPM_BASE + 0x3d8)
-#define SPM_PCM_EVENT_VECTOR7 (SPM_BASE + 0x3dc)
-#define SPM_PCM_SW_INT_SET (SPM_BASE + 0x3e0)
-#define SPM_PCM_SW_INT_CLEAR (SPM_BASE + 0x3e4)
-#define SPM_CLK_CON (SPM_BASE + 0x400)
-#define SPM_SLEEP_PTPOD2_CON (SPM_BASE + 0x408)
-#define SPM_APMCU_PWRCTL (SPM_BASE + 0x600)
-#define SPM_AP_DVFS_CON_SET (SPM_BASE + 0x604)
-#define SPM_AP_STANBY_CON (SPM_BASE + 0x608)
-#define SPM_PWR_STATUS (SPM_BASE + 0x60c)
-#define SPM_PWR_STATUS_2ND (SPM_BASE + 0x610)
-#define SPM_AP_BSI_REQ (SPM_BASE + 0x614)
-#define SPM_SLEEP_TIMER_STA (SPM_BASE + 0x720)
-#define SPM_SLEEP_WAKEUP_EVENT_MASK (SPM_BASE + 0x810)
-#define SPM_SLEEP_CPU_WAKEUP_EVENT (SPM_BASE + 0x814)
-#define SPM_SLEEP_MD32_WAKEUP_EVENT_MASK (SPM_BASE + 0x818)
-#define SPM_PCM_WDT_TIMER_VAL (SPM_BASE + 0x824)
-#define SPM_PCM_WDT_TIMER_OUT (SPM_BASE + 0x828)
-#define SPM_PCM_MD32_MAILBOX (SPM_BASE + 0x830)
-#define SPM_PCM_MD32_IRQ (SPM_BASE + 0x834)
-#define SPM_SLEEP_ISR_MASK (SPM_BASE + 0x900)
-#define SPM_SLEEP_ISR_STATUS (SPM_BASE + 0x904)
-#define SPM_SLEEP_ISR_RAW_STA (SPM_BASE + 0x910)
-#define SPM_SLEEP_MD32_ISR_RAW_STA (SPM_BASE + 0x914)
-#define SPM_SLEEP_WAKEUP_MISC (SPM_BASE + 0x918)
-#define SPM_SLEEP_BUS_PROTECT_RDY (SPM_BASE + 0x91c)
-#define SPM_SLEEP_SUBSYS_IDLE_STA (SPM_BASE + 0x920)
-#define SPM_PCM_RESERVE (SPM_BASE + 0xb00)
-#define SPM_PCM_RESERVE2 (SPM_BASE + 0xb04)
-#define SPM_PCM_FLAGS (SPM_BASE + 0xb08)
-#define SPM_PCM_SRC_REQ (SPM_BASE + 0xb0c)
-#define SPM_PCM_DEBUG_CON (SPM_BASE + 0xb20)
-#define SPM_CA7_CPU0_IRQ_MASK (SPM_BASE + 0xb30)
-#define SPM_CA7_CPU1_IRQ_MASK (SPM_BASE + 0xb34)
-#define SPM_CA7_CPU2_IRQ_MASK (SPM_BASE + 0xb38)
-#define SPM_CA7_CPU3_IRQ_MASK (SPM_BASE + 0xb3c)
-#define SPM_CA15_CPU0_IRQ_MASK (SPM_BASE + 0xb40)
-#define SPM_CA15_CPU1_IRQ_MASK (SPM_BASE + 0xb44)
-#define SPM_CA15_CPU2_IRQ_MASK (SPM_BASE + 0xb48)
-#define SPM_CA15_CPU3_IRQ_MASK (SPM_BASE + 0xb4c)
-#define SPM_PCM_PASR_DPD_0 (SPM_BASE + 0xb60)
-#define SPM_PCM_PASR_DPD_1 (SPM_BASE + 0xb64)
-#define SPM_PCM_PASR_DPD_2 (SPM_BASE + 0xb68)
-#define SPM_PCM_PASR_DPD_3 (SPM_BASE + 0xb6c)
-#define SPM_SLEEP_CA7_WFI0_EN (SPM_BASE + 0xf00)
-#define SPM_SLEEP_CA7_WFI1_EN (SPM_BASE + 0xf04)
-#define SPM_SLEEP_CA7_WFI2_EN (SPM_BASE + 0xf08)
-#define SPM_SLEEP_CA7_WFI3_EN (SPM_BASE + 0xf0c)
-#define SPM_SLEEP_CA15_WFI0_EN (SPM_BASE + 0xf10)
-#define SPM_SLEEP_CA15_WFI1_EN (SPM_BASE + 0xf14)
-#define SPM_SLEEP_CA15_WFI2_EN (SPM_BASE + 0xf18)
-#define SPM_SLEEP_CA15_WFI3_EN (SPM_BASE + 0xf1c)
-
-#define SPM_PROJECT_CODE 0xb16
-
-#define SPM_REGWR_EN (1U << 0)
-#define SPM_REGWR_CFG_KEY (SPM_PROJECT_CODE << 16)
-
-#define SPM_CPU_PDN_DIS (1U << 0)
-#define SPM_INFRA_PDN_DIS (1U << 1)
-#define SPM_DDRPHY_PDN_DIS (1U << 2)
-#define SPM_DUALVCORE_PDN_DIS (1U << 3)
-#define SPM_PASR_DIS (1U << 4)
-#define SPM_DPD_DIS (1U << 5)
-#define SPM_SODI_DIS (1U << 6)
-#define SPM_MEMPLL_RESET (1U << 7)
-#define SPM_MAINPLL_PDN_DIS (1U << 8)
-#define SPM_CPU_DVS_DIS (1U << 9)
-#define SPM_CPU_DORMANT (1U << 10)
-#define SPM_EXT_VSEL_GPIO103 (1U << 11)
-#define SPM_DDR_HIGH_SPEED (1U << 12)
-#define SPM_OPT (1U << 13)
-
-#define POWER_ON_VAL1_DEF 0x01011820
-#define PCM_FSM_STA_DEF 0x48490
-#define PCM_END_FSM_STA_DEF 0x08490
-#define PCM_END_FSM_STA_MASK 0x3fff0
-#define PCM_HANDSHAKE_SEND1 0xbeefbeef
-
-#define PCM_WDT_TIMEOUT (30 * 32768)
-#define PCM_TIMER_MAX (0xffffffff - PCM_WDT_TIMEOUT)
-
-#define CON0_PCM_KICK (1U << 0)
-#define CON0_IM_KICK (1U << 1)
-#define CON0_IM_SLEEP_DVS (1U << 3)
-#define CON0_PCM_SW_RESET (1U << 15)
-#define CON0_CFG_KEY (SPM_PROJECT_CODE << 16)
-
-#define CON1_IM_SLAVE (1U << 0)
-#define CON1_MIF_APBEN (1U << 3)
-#define CON1_PCM_TIMER_EN (1U << 5)
-#define CON1_IM_NONRP_EN (1U << 6)
-#define CON1_PCM_WDT_EN (1U << 8)
-#define CON1_PCM_WDT_WAKE_MODE (1U << 9)
-#define CON1_SPM_SRAM_SLP_B (1U << 10)
-#define CON1_SPM_SRAM_ISO_B (1U << 11)
-#define CON1_EVENT_LOCK_EN (1U << 12)
-#define CON1_CFG_KEY (SPM_PROJECT_CODE << 16)
-
-#define PCM_PWRIO_EN_R0 (1U << 0)
-#define PCM_PWRIO_EN_R7 (1U << 7)
-#define PCM_RF_SYNC_R0 (1U << 16)
-#define PCM_RF_SYNC_R2 (1U << 18)
-#define PCM_RF_SYNC_R6 (1U << 22)
-#define PCM_RF_SYNC_R7 (1U << 23)
-
-#define CC_SYSCLK0_EN_0 (1U << 0)
-#define CC_SYSCLK0_EN_1 (1U << 1)
-#define CC_SYSCLK1_EN_0 (1U << 2)
-#define CC_SYSCLK1_EN_1 (1U << 3)
-#define CC_SYSSETTLE_SEL (1U << 4)
-#define CC_LOCK_INFRA_DCM (1U << 5)
-#define CC_SRCLKENA_MASK_0 (1U << 6)
-#define CC_CXO32K_RM_EN_MD1 (1U << 9)
-#define CC_CXO32K_RM_EN_MD2 (1U << 10)
-#define CC_CLKSQ1_SEL (1U << 12)
-#define CC_DISABLE_DORM_PWR (1U << 14)
-#define CC_MD32_DCM_EN (1U << 18)
-
-#define WFI_OP_AND 1
-#define WFI_OP_OR 0
-
-#define WAKE_MISC_PCM_TIMER (1U << 19)
-#define WAKE_MISC_CPU_WAKE (1U << 20)
-
-/* define WAKE_SRC_XXX */
-#define WAKE_SRC_SPM_MERGE (1 << 0)
-#define WAKE_SRC_KP (1 << 2)
-#define WAKE_SRC_WDT (1 << 3)
-#define WAKE_SRC_GPT (1 << 4)
-#define WAKE_SRC_EINT (1 << 6)
-#define WAKE_SRC_LOW_BAT (1 << 9)
-#define WAKE_SRC_MD32 (1 << 10)
-#define WAKE_SRC_USB_CD (1 << 14)
-#define WAKE_SRC_USB_PDN (1 << 15)
-#define WAKE_SRC_AFE (1 << 20)
-#define WAKE_SRC_THERM (1 << 21)
-#define WAKE_SRC_SYSPWREQ (1 << 24)
-#define WAKE_SRC_SEJ (1 << 27)
-#define WAKE_SRC_ALL_MD32 (1 << 28)
-#define WAKE_SRC_CPU_IRQ (1 << 29)
-
-#endif /* SPM_H */
diff --git a/plat/mediatek/mt6795/plat_delay_timer.c b/plat/mediatek/mt6795/plat_delay_timer.c
deleted file mode 100644
index 965b653..0000000
--- a/plat/mediatek/mt6795/plat_delay_timer.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <arch_helpers.h>
-#include <drivers/delay_timer.h>
-
-static uint32_t plat_get_timer_value(void)
-{
- /*
- * Generic delay timer implementation expects the timer to be a down
- * counter. We apply bitwise NOT operator to the tick values returned
- * by read_cntpct_el0() to simulate the down counter.
- */
- return (uint32_t)(~read_cntpct_el0());
-}
-
-static const timer_ops_t plat_timer_ops = {
- .get_timer_value = plat_get_timer_value,
- .clk_mult = 1,
- .clk_div = SYS_COUNTER_FREQ_IN_MHZ,
-};
-
-void plat_delay_timer_init(void)
-{
- timer_init(&plat_timer_ops);
-}
diff --git a/plat/mediatek/mt6795/plat_mt_gic.c b/plat/mediatek/mt6795/plat_mt_gic.c
deleted file mode 100644
index 20cb26d..0000000
--- a/plat/mediatek/mt6795/plat_mt_gic.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <common/interrupt_props.h>
-#include <drivers/arm/gicv2.h>
-#include <plat/common/platform.h>
-
-static const interrupt_prop_t g0_interrupt_props[] = {
- INTR_PROP_DESC(FIQ_SMP_CALL_SGI, GIC_HIGHEST_SEC_PRIORITY,
- GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
-};
-
-gicv2_driver_data_t arm_gic_data = {
- .gicd_base = BASE_GICD_BASE,
- .gicc_base = BASE_GICC_BASE,
- .interrupt_props = g0_interrupt_props,
- .interrupt_props_num = ARRAY_SIZE(g0_interrupt_props),
-};
-
-void plat_mt_gic_driver_init(void)
-{
- gicv2_driver_init(&arm_gic_data);
-}
-
-void plat_mt_gic_init(void)
-{
- gicv2_distif_init();
- gicv2_pcpu_distif_init();
- gicv2_cpuif_enable();
-}
-
-void plat_mt_gic_cpuif_enable(void)
-{
- gicv2_cpuif_enable();
-}
-
-void plat_mt_gic_cpuif_disable(void)
-{
- gicv2_cpuif_disable();
-}
-
-void plat_mt_gic_pcpu_init(void)
-{
- gicv2_pcpu_distif_init();
-}
diff --git a/plat/mediatek/mt6795/plat_pm.c b/plat/mediatek/mt6795/plat_pm.c
deleted file mode 100644
index 0dfbd18..0000000
--- a/plat/mediatek/mt6795/plat_pm.c
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <errno.h>
-
-#include <platform_def.h>
-
-#include <arch_helpers.h>
-#include <common/debug.h>
-#include <drivers/arm/cci.h>
-#include <drivers/console.h>
-#include <lib/bakery_lock.h>
-#include <lib/mmio.h>
-#include <lib/psci/psci.h>
-
-#include <mcucfg.h>
-#include <plat_private.h>
-#include <power_tracer.h>
-#include <scu.h>
-
-struct core_context {
- unsigned long timer_data[8];
- unsigned int count;
- unsigned int rst;
- unsigned int abt;
- unsigned int brk;
-};
-
-struct cluster_context {
- struct core_context core[PLATFORM_MAX_CPUS_PER_CLUSTER];
-};
-
-/*
- * Top level structure to hold the complete context of a multi cluster system
- */
-struct system_context {
- struct cluster_context cluster[PLATFORM_CLUSTER_COUNT];
-};
-
-/*
- * Top level structure which encapsulates the context of the entire system
- */
-static struct system_context dormant_data[1];
-
-static inline struct cluster_context *system_cluster(
- struct system_context *system,
- uint32_t clusterid)
-{
- return &system->cluster[clusterid];
-}
-
-static inline struct core_context *cluster_core(struct cluster_context *cluster,
- uint32_t cpuid)
-{
- return &cluster->core[cpuid];
-}
-
-static struct cluster_context *get_cluster_data(unsigned long mpidr)
-{
- uint32_t clusterid;
-
- clusterid = (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
-
- return system_cluster(dormant_data, clusterid);
-}
-
-static struct core_context *get_core_data(unsigned long mpidr)
-{
- struct cluster_context *cluster;
- uint32_t cpuid;
-
- cluster = get_cluster_data(mpidr);
- cpuid = mpidr & MPIDR_CPU_MASK;
-
- return cluster_core(cluster, cpuid);
-}
-
-static void mt_save_generic_timer(unsigned long *container)
-{
- uint64_t ctl;
- uint64_t val;
-
- __asm__ volatile("mrs %x0, cntkctl_el1\n\t"
- "mrs %x1, cntp_cval_el0\n\t"
- "stp %x0, %x1, [%2, #0]"
- : "=&r" (ctl), "=&r" (val)
- : "r" (container)
- : "memory");
-
- __asm__ volatile("mrs %x0, cntp_tval_el0\n\t"
- "mrs %x1, cntp_ctl_el0\n\t"
- "stp %x0, %x1, [%2, #16]"
- : "=&r" (val), "=&r" (ctl)
- : "r" (container)
- : "memory");
-
- __asm__ volatile("mrs %x0, cntv_tval_el0\n\t"
- "mrs %x1, cntv_ctl_el0\n\t"
- "stp %x0, %x1, [%2, #32]"
- : "=&r" (val), "=&r" (ctl)
- : "r" (container)
- : "memory");
-}
-
-static void mt_restore_generic_timer(unsigned long *container)
-{
- uint64_t ctl;
- uint64_t val;
-
- __asm__ volatile("ldp %x0, %x1, [%2, #0]\n\t"
- "msr cntkctl_el1, %x0\n\t"
- "msr cntp_cval_el0, %x1"
- : "=&r" (ctl), "=&r" (val)
- : "r" (container)
- : "memory");
-
- __asm__ volatile("ldp %x0, %x1, [%2, #16]\n\t"
- "msr cntp_tval_el0, %x0\n\t"
- "msr cntp_ctl_el0, %x1"
- : "=&r" (val), "=&r" (ctl)
- : "r" (container)
- : "memory");
-
- __asm__ volatile("ldp %x0, %x1, [%2, #32]\n\t"
- "msr cntv_tval_el0, %x0\n\t"
- "msr cntv_ctl_el0, %x1"
- : "=&r" (val), "=&r" (ctl)
- : "r" (container)
- : "memory");
-}
-
-static void stop_generic_timer(void)
-{
- /*
- * Disable the timer and mask the irq to prevent
- * suprious interrupts on this cpu interface. It
- * will bite us when we come back if we don't. It
- * will be replayed on the inbound cluster.
- */
- uint64_t cntpctl = read_cntp_ctl_el0();
-
- write_cntp_ctl_el0(clr_cntp_ctl_enable(cntpctl));
-}
-
-static void mt_cpu_save(unsigned long mpidr)
-{
- struct core_context *core;
-
- core = get_core_data(mpidr);
- mt_save_generic_timer(core->timer_data);
-
- /* disable timer irq, and upper layer should enable it again. */
- stop_generic_timer();
-}
-
-static void mt_cpu_restore(unsigned long mpidr)
-{
- struct core_context *core;
-
- core = get_core_data(mpidr);
- mt_restore_generic_timer(core->timer_data);
-}
-
-static void mt_platform_save_context(unsigned long mpidr)
-{
- /* mcusys_save_context: */
- mt_cpu_save(mpidr);
-}
-
-static void mt_platform_restore_context(unsigned long mpidr)
-{
- /* mcusys_restore_context: */
- mt_cpu_restore(mpidr);
-}
-
-/*******************************************************************************
-* Private function which is used to determine if any platform actions
-* should be performed for the specified affinity instance given its
-* state. Nothing needs to be done if the 'state' is not off or if this is not
-* the highest affinity level which will enter the 'state'.
-*******************************************************************************/
-static int32_t plat_do_plat_actions(unsigned int afflvl, unsigned int state)
-{
- unsigned int max_phys_off_afflvl;
-
- assert(afflvl <= MPIDR_AFFLVL2);
-
- if (state != PSCI_STATE_OFF)
- return -EAGAIN;
-
- /*
- * Find the highest affinity level which will be suspended and postpone
- * all the platform specific actions until that level is hit.
- */
- max_phys_off_afflvl = psci_get_max_phys_off_afflvl();
- assert(max_phys_off_afflvl != PSCI_INVALID_DATA);
- if (afflvl != max_phys_off_afflvl)
- return -EAGAIN;
-
- return 0;
-}
-
-/*******************************************************************************
- * MTK_platform handler called when an affinity instance is about to enter
- * standby.
- ******************************************************************************/
-static void plat_affinst_standby(unsigned int power_state)
-{
- unsigned int target_afflvl;
-
- /* Sanity check the requested state */
- target_afflvl = psci_get_pstate_afflvl(power_state);
-
- /*
- * It's possible to enter standby only on affinity level 0 i.e. a cpu
- * on the MTK_platform. Ignore any other affinity level.
- */
- if (target_afflvl == MPIDR_AFFLVL0) {
- /*
- * Enter standby state. dsb is good practice before using wfi
- * to enter low power states.
- */
- dsb();
- wfi();
- }
-}
-
-/*******************************************************************************
- * MTK_platform handler called when an affinity instance is about to be turned
- * on. The level and mpidr determine the affinity instance.
- ******************************************************************************/
-static int plat_affinst_on(unsigned long mpidr,
- unsigned long sec_entrypoint,
- unsigned int afflvl,
- unsigned int state)
-{
- int rc = PSCI_E_SUCCESS;
- unsigned long cpu_id;
- unsigned long cluster_id;
- uintptr_t rv;
-
- /*
- * It's possible to turn on only affinity level 0 i.e. a cpu
- * on the MTK_platform. Ignore any other affinity level.
- */
- if (afflvl != MPIDR_AFFLVL0)
- return rc;
-
- cpu_id = mpidr & MPIDR_CPU_MASK;
- cluster_id = mpidr & MPIDR_CLUSTER_MASK;
-
- if (cluster_id)
- rv = (uintptr_t)&mt6795_mcucfg->mp1_rv_addr[cpu_id].rv_addr_lw;
- else
- rv = (uintptr_t)&mt6795_mcucfg->mp0_rv_addr[cpu_id].rv_addr_lw;
-
- mmio_write_32(rv, sec_entrypoint);
- INFO("mt_on[%ld:%ld], entry %x\n",
- cluster_id, cpu_id, mmio_read_32(rv));
-
- return rc;
-}
-
-/*******************************************************************************
- * MTK_platform handler called when an affinity instance is about to be turned
- * off. The level and mpidr determine the affinity instance. The 'state' arg.
- * allows the platform to decide whether the cluster is being turned off and
- * take apt actions.
- *
- * CAUTION: This function is called with coherent stacks so that caches can be
- * turned off, flushed and coherency disabled. There is no guarantee that caches
- * will remain turned on across calls to this function as each affinity level is
- * dealt with. So do not write & read global variables across calls. It will be
- * wise to do flush a write to the global to prevent unpredictable results.
- ******************************************************************************/
-static void plat_affinst_off(unsigned int afflvl, unsigned int state)
-{
- unsigned long mpidr = read_mpidr_el1();
-
- /* Determine if any platform actions need to be executed. */
- if (plat_do_plat_actions(afflvl, state) == -EAGAIN)
- return;
-
- /* Prevent interrupts from spuriously waking up this cpu */
- plat_mt_gic_cpuif_disable();
-
- trace_power_flow(mpidr, CPU_DOWN);
-
- if (afflvl != MPIDR_AFFLVL0) {
- /* Disable coherency if this cluster is to be turned off */
- plat_cci_disable();
-
- trace_power_flow(mpidr, CLUSTER_DOWN);
- }
-}
-
-/*******************************************************************************
- * MTK_platform handler called when an affinity instance is about to be
- * suspended. The level and mpidr determine the affinity instance. The 'state'
- * arg. allows the platform to decide whether the cluster is being turned off
- * and take apt actions.
- *
- * CAUTION: This function is called with coherent stacks so that caches can be
- * turned off, flushed and coherency disabled. There is no guarantee that caches
- * will remain turned on across calls to this function as each affinity level is
- * dealt with. So do not write & read global variables across calls. It will be
- * wise to do flush a write to the global to prevent unpredictable results.
- ******************************************************************************/
-static void plat_affinst_suspend(unsigned long sec_entrypoint,
- unsigned int afflvl,
- unsigned int state)
-{
- unsigned long mpidr = read_mpidr_el1();
- unsigned long cluster_id;
- unsigned long cpu_id;
- uintptr_t rv;
-
- /* Determine if any platform actions need to be executed. */
- if (plat_do_plat_actions(afflvl, state) == -EAGAIN)
- return;
-
- cpu_id = mpidr & MPIDR_CPU_MASK;
- cluster_id = mpidr & MPIDR_CLUSTER_MASK;
-
- if (cluster_id)
- rv = (uintptr_t)&mt6795_mcucfg->mp1_rv_addr[cpu_id].rv_addr_lw;
- else
- rv = (uintptr_t)&mt6795_mcucfg->mp0_rv_addr[cpu_id].rv_addr_lw;
-
- mmio_write_32(rv, sec_entrypoint);
-
- if (afflvl >= MPIDR_AFFLVL0)
- mt_platform_save_context(mpidr);
-
- /* Perform the common cluster specific operations */
- if (afflvl >= MPIDR_AFFLVL1) {
- /* Disable coherency if this cluster is to be turned off */
- plat_cci_disable();
- disable_scu(mpidr);
-
- trace_power_flow(mpidr, CLUSTER_SUSPEND);
- }
-
- if (afflvl >= MPIDR_AFFLVL2) {
- /* Prevent interrupts from spuriously waking up this cpu */
- plat_mt_gic_cpuif_disable();
- }
-}
-
-/*******************************************************************************
- * MTK_platform handler called when an affinity instance has just been powered
- * on after being turned off earlier. The level and mpidr determine the affinity
- * instance. The 'state' arg. allows the platform to decide whether the cluster
- * was turned off prior to wakeup and do what's necessary to setup it up
- * correctly.
- ******************************************************************************/
-static void plat_affinst_on_finish(unsigned int afflvl, unsigned int state)
-{
- unsigned long mpidr = read_mpidr_el1();
-
- /* Determine if any platform actions need to be executed. */
- if (plat_do_plat_actions(afflvl, state) == -EAGAIN)
- return;
-
- /* Perform the common cluster specific operations */
- if (afflvl >= MPIDR_AFFLVL1) {
- enable_scu(mpidr);
-
- /* Enable coherency if this cluster was off */
- plat_cci_enable();
- trace_power_flow(mpidr, CLUSTER_UP);
- }
-
- /* Enable the gic cpu interface */
- plat_mt_gic_cpuif_enable();
- plat_mt_gic_pcpu_init();
- trace_power_flow(mpidr, CPU_UP);
-}
-
-/*******************************************************************************
- * MTK_platform handler called when an affinity instance has just been powered
- * on after having been suspended earlier. The level and mpidr determine the
- * affinity instance.
- ******************************************************************************/
-static void plat_affinst_suspend_finish(unsigned int afflvl, unsigned int state)
-{
- unsigned long mpidr = read_mpidr_el1();
-
- /* Determine if any platform actions need to be executed. */
- if (plat_do_plat_actions(afflvl, state) == -EAGAIN)
- return;
-
- if (afflvl >= MPIDR_AFFLVL2) {
- /* Enable the gic cpu interface */
- plat_mt_gic_init();
- plat_mt_gic_cpuif_enable();
- }
-
- /* Perform the common cluster specific operations */
- if (afflvl >= MPIDR_AFFLVL1) {
- enable_scu(mpidr);
-
- /* Enable coherency if this cluster was off */
- plat_cci_enable();
- trace_power_flow(mpidr, CLUSTER_UP);
- }
-
- if (afflvl >= MPIDR_AFFLVL0)
- mt_platform_restore_context(mpidr);
-
- plat_mt_gic_pcpu_init();
-}
-
-static unsigned int plat_get_sys_suspend_power_state(void)
-{
- /* StateID: 0, StateType: 1(power down), PowerLevel: 2(system) */
- return psci_make_powerstate(0, 1, 2);
-}
-
-/*******************************************************************************
- * MTK handlers to shutdown/reboot the system
- ******************************************************************************/
-static void __dead2 plat_system_off(void)
-{
- INFO("MTK System Off\n");
- wfi();
- ERROR("MTK System Off: operation not handled.\n");
- panic();
-}
-
-static void __dead2 plat_system_reset(void)
-{
- /* Write the System Configuration Control Register */
- INFO("MTK System Reset\n");
-
- mmio_clrbits_32(MTK_WDT_BASE,
- (MTK_WDT_MODE_DUAL_MODE | MTK_WDT_MODE_IRQ));
- mmio_setbits_32(MTK_WDT_BASE, (MTK_WDT_MODE_KEY | MTK_WDT_MODE_EXTEN));
- mmio_setbits_32(MTK_WDT_SWRST, MTK_WDT_SWRST_KEY);
-
- wfi();
- ERROR("MTK System Reset: operation not handled.\n");
- panic();
-}
-
-/*******************************************************************************
- * Export the platform handlers to enable psci to invoke them
- ******************************************************************************/
-static const plat_pm_ops_t plat_plat_pm_ops = {
- .affinst_standby = plat_affinst_standby,
- .affinst_on = plat_affinst_on,
- .affinst_off = plat_affinst_off,
- .affinst_suspend = plat_affinst_suspend,
- .affinst_on_finish = plat_affinst_on_finish,
- .affinst_suspend_finish = plat_affinst_suspend_finish,
- .system_off = plat_system_off,
- .system_reset = plat_system_reset,
- .get_sys_suspend_power_state = plat_get_sys_suspend_power_state,
-};
-
-/*******************************************************************************
- * Export the platform specific power ops & initialize the mtk_platform power
- * controller
- ******************************************************************************/
-int platform_setup_pm(const plat_pm_ops_t **plat_ops)
-{
- *plat_ops = &plat_plat_pm_ops;
- return 0;
-}
diff --git a/plat/mediatek/mt6795/plat_topology.c b/plat/mediatek/mt6795/plat_topology.c
deleted file mode 100644
index 7425d26..0000000
--- a/plat/mediatek/mt6795/plat_topology.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <arch.h>
-#include <lib/psci/psci.h>
-
-unsigned int plat_get_aff_count(unsigned int aff_lvl, unsigned long mpidr)
-{
- /* Report 1 (absent) instance at levels higher that the cluster level */
- if (aff_lvl > MPIDR_AFFLVL1)
- return PLATFORM_SYSTEM_COUNT;
-
- if (aff_lvl == MPIDR_AFFLVL1)
- return PLATFORM_CLUSTER_COUNT;
-
- return mpidr & 0x100 ? PLATFORM_CLUSTER1_CORE_COUNT :
- PLATFORM_CLUSTER0_CORE_COUNT;
-}
-
-unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr)
-{
- return aff_lvl <= MPIDR_AFFLVL2 ? PSCI_AFF_PRESENT : PSCI_AFF_ABSENT;
-}
-
-int mt_setup_topology(void)
-{
- /* [TODO] Make topology configurable via SCC */
- return 0;
-}
diff --git a/plat/mediatek/mt6795/platform.mk b/plat/mediatek/mt6795/platform.mk
deleted file mode 100644
index 4ab692d..0000000
--- a/plat/mediatek/mt6795/platform.mk
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-MTK_PLAT := plat/mediatek
-MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
-
-# Add OEM customized codes
-OEMS := true
-MTK_SIP_KERNEL_BOOT_ENABLE := 1
-
-
-ifneq (${OEMS},none)
- OEMS_INCLUDES := -I${MTK_PLAT}/common/custom/
- OEMS_SOURCES := ${MTK_PLAT}/common/custom/oem_svc.c
-endif
-
-PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
- -I${MTK_PLAT}/common/drivers/uart \
- -I${MTK_PLAT_SOC}/ \
- -I${MTK_PLAT_SOC}/drivers/timer/ \
- -I${MTK_PLAT_SOC}/include/ \
- -Iinclude/plat/arm/common/ \
- ${OEMS_INCLUDES}
-
-PLAT_BL_COMMON_SOURCES := lib/xlat_tables/aarch64/xlat_tables.c \
- lib/xlat_tables/xlat_tables_common.c \
- plat/common/plat_gic.c
-
-BL31_SOURCES += drivers/arm/cci/cci.c \
- drivers/delay_timer/generic_delay_timer.c \
- drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v2/gicv2_main.c \
- drivers/arm/gic/v2/gicv2_helpers.c \
- plat/common/plat_gicv2.c \
- drivers/console/aarch64/console.S \
- drivers/delay_timer/delay_timer.c \
- lib/cpus/aarch64/cortex_a53.S \
- ${MTK_PLAT_SOC}/bl31_plat_setup.c \
- ${MTK_PLAT_SOC}/plat_mt_gic.c \
- ${MTK_PLAT}/common/mtk_sip_svc.c \
- ${MTK_PLAT}/common/mtk_plat_common.c \
- ${MTK_PLAT}/common/drivers/uart/8250_console.S \
- ${MTK_PLAT_SOC}/aarch64/plat_helpers.S \
- ${MTK_PLAT_SOC}/drivers/timer/mt_cpuxgpt.c \
- ${MTK_PLAT_SOC}/plat_delay_timer.c \
- ${MTK_PLAT_SOC}/plat_pm.c \
- ${MTK_PLAT_SOC}/plat_topology.c \
- ${MTK_PLAT_SOC}/power_tracer.c \
- ${MTK_PLAT_SOC}/scu.c \
- ${OEMS_SOURCES}
-
-# Enable workarounds for selected Cortex-A53 erratas.
-ERRATA_A53_826319 := 1
-ERRATA_A53_836870 := 1
-
-WORKAROUND_CVE_2017_5715 := 0
-
-# indicate the reset vector address can be programmed
-PROGRAMMABLE_RESET_ADDRESS := 1
-
-$(eval $(call add_define,MTK_SIP_KERNEL_BOOT_ENABLE))
-
-# Do not enable SVE
-ENABLE_SVE_FOR_NS := 0
diff --git a/plat/mediatek/mt6795/power_tracer.c b/plat/mediatek/mt6795/power_tracer.c
deleted file mode 100644
index 64d086d..0000000
--- a/plat/mediatek/mt6795/power_tracer.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <common/debug.h>
-
-#include <power_tracer.h>
-
-#define trace_log(...) INFO("psci: " __VA_ARGS__)
-
-void trace_power_flow(unsigned long mpidr, unsigned char mode)
-{
- switch (mode) {
- case CPU_UP:
- trace_log("core %lld:%lld ON\n",
- (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS,
- (mpidr & MPIDR_CPU_MASK));
- break;
- case CPU_DOWN:
- trace_log("core %lld:%lld OFF\n",
- (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS,
- (mpidr & MPIDR_CPU_MASK));
- break;
- case CPU_SUSPEND:
- trace_log("core %lld:%lld SUSPEND\n",
- (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS,
- (mpidr & MPIDR_CPU_MASK));
- break;
- case CLUSTER_UP:
- trace_log("cluster %lld ON\n",
- (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS);
- break;
- case CLUSTER_DOWN:
- trace_log("cluster %lld OFF\n",
- (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS);
- break;
- case CLUSTER_SUSPEND:
- trace_log("cluster %lld SUSPEND\n",
- (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS);
- break;
- default:
- trace_log("unknown power mode\n");
- break;
- }
-}
diff --git a/plat/mediatek/mt6795/scu.c b/plat/mediatek/mt6795/scu.c
deleted file mode 100644
index 3b74527..0000000
--- a/plat/mediatek/mt6795/scu.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <lib/mmio.h>
-
-#include <mcucfg.h>
-
-void disable_scu(unsigned long mpidr)
-{
- if (mpidr & MPIDR_CLUSTER_MASK)
- mmio_setbits_32((uintptr_t)&mt6795_mcucfg->mp1_miscdbg,
- MP1_ACINACTM);
- else
- mmio_setbits_32((uintptr_t)&mt6795_mcucfg->mp0_axi_config,
- MP0_ACINACTM);
-}
-
-void enable_scu(unsigned long mpidr)
-{
- if (mpidr & MPIDR_CLUSTER_MASK)
- mmio_clrbits_32((uintptr_t)&mt6795_mcucfg->mp1_miscdbg,
- MP1_ACINACTM);
- else
- mmio_clrbits_32((uintptr_t)&mt6795_mcucfg->mp0_axi_config,
- MP0_ACINACTM);
-}
diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c
index 47ec791..0c184f4 100644
--- a/plat/qemu/common/qemu_common.c
+++ b/plat/qemu/common/qemu_common.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,6 +11,7 @@
#include <common/bl_common.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
#include "qemu_private.h"
#define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \
@@ -160,4 +161,9 @@
DEFINE_CONFIGURE_MMU_EL(svc_mon)
#endif
-
+#if MEASURED_BOOT || TRUSTED_BOARD_BOOT
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+ return get_mbedtls_heap_helper(heap_addr, heap_size);
+}
+#endif
diff --git a/plat/qemu/common/qemu_private.h b/plat/qemu/common/qemu_private.h
index 4dc62f5..c313cb6 100644
--- a/plat/qemu/common/qemu_private.h
+++ b/plat/qemu/common/qemu_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -34,4 +34,18 @@
void qemu_pwr_gic_on_finish(void);
void qemu_pwr_gic_off(void);
+int qemu_set_tos_fw_info(uintptr_t config_base, uintptr_t log_addr,
+ size_t log_size);
+
+int qemu_set_nt_fw_info(
+/*
+ * Currently OP-TEE does not support reading DTBs from Secure memory
+ * and this option should be removed when feature is supported.
+ */
+#ifdef SPD_opteed
+ uintptr_t log_addr,
+#endif
+ size_t log_size,
+ uintptr_t *ns_log_addr);
+
#endif /* QEMU_PRIVATE_H */
diff --git a/plat/qemu/common/qemu_trusted_boot.c b/plat/qemu/common/qemu_trusted_boot.c
index 1ef7e43..6a8edca 100644
--- a/plat/qemu/common/qemu_trusted_boot.c
+++ b/plat/qemu/common/qemu_trusted_boot.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -29,8 +29,3 @@
{
return 1;
}
-
-int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
-{
- return get_mbedtls_heap_helper(heap_addr, heap_size);
-}
diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h
index c02eff9..78467c4 100644
--- a/plat/qemu/qemu/include/platform_def.h
+++ b/plat/qemu/qemu/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -270,4 +270,9 @@
*/
#define SYS_COUNTER_FREQ_IN_TICKS ((1000 * 1000 * 1000) / 16)
+/*
+ * Maximum size of Event Log buffer used in Measured Boot Event Log driver
+ */
+#define PLAT_EVENT_LOG_MAX_SIZE UL(0x400)
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index a8f978a..6a877c3 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -57,11 +57,7 @@
ifneq (${TRUSTED_BOARD_BOOT},0)
- include drivers/auth/mbedtls/mbedtls_crypto.mk
- include drivers/auth/mbedtls/mbedtls_x509.mk
-
AUTH_SOURCES := drivers/auth/auth_mod.c \
- drivers/auth/crypto_mod.c \
drivers/auth/img_parser_mod.c \
drivers/auth/tbbr/tbbr_cot_common.c
@@ -78,6 +74,8 @@
$(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S \
drivers/auth/tbbr/tbbr_cot_bl2.c
+ include drivers/auth/mbedtls/mbedtls_x509.mk
+
ROT_KEY = $(BUILD_PLAT)/rot_key.pem
ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin
@@ -98,6 +96,34 @@
openssl dgst -sha256 -binary > $@ 2>/dev/null
endif
+# 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/event_log/event_log.mk
+ $(info Including ${MEASURED_BOOT_MK})
+ include ${MEASURED_BOOT_MK}
+
+ BL2_SOURCES += plat/qemu/qemu/qemu_measured_boot.c \
+ plat/qemu/qemu/qemu_common_measured_boot.c \
+ plat/qemu/qemu/qemu_helpers.c \
+ ${EVENT_LOG_SOURCES}
+
+ BL1_SOURCES += plat/qemu/qemu/qemu_bl1_measured_boot.c
+
+endif
+
+ifneq ($(filter 1,${MEASURED_BOOT} ${TRUSTED_BOARD_BOOT}),)
+ CRYPTO_SOURCES := drivers/auth/crypto_mod.c
+
+ BL1_SOURCES += ${CRYPTO_SOURCES}
+ BL2_SOURCES += ${CRYPTO_SOURCES}
+
+ # We expect to locate the *.mk files under the directories specified below
+ #
+ include drivers/auth/mbedtls/mbedtls_crypto.mk
+endif
+
BL1_SOURCES += drivers/io/io_semihosting.c \
drivers/io/io_storage.c \
drivers/io/io_fip.c \
@@ -131,6 +157,7 @@
${PLAT_QEMU_COMMON_PATH}/qemu_bl2_mem_params_desc.c \
${PLAT_QEMU_COMMON_PATH}/qemu_image_load.c \
common/fdt_fixup.c \
+ common/fdt_wrappers.c \
common/desc_image_load.c
ifeq ($(add-lib-optee),yes)
diff --git a/plat/qemu/qemu/qemu_bl1_measured_boot.c b/plat/qemu/qemu/qemu_bl1_measured_boot.c
new file mode 100644
index 0000000..3d20f97
--- /dev/null
+++ b/plat/qemu/qemu/qemu_bl1_measured_boot.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022, Linaro.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <common/desc_image_load.h>
+
+/*
+ * Add dummy functions for measured boot for BL1.
+ * In most of the SoC's, ROM/BL1 code is pre-built. So we are assumimg that
+ * it doesn't have the capability to do measurements and extend eventlog.
+ * hence these are dummy functions.
+ */
+void bl1_plat_mboot_init(void)
+{
+}
+
+void bl1_plat_mboot_finish(void)
+{
+}
+
+int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
+{
+ return 0;
+}
diff --git a/plat/qemu/qemu/qemu_common_measured_boot.c b/plat/qemu/qemu/qemu_common_measured_boot.c
new file mode 100644
index 0000000..41f7f87
--- /dev/null
+++ b/plat/qemu/qemu/qemu_common_measured_boot.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022, Linaro.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <common/desc_image_load.h>
+#include <drivers/measured_boot/event_log/event_log.h>
+#include <plat/common/platform.h>
+
+extern event_log_metadata_t qemu_event_log_metadata[];
+
+const event_log_metadata_t *plat_event_log_get_metadata(void)
+{
+ return qemu_event_log_metadata;
+}
+
+int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
+{
+ /* Calculate image hash and record data in Event Log */
+ int err = event_log_measure_and_record(image_data->image_base,
+ image_data->image_size,
+ image_id);
+ if (err != 0) {
+ ERROR("%s%s image id %u (%i)\n",
+ "Failed to ", "record", image_id, err);
+ return err;
+ }
+
+ return 0;
+}
diff --git a/plat/qemu/qemu/qemu_helpers.c b/plat/qemu/qemu/qemu_helpers.c
new file mode 100644
index 0000000..01b8249
--- /dev/null
+++ b/plat/qemu/qemu/qemu_helpers.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2022, Linaro.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#if MEASURED_BOOT
+#include <common/desc_image_load.h>
+#endif
+#include <common/fdt_wrappers.h>
+
+#include <libfdt.h>
+
+#ifdef SPD_opteed
+/*
+ * Currently OP-TEE does not support reading DTBs from Secure memory
+ * and this property should be removed when this feature is supported.
+ */
+#define DTB_PROP_HW_SM_LOG_ADDR "tpm_event_log_sm_addr"
+#endif
+
+#define DTB_PROP_HW_LOG_ADDR "tpm_event_log_addr"
+#define DTB_PROP_HW_LOG_SIZE "tpm_event_log_size"
+
+#if MEASURED_BOOT
+
+#ifdef SPD_opteed
+int qemu_set_tee_fw_info(uintptr_t config_base, uintptr_t log_addr,
+ size_t log_size)
+{
+ int offs, err = 0;
+ void *dtb = (void *)config_base;
+ const char *compatible = "arm,tpm_event_log";
+ uint64_t sec_base = cpu_to_fdt64(log_addr);
+ uint32_t sz = cpu_to_fdt32(log_size);
+
+ offs = fdtw_find_or_add_subnode(dtb, 0, "tpm-event-log");
+ if (offs < 0) {
+ ERROR("Failed to add node tpm-event-log %d\n", offs);
+ return offs;
+ }
+
+ if (fdt_appendprop(dtb, offs, "compatible", compatible,
+ strlen(compatible) + 1) < 0) {
+ return -1;
+ }
+
+ err = fdt_setprop(dtb, offs, DTB_PROP_HW_SM_LOG_ADDR, &sec_base, 8);
+ if (err < 0) {
+ ERROR("Failed to add log addr err %d\n", err);
+ return err;
+ }
+
+ err = fdt_setprop(dtb, offs, DTB_PROP_HW_LOG_SIZE, &sz, 4);
+ if (err < 0) {
+ ERROR("Failed to add log addr err %d\n", err);
+ return err;
+ }
+
+ return err;
+}
+#endif
+
+/*
+ * Write the Event Log address and its size in the DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ * 0 = success
+ * < 0 = error
+ */
+static int qemu_set_event_log_info(uintptr_t config_base,
+#ifdef SPD_opteed
+ uintptr_t sm_log_addr,
+#endif
+ uintptr_t log_addr, size_t log_size)
+{
+ /* As libfdt uses void *, we can't avoid this cast */
+ void *dtb = (void *)config_base;
+ const char *compatible_tpm = "tcg,tpm-tis-mmio";
+ uint64_t base = cpu_to_fdt64(log_addr);
+ uint32_t sz = cpu_to_fdt32(log_size);
+ int err, node;
+
+ err = fdt_open_into(dtb, dtb, PLAT_QEMU_DT_MAX_SIZE);
+ if (err < 0) {
+ ERROR("Invalid Device Tree at %p: error %d\n", dtb, err);
+ return err;
+ }
+
+ /*
+ * Verify that the DTB is valid, before attempting to write to it,
+ * and get the DTB root node.
+ */
+
+ /* Check if the pointer to DT is correct */
+ err = fdt_check_header(dtb);
+ if (err < 0) {
+ WARN("Invalid DTB file passed\n");
+ return err;
+ }
+
+ /*
+ * Find the TPM node in device tree. On qemu, we assume it will
+ * be sw-tpm.
+ */
+ node = fdt_node_offset_by_compatible(dtb, -1, compatible_tpm);
+ if (node < 0) {
+ ERROR("The compatible property '%s' not%s", compatible_tpm,
+ " found in the config\n");
+ return node;
+ }
+
+ err = fdt_setprop(dtb, node, DTB_PROP_HW_LOG_ADDR, &base, 8);
+ if (err < 0) {
+ ERROR("Failed to add log addr err %d\n", err);
+ return err;
+ }
+
+ err = fdt_setprop(dtb, node, DTB_PROP_HW_LOG_SIZE, &sz, 4);
+ if (err < 0) {
+ ERROR("Failed to add log addr err %d\n", err);
+ return err;
+ }
+
+#ifdef SPD_opteed
+ err = qemu_set_tee_fw_info(config_base, sm_log_addr, log_size);
+ if (err < 0) {
+ ERROR("Failed to add tpm-event-node at %p: err %d\n", dtb, err);
+ return err;
+ }
+#endif
+
+ err = fdt_pack(dtb);
+ if (err < 0) {
+ ERROR("Failed to pack Device Tree at %p: err %d\n", dtb, err);
+ return err;
+ }
+
+ /*
+ * Ensure that the info written to the DTB is visible
+ * to other images.
+ */
+ flush_dcache_range(config_base, fdt_totalsize(dtb));
+
+ return err;
+}
+
+/*
+ * This function writes the Event Log address and its size
+ * in the TOS_FW_CONFIG DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ * 0 = success
+ * < 0 = error
+ */
+int qemu_set_tos_fw_info(uintptr_t config_base, uintptr_t log_addr,
+ size_t log_size)
+{
+ int err = 0;
+
+ assert(config_base != 0UL);
+ assert(log_addr != 0UL);
+
+ /*
+ * FIXME - add code to add/update Log address and it's
+ * size in TOS FW CONFIG.
+ * For now we don't have support for TOS FW config in OP-TEE.
+ * So leave this function blank
+ */
+
+ return err;
+}
+
+/*
+ * This function writes the Event Log address and its size
+ * in the QEMU DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ * 0 = success
+ * < 0 = error
+ */
+int qemu_set_nt_fw_info(
+#ifdef SPD_opteed
+ uintptr_t log_addr,
+#endif
+ size_t log_size, uintptr_t *ns_log_addr)
+{
+ uintptr_t ns_addr;
+ int err;
+
+ assert(ns_log_addr != NULL);
+
+ ns_addr = PLAT_QEMU_DT_BASE + PLAT_QEMU_DT_MAX_SIZE;
+
+ /* Write the Event Log address and its size in the DTB */
+ err = qemu_set_event_log_info(PLAT_QEMU_DT_BASE,
+#ifdef SPD_opteed
+ log_addr,
+#endif
+ ns_addr, log_size);
+
+ /* Return Event Log address in Non-secure memory */
+ *ns_log_addr = (err < 0) ? 0UL : ns_addr;
+ return err;
+}
+#endif /* MEASURED_BOOT */
diff --git a/plat/qemu/qemu/qemu_measured_boot.c b/plat/qemu/qemu/qemu_measured_boot.c
new file mode 100644
index 0000000..d9e475a
--- /dev/null
+++ b/plat/qemu/qemu/qemu_measured_boot.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022, Linaro.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <drivers/measured_boot/event_log/event_log.h>
+#include <plat/common/common_def.h>
+#include <tools_share/tbbr_oid.h>
+
+#include "../common/qemu_private.h"
+
+/* Event Log data */
+static uint8_t event_log[PLAT_EVENT_LOG_MAX_SIZE];
+static uint64_t event_log_base;
+
+/* FVP table with platform specific image IDs, names and PCRs */
+const event_log_metadata_t qemu_event_log_metadata[] = {
+ { BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 },
+ { BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 },
+ { BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 },
+ { BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 },
+ { BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 },
+ { HW_CONFIG_ID, EVLOG_HW_CONFIG_STRING, PCR_0 },
+ { NT_FW_CONFIG_ID, EVLOG_NT_FW_CONFIG_STRING, PCR_0 },
+ { SCP_BL2_IMAGE_ID, EVLOG_SCP_BL2_STRING, PCR_0 },
+ { SOC_FW_CONFIG_ID, EVLOG_SOC_FW_CONFIG_STRING, PCR_0 },
+ { TOS_FW_CONFIG_ID, EVLOG_TOS_FW_CONFIG_STRING, PCR_0 },
+
+ { EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */
+};
+
+void bl2_plat_mboot_init(void)
+{
+ /*
+ * Here we assume that BL1/ROM code doesn't have the driver
+ * to measure the BL2 code which is a common case for
+ * already existing platforms
+ */
+ event_log_init(event_log, event_log + sizeof(event_log));
+ event_log_write_header();
+
+ /*
+ * TBD - Add code to do self measurement of BL2 code and add an
+ * event for BL2 measurement
+ */
+
+ event_log_base = (uintptr_t)event_log;
+}
+
+void bl2_plat_mboot_finish(void)
+{
+ int rc;
+
+ /* Event Log address in Non-Secure memory */
+ uintptr_t ns_log_addr;
+
+ /* Event Log filled size */
+ size_t event_log_cur_size;
+
+ event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base);
+
+ rc = qemu_set_nt_fw_info(
+#ifdef SPD_opteed
+ (uintptr_t)event_log_base,
+#endif
+ event_log_cur_size, &ns_log_addr);
+ if (rc != 0) {
+ ERROR("%s(): Unable to update %s_FW_CONFIG\n",
+ __func__, "NT");
+ /*
+ * It is a fatal error because on QEMU secure world software
+ * assumes that a valid event log exists and will use it to
+ * record the measurements into the fTPM or sw-tpm.
+ * Note: In QEMU platform, OP-TEE uses nt_fw_config to get the
+ * secure Event Log buffer address.
+ */
+ panic();
+ }
+
+ /* Copy Event Log to Non-secure memory */
+ (void)memcpy((void *)ns_log_addr, (const void *)event_log_base,
+ event_log_cur_size);
+
+ /* Ensure that the Event Log is visible in Non-secure memory */
+ flush_dcache_range(ns_log_addr, event_log_cur_size);
+
+#if defined(SPD_tspd) || defined(SPD_spmd)
+ /* Set Event Log data in TOS_FW_CONFIG */
+ rc = qemu_set_tos_fw_info((uintptr_t)event_log_base,
+ event_log_cur_size);
+ if (rc != 0) {
+ ERROR("%s(): Unable to update %s_FW_CONFIG\n",
+ __func__, "TOS");
+ panic();
+ }
+#endif /* defined(SPD_tspd) || defined(SPD_spmd) */
+
+ dump_event_log((uint8_t *)event_log_base, event_log_cur_size);
+}
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index e129dfd..7cd5eb5 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -409,6 +409,7 @@
gpt_init_done = true;
} else {
bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+ assert(bl_mem_params != NULL);
mmc_block_dev_spec.buffer.offset = bl_mem_params->image_info.image_base;
mmc_block_dev_spec.buffer.length = bl_mem_params->image_info.image_max_size;
@@ -485,22 +486,46 @@
#if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT
/*
- * Eventually, this function will return the
- * boot index to be passed on to the Update
- * Agent after performing certain checks like
- * a watchdog timeout, or Auth failure while
- * trying to load from a certain bank.
- * For now, since we do not have that logic
- * implemented, just pass the active_index
- * read from the metadata.
+ * In each boot in non-trial mode, we set the BKP register to
+ * FWU_MAX_TRIAL_REBOOT, and return the active_index from metadata.
+ *
+ * As long as the update agent didn't update the "accepted" field in metadata
+ * (i.e. we are in trial mode), we select the new active_index.
+ * To avoid infinite boot loop at trial boot we decrement a BKP register.
+ * If this counter is 0:
+ * - an unexpected TAMPER event raised (that resets the BKP registers to 0)
+ * - a power-off occurs before the update agent was able to update the
+ * "accepted' field
+ * - we already boot FWU_MAX_TRIAL_REBOOT times in trial mode.
+ * we select the previous_active_index.
*/
+#define INVALID_BOOT_IDX 0xFFFFFFFF
+
uint32_t plat_fwu_get_boot_idx(void)
{
- const struct fwu_metadata *metadata;
+ /*
+ * Select boot index and update boot counter only once per boot
+ * even if this function is called several times.
+ */
+ static uint32_t boot_idx = INVALID_BOOT_IDX;
+ const struct fwu_metadata *data;
- metadata = fwu_get_metadata();
+ data = fwu_get_metadata();
+
+ if (boot_idx == INVALID_BOOT_IDX) {
+ boot_idx = data->active_index;
+ if (fwu_is_trial_run_state()) {
+ if (stm32_get_and_dec_fwu_trial_boot_cnt() == 0U) {
+ WARN("Trial FWU fails %u times\n",
+ FWU_MAX_TRIAL_REBOOT);
+ boot_idx = data->previous_active_index;
+ }
+ } else {
+ stm32_set_max_fwu_trial_boot_cnt();
+ }
+ }
- return metadata->active_index;
+ return boot_idx;
}
static void *stm32_get_image_spec(const uuid_t *img_type_uuid)
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h
index d8d1c13..0010cd8 100644
--- a/plat/st/common/include/stm32mp_common.h
+++ b/plat/st/common/include/stm32mp_common.h
@@ -129,6 +129,8 @@
#if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
void stm32mp1_fwu_set_boot_idx(void);
+uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void);
+void stm32_set_max_fwu_trial_boot_cnt(void);
#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */
#endif /* STM32MP_COMMON_H */
diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c
index ea71571..c9efeb5 100644
--- a/plat/st/common/stm32mp_dt.c
+++ b/plat/st/common/stm32mp_dt.c
@@ -11,8 +11,6 @@
#include <common/fdt_wrappers.h>
#include <drivers/st/regulator.h>
#include <drivers/st/stm32_gpio.h>
-#include <drivers/st/stm32mp1_ddr.h>
-#include <drivers/st/stm32mp1_ram.h>
#include <libfdt.h>
#include <platform_def.h>
@@ -328,48 +326,32 @@
int dt_find_otp_name(const char *name, uint32_t *otp, uint32_t *otp_len)
{
int node;
- int index, len;
+ int len;
const fdt32_t *cuint;
if ((name == NULL) || (otp == NULL)) {
return -FDT_ERR_BADVALUE;
}
- node = fdt_node_offset_by_compatible(fdt, -1, DT_NVMEM_LAYOUT_COMPAT);
+ node = fdt_node_offset_by_compatible(fdt, -1, DT_BSEC_COMPAT);
if (node < 0) {
return node;
}
- index = fdt_stringlist_search(fdt, node, "nvmem-cell-names", name);
- if (index < 0) {
- return index;
- }
-
- cuint = fdt_getprop(fdt, node, "nvmem-cells", &len);
- if (cuint == NULL) {
- return -FDT_ERR_NOTFOUND;
- }
-
- if ((index * (int)sizeof(uint32_t)) > len) {
- return -FDT_ERR_BADVALUE;
- }
-
- cuint += index;
-
- node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+ node = fdt_subnode_offset(fdt, node, name);
if (node < 0) {
- ERROR("Malformed nvmem_layout node: ignored\n");
+ ERROR("nvmem node %s not found\n", name);
return node;
}
cuint = fdt_getprop(fdt, node, "reg", &len);
if ((cuint == NULL) || (len != (2 * (int)sizeof(uint32_t)))) {
- ERROR("Malformed nvmem_layout node: ignored\n");
+ ERROR("Malformed nvmem node %s: ignored\n", name);
return -FDT_ERR_BADVALUE;
}
if (fdt32_to_cpu(*cuint) % sizeof(uint32_t)) {
- ERROR("Misaligned nvmem_layout element: ignored\n");
+ ERROR("Misaligned nvmem %s element: ignored\n", name);
return -FDT_ERR_BADVALUE;
}
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 88d0f8a..6f5fcc7 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -432,7 +432,8 @@
#if !STM32MP_USE_STM32IMAGE
case FW_CONFIG_ID:
/* Set global DTB info for fixed fw_config information */
- set_config_info(STM32MP_FW_CONFIG_BASE, STM32MP_FW_CONFIG_MAX_SIZE, FW_CONFIG_ID);
+ set_config_info(STM32MP_FW_CONFIG_BASE, ~0UL, STM32MP_FW_CONFIG_MAX_SIZE,
+ FW_CONFIG_ID);
fconf_populate("FW_CONFIG", STM32MP_FW_CONFIG_BASE);
idx = dyn_cfg_dtb_info_get_index(TOS_FW_CONFIG_ID);
@@ -462,12 +463,14 @@
/* In case of OPTEE, initialize address space with tos_fw addr */
pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+ assert(pager_mem_params != NULL);
pager_mem_params->image_info.image_base = config_info->config_addr;
pager_mem_params->image_info.image_max_size =
config_info->config_max_size;
/* Init base and size for pager if exist */
paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
+ assert(paged_mem_params != NULL);
paged_mem_params->image_info.image_base = STM32MP_DDR_BASE +
(dt_get_ddr_size() - STM32MP_DDR_S_SIZE -
STM32MP_DDR_SHMEM_SIZE);
@@ -525,6 +528,7 @@
#if !STM32MP_USE_STM32IMAGE
bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
tos_fw_mem_params = get_bl_mem_params_node(TOS_FW_CONFIG_ID);
+ assert(tos_fw_mem_params != NULL);
bl_mem_params->image_info.image_max_size +=
tos_fw_mem_params->image_info.image_max_size;
#endif /* !STM32MP_USE_STM32IMAGE */
diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c
index 36a3a1c..76af0fc 100644
--- a/plat/st/stm32mp1/plat_image_load.c
+++ b/plat/st/stm32mp1/plat_image_load.c
@@ -1,14 +1,14 @@
/*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <platform_def.h>
-
#include <common/desc_image_load.h>
#include <plat/common/platform.h>
+#include <platform_def.h>
+
/*******************************************************************************
* This function flushes the data structures so that they are visible
* in memory for the next BL image.
@@ -27,6 +27,8 @@
bl_mem_params_node_t *bl33 = get_bl_mem_params_node(BL33_IMAGE_ID);
uint32_t ddr_ns_size = stm32mp_get_ddr_ns_size();
+ assert(bl33 != NULL);
+
/* Max size is non-secure DDR end address minus image_base */
bl33->image_info.image_max_size = STM32MP_DDR_BASE + ddr_ns_size -
bl33->image_info.image_base;
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index a890534..9e67989 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -146,7 +146,7 @@
endif
$(eval DTC_V = $(shell $(DTC) -v | awk '{print $$NF}'))
-$(eval DTC_VERSION = $(shell printf "%d" $(shell echo ${DTC_V} | cut -d- -f1 | sed "s/\./0/g" | grep -o [0-9]*)))
+$(eval DTC_VERSION = $(shell printf "%d" $(shell echo ${DTC_V} | cut -d- -f1 | sed "s/\./0/g" | grep -o "[0-9]*")))
DTC_CPPFLAGS += ${INCLUDES}
DTC_FLAGS += -Wno-unit_address_vs_reg
ifeq ($(shell test $(DTC_VERSION) -ge 10601; echo $$?),0)
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index d869978..7e0745a 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -511,6 +511,9 @@
/* UID OTP */
#define UID_WORD_NB U(3)
+/* FWU configuration (max supported value is 15) */
+#define FWU_MAX_TRIAL_REBOOT U(3)
+
/*******************************************************************************
* STM32MP1 TAMP
******************************************************************************/
@@ -621,7 +624,6 @@
#define DT_DDR_COMPAT "st,stm32mp1-ddr"
#endif
#define DT_IWDG_COMPAT "st,stm32mp1-iwdg"
-#define DT_NVMEM_LAYOUT_COMPAT "st,stm32-nvmem-layout"
#define DT_PWR_COMPAT "st,stm32mp1,pwr-reg"
#if STM32MP13
#define DT_RCC_CLK_COMPAT "st,stm32mp13-rcc"
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index a9b9f4c..1617afd 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -46,7 +46,16 @@
#define TAMP_BOOT_MODE_ITF_MASK U(0x0000FF00)
#define TAMP_BOOT_MODE_ITF_SHIFT 8
-#define TAMP_BOOT_COUNTER_REG_ID U(21)
+/*
+ * Backup register to store fwu update information.
+ * It should be writeable only by secure world, but also readable by non secure
+ * (so it should be in Zone 2).
+ */
+#define TAMP_BOOT_FWU_INFO_REG_ID U(10)
+#define TAMP_BOOT_FWU_INFO_IDX_MSK U(0xF)
+#define TAMP_BOOT_FWU_INFO_IDX_OFF U(0)
+#define TAMP_BOOT_FWU_INFO_CNT_MSK U(0xF0)
+#define TAMP_BOOT_FWU_INFO_CNT_OFF U(4)
#if defined(IMAGE_BL2)
#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
@@ -732,9 +741,42 @@
#if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
void stm32mp1_fwu_set_boot_idx(void)
{
+ clk_enable(RTCAPB);
+ mmio_clrsetbits_32(tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID),
+ TAMP_BOOT_FWU_INFO_IDX_MSK,
+ (plat_fwu_get_boot_idx() << TAMP_BOOT_FWU_INFO_IDX_OFF) &
+ TAMP_BOOT_FWU_INFO_IDX_MSK);
+ clk_disable(RTCAPB);
+}
+
+uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void)
+{
+ uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
+ uint32_t try_cnt;
+
+ clk_enable(RTCAPB);
+ try_cnt = (mmio_read_32(bkpr_fwu_cnt) & TAMP_BOOT_FWU_INFO_CNT_MSK) >>
+ TAMP_BOOT_FWU_INFO_CNT_OFF;
+
+ assert(try_cnt <= FWU_MAX_TRIAL_REBOOT);
+
+ if (try_cnt != 0U) {
+ mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
+ (try_cnt - 1U) << TAMP_BOOT_FWU_INFO_CNT_OFF);
+ }
+ clk_disable(RTCAPB);
+
+ return try_cnt;
+}
+
+void stm32_set_max_fwu_trial_boot_cnt(void)
+{
+ uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
+
clk_enable(RTCAPB);
- mmio_write_32(tamp_bkpr(TAMP_BOOT_COUNTER_REG_ID),
- plat_fwu_get_boot_idx());
+ mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
+ (FWU_MAX_TRIAL_REBOOT << TAMP_BOOT_FWU_INFO_CNT_OFF) &
+ TAMP_BOOT_FWU_INFO_CNT_MSK);
clk_disable(RTCAPB);
}
#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */
diff --git a/plat/ti/k3/board/lite/include/board_def.h b/plat/ti/k3/board/lite/include/board_def.h
index 18b7f42..fd4e5b1 100644
--- a/plat/ti/k3/board/lite/include/board_def.h
+++ b/plat/ti/k3/board/lite/include/board_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -33,7 +33,7 @@
* defined as default for our platform.
*/
#define SEC_SRAM_BASE UL(0x00000000) /* PIE remapped on fly */
-#define SEC_SRAM_SIZE UL(0x0001c000) /* 112k */
+#define SEC_SRAM_SIZE UL(0x00020000) /* 128k */
#define PLAT_MAX_OFF_STATE U(2)
#define PLAT_MAX_RET_STATE U(1)
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
index 2c3313c..2cbfa3d 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
@@ -2,7 +2,7 @@
* Texas Instruments System Control Interface Driver
* Based on Linux and U-Boot implementation
*
- * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -1664,6 +1664,57 @@
}
/**
+ * ti_sci_enter_sleep - Command to initiate system transition into suspend.
+ *
+ * @proc_id: Processor ID.
+ * @mode: Low power mode to enter.
+ * @core_resume_addr: Address that core should be
+ * resumed from after low power transition.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_enter_sleep(uint8_t proc_id,
+ uint8_t mode,
+ uint64_t core_resume_addr)
+{
+ struct ti_sci_msg_req_enter_sleep req;
+ struct ti_sci_msg_hdr *hdr;
+ struct k3_sec_proxy_msg tx_message;
+ int ret;
+
+ /* Ensure we have sane transfer size */
+ if (sizeof(req) > TI_SCI_MAX_MESSAGE_SIZE) {
+ return -ERANGE;
+ }
+
+ hdr = (struct ti_sci_msg_hdr *)&req;
+ hdr->seq = ++message_sequence;
+ hdr->type = TI_SCI_MSG_ENTER_SLEEP;
+ hdr->host = TI_SCI_HOST_ID;
+ /* Setup with NORESPONSE flag to keep response queue clean */
+ hdr->flags = TI_SCI_FLAG_REQ_GENERIC_NORESPONSE;
+
+ req.processor_id = proc_id;
+ req.mode = mode;
+ req.core_resume_lo = core_resume_addr & TISCI_ADDR_LOW_MASK;
+ req.core_resume_hi = (core_resume_addr & TISCI_ADDR_HIGH_MASK) >>
+ TISCI_ADDR_HIGH_SHIFT;
+
+ tx_message.buf = (uint8_t *)&req;
+ tx_message.len = sizeof(req);
+
+ /* Send message */
+ ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, &tx_message);
+ if (ret != 0) {
+ ERROR("Message sending failed (%d)\n", ret);
+ return ret;
+ }
+
+ /* Return without waiting for response */
+ return 0;
+}
+
+/**
* ti_sci_init() - Basic initialization
*
* Return: 0 if all goes well, else appropriate error message
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
index c7b09b3..06944a7 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
@@ -2,7 +2,7 @@
* Texas Instruments System Control Interface API
* Based on Linux and U-Boot implementation
*
- * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -207,6 +207,22 @@
uint32_t status_flags_1_clr_any_wait);
/**
+ * System Low Power Operations
+ *
+ * - ti_sci_enter_sleep - Command to initiate system transition into suspend.
+ * @proc_id: Processor ID.
+ * @mode: Low power mode to enter.
+ * @core_resume_addr: Address that core should be resumed from
+ * after low power transition.
+ *
+ * NOTE: for all these functions, the following are generic in nature:
+ * Returns 0 for successful request, else returns corresponding error message.
+ */
+int ti_sci_enter_sleep(uint8_t proc_id,
+ uint8_t mode,
+ uint64_t core_resume_addr);
+
+/**
* ti_sci_init() - Basic initialization
*
* Return: 0 if all goes good, else appropriate error message.
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
index 310bf45..d220612 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
@@ -5,7 +5,7 @@
* The system works in a message response protocol
* See: http://processors.wiki.ti.com/index.php/TISCI for details
*
- * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -28,6 +28,9 @@
#define TI_SCI_MSG_GET_DEVICE_STATE 0x0201
#define TI_SCI_MSG_SET_DEVICE_RESETS 0x0202
+/* Low Power Mode Requests */
+#define TI_SCI_MSG_ENTER_SLEEP 0x0301
+
/* Clock requests */
#define TI_SCI_MSG_SET_CLOCK_STATE 0x0100
#define TI_SCI_MSG_GET_CLOCK_STATE 0x0101
@@ -706,4 +709,26 @@
uint32_t status_flags_1_clr_any_wait;
} __packed;
+/**
+ * struct ti_sci_msg_req_enter_sleep - Request for TI_SCI_MSG_ENTER_SLEEP.
+ *
+ * @hdr Generic Header
+ * @mode Low power mode to enter.
+ * @proc_id Processor id to be restored.
+ * @core_resume_lo Low 32-bits of physical pointer to address for core
+ * to begin execution upon resume.
+ * @core_resume_hi High 32-bits of physical pointer to address for core
+ * to begin execution upon resume.
+ *
+ * This message is to be sent after TI_SCI_MSG_PREPARE_SLEEP is sent from OS
+ * and is what actually triggers entry into the specified low power mode.
+ */
+struct ti_sci_msg_req_enter_sleep {
+ struct ti_sci_msg_hdr hdr;
+ uint8_t mode;
+ uint8_t processor_id;
+ uint32_t core_resume_lo;
+ uint32_t core_resume_hi;
+} __packed;
+
#endif /* TI_SCI_PROTOCOL_H */
diff --git a/plat/ti/k3/common/k3_gicv3.c b/plat/ti/k3/common/k3_gicv3.c
index 1932eaa..0199822 100644
--- a/plat/ti/k3/common/k3_gicv3.c
+++ b/plat/ti/k3/common/k3_gicv3.c
@@ -19,6 +19,11 @@
/* The GICv3 driver only needs to be initialized in EL3 */
uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+#if K3_PM_SYSTEM_SUSPEND
+static gicv3_redist_ctx_t rdist_ctx[PLATFORM_CORE_COUNT];
+static gicv3_dist_ctx_t dist_ctx;
+#endif
+
static const interrupt_prop_t k3_interrupt_props[] = {
PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S),
PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0)
@@ -88,3 +93,21 @@
{
gicv3_rdistif_init(plat_my_core_pos());
}
+
+#if K3_PM_SYSTEM_SUSPEND
+void k3_gic_save_context(void)
+{
+ for (unsigned int i = 0U; i < PLATFORM_CORE_COUNT; i++) {
+ gicv3_rdistif_save(i, &rdist_ctx[i]);
+ }
+ gicv3_distif_save(&dist_ctx);
+}
+
+void k3_gic_restore_context(void)
+{
+ gicv3_distif_init_restore(&dist_ctx);
+ for (unsigned int i = 0U; i < PLATFORM_CORE_COUNT; i++) {
+ gicv3_rdistif_init_restore(i, &rdist_ctx[i]);
+ }
+}
+#endif
diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c
index 0500740..6febbc6 100644
--- a/plat/ti/k3/common/k3_psci.c
+++ b/plat/ti/k3/common/k3_psci.c
@@ -234,11 +234,50 @@
return PSCI_E_SUCCESS;
}
+#if K3_PM_SYSTEM_SUSPEND
+static void k3_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+ unsigned int core, proc_id;
+
+ core = plat_my_core_pos();
+ proc_id = PLAT_PROC_START_ID + core;
+
+ /* Prevent interrupts from spuriously waking up this cpu */
+ k3_gic_cpuif_disable();
+ k3_gic_save_context();
+
+ k3_pwr_domain_off(target_state);
+
+ ti_sci_enter_sleep(proc_id, 0, k3_sec_entrypoint);
+}
+
+static void k3_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
+{
+ k3_gic_restore_context();
+ k3_gic_cpuif_enable();
+}
+
+static void k3_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+ unsigned int i;
+
+ /* CPU & cluster off, system in retention */
+ for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) {
+ req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+ }
+}
+#endif
+
static const plat_psci_ops_t k3_plat_psci_ops = {
.cpu_standby = k3_cpu_standby,
.pwr_domain_on = k3_pwr_domain_on,
.pwr_domain_off = k3_pwr_domain_off,
.pwr_domain_on_finish = k3_pwr_domain_on_finish,
+#if K3_PM_SYSTEM_SUSPEND
+ .pwr_domain_suspend = k3_pwr_domain_suspend,
+ .pwr_domain_suspend_finish = k3_pwr_domain_suspend_finish,
+ .get_sys_suspend_power_state = k3_get_sys_suspend_power_state,
+#endif
.system_off = k3_system_off,
.system_reset = k3_system_reset,
.validate_power_state = k3_validate_power_state,
diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk
index ab7366b..e299c30 100644
--- a/plat/ti/k3/common/plat_common.mk
+++ b/plat/ti/k3/common/plat_common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -45,6 +45,10 @@
K3_USART_BAUD := 115200
$(eval $(call add_define,K3_USART_BAUD))
+# Enable system suspend modes
+K3_PM_SYSTEM_SUSPEND := 0
+$(eval $(call add_define,K3_PM_SYSTEM_SUSPEND))
+
# Libraries
include lib/xlat_tables_v2/xlat_tables.mk
diff --git a/plat/ti/k3/include/k3_gicv3.h b/plat/ti/k3/include/k3_gicv3.h
index 2329a16..2c68a75 100644
--- a/plat/ti/k3/include/k3_gicv3.h
+++ b/plat/ti/k3/include/k3_gicv3.h
@@ -14,5 +14,7 @@
void k3_gic_cpuif_enable(void);
void k3_gic_cpuif_disable(void);
void k3_gic_pcpu_init(void);
+void k3_gic_save_context(void);
+void k3_gic_restore_context(void);
#endif /* K3_GICV3_H */
diff --git a/plat/xilinx/common/ipi.c b/plat/xilinx/common/ipi.c
index 0b8020b..2f52f38 100644
--- a/plat/xilinx/common/ipi.c
+++ b/plat/xilinx/common/ipi.c
@@ -69,8 +69,9 @@
{
int ret = 1;
- if (remote >= ipi_total || local >= ipi_total)
+ if (remote >= ipi_total || local >= ipi_total) {
ret = 0;
+ }
return ret;
}
@@ -88,12 +89,15 @@
{
int ret = 0;
- if (!is_ipi_mb_within_range(local, remote))
+ if (!is_ipi_mb_within_range(local, remote)) {
ret = -EINVAL;
- else if (IPI_IS_SECURE(local) && !is_secure)
+ } else if (IPI_IS_SECURE(local) && !is_secure) {
ret = -EPERM;
- else if (IPI_IS_SECURE(remote) && !is_secure)
+ } else if (IPI_IS_SECURE(remote) && !is_secure) {
ret = -EPERM;
+ } else {
+ /* To fix the misra 15.7 warning */
+ }
return ret;
}
@@ -141,11 +145,13 @@
uint32_t status;
status = mmio_read_32(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
- if (status & IPI_BIT_MASK(remote))
+ if (status & IPI_BIT_MASK(remote)) {
ret |= IPI_MB_STATUS_SEND_PENDING;
+ }
status = mmio_read_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
- if (status & IPI_BIT_MASK(remote))
+ if (status & IPI_BIT_MASK(remote)) {
ret |= IPI_MB_STATUS_RECV_PENDING;
+ }
return ret;
}
diff --git a/plat/xilinx/common/plat_startup.c b/plat/xilinx/common/plat_startup.c
index f02f41e..b8f88c4 100644
--- a/plat/xilinx/common/plat_startup.c
+++ b/plat/xilinx/common/plat_startup.c
@@ -123,10 +123,11 @@
flags >>= FSBL_FLAGS_ENDIAN_SHIFT;
- if (flags == FSBL_FLAGS_ENDIAN_BE)
+ if (flags == FSBL_FLAGS_ENDIAN_BE) {
return SPSR_E_BIG;
- else
+ } else {
return SPSR_E_LITTLE;
+ }
}
/**
@@ -226,30 +227,33 @@
if (target_secure == FSBL_FLAGS_SECURE) {
image = bl32;
- if (target_estate == FSBL_FLAGS_ESTATE_A32)
+ if (target_estate == FSBL_FLAGS_ESTATE_A32) {
bl32->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
target_endianness,
DISABLE_ALL_EXCEPTIONS);
- else
+ } else {
bl32->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
+ }
} else {
image = bl33;
if (target_estate == FSBL_FLAGS_ESTATE_A32) {
- if (target_el == FSBL_FLAGS_EL2)
+ if (target_el == FSBL_FLAGS_EL2) {
target_el = MODE32_hyp;
- else
+ } else {
target_el = MODE32_sys;
+ }
bl33->spsr = SPSR_MODE32(target_el, SPSR_T_ARM,
target_endianness,
DISABLE_ALL_EXCEPTIONS);
} else {
- if (target_el == FSBL_FLAGS_EL2)
+ if (target_el == FSBL_FLAGS_EL2) {
target_el = MODE_EL2;
- else
+ } else {
target_el = MODE_EL1;
+ }
bl33->spsr = SPSR_64(target_el, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
@@ -262,10 +266,11 @@
target_el);
image->pc = ATFHandoffParams->partition[i].entry_point;
- if (target_endianness == SPSR_E_BIG)
+ if (target_endianness == SPSR_E_BIG) {
EP_SET_EE(image->h.attr, EP_EE_BIG);
- else
+ } else {
EP_SET_EE(image->h.attr, EP_EE_LITTLE);
+ }
}
return FSBL_HANDOFF_SUCCESS;
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 03a7278..1d1ba85 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -154,14 +154,16 @@
value++;
}
#if IPI_CRC_CHECK
- for (j = 0; j < PAYLOAD_ARG_CNT; j++)
+ for (j = 0; j < PAYLOAD_ARG_CNT; j++) {
response_payload[j] = mmio_read_32(buffer_base +
(j * PAYLOAD_ARG_SIZE));
+ }
if (response_payload[PAYLOAD_CRC_POS] !=
- calculate_crc(response_payload, IPI_W0_TO_W6_SIZE))
+ calculate_crc(response_payload, IPI_W0_TO_W6_SIZE)) {
NOTICE("ERROR in CRC response payload value:0x%x\n",
response_payload[PAYLOAD_CRC_POS]);
+ }
#endif
return mmio_read_32(buffer_base);
@@ -186,22 +188,25 @@
IPI_BUFFER_TARGET_LOCAL_OFFSET +
IPI_BUFFER_REQ_OFFSET;
- if (count > IPI_BUFFER_MAX_WORDS)
+ if (count > IPI_BUFFER_MAX_WORDS) {
count = IPI_BUFFER_MAX_WORDS;
+ }
for (i = 0; i <= count; i++) {
*value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
value++;
}
#if IPI_CRC_CHECK
- for (j = 0; j < PAYLOAD_ARG_CNT; j++)
+ for (j = 0; j < PAYLOAD_ARG_CNT; j++) {
response_payload[j] = mmio_read_32(buffer_base +
(j * PAYLOAD_ARG_SIZE));
+ }
if (response_payload[PAYLOAD_CRC_POS] !=
- calculate_crc(response_payload, IPI_W0_TO_W6_SIZE))
+ calculate_crc(response_payload, IPI_W0_TO_W6_SIZE)) {
NOTICE("ERROR in CRC response payload value:0x%x\n",
response_payload[PAYLOAD_CRC_POS]);
+ }
#endif
}
@@ -226,8 +231,9 @@
bakery_lock_get(&pm_secure_lock);
ret = pm_ipi_send_common(proc, payload, IPI_BLOCKING);
- if (ret != PM_RET_SUCCESS)
+ if (ret != PM_RET_SUCCESS) {
goto unlock;
+ }
ret = ERROR_CODE_MASK & (pm_ipi_buff_read(proc, value, count));
@@ -253,14 +259,15 @@
ret = ipi_mb_enquire_status(proc->ipi->local_ipi_id,
proc->ipi->remote_ipi_id);
- if (ret & IPI_MB_STATUS_RECV_PENDING)
+ if (ret & IPI_MB_STATUS_RECV_PENDING) {
return 1;
- else
+ } else {
return 0;
+ }
}
#if IPI_CRC_CHECK
-uint32_t calculate_crc(uint32_t *payload, uint32_t bufsize)
+uint32_t calculate_crc(uint32_t payload[PAYLOAD_ARG_CNT], uint32_t bufsize)
{
uint32_t crcinit = CRC_INIT_VALUE;
uint32_t order = CRC_ORDER;
diff --git a/plat/xilinx/versal/include/versal_def.h b/plat/xilinx/versal/include/versal_def.h
index 9372954..731742d 100644
--- a/plat/xilinx/versal/include/versal_def.h
+++ b/plat/xilinx/versal/include/versal_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,6 +20,8 @@
/* List all supported platforms */
#define VERSAL_PLATFORM_ID_versal_virt 1
+#define VERSAL_PLATFORM_ID_spp_itr6 2
+#define VERSAL_PLATFORM_ID_emu_itr6 3
#define VERSAL_PLATFORM_ID_silicon 4
#define VERSAL_PLATFORM_IS(con) (VERSAL_PLATFORM_ID_ ## con == VERSAL_PLATFORM)
@@ -92,6 +94,16 @@
# define VERSAL_UART_CLOCK 100000000
# define VERSAL_UART_BAUDRATE 115200
# define VERSAL_CPU_CLOCK 100000000
+#elif VERSAL_PLATFORM_IS(spp_itr6)
+# define PLATFORM_NAME "SPP ITR6"
+# define VERSAL_UART_CLOCK 25000000
+# define VERSAL_UART_BAUDRATE 115200
+# define VERSAL_CPU_CLOCK 2720000
+#elif VERSAL_PLATFORM_IS(emu_itr6)
+# define PLATFORM_NAME "EMU ITR6"
+# define VERSAL_UART_CLOCK 212000
+# define VERSAL_UART_BAUDRATE 9600
+# define VERSAL_CPU_CLOCK 212000
#endif
/* Access control register defines */
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c
index 534d910..c7b6047 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.c
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -25,6 +25,8 @@
#define LOADER_MODULE_ID 0x7U
#define MODE 0x80000000U
+#define MODULE_ID_MASK 0x0000ff00
+
/* default shutdown/reboot scope is system(2) */
static unsigned int pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM;
@@ -73,38 +75,29 @@
/* PM API functions */
/**
- * pm_get_api_version() - Get version number of PMC PM firmware
- * @version Returns 32-bit version number of PMC Power Management Firmware
+ * pm_handle_eemi_call() - PM call for processor to send eemi payload
* @flag 0 - Call from secure source
* 1 - Call from non-secure source
+ * @x0 to x5 Arguments received per SMC64 standard
+ * @result Payload received from firmware
*
- * @return Returns status, either success or error+reason
+ * @return PM_RET_SUCCESS on success or error code
*/
-enum pm_ret_status pm_get_api_version(unsigned int *version, uint32_t flag)
+enum pm_ret_status pm_handle_eemi_call(uint32_t flag, uint32_t x0, uint32_t x1,
+ uint32_t x2, uint32_t x3, uint32_t x4,
+ uint32_t x5, uint64_t *result)
{
- uint32_t payload[PAYLOAD_ARG_CNT];
+ uint32_t payload[PAYLOAD_ARG_CNT] = {0};
+ uint32_t module_id;
- /* Send request to the PMC */
- PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, flag, PM_GET_API_VERSION);
- return pm_ipi_send_sync(primary_proc, payload, version, 1);
-}
+ module_id = (x0 & MODULE_ID_MASK) >> 8;
-/**
- * pm_init_finalize() - Call to notify PMC PM firmware that master has power
- * management enabled and that it has finished its
- * initialization
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Status returned by the PMU firmware
- */
-enum pm_ret_status pm_init_finalize(uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
+ //default module id is for LIBPM
+ if (module_id == 0)
+ module_id = LIBPM_MODULE_ID;
- /* Send request to the PMU */
- PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, flag, PM_INIT_FINALIZE);
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+ PM_PACK_PAYLOAD6(payload, module_id, flag, x0, x1, x2, x3, x4, x5);
+ return pm_ipi_send_sync(primary_proc, payload, (uint32_t *)result, PAYLOAD_ARG_CNT);
}
/**
@@ -235,134 +228,6 @@
}
/**
- * pm_request_device() - Request a device
- * @device_id Device ID
- * @capabilities Requested capabilities for the device
- * @qos Required Quality of Service
- * @ack Flag to specify whether acknowledge requested
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_request_device(uint32_t device_id, uint32_t capabilities,
- uint32_t qos, uint32_t ack, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REQUEST_DEVICE,
- device_id, capabilities, qos, ack);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_release_device() - Release a device
- * @device_id Device ID
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_release_device(uint32_t device_id, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_RELEASE_DEVICE,
- device_id);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_set_requirement() - Set requirement for the device
- * @device_id Device ID
- * @capabilities Requested capabilities for the device
- * @latency Requested maximum latency
- * @qos Required Quality of Service
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_set_requirement(uint32_t device_id, uint32_t capabilities,
- uint32_t latency, uint32_t qos,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_SET_REQUIREMENT,
- device_id, capabilities, latency, qos);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_get_device_status() - Get device's status
- * @device_id Device ID
- * @response Buffer to store device status response
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_get_device_status(uint32_t device_id, uint32_t *response,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_GET_DEVICE_STATUS,
- device_id);
-
- return pm_ipi_send_sync(primary_proc, payload, response, 3);
-}
-
-/**
- * pm_reset_assert() - Assert/De-assert reset
- * @reset Reset ID
- * @assert Assert (1) or de-assert (0)
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_reset_assert(uint32_t reset, bool assert, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_RESET_ASSERT, reset,
- assert);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_reset_get_status() - Get current status of a reset line
- * @reset Reset ID
- * @status Returns current status of selected reset ID
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_reset_get_status(uint32_t reset, uint32_t *status,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_RESET_ASSERT,
- reset);
-
- return pm_ipi_send_sync(primary_proc, payload, status, 1);
-}
-
-/**
* pm_get_callbackdata() - Read from IPI response buffer
* @data - array of PAYLOAD_ARG_CNT elements
* @flag - 0 - Call from secure source
@@ -382,294 +247,12 @@
}
/**
- * pm_pinctrl_request() - Request a pin
- * @pin Pin ID
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_request(uint32_t pin, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PINCTRL_REQUEST,
- pin);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pinctrl_release() - Release a pin
- * @pin Pin ID
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_release(uint32_t pin, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PINCTRL_RELEASE,
- pin);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pinctrl_set_function() - Set pin function
- * @pin Pin ID
- * @function Function ID
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_set_function(uint32_t pin, uint32_t function,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag,
- PM_PINCTRL_SET_FUNCTION, pin, function)
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pinctrl_get_function() - Get function set on the pin
- * @pin Pin ID
- * @function Function set on the pin
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_get_function(uint32_t pin, uint32_t *function,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
- PM_PINCTRL_SET_FUNCTION, pin);
-
- return pm_ipi_send_sync(primary_proc, payload, function, 1);
-}
-
-/**
- * pm_pinctrl_set_pin_param() - Set configuration parameter for the pin
- * @pin Pin ID
- * @param Parameter ID
- * @value Parameter value
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_set_pin_param(uint32_t pin, uint32_t param,
- uint32_t value, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag,
- PM_PINCTRL_CONFIG_PARAM_SET, pin, param, value);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pinctrl_get_pin_param() - Get configuration parameter value for the pin
- * @pin Pin ID
- * @param Parameter ID
- * @value Buffer to store parameter value
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_get_pin_param(uint32_t pin, uint32_t param,
- uint32_t *value, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag,
- PM_PINCTRL_CONFIG_PARAM_GET, pin, param);
-
- return pm_ipi_send_sync(primary_proc, payload, value, 1);
-}
-
-/**
- * pm_clock_enable() - Enable the clock
- * @clk_id Clock ID
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_enable(uint32_t clk_id, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_ENABLE,
- clk_id);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_clock_disable() - Disable the clock
- * @clk_id Clock ID
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_disable(uint32_t clk_id, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_DISABLE,
- clk_id);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_clock_get_state() - Get clock status
- * @clk_id Clock ID
- * @state: Buffer to store clock status (1: Enabled, 0:Disabled)
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_get_state(uint32_t clk_id, uint32_t *state,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETSTATE,
- clk_id);
-
- return pm_ipi_send_sync(primary_proc, payload, state, 1);
-}
-
-/**
- * pm_clock_set_divider() - Set divider for the clock
- * @clk_id Clock ID
- * @divider Divider value
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_set_divider(uint32_t clk_id, uint32_t divider,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_SETDIVIDER,
- clk_id, divider);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_clock_get_divider() - Get divider value for the clock
- * @clk_id Clock ID
- * @divider: Buffer to store clock divider value
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_get_divider(uint32_t clk_id, uint32_t *divider,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETDIVIDER,
- clk_id);
-
- return pm_ipi_send_sync(primary_proc, payload, divider, 1);
-}
-
-/**
- * pm_clock_set_parent() - Set parent for the clock
- * @clk_id Clock ID
- * @parent Parent ID
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_set_parent(uint32_t clk_id, uint32_t parent,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_SETPARENT,
- clk_id, parent);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_clock_get_parent() - Get parent value for the clock
- * @clk_id Clock ID
- * @parent: Buffer to store clock parent value
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
+ * pm_pll_set_param() - Set PLL parameter
*
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETPARENT,
- clk_id);
-
- return pm_ipi_send_sync(primary_proc, payload, parent, 1);
-}
-/**
- * pm_clock_get_rate() - Get the rate value for the clock
- * @clk_id Clock ID
- * @rate: Buffer to store clock rate value
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
*
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_get_rate(uint32_t clk_id, uint32_t *clk_rate,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETRATE,
- clk_id);
-
- return pm_ipi_send_sync(primary_proc, payload, clk_rate, 2);
-}
-
-/**
- * pm_pll_set_param() - Set PLL parameter
* @clk_id PLL clock ID
* @param PLL parameter ID
* @value Value to set for PLL parameter
@@ -692,6 +275,11 @@
/**
* pm_pll_get_param() - Get PLL parameter value
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
* @clk_id PLL clock ID
* @param PLL parameter ID
* @value: Buffer to store PLL parameter value
@@ -714,6 +302,11 @@
/**
* pm_pll_set_mode() - Set PLL mode
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
* @clk_id PLL clock ID
* @mode PLL mode
* @flag 0 - Call from secure source
@@ -735,6 +328,11 @@
/**
* pm_pll_get_mode() - Get PLL mode
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
* @clk_id PLL clock ID
* @mode: Buffer to store PLL mode
* @flag 0 - Call from secure source
@@ -808,22 +406,28 @@
}
/**
-* pm_query_data() - PM API for querying firmware data
-* @qid The type of data to query
-* @arg1 Argument 1 to requested query data call
-* @arg2 Argument 2 to requested query data call
-* @arg3 Argument 3 to requested query data call
-* @data Returned output data
-* @flag 0 - Call from secure source
-* 1 - Call from non-secure source
-*
-* This function returns requested data.
-*/
+ * pm_query_data() - PM API for querying firmware data
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
+ * @qid The type of data to query
+ * @arg1 Argument 1 to requested query data call
+ * @arg2 Argument 2 to requested query data call
+ * @arg3 Argument 3 to requested query data call
+ * @data Returned output data
+ * @flag 0 - Call from secure source
+ * 1 - Call from non-secure source
+ *
+ * @retur - 0 if success else non-zero error code of type
+ * enum pm_ret_status
+ */
enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
uint32_t arg3, uint32_t *data, uint32_t flag)
{
uint32_t ret;
- uint32_t version;
+ uint32_t version[PAYLOAD_ARG_CNT] = {0};
uint32_t payload[PAYLOAD_ARG_CNT];
uint32_t fw_api_version;
@@ -831,42 +435,50 @@
PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_QUERY_DATA, qid,
arg1, arg2, arg3);
- ret = pm_feature_check(PM_QUERY_DATA, &version, flag);
- if (PM_RET_SUCCESS == ret) {
- fw_api_version = version & 0xFFFFU;
- if ((2U == fw_api_version) &&
- ((XPM_QID_CLOCK_GET_NAME == qid) ||
- (XPM_QID_PINCTRL_GET_FUNCTION_NAME == qid))) {
- ret = pm_ipi_send_sync(primary_proc, payload, data, 8);
- ret = data[0];
- data[0] = data[1];
- data[1] = data[2];
- data[2] = data[3];
+ ret = pm_feature_check(PM_QUERY_DATA, &version[0], flag);
+ if (ret == PM_RET_SUCCESS) {
+ fw_api_version = version[0] & 0xFFFF;
+ if ((fw_api_version == 2U) &&
+ ((qid == XPM_QID_CLOCK_GET_NAME) ||
+ (qid == XPM_QID_PINCTRL_GET_FUNCTION_NAME))) {
+ ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
+ if (ret == PM_RET_SUCCESS) {
+ ret = data[0];
+ data[0] = data[1];
+ data[1] = data[2];
+ data[2] = data[3];
+ }
} else {
- ret = pm_ipi_send_sync(primary_proc, payload, data, 4);
+ ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
}
}
return ret;
}
/**
* pm_api_ioctl() - PM IOCTL API for device control and configs
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
* @device_id Device ID
* @ioctl_id ID of the requested IOCTL
* @arg1 Argument 1 to requested IOCTL call
* @arg2 Argument 2 to requested IOCTL call
+ * @arg3 Argument 3 to requested IOCTL call
* @value Returned output value
* @flag 0 - Call from secure source
* 1 - Call from non-secure source
*
* This function calls IOCTL to firmware for device control and configuration.
*
- * @return Returns status, either success or error+reason
+ * @return Returns status, either 0 on success or non-zero error code
+ * of type enum pm_ret_status
*/
enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
- uint32_t arg1, uint32_t arg2, uint32_t *value,
- uint32_t flag)
+ uint32_t arg1, uint32_t arg2, uint32_t arg3,
+ uint32_t *value, uint32_t flag)
{
- uint32_t payload[PAYLOAD_ARG_CNT];
enum pm_ret_status ret;
switch (ioctl_id) {
@@ -892,11 +504,7 @@
ret = PM_RET_SUCCESS;
break;
default:
- /* Send request to the PMC */
- PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_IOCTL,
- device_id, ioctl_id, arg1, arg2);
- ret = pm_ipi_send_sync(primary_proc, payload, value, 1);
- break;
+ return PM_RET_ERROR_NOTSUPPORTED;
}
return ret;
@@ -923,116 +531,48 @@
}
/**
- * pm_get_chipid() - Read silicon ID registers
- * @value Buffer for return values. Must be large enough
- * to hold 8 bytes.
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns silicon ID registers
- */
-enum pm_ret_status pm_get_chipid(uint32_t *value, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, flag, PM_GET_CHIPID);
-
- return pm_ipi_send_sync(primary_proc, payload, value, 2);
-}
-
-/**
* pm_feature_check() - Returns the supported API version if supported
* @api_id API ID to check
- * @value Returned supported API version
* @flag 0 - Call from secure source
* 1 - Call from non-secure source
+ * @ret_payload pointer to array of PAYLOAD_ARG_CNT number of
+ * words Returned supported API version and bitmasks
+ * for IOCTL and QUERY ID
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version,
+enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *ret_payload,
uint32_t flag)
{
- uint32_t payload[PAYLOAD_ARG_CNT], fw_api_version;
- enum pm_ret_status status = PM_RET_ERROR_NOFEATURE;
+ uint32_t payload[PAYLOAD_ARG_CNT];
+ uint32_t module_id;
+ /* Return version of API which are implemented in ATF only */
switch (api_id) {
case PM_GET_CALLBACK_DATA:
case PM_GET_TRUSTZONE_VERSION:
+ ret_payload[0] = PM_API_VERSION_2;
+ return PM_RET_SUCCESS;
case PM_LOAD_PDI:
- *version = (PM_API_BASE_VERSION << 16);
- status = PM_RET_SUCCESS;
- break;
- case PM_GET_API_VERSION:
- case PM_GET_DEVICE_STATUS:
- case PM_GET_OP_CHARACTERISTIC:
- case PM_REQ_SUSPEND:
- case PM_SELF_SUSPEND:
- case PM_FORCE_POWERDOWN:
- case PM_ABORT_SUSPEND:
- case PM_REQ_WAKEUP:
- case PM_SET_WAKEUP_SOURCE:
- case PM_SYSTEM_SHUTDOWN:
- case PM_REQUEST_DEVICE:
- case PM_RELEASE_DEVICE:
- case PM_SET_REQUIREMENT:
- case PM_RESET_ASSERT:
- case PM_RESET_GET_STATUS:
- case PM_GET_CHIPID:
- case PM_PINCTRL_REQUEST:
- case PM_PINCTRL_RELEASE:
- case PM_PINCTRL_GET_FUNCTION:
- case PM_PINCTRL_SET_FUNCTION:
- case PM_PINCTRL_CONFIG_PARAM_GET:
- case PM_PINCTRL_CONFIG_PARAM_SET:
- case PM_IOCTL:
- case PM_CLOCK_ENABLE:
- case PM_CLOCK_DISABLE:
- case PM_CLOCK_GETSTATE:
- case PM_CLOCK_SETDIVIDER:
- case PM_CLOCK_GETDIVIDER:
- case PM_CLOCK_SETPARENT:
- case PM_CLOCK_GETPARENT:
- case PM_CLOCK_GETRATE:
- case PM_PLL_SET_PARAMETER:
- case PM_PLL_GET_PARAMETER:
- case PM_PLL_SET_MODE:
- case PM_PLL_GET_MODE:
- case PM_FEATURE_CHECK:
- case PM_INIT_FINALIZE:
- case PM_SET_MAX_LATENCY:
- case PM_REGISTER_NOTIFIER:
- *version = (PM_API_BASE_VERSION << 16);
- status = PM_RET_SUCCESS;
- break;
- case PM_QUERY_DATA:
- *version = (PM_API_QUERY_DATA_VERSION << 16);
- status = PM_RET_SUCCESS;
- break;
+ ret_payload[0] = PM_API_BASE_VERSION;
+ return PM_RET_SUCCESS;
default:
- *version = 0U;
- status = PM_RET_ERROR_NOFEATURE;
break;
}
- if (status != PM_RET_SUCCESS) {
- goto done;
+ module_id = (api_id & MODULE_ID_MASK) >> 8;
+
+ /*
+ * feature check should be done only for LIBPM module
+ * If module_id is 0, then we consider it LIBPM module as default id
+ */
+ if ((module_id > 0) && (module_id != LIBPM_MODULE_ID)) {
+ return PM_RET_SUCCESS;
}
PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
PM_FEATURE_CHECK, api_id);
-
- status = pm_ipi_send_sync(primary_proc, payload, &fw_api_version, 1);
- if (status != PM_RET_SUCCESS) {
- goto done;
- }
-
- *version |= fw_api_version;
-
- status = PM_RET_SUCCESS;
-
-done:
- return status;
+ return pm_ipi_send_sync(primary_proc, payload, ret_payload, PAYLOAD_ARG_CNT);
}
/**
@@ -1060,54 +600,6 @@
}
/**
- * pm_get_op_characteristic() - PM call to request operating characteristics
- * of a device
- * @device_id Device id
- * @type Type of the operating characteristic
- * (power, temperature and latency)
- * @result Returns the operating characteristic for the requested device,
- * specified by the type
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_get_op_characteristic(uint32_t device_id,
- enum pm_opchar_type type,
- uint32_t *result, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag,
- PM_GET_OP_CHARACTERISTIC, device_id, type);
- return pm_ipi_send_sync(primary_proc, payload, result, 1);
-}
-
-/**
- * pm_set_max_latency() - PM call to change in the maximum wake-up latency
- * requirements for a specific device currently
- * used by that CPU.
- * @device_id Device ID
- * @latency Latency value
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_set_max_latency(uint32_t device_id, uint32_t latency,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_SET_MAX_LATENCY,
- device_id, latency);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
* pm_register_notifier() - PM call to register a subsystem to be notified
* about the device event
* @device_id Device ID for the Node to which the event is related
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h
index 5a92704..86a46d0 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.h
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,8 +14,9 @@
* PM API function declarations
**********************************************************/
-enum pm_ret_status pm_get_api_version(unsigned int *version, uint32_t flag);
-enum pm_ret_status pm_init_finalize(uint32_t flag);
+enum pm_ret_status pm_handle_eemi_call(uint32_t flag, uint32_t x0, uint32_t x1,
+ uint32_t x2, uint32_t x3, uint32_t x4,
+ uint32_t x5, uint64_t *result);
enum pm_ret_status pm_self_suspend(uint32_t nid,
unsigned int latency,
unsigned int state,
@@ -29,42 +30,7 @@
uintptr_t address, uint8_t ack, uint32_t flag);
enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t device_id,
uint8_t enable, uint32_t flag);
-enum pm_ret_status pm_request_device(uint32_t device_id, uint32_t capabilities,
- uint32_t qos, uint32_t ack, uint32_t flag);
-enum pm_ret_status pm_release_device(uint32_t device_id, uint32_t flag);
-enum pm_ret_status pm_set_requirement(uint32_t device_id, uint32_t capabilities,
- uint32_t latency, uint32_t qos,
- uint32_t flag);
-enum pm_ret_status pm_get_device_status(uint32_t device_id, uint32_t *response,
- uint32_t flag);
-enum pm_ret_status pm_reset_assert(uint32_t reset, bool assert, uint32_t flag);
-enum pm_ret_status pm_reset_get_status(uint32_t reset, uint32_t *status,
- uint32_t flag);
void pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag);
-enum pm_ret_status pm_pinctrl_request(uint32_t pin, uint32_t flag);
-enum pm_ret_status pm_pinctrl_release(uint32_t pin, uint32_t flag);
-enum pm_ret_status pm_pinctrl_set_function(uint32_t pin, uint32_t function,
- uint32_t flag);
-enum pm_ret_status pm_pinctrl_get_function(uint32_t pin, uint32_t *function,
- uint32_t flag);
-enum pm_ret_status pm_pinctrl_set_pin_param(uint32_t pin, uint32_t param,
- uint32_t value, uint32_t flag);
-enum pm_ret_status pm_pinctrl_get_pin_param(uint32_t pin, uint32_t param,
- uint32_t *value, uint32_t flag);
-enum pm_ret_status pm_clock_enable(uint32_t clk_id, uint32_t flag);
-enum pm_ret_status pm_clock_disable(uint32_t clk_id, uint32_t flag);
-enum pm_ret_status pm_clock_get_state(uint32_t clk_id, uint32_t *state,
- uint32_t flag);
-enum pm_ret_status pm_clock_set_divider(uint32_t clk_id, uint32_t divider,
- uint32_t flag);
-enum pm_ret_status pm_clock_get_divider(uint32_t clk_id, uint32_t *divider,
- uint32_t flag);
-enum pm_ret_status pm_clock_set_parent(uint32_t clk_id, uint32_t parent,
- uint32_t flag);
-enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent,
- uint32_t flag);
-enum pm_ret_status pm_clock_get_rate(uint32_t clk_id, uint32_t *clk_rate,
- uint32_t flag);
enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
uint32_t value, uint32_t flag);
enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
@@ -78,21 +44,15 @@
enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
uint32_t flag);
enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
- uint32_t arg1, uint32_t arg2, uint32_t *value,
- uint32_t flag);
+ uint32_t arg1, uint32_t arg2, uint32_t arg3,
+ uint32_t *value, uint32_t flag);
enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
uint32_t arg3, uint32_t *data, uint32_t flag);
unsigned int pm_get_shutdown_scope(void);
-enum pm_ret_status pm_get_chipid(uint32_t *value, uint32_t flag);
-enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version,
+enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *ret_payload,
uint32_t flag);
enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low,
uint32_t address_high, uint32_t flag);
-enum pm_ret_status pm_get_op_characteristic(uint32_t device_id,
- enum pm_opchar_type type,
- uint32_t *result, uint32_t flag);
-enum pm_ret_status pm_set_max_latency(uint32_t device_id, uint32_t latency,
- uint32_t flag);
enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event,
uint32_t wake, uint32_t enable,
uint32_t flag);
diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index 4c1d340..4012f32 100644
--- a/plat/xilinx/versal/pm_service/pm_client.c
+++ b/plat/xilinx/versal/pm_service/pm_client.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,6 +21,7 @@
#include <plat/common/platform.h>
#include "pm_api_sys.h"
#include "pm_client.h"
+#include "pm_defs.h"
#define UNDEFINED_CPUID (~0)
#define IRQ_MAX 142U
@@ -147,14 +148,16 @@
node_idx = irq_to_pm_node_idx(irq);
reg &= ~lowest_set;
- if ((node_idx != XPM_NODEIDX_DEV_MIN) &&
- (pm_wakeup_nodes_set[node_idx] == 0U)) {
- /* Get device ID from node index */
- device_id = PERIPH_DEVID(node_idx);
- ret = pm_set_wakeup_source(node_id,
- device_id, 1,
- SECURE_FLAG);
- pm_wakeup_nodes_set[node_idx] = (uint8_t)(!ret);
+ if (node_idx > XPM_NODEIDX_DEV_MIN && node_idx < XPM_NODEIDX_DEV_MAX) {
+ if (pm_wakeup_nodes_set[node_idx] == 0U) {
+ /* Get device ID from node index */
+ device_id = PERIPH_DEVID(node_idx);
+ ret = pm_set_wakeup_source(node_id,
+ device_id, 1,
+ SECURE_FLAG);
+ pm_wakeup_nodes_set[node_idx] = (ret == PM_RET_SUCCESS) ?
+ 1 : 0;
+ }
}
}
}
diff --git a/plat/xilinx/versal/pm_service/pm_defs.h b/plat/xilinx/versal/pm_service/pm_defs.h
index 08b46e2..3785650 100644
--- a/plat/xilinx/versal/pm_service/pm_defs.h
+++ b/plat/xilinx/versal/pm_service/pm_defs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -38,13 +38,11 @@
/* PM API Versions */
#define PM_API_BASE_VERSION 1U
+#define PM_API_VERSION_2 2U
#define PM_API_QUERY_DATA_VERSION 2U
/* PM API ids */
-#define PM_GET_API_VERSION 1U
-#define PM_GET_DEVICE_STATUS 3U
-#define PM_GET_OP_CHARACTERISTIC 4U
#define PM_REGISTER_NOTIFIER 5U
#define PM_REQ_SUSPEND 6U
#define PM_SELF_SUSPEND 7U
@@ -53,31 +51,8 @@
#define PM_REQ_WAKEUP 10U
#define PM_SET_WAKEUP_SOURCE 11U
#define PM_SYSTEM_SHUTDOWN 12U
-#define PM_REQUEST_DEVICE 13U
-#define PM_RELEASE_DEVICE 14U
-#define PM_SET_REQUIREMENT 15U
-#define PM_SET_MAX_LATENCY 16U
-#define PM_RESET_ASSERT 17U
-#define PM_RESET_GET_STATUS 18U
-#define PM_INIT_FINALIZE 21U
-#define PM_GET_CHIPID 24U
-#define PM_PINCTRL_REQUEST 28U
-#define PM_PINCTRL_RELEASE 29U
-#define PM_PINCTRL_GET_FUNCTION 30U
-#define PM_PINCTRL_SET_FUNCTION 31U
-#define PM_PINCTRL_CONFIG_PARAM_GET 32U
-#define PM_PINCTRL_CONFIG_PARAM_SET 33U
#define PM_IOCTL 34U
#define PM_QUERY_DATA 35U
-#define PM_CLOCK_ENABLE 36U
-#define PM_CLOCK_DISABLE 37U
-#define PM_CLOCK_GETSTATE 38U
-#define PM_CLOCK_SETDIVIDER 39U
-#define PM_CLOCK_GETDIVIDER 40U
-#define PM_CLOCK_SETRATE 41U
-#define PM_CLOCK_GETRATE 42U
-#define PM_CLOCK_SETPARENT 43U
-#define PM_CLOCK_GETPARENT 44U
#define PM_PLL_SET_PARAMETER 48U
#define PM_PLL_GET_PARAMETER 49U
#define PM_PLL_SET_MODE 50U
diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c
index b082acb..75c1268 100644
--- a/plat/xilinx/versal/pm_service/pm_svc_main.c
+++ b/plat/xilinx/versal/pm_service/pm_svc_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -114,49 +114,84 @@
}
/**
- * pm_smc_handler() - SMC handler for PM-API calls coming from EL1/EL2.
- * @smc_fid - Function Identifier
- * @x1 - x4 - Arguments
- * @cookie - Unused
- * @handler - Pointer to caller's context structure
+ * eemi_for_compatibility() - EEMI calls handler for deprecated calls
*
- * @return - Unused
- *
- * Determines that smc_fid is valid and supported PM SMC Function ID from the
- * list of pm_api_ids, otherwise completes the request with
- * the unknown SMC Function ID
+ * @return - If EEMI API found then, uintptr_t type address, else 0
*
- * The SMC calls for PM service are forwarded from SIP Service SMC handler
- * function with rt_svc_handle signature
+ * Some EEMI API's use case needs to be changed in Linux driver, so they
+ * can take advantage of common EEMI handler in TF-A. As of now the old
+ * implementation of these APIs are required to maintain backward compatibility
+ * until their use case in linux driver changes.
*/
-uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
- uint64_t x4, void *cookie, void *handle, uint64_t flags)
+static uintptr_t eemi_for_compatibility(uint32_t api_id, uint32_t *pm_arg,
+ void *handle, uint32_t security_flag)
{
enum pm_ret_status ret;
- uint32_t pm_arg[4];
- uint32_t security_flag = SECURE_FLAG;
+ switch (api_id) {
- /* Handle case where PM wasn't initialized properly */
- if (pm_up == false) {
- SMC_RET1(handle, SMC_UNK);
+ case PM_IOCTL:
+ {
+ uint32_t value;
+
+ ret = pm_api_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
+ pm_arg[3], pm_arg[4],
+ &value, security_flag);
+ if (ret == PM_RET_ERROR_NOTSUPPORTED)
+ return (uintptr_t)0;
+
+ SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
}
- pm_arg[0] = (uint32_t)x1;
- pm_arg[1] = (uint32_t)(x1 >> 32);
- pm_arg[2] = (uint32_t)x2;
- pm_arg[3] = (uint32_t)(x2 >> 32);
+ case PM_QUERY_DATA:
+ {
+ uint32_t data[PAYLOAD_ARG_CNT] = { 0 };
- /*
- * Mark BIT24 payload (i.e 1st bit of pm_arg[3] ) as non-secure (1)
- * if smc called is non secure
- */
- if (is_caller_non_secure(flags) != 0) {
- security_flag = NON_SECURE_FLAG;
+ ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
+ pm_arg[3], data, security_flag);
+
+ SMC_RET2(handle, (uint64_t)ret | ((uint64_t)data[0] << 32),
+ (uint64_t)data[1] | ((uint64_t)data[2] << 32));
+ }
+
+ case PM_FEATURE_CHECK:
+ {
+ uint32_t result[PAYLOAD_ARG_CNT] = {0U};
+
+ ret = pm_feature_check(pm_arg[0], result, security_flag);
+ SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32),
+ (uint64_t)result[1] | ((uint64_t)result[2] << 32));
+ }
+
+ case PM_LOAD_PDI:
+ {
+ ret = pm_load_pdi(pm_arg[0], pm_arg[1], pm_arg[2],
+ security_flag);
+ SMC_RET1(handle, (uint64_t)ret);
+ }
+
+ default:
+ return (uintptr_t)0;
}
+}
- switch (smc_fid & FUNCID_NUM_MASK) {
- /* PM API Functions */
+/**
+ * eemi_psci_debugfs_handler() - EEMI API invoked from PSCI
+ *
+ * These EEMI APIs performs CPU specific power management tasks.
+ * These EEMI APIs are invoked either from PSCI or from debugfs in kernel.
+ * These calls require CPU specific processing before sending IPI request to
+ * Platform Management Controller. For example enable/disable CPU specific
+ * interrupts. This requires separate handler for these calls and may not be
+ * handled using common eemi handler
+ */
+static uintptr_t eemi_psci_debugfs_handler(uint32_t api_id, uint32_t *pm_arg,
+ void *handle, uint32_t security_flag)
+{
+ enum pm_ret_status ret;
+
+ switch (api_id) {
+
case PM_SELF_SUSPEND:
ret = pm_self_suspend(pm_arg[0], pm_arg[1], pm_arg[2],
pm_arg[3], security_flag);
@@ -179,65 +214,22 @@
ret = pm_system_shutdown(pm_arg[0], pm_arg[1], security_flag);
SMC_RET1(handle, (uint64_t)ret);
- case PM_REQ_WAKEUP:
- ret = pm_req_wakeup(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3],
- security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_SET_WAKEUP_SOURCE:
- ret = pm_set_wakeup_source(pm_arg[0], pm_arg[1], pm_arg[2],
- security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_REQUEST_DEVICE:
- ret = pm_request_device(pm_arg[0], pm_arg[1], pm_arg[2],
- pm_arg[3], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_RELEASE_DEVICE:
- ret = pm_release_device(pm_arg[0], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_SET_REQUIREMENT:
- ret = pm_set_requirement(pm_arg[0], pm_arg[1], pm_arg[2],
- pm_arg[3], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_GET_API_VERSION:
- {
- uint32_t api_version;
-
- ret = pm_get_api_version(&api_version, security_flag);
- SMC_RET1(handle, (u_register_t)PM_RET_SUCCESS |
- ((u_register_t)api_version << 32));
- }
-
- case PM_GET_DEVICE_STATUS:
- {
- uint32_t buff[3];
-
- ret = pm_get_device_status(pm_arg[0], buff, security_flag);
- SMC_RET2(handle, (u_register_t)ret | ((u_register_t)buff[0] << 32),
- (u_register_t)buff[1] | ((u_register_t)buff[2] << 32));
- }
-
- case PM_RESET_ASSERT:
- ret = pm_reset_assert(pm_arg[0], pm_arg[1], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_RESET_GET_STATUS:
- {
- uint32_t reset_status;
-
- ret = pm_reset_get_status(pm_arg[0], &reset_status,
- security_flag);
- SMC_RET1(handle, (u_register_t)ret |
- ((u_register_t)reset_status << 32));
+ default:
+ return (uintptr_t)0;
}
+}
- case PM_INIT_FINALIZE:
- ret = pm_init_finalize(security_flag);
- SMC_RET1(handle, (uint64_t)ret);
+/**
+ * TF_A_specific_handler() - SMC handler for TF-A specific functionality
+ *
+ * These EEMI calls performs functionality that does not require
+ * IPI transaction. The handler ends in TF-A and returns requested data to
+ * kernel from TF-A
+ */
+static uintptr_t TF_A_specific_handler(uint32_t api_id, uint32_t *pm_arg,
+ void *handle, uint32_t security_flag)
+{
+ switch (api_id) {
case PM_GET_CALLBACK_DATA:
{
@@ -245,192 +237,115 @@
pm_get_callbackdata(result, ARRAY_SIZE(result), security_flag);
SMC_RET2(handle,
- (u_register_t)result[0] | ((u_register_t)result[1] << 32),
- (u_register_t)result[2] | ((u_register_t)result[3] << 32));
- }
-
- case PM_PINCTRL_REQUEST:
- ret = pm_pinctrl_request(pm_arg[0], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_PINCTRL_RELEASE:
- ret = pm_pinctrl_release(pm_arg[0], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_PINCTRL_GET_FUNCTION:
- {
- uint32_t value = 0;
-
- ret = pm_pinctrl_get_function(pm_arg[0], &value, security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
+ (uint64_t)result[0] | ((uint64_t)result[1] << 32),
+ (uint64_t)result[2] | ((uint64_t)result[3] << 32));
}
- case PM_PINCTRL_SET_FUNCTION:
- ret = pm_pinctrl_set_function(pm_arg[0], pm_arg[1],
- security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_PINCTRL_CONFIG_PARAM_GET:
- {
- uint32_t value;
-
- ret = pm_pinctrl_get_pin_param(pm_arg[0], pm_arg[1], &value,
- security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
- }
-
- case PM_PINCTRL_CONFIG_PARAM_SET:
- ret = pm_pinctrl_set_pin_param(pm_arg[0], pm_arg[1], pm_arg[2],
- security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_IOCTL:
- {
- uint32_t value;
-
- ret = pm_api_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
- pm_arg[3], &value, security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
- }
-
- case PM_QUERY_DATA:
- {
- uint32_t data[8] = { 0 };
-
- ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
- pm_arg[3], data, security_flag);
-
- SMC_RET2(handle, (u_register_t)ret | ((u_register_t)data[0] << 32),
- (u_register_t)data[1] | ((u_register_t)data[2] << 32));
-
- }
- case PM_CLOCK_ENABLE:
- ret = pm_clock_enable(pm_arg[0], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_CLOCK_DISABLE:
- ret = pm_clock_disable(pm_arg[0], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_CLOCK_GETSTATE:
- {
- uint32_t value;
-
- ret = pm_clock_get_state(pm_arg[0], &value, security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
- }
-
- case PM_CLOCK_SETDIVIDER:
- ret = pm_clock_set_divider(pm_arg[0], pm_arg[1], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_CLOCK_GETDIVIDER:
- {
- uint32_t value;
-
- ret = pm_clock_get_divider(pm_arg[0], &value, security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
- }
-
- case PM_CLOCK_SETPARENT:
- ret = pm_clock_set_parent(pm_arg[0], pm_arg[1], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_CLOCK_GETPARENT:
- {
- uint32_t value;
-
- ret = pm_clock_get_parent(pm_arg[0], &value, security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
- }
-
- case PM_CLOCK_GETRATE:
- {
- uint32_t rate[2] = { 0 };
-
- ret = pm_clock_get_rate(pm_arg[0], rate, security_flag);
- SMC_RET2(handle, (u_register_t)ret | ((u_register_t)rate[0] << 32),
- (u_register_t)rate[1] | ((u_register_t)0U << 32));
- }
-
- case PM_PLL_SET_PARAMETER:
- ret = pm_pll_set_param(pm_arg[0], pm_arg[1], pm_arg[2],
- security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_PLL_GET_PARAMETER:
- {
- uint32_t value;
+ case PM_GET_TRUSTZONE_VERSION:
+ SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
+ ((uint64_t)VERSAL_TZ_VERSION << 32));
- ret = pm_pll_get_param(pm_arg[0], pm_arg[1], &value,
- security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value << 32));
+ default:
+ return (uintptr_t)0;
}
-
- case PM_PLL_SET_MODE:
- ret = pm_pll_set_mode(pm_arg[0], pm_arg[1], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
+}
- case PM_PLL_GET_MODE:
- {
- uint32_t mode;
+/**
+ * eemi_handler() - Prepare EEMI payload and perform IPI transaction
+ *
+ * EEMI - Embedded Energy Management Interface is Xilinx proprietary protocol
+ * to allow communication between power management controller and different
+ * processing clusters.
+ *
+ * This handler prepares EEMI protocol payload received from kernel and performs
+ * IPI transaction.
+ */
+static uintptr_t eemi_handler(uint32_t api_id, uint32_t *pm_arg,
+ void *handle, uint32_t security_flag)
+{
+ enum pm_ret_status ret;
+ uint32_t buf[PAYLOAD_ARG_CNT] = {0};
- ret = pm_pll_get_mode(pm_arg[0], &mode, security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)mode << 32));
+ ret = pm_handle_eemi_call(security_flag, api_id, pm_arg[0], pm_arg[1],
+ pm_arg[2], pm_arg[3], pm_arg[4],
+ (uint64_t *)buf);
+ /*
+ * Two IOCTLs, to get clock name and pinctrl name of pm_query_data API
+ * receives 5 words of respoonse from firmware. Currently linux driver can
+ * receive only 4 words from TF-A. So, this needs to be handled separately
+ * than other eemi calls.
+ */
+ if (api_id == PM_QUERY_DATA) {
+ if ((pm_arg[0] == XPM_QID_CLOCK_GET_NAME ||
+ pm_arg[0] == XPM_QID_PINCTRL_GET_FUNCTION_NAME) &&
+ ret == PM_RET_SUCCESS) {
+ SMC_RET2(handle, (uint64_t)buf[0] | ((uint64_t)buf[1] << 32),
+ (uint64_t)buf[2] | ((uint64_t)buf[3] << 32));
+ }
}
- case PM_GET_TRUSTZONE_VERSION:
- SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
- ((uint64_t)VERSAL_TZ_VERSION << 32));
-
- case PM_GET_CHIPID:
- {
- uint32_t result[2];
+ SMC_RET2(handle, (uint64_t)ret | ((uint64_t)buf[0] << 32),
+ (uint64_t)buf[1] | ((uint64_t)buf[2] << 32));
+}
- ret = pm_get_chipid(result, security_flag);
- SMC_RET2(handle, (u_register_t)ret | ((u_register_t)result[0] << 32),
- (u_register_t)result[1] | ((u_register_t)0U << 32));
- }
+/**
+ * pm_smc_handler() - SMC handler for PM-API calls coming from EL1/EL2.
+ * @smc_fid - Function Identifier
+ * @x1 - x4 - SMC64 Arguments from kernel
+ * x3 (upper 32-bits) and x4 are Unused
+ * @cookie - Unused
+ * @handler - Pointer to caller's context structure
+ *
+ * @return - Unused
+ *
+ * Determines that smc_fid is valid and supported PM SMC Function ID from the
+ * list of pm_api_ids, otherwise completes the request with
+ * the unknown SMC Function ID
+ *
+ * The SMC calls for PM service are forwarded from SIP Service SMC handler
+ * function with rt_svc_handle signature
+ */
+uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
+ uint64_t x4, void *cookie, void *handle, uint64_t flags)
+{
+ uintptr_t ret;
+ uint32_t pm_arg[PAYLOAD_ARG_CNT] = {0};
+ uint32_t security_flag = SECURE_FLAG;
+ uint32_t api_id;
- case PM_FEATURE_CHECK:
- {
- uint32_t version;
+ /* Handle case where PM wasn't initialized properly */
+ if (!pm_up)
+ SMC_RET1(handle, SMC_UNK);
- ret = pm_feature_check(pm_arg[0], &version, security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)version << 32));
+ /*
+ * Mark BIT24 payload (i.e 1st bit of pm_arg[3] ) as non-secure (1)
+ * if smc called is non secure
+ */
+ if (is_caller_non_secure(flags)) {
+ security_flag = NON_SECURE_FLAG;
}
- case PM_LOAD_PDI:
- {
- ret = pm_load_pdi(pm_arg[0], pm_arg[1], pm_arg[2],
- security_flag);
- SMC_RET1(handle, (u_register_t)ret);
- }
+ pm_arg[0] = (uint32_t)x1;
+ pm_arg[1] = (uint32_t)(x1 >> 32);
+ pm_arg[2] = (uint32_t)x2;
+ pm_arg[3] = (uint32_t)(x2 >> 32);
+ pm_arg[4] = (uint32_t)x3;
+ (void)(x4);
+ api_id = smc_fid & FUNCID_NUM_MASK;
- case PM_GET_OP_CHARACTERISTIC:
- {
- uint32_t result;
+ ret = eemi_for_compatibility(api_id, pm_arg, handle, security_flag);
+ if (ret != (uintptr_t)0)
+ return ret;
- ret = pm_get_op_characteristic(pm_arg[0], pm_arg[1], &result,
- security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)result << 32));
- }
+ ret = eemi_psci_debugfs_handler(api_id, pm_arg, handle, flags);
+ if (ret != (uintptr_t)0)
+ return ret;
- case PM_SET_MAX_LATENCY:
- {
- ret = pm_set_max_latency(pm_arg[0], pm_arg[1], security_flag);
- SMC_RET1(handle, (u_register_t)ret);
- }
+ ret = TF_A_specific_handler(api_id, pm_arg, handle, security_flag);
+ if (ret != (uintptr_t)0)
+ return ret;
- case PM_REGISTER_NOTIFIER:
- {
- ret = pm_register_notifier(pm_arg[0], pm_arg[1], pm_arg[2],
- pm_arg[3], security_flag);
- SMC_RET1(handle, (u_register_t)ret);
- }
+ ret = eemi_handler(api_id, pm_arg, handle, security_flag);
- default:
- WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
- SMC_RET1(handle, SMC_UNK);
- }
+ return ret;
}
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index fae73cf..32b0123 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -47,10 +47,11 @@
{
unsigned int ver = zynqmp_get_silicon_ver();
- if (ver == ZYNQMP_CSU_VERSION_QEMU)
+ if (ver == ZYNQMP_CSU_VERSION_QEMU) {
return 133000000;
- else
+ } else {
return 100000000;
+ }
}
#if LOG_LEVEL >= LOG_LEVEL_NOTICE
@@ -232,8 +233,9 @@
chipid[0] = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
chipid[1] = mmio_read_32(EFUSE_BASEADDR + EFUSE_IPDISABLE_OFFSET);
#else
- if (pm_get_chipid(chipid) != PM_RET_SUCCESS)
+ if (pm_get_chipid(chipid) != PM_RET_SUCCESS) {
return "XCZUUNKN";
+ }
#endif
id = chipid[0] & (ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
@@ -243,8 +245,9 @@
for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
if (zynqmp_devices[i].id == id &&
- zynqmp_devices[i].ver == (ver & ZYNQMP_CSU_VERSION_MASK))
+ zynqmp_devices[i].ver == (ver & ZYNQMP_CSU_VERSION_MASK)) {
break;
+ }
}
if (i >= ARRAY_SIZE(zynqmp_devices)) {
@@ -255,11 +258,13 @@
}
}
- if (!zynqmp_devices[i].evexists)
+ if (!zynqmp_devices[i].evexists) {
return zynqmp_devices[i].name;
+ }
- if (ver & ZYNQMP_PL_STATUS_MASK)
+ if ((ver & ZYNQMP_PL_STATUS_MASK) != 0U) {
return zynqmp_devices[i].name;
+ }
len = strlen(zynqmp_devices[i].name) - 2;
for (j = 0; j < strlen(name); j++) {
@@ -329,8 +334,8 @@
break;
}
- NOTICE("TF-A running on %s/%s at 0x%x\n",
- zynqmp_print_silicon_idcode(), label, BL31_BASE);
+ VERBOSE("TF-A running on %s/%s at 0x%x\n",
+ zynqmp_print_silicon_idcode(), label, BL31_BASE);
VERBOSE("TF-A running on v%d/RTL%d.%d\n",
zynqmp_get_ps_ver(), (rtl & 0xf0) >> 4, rtl & 0xf);
}
@@ -345,8 +350,9 @@
ret = pm_mmio_read(CRL_APB_BOOT_MODE_USER, &r);
- if (ret != PM_RET_SUCCESS)
+ if (ret != PM_RET_SUCCESS) {
r = mmio_read_32(CRL_APB_BOOT_MODE_USER);
+ }
return r & CRL_APB_BOOT_MODE_MASK;
}
@@ -373,8 +379,9 @@
{
unsigned int ver = zynqmp_get_silicon_ver();
- if (ver == ZYNQMP_CSU_VERSION_QEMU)
+ if (ver == ZYNQMP_CSU_VERSION_QEMU) {
return 65000000;
- else
+ } else {
return mmio_read_32(IOU_SCNTRS_BASEFREQ);
+ }
}
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 58eee3a..5ad33cc 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -83,6 +83,8 @@
if (rc == 0) {
panic();
}
+ } else {
+ ERROR("BL31: No console device found.\n");
}
/* Initialize the platform config for future decision making */
zynqmp_config_setup();
@@ -119,10 +121,10 @@
panic();
}
}
- if (bl32_image_ep_info.pc) {
+ if (bl32_image_ep_info.pc != 0) {
VERBOSE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
}
- if (bl33_image_ep_info.pc) {
+ if (bl33_image_ep_info.pc != 0) {
VERBOSE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
}
}
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index 1c4daa1..9c1600a 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -37,11 +37,11 @@
*/
#ifndef ZYNQMP_ATF_MEM_BASE
#if !DEBUG && defined(SPD_none) && !SDEI_SUPPORT
-# define BL31_BASE 0xfffea000
-# define BL31_LIMIT 0x100000000
+# define BL31_BASE U(0xfffea000)
+# define BL31_LIMIT U(0x100000000)
#else
-# define BL31_BASE 0x1000
-# define BL31_LIMIT 0x7ffff
+# define BL31_BASE U(0x1000)
+# define BL31_LIMIT U(0x7ffff)
#endif
#else
# define BL31_BASE (ZYNQMP_ATF_MEM_BASE)
@@ -55,8 +55,8 @@
* BL32 specific defines.
******************************************************************************/
#ifndef ZYNQMP_BL32_MEM_BASE
-# define BL32_BASE 0x60000000
-# define BL32_LIMIT 0x7fffffff
+# define BL32_BASE U(0x60000000)
+# define BL32_LIMIT U(0x7fffffff)
#else
# define BL32_BASE (ZYNQMP_BL32_MEM_BASE)
# define BL32_LIMIT (ZYNQMP_BL32_MEM_BASE + ZYNQMP_BL32_MEM_SIZE - 1)
@@ -66,7 +66,7 @@
* BL33 specific defines.
******************************************************************************/
#ifndef PRELOADED_BL33_BASE
-# define PLAT_ARM_NS_IMAGE_BASE 0x8000000
+# define PLAT_ARM_NS_IMAGE_BASE U(0x8000000)
#else
# define PLAT_ARM_NS_IMAGE_BASE PRELOADED_BL33_BASE
#endif
@@ -83,9 +83,9 @@
/*******************************************************************************
* Platform specific page table and MMU setup constants
******************************************************************************/
-#define XILINX_OF_BOARD_DTB_ADDR 0x100000
-#define XILINX_OF_BOARD_DTB_MAX_SIZE 0x200000
-#define PLAT_DDR_LOWMEM_MAX 0x80000000
+#define XILINX_OF_BOARD_DTB_ADDR U(0x100000)
+#define XILINX_OF_BOARD_DTB_MAX_SIZE U(0x200000)
+#define PLAT_DDR_LOWMEM_MAX U(0x80000000)
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index 7e58391..19b6937 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -74,11 +74,11 @@
#define ZYNQMP_ULPI_RESET_VAL_LOW CRL_APB_BOOT_ENABLE_PIN_1
/* system counter registers and bitfields */
-#define IOU_SCNTRS_BASE 0xFF260000
+#define IOU_SCNTRS_BASE U(0xFF260000)
#define IOU_SCNTRS_BASEFREQ (IOU_SCNTRS_BASE + 0x20)
/* APU registers and bitfields */
-#define APU_BASE 0xFD5C0000
+#define APU_BASE U(0xFD5C0000)
#define APU_CONFIG_0 (APU_BASE + 0x20)
#define APU_RVBAR_L_0 (APU_BASE + 0x40)
#define APU_RVBAR_H_0 (APU_BASE + 0x44)
@@ -91,7 +91,7 @@
#define APU_3_PWRCTL_CPUPWRDWNREQ_MASK 8
/* PMU registers and bitfields */
-#define PMU_GLOBAL_BASE 0xFFD80000
+#define PMU_GLOBAL_BASE U(0xFFD80000)
#define PMU_GLOBAL_CNTRL (PMU_GLOBAL_BASE + 0)
#define PMU_GLOBAL_GEN_STORAGE6 (PMU_GLOBAL_BASE + 0x48)
#define PMU_GLOBAL_REQ_PWRUP_STATUS (PMU_GLOBAL_BASE + 0x110)
@@ -104,22 +104,22 @@
/*******************************************************************************
* CCI-400 related constants
******************************************************************************/
-#define PLAT_ARM_CCI_BASE 0xFD6E0000
+#define PLAT_ARM_CCI_BASE U(0xFD6E0000)
#define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX 3
#define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX 4
/*******************************************************************************
* GIC-400 & interrupt handling related constants
******************************************************************************/
-#define BASE_GICD_BASE 0xF9010000
-#define BASE_GICC_BASE 0xF9020000
-#define BASE_GICH_BASE 0xF9040000
-#define BASE_GICV_BASE 0xF9060000
+#define BASE_GICD_BASE U(0xF9010000)
+#define BASE_GICC_BASE U(0xF9020000)
+#define BASE_GICH_BASE U(0xF9040000)
+#define BASE_GICV_BASE U(0xF9060000)
#if ZYNQMP_WDT_RESTART
#define IRQ_SEC_IPI_APU 67
#define IRQ_TTC3_1 77
-#define TTC3_BASE_ADDR 0xFF140000
+#define TTC3_BASE_ADDR U(0xFF140000)
#define TTC3_INTR_REGISTER_1 (TTC3_BASE_ADDR + 0x54)
#define TTC3_INTR_ENABLE_1 (TTC3_BASE_ADDR + 0x60)
#endif
@@ -140,8 +140,8 @@
/*******************************************************************************
* UART related constants
******************************************************************************/
-#define ZYNQMP_UART0_BASE 0xFF000000
-#define ZYNQMP_UART1_BASE 0xFF010000
+#define ZYNQMP_UART0_BASE U(0xFF000000)
+#define ZYNQMP_UART1_BASE U(0xFF010000)
#if ZYNQMP_CONSOLE_IS(cadence) || ZYNQMP_CONSOLE_IS(dcc)
# define ZYNQMP_UART_BASE ZYNQMP_UART0_BASE
@@ -169,7 +169,7 @@
#define ZYNQMP_PS_VER_MASK 0xF
#define ZYNQMP_PS_VER_SHIFT 0
-#define ZYNQMP_CSU_BASEADDR 0xFFCA0000
+#define ZYNQMP_CSU_BASEADDR U(0xFFCA0000)
#define ZYNQMP_CSU_IDCODE_OFFSET 0x40
#define ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT 0
@@ -199,7 +199,7 @@
#define ZYNQMP_CSU_VERSION_OFFSET 0x44
/* Efuse */
-#define EFUSE_BASEADDR 0xFFCC0000
+#define EFUSE_BASEADDR U(0xFFCC0000)
#define EFUSE_IPDISABLE_OFFSET 0x1018
#define EFUSE_IPDISABLE_VERSION 0x1FFU
#define ZYNQMP_EFUSE_IPDISABLE_SHIFT 20
@@ -357,9 +357,9 @@
#define FABRIC_WIDTH U(3)
/* CSUDMA Module Base Address*/
-#define CSUDMA_BASE 0xFFC80000
+#define CSUDMA_BASE U(0xFFC80000)
/* RSA-CORE Module Base Address*/
-#define RSA_CORE_BASE 0xFFCE0000
+#define RSA_CORE_BASE U(0xFFCE0000)
#endif /* ZYNQMP_DEF_H */
diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c
index b2b473a..881dfe6 100644
--- a/plat/xilinx/zynqmp/plat_psci.c
+++ b/plat/xilinx/zynqmp/plat_psci.c
@@ -38,9 +38,9 @@
VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr);
- if (cpu_id == -1)
+ if (cpu_id == -1) {
return PSCI_E_INTERN_FAIL;
-
+ }
proc = pm_get_proc(cpu_id);
/* Check the APU proc status before wakeup */
@@ -63,9 +63,10 @@
unsigned int cpu_id = plat_my_core_pos();
const struct pm_proc *proc = pm_get_proc(cpu_id);
- for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
+ for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
__func__, i, target_state->pwr_domain_state[i]);
+ }
/* Prevent interrupts from spuriously waking up this cpu */
gicv2_cpuif_disable();
@@ -106,9 +107,10 @@
static void zynqmp_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
- for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
+ for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
__func__, i, target_state->pwr_domain_state[i]);
+ }
plat_arm_gic_pcpu_init();
gicv2_cpuif_enable();
}
@@ -118,9 +120,10 @@
unsigned int cpu_id = plat_my_core_pos();
const struct pm_proc *proc = pm_get_proc(cpu_id);
- for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
+ for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
__func__, i, target_state->pwr_domain_state[i]);
+ }
/* Clear the APU power control register for this cpu */
pm_client_wakeup(proc);
@@ -149,8 +152,9 @@
pm_system_shutdown(PMF_SHUTDOWN_TYPE_SHUTDOWN,
pm_get_shutdown_scope());
- while (1)
+ while (1) {
wfi();
+ }
}
static void __dead2 zynqmp_system_reset(void)
@@ -162,8 +166,9 @@
pm_system_shutdown(PMF_SHUTDOWN_TYPE_RESET,
pm_get_shutdown_scope());
- while (1)
+ while (1) {
wfi();
+ }
}
int zynqmp_validate_power_state(unsigned int power_state,
@@ -176,14 +181,15 @@
assert(req_state);
/* Sanity check the requested state */
- if (pstate == PSTATE_TYPE_STANDBY)
+ if (pstate == PSTATE_TYPE_STANDBY) {
req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE;
- else
+ } else {
req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE;
-
+ }
/* We expect the 'state id' to be zero */
- if (psci_get_pstate_id(power_state))
+ if (psci_get_pstate_id(power_state)) {
return PSCI_E_INVALID_PARAMS;
+ }
return PSCI_E_SUCCESS;
}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index 4109830..1ea741c 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -2446,16 +2446,17 @@
*/
void pm_api_clock_get_name(unsigned int clock_id, char *name)
{
- if (clock_id == CLK_MAX)
+ if (clock_id == CLK_MAX) {
memcpy(name, END_OF_CLK, sizeof(END_OF_CLK) > CLK_NAME_LEN ?
CLK_NAME_LEN : sizeof(END_OF_CLK));
- else if (!pm_clock_valid(clock_id))
+ } else if (!pm_clock_valid(clock_id)) {
memset(name, 0, CLK_NAME_LEN);
- else if (clock_id < CLK_MAX_OUTPUT_CLK)
+ } else if (clock_id < CLK_MAX_OUTPUT_CLK) {
memcpy(name, clocks[clock_id].name, CLK_NAME_LEN);
- else
+ } else {
memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name,
CLK_NAME_LEN);
+ }
}
/**
@@ -2480,24 +2481,28 @@
unsigned int i;
uint16_t typeflags;
- if (!pm_clock_valid(clock_id))
+ if (!pm_clock_valid(clock_id)) {
return PM_RET_ERROR_ARGS;
+ }
- if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
return PM_RET_ERROR_NOTSUPPORTED;
-
+ }
memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN);
clock_nodes = *clocks[clock_id].nodes;
num_nodes = clocks[clock_id].num_nodes;
/* Skip parent till index */
- if (index >= num_nodes)
+ if (index >= num_nodes) {
return PM_RET_SUCCESS;
+ }
for (i = 0; i < 3U; i++) {
- if ((index + i) == num_nodes)
+ if ((index + i) == num_nodes) {
break;
+ }
+
topology[i] = clock_nodes[index + i].type;
topology[i] |= clock_nodes[index + i].clkflags <<
CLK_CLKFLAGS_SHIFT;
@@ -2531,11 +2536,13 @@
uint8_t num_nodes;
unsigned int type, i;
- if (!pm_clock_valid(clock_id))
+ if (!pm_clock_valid(clock_id)) {
return PM_RET_ERROR_ARGS;
+ }
- if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
return PM_RET_ERROR_NOTSUPPORTED;
+ }
clock_nodes = *clocks[clock_id].nodes;
num_nodes = clocks[clock_id].num_nodes;
@@ -2550,8 +2557,9 @@
}
/* Clock is not fixed clock */
- if (i == num_nodes)
+ if (i == num_nodes) {
return PM_RET_ERROR_ARGS;
+ }
return PM_RET_SUCCESS;
}
@@ -2580,27 +2588,33 @@
unsigned int i;
int32_t *clk_parents;
- if (!pm_clock_valid(clock_id))
+ if (!pm_clock_valid(clock_id)) {
return PM_RET_ERROR_ARGS;
+ }
- if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
return PM_RET_ERROR_NOTSUPPORTED;
+ }
clk_parents = *clocks[clock_id].parents;
- if (clk_parents == NULL)
+ if (clk_parents == NULL) {
return PM_RET_ERROR_ARGS;
+ }
memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN);
/* Skip parent till index */
- for (i = 0; i < index; i++)
- if (clk_parents[i] == CLK_NA_PARENT)
+ for (i = 0; i < index; i++) {
+ if (clk_parents[i] == CLK_NA_PARENT) {
return PM_RET_SUCCESS;
+ }
+ }
for (i = 0; i < 3; i++) {
parents[i] = clk_parents[index + i];
- if (clk_parents[index + i] == CLK_NA_PARENT)
+ if (clk_parents[index + i] == CLK_NA_PARENT) {
break;
+ }
}
return PM_RET_SUCCESS;
@@ -2619,8 +2633,9 @@
enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id,
uint32_t *attr)
{
- if (clock_id >= CLK_MAX)
+ if (clock_id >= CLK_MAX) {
return PM_RET_ERROR_ARGS;
+ }
/* Clock valid bit */
*attr = pm_clock_valid(clock_id);
@@ -2648,8 +2663,9 @@
uint32_t i;
struct pm_clock_node *nodes;
- if (clock_id >= CLK_MAX_OUTPUT_CLK)
+ if (clock_id >= CLK_MAX_OUTPUT_CLK) {
return PM_RET_ERROR_ARGS;
+ }
nodes = *clocks[clock_id].nodes;
for (i = 0; i < clocks[clock_id].num_nodes; i++) {
@@ -2738,8 +2754,9 @@
uint32_t i;
for (i = 0; i < ARRAY_SIZE(pm_plls); i++) {
- if (pm_plls[i].cid == clock_id)
+ if (pm_plls[i].cid == clock_id) {
return &pm_plls[i];
+ }
}
return NULL;
@@ -2798,12 +2815,14 @@
*/
enum pm_ret_status pm_clock_pll_enable(struct pm_pll *pll)
{
- if (!pll)
+ if (!pll) {
return PM_RET_ERROR_ARGS;
+ }
/* Set the PLL mode according to the buffered mode value */
- if (pll->mode == PLL_FRAC_MODE)
+ if (pll->mode == PLL_FRAC_MODE) {
return pm_pll_set_mode(pll->nid, PM_PLL_MODE_FRACTIONAL);
+ }
return pm_pll_set_mode(pll->nid, PM_PLL_MODE_INTEGER);
}
@@ -2819,8 +2838,9 @@
*/
enum pm_ret_status pm_clock_pll_disable(struct pm_pll *pll)
{
- if (!pll)
+ if (!pll) {
return PM_RET_ERROR_ARGS;
+ }
return pm_pll_set_mode(pll->nid, PM_PLL_MODE_RESET);
}
@@ -2842,17 +2862,20 @@
enum pm_ret_status status;
enum pm_pll_mode mode;
- if (!pll || !state)
+ if (!pll || !state) {
return PM_RET_ERROR_ARGS;
+ }
status = pm_pll_get_mode(pll->nid, &mode);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
- if (mode == PM_PLL_MODE_RESET)
+ if (mode == PM_PLL_MODE_RESET) {
*state = 0;
- else
+ } else {
*state = 1;
+ }
return PM_RET_SUCCESS;
}
@@ -2873,17 +2896,21 @@
enum clock_id clock_id,
unsigned int parent_index)
{
- if (!pll)
+ if (!pll) {
return PM_RET_ERROR_ARGS;
- if (pll->pre_src == clock_id)
+ }
+ if (pll->pre_src == clock_id) {
return pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_PRE_SRC,
parent_index);
- if (pll->post_src == clock_id)
+ }
+ if (pll->post_src == clock_id) {
return pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_POST_SRC,
parent_index);
- if (pll->div2 == clock_id)
+ }
+ if (pll->div2 == clock_id) {
return pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_DIV2,
parent_index);
+ }
return PM_RET_ERROR_ARGS;
}
@@ -2902,17 +2929,21 @@
enum clock_id clock_id,
unsigned int *parent_index)
{
- if (!pll)
+ if (!pll) {
return PM_RET_ERROR_ARGS;
- if (pll->pre_src == clock_id)
+ }
+ if (pll->pre_src == clock_id) {
return pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_PRE_SRC,
parent_index);
- if (pll->post_src == clock_id)
+ }
+ if (pll->post_src == clock_id) {
return pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_POST_SRC,
parent_index);
- if (pll->div2 == clock_id)
+ }
+ if (pll->div2 == clock_id) {
return pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_DIV2,
parent_index);
+ }
if (pll->bypass == clock_id) {
*parent_index = 0;
return PM_RET_SUCCESS;
@@ -2935,8 +2966,9 @@
{
struct pm_pll *pll = pm_clock_get_pll(clock_id);
- if (!pll || (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE))
+ if (!pll || (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE)) {
return PM_RET_ERROR_ARGS;
+ }
pll->mode = mode;
return PM_RET_SUCCESS;
@@ -2956,8 +2988,9 @@
{
struct pm_pll *pll = pm_clock_get_pll(clock_id);
- if (!pll || !mode)
+ if (!pll || !mode) {
return PM_RET_ERROR_ARGS;
+ }
*mode = pll->mode;
return PM_RET_SUCCESS;
@@ -2971,11 +3004,13 @@
*/
enum pm_ret_status pm_clock_id_is_valid(unsigned int clock_id)
{
- if (!pm_clock_valid(clock_id))
+ if (!pm_clock_valid(clock_id)) {
return PM_RET_ERROR_ARGS;
+ }
- if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
return PM_RET_ERROR_NOTSUPPORTED;
+ }
return PM_RET_SUCCESS;
}
@@ -2992,8 +3027,9 @@
uint32_t i;
struct pm_clock_node *nodes;
- if (clock_id >= CLK_MAX_OUTPUT_CLK)
+ if (clock_id >= CLK_MAX_OUTPUT_CLK) {
return 0;
+ }
nodes = *clocks[clock_id].nodes;
for (i = 0; i < clocks[clock_id].num_nodes; i++) {
@@ -3003,6 +3039,8 @@
} else if (nodes[i].type == TYPE_DIV2) {
if (div_id == PM_CLOCK_DIV1_ID)
return 1;
+ } else {
+ /* To fix the misra 15.7 warning */
}
}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index a87681b..f12143a 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -35,10 +35,11 @@
val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
val &= ZYNQMP_SLSPLIT_MASK;
- if (val == 0)
+ if (val == 0) {
*mode = PM_RPU_MODE_LOCKSTEP;
- else
+ } else {
*mode = PM_RPU_MODE_SPLIT;
+ }
return PM_RET_SUCCESS;
}
@@ -58,8 +59,9 @@
{
unsigned int val;
- if (mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET)
+ if (mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET) {
return PM_RET_ERROR_ACCESS;
+ }
val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
@@ -94,21 +96,23 @@
{
unsigned int rpu_cfg_addr, val;
- if (nid == NODE_RPU_0)
+ if (nid == NODE_RPU_0) {
rpu_cfg_addr = ZYNQMP_RPU0_CFG;
- else if (nid == NODE_RPU_1)
+ } else if (nid == NODE_RPU_1) {
rpu_cfg_addr = ZYNQMP_RPU1_CFG;
- else
+ } else {
return PM_RET_ERROR_ARGS;
+ }
val = mmio_read_32(rpu_cfg_addr);
- if (value == PM_RPU_BOOTMEM_LOVEC)
+ if (value == PM_RPU_BOOTMEM_LOVEC) {
val &= ~ZYNQMP_VINITHI_MASK;
- else if (value == PM_RPU_BOOTMEM_HIVEC)
+ } else if (value == PM_RPU_BOOTMEM_HIVEC) {
val |= ZYNQMP_VINITHI_MASK;
- else
+ } else {
return PM_RET_ERROR_ARGS;
+ }
mmio_write_32(rpu_cfg_addr, val);
@@ -130,12 +134,13 @@
val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
- if (value == PM_RPU_TCM_SPLIT)
+ if (value == PM_RPU_TCM_SPLIT) {
val &= ~ZYNQMP_TCM_COMB_MASK;
- else if (value == PM_RPU_TCM_COMB)
+ } else if (value == PM_RPU_TCM_COMB) {
val |= ZYNQMP_TCM_COMB_MASK;
- else
+ } else {
return PM_RET_ERROR_ARGS;
+ }
mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
@@ -155,8 +160,9 @@
unsigned int value)
{
if ((value != PM_TAPDELAY_BYPASS_ENABLE &&
- value != PM_TAPDELAY_BYPASS_DISABLE) || type >= PM_TAPDELAY_MAX)
+ value != PM_TAPDELAY_BYPASS_DISABLE) || type >= PM_TAPDELAY_MAX) {
return PM_RET_ERROR_ARGS;
+ }
return pm_mmio_write(IOU_TAPDLY_BYPASS, TAP_DELAY_MASK, value << type);
}
@@ -178,8 +184,9 @@
unsigned int val, mask, shift;
enum pm_ret_status ret;
- if (value != PM_SGMII_DISABLE && value != PM_SGMII_ENABLE)
+ if (value != PM_SGMII_DISABLE && value != PM_SGMII_ENABLE) {
return PM_RET_ERROR_ARGS;
+ }
switch (nid) {
case NODE_ETH_0:
@@ -206,8 +213,9 @@
mask = SGMII_SD_MASK << SGMII_SD_OFFSET * shift;
val = SGMII_PCS_SD_1 << SGMII_SD_OFFSET * shift;
ret = pm_mmio_write(IOU_GEM_CTRL, mask, val);
- if (ret != PM_RET_SUCCESS)
+ if (ret != PM_RET_SUCCESS) {
return ret;
+ }
/* Set the GEM to SGMII mode */
mask = GEM_CLK_CTRL_MASK << GEM_CLK_CTRL_OFFSET * shift;
@@ -248,11 +256,13 @@
case PM_DLL_RESET_ASSERT:
case PM_DLL_RESET_PULSE:
ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, val);
- if (ret != PM_RET_SUCCESS)
+ if (ret != PM_RET_SUCCESS) {
return ret;
+ }
- if (type == PM_DLL_RESET_ASSERT)
+ if (type == PM_DLL_RESET_ASSERT) {
break;
+ }
mdelay(1);
/* Fallthrough */
case PM_DLL_RESET_RELEASE:
@@ -310,31 +320,44 @@
ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
(ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
(ZYNQMP_SD_ITAPCHGWIN << shift));
- if (ret != PM_RET_SUCCESS)
+
+ if (ret != PM_RET_SUCCESS) {
goto reset_release;
- if (value == 0)
+ }
+
+ if (value == 0) {
ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
(ZYNQMP_SD_ITAPDLYENA_MASK <<
shift), 0);
- else
+ } else {
ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
(ZYNQMP_SD_ITAPDLYENA_MASK <<
shift), (ZYNQMP_SD_ITAPDLYENA <<
shift));
- if (ret != PM_RET_SUCCESS)
+ }
+
+ if (ret != PM_RET_SUCCESS) {
goto reset_release;
+ }
+
ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
(ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
(value << shift));
- if (ret != PM_RET_SUCCESS)
+
+ if (ret != PM_RET_SUCCESS) {
goto reset_release;
+ }
+
ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
(ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
} else if (type == PM_TAPDELAY_OUTPUT) {
ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
(ZYNQMP_SD_OTAPDLYENA_MASK << shift), 0);
- if (ret != PM_RET_SUCCESS)
+
+ if (ret != PM_RET_SUCCESS) {
goto reset_release;
+ }
+
ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
(ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
(value << shift));
@@ -401,8 +424,9 @@
/* Get PLL node ID using PLL clock ID */
status = pm_clock_get_pll_node_id(pll, &pll_nid);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
return pm_pll_set_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
}
@@ -425,8 +449,9 @@
/* Get PLL node ID using PLL clock ID */
status = pm_clock_get_pll_node_id(pll, &pll_nid);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
return pm_pll_get_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
}
@@ -444,8 +469,9 @@
static enum pm_ret_status pm_ioctl_write_ggs(unsigned int index,
unsigned int value)
{
- if (index >= GGS_NUM_REGS)
+ if (index >= GGS_NUM_REGS) {
return PM_RET_ERROR_ARGS;
+ }
return pm_mmio_write(GGS_BASEADDR + (index << 2),
0xFFFFFFFFU, value);
@@ -464,8 +490,9 @@
static enum pm_ret_status pm_ioctl_read_ggs(unsigned int index,
unsigned int *value)
{
- if (index >= GGS_NUM_REGS)
+ if (index >= GGS_NUM_REGS) {
return PM_RET_ERROR_ARGS;
+ }
return pm_mmio_read(GGS_BASEADDR + (index << 2), value);
}
@@ -483,8 +510,9 @@
static enum pm_ret_status pm_ioctl_write_pggs(unsigned int index,
unsigned int value)
{
- if (index >= PGGS_NUM_REGS)
+ if (index >= PGGS_NUM_REGS) {
return PM_RET_ERROR_ARGS;
+ }
return pm_mmio_write(PGGS_BASEADDR + (index << 2),
0xFFFFFFFFU, value);
@@ -503,31 +531,33 @@
unsigned int value)
{
unsigned int mask;
- unsigned int regarr[] = {0xFD360000,
- 0xFD360014,
- 0xFD370000,
- 0xFD370014,
- 0xFD380000,
- 0xFD380014,
- 0xFD390000,
- 0xFD390014,
- 0xFD3a0000,
- 0xFD3a0014,
- 0xFD3b0000,
- 0xFD3b0014,
- 0xFF9b0000,
- 0xFF9b0014,
- 0xFD615000,
- 0xFF419000,
+ unsigned int regarr[] = {0xFD360000U,
+ 0xFD360014U,
+ 0xFD370000U,
+ 0xFD370014U,
+ 0xFD380000U,
+ 0xFD380014U,
+ 0xFD390000U,
+ 0xFD390014U,
+ 0xFD3a0000U,
+ 0xFD3a0014U,
+ 0xFD3b0000U,
+ 0xFD3b0014U,
+ 0xFF9b0000U,
+ 0xFF9b0014U,
+ 0xFD615000U,
+ 0xFF419000U,
};
- if (index >= ARRAY_SIZE(regarr))
+ if (index >= ARRAY_SIZE(regarr)) {
return PM_RET_ERROR_ARGS;
+ }
- if (index < AFIFM6_WRCTRL)
+ if (index < AFIFM6_WRCTRL) {
mask = FABRIC_WIDTH;
- else
+ } else {
mask = 0xf00;
+ }
return pm_mmio_write(regarr[index], mask, value);
}
@@ -545,8 +575,9 @@
static enum pm_ret_status pm_ioctl_read_pggs(unsigned int index,
unsigned int *value)
{
- if (index >= PGGS_NUM_REGS)
+ if (index >= PGGS_NUM_REGS) {
return PM_RET_ERROR_ARGS;
+ }
return pm_mmio_read(PGGS_BASEADDR + (index << 2), value);
}
@@ -565,16 +596,18 @@
ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
ZYNQMP_ULPI_RESET_VAL_HIGH);
- if (ret != PM_RET_SUCCESS)
+ if (ret != PM_RET_SUCCESS) {
return ret;
+ }
/* Drive ULPI assert for atleast 1ms */
mdelay(1);
ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
ZYNQMP_ULPI_RESET_VAL_LOW);
- if (ret != PM_RET_SUCCESS)
+ if (ret != PM_RET_SUCCESS) {
return ret;
+ }
/* Drive ULPI de-assert for atleast 1ms */
mdelay(1);
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
index 9a6b497..75e0499 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
@@ -2549,17 +2549,20 @@
int i = 0;
uint16_t *grps;
- if (fid >= MAX_FUNCTION)
+ if (fid >= MAX_FUNCTION) {
return PM_RET_ERROR_ARGS;
+ }
*ngroups = 0;
grps = *pinctrl_functions[fid].groups;
- if (grps == NULL)
+ if (grps == NULL) {
return PM_RET_SUCCESS;
+ }
- while (grps[i++] != (uint16_t)END_OF_GROUPS)
+ while (grps[i++] != (uint16_t)END_OF_GROUPS) {
(*ngroups)++;
+ }
return PM_RET_SUCCESS;
}
@@ -2574,10 +2577,11 @@
*/
void pm_api_pinctrl_get_function_name(unsigned int fid, char *name)
{
- if (fid >= MAX_FUNCTION)
+ if (fid >= MAX_FUNCTION) {
memcpy(name, END_OF_FUNCTION, FUNCTION_NAME_LEN);
- else
+ } else {
memcpy(name, pinctrl_functions[fid].name, FUNCTION_NAME_LEN);
+ }
}
/**
@@ -2605,24 +2609,29 @@
unsigned int i;
uint16_t *grps;
- if (fid >= MAX_FUNCTION)
+ if (fid >= MAX_FUNCTION) {
return PM_RET_ERROR_ARGS;
+ }
memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
grps = *pinctrl_functions[fid].groups;
- if (grps == NULL)
+ if (grps == NULL) {
return PM_RET_SUCCESS;
+ }
/* Skip groups till index */
- for (i = 0; i < index; i++)
- if (grps[i] == (uint16_t)END_OF_GROUPS)
+ for (i = 0; i < index; i++) {
+ if (grps[i] == (uint16_t)END_OF_GROUPS) {
return PM_RET_SUCCESS;
+ }
+ }
for (i = 0; i < NUM_GROUPS_PER_RESP; i++) {
groups[i] = grps[index + i];
- if (groups[i] == (uint16_t)END_OF_GROUPS)
+ if (groups[i] == (uint16_t)END_OF_GROUPS) {
break;
+ }
}
return PM_RET_SUCCESS;
@@ -2653,24 +2662,29 @@
unsigned int i;
uint16_t *grps;
- if (pin >= MAX_PIN)
+ if (pin >= MAX_PIN) {
return PM_RET_ERROR_ARGS;
+ }
memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
grps = *zynqmp_pin_groups[pin].groups;
- if (!grps)
+ if (grps == NULL) {
return PM_RET_SUCCESS;
+ }
/* Skip groups till index */
- for (i = 0; i < index; i++)
- if (grps[i] == (uint16_t)END_OF_GROUPS)
+ for (i = 0; i < index; i++) {
+ if (grps[i] == (uint16_t)END_OF_GROUPS) {
return PM_RET_SUCCESS;
+ }
+ }
for (i = 0; i < NUM_GROUPS_PER_RESP; i++) {
groups[i] = grps[index + i];
- if (groups[i] == (uint16_t)END_OF_GROUPS)
+ if (groups[i] == (uint16_t)END_OF_GROUPS) {
break;
+ }
}
return PM_RET_SUCCESS;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index f9af451..e524ba5 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
@@ -306,10 +306,11 @@
/* Send request to the PMU */
PM_PACK_PAYLOAD5(payload, PM_REQ_SUSPEND, target, ack, latency, state);
- if (ack == REQ_ACK_BLOCKING)
+ if (ack == REQ_ACK_BLOCKING) {
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
- else
+ } else {
return pm_ipi_send(primary_proc, payload);
+ }
}
/**
@@ -345,10 +346,11 @@
PM_PACK_PAYLOAD5(payload, PM_REQ_WAKEUP, target, encoded_address,
encoded_address >> 32, ack);
- if (ack == REQ_ACK_BLOCKING)
+ if (ack == REQ_ACK_BLOCKING) {
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
- else
+ } else {
return pm_ipi_send(primary_proc, payload);
+ }
}
/**
@@ -367,10 +369,11 @@
/* Send request to the PMU */
PM_PACK_PAYLOAD3(payload, PM_FORCE_POWERDOWN, target, ack);
- if (ack == REQ_ACK_BLOCKING)
+ if (ack == REQ_ACK_BLOCKING) {
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
- else
+ } else {
return pm_ipi_send(primary_proc, payload);
+ }
}
/**
@@ -459,10 +462,11 @@
PM_PACK_PAYLOAD5(payload, PM_REQ_NODE, nid, capabilities, qos, ack);
- if (ack == REQ_ACK_BLOCKING)
+ if (ack == REQ_ACK_BLOCKING) {
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
- else
+ } else {
return pm_ipi_send(primary_proc, payload);
+ }
}
/**
@@ -486,10 +490,11 @@
PM_PACK_PAYLOAD5(payload, PM_SET_REQUIREMENT, nid, capabilities, qos,
ack);
- if (ack == REQ_ACK_BLOCKING)
+ if (ack == REQ_ACK_BLOCKING) {
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
- else
+ } else {
return pm_ipi_send(primary_proc, payload);
+ }
}
/* Miscellaneous API functions */
@@ -689,8 +694,9 @@
void pm_get_callbackdata(uint32_t *data, size_t count)
{
/* Return if interrupt is not from PMU */
- if (!pm_ipi_irq_status(primary_proc))
+ if (!pm_ipi_irq_status(primary_proc)) {
return;
+ }
pm_ipi_buff_read_callb(data, count);
pm_ipi_irq_clear(primary_proc);
@@ -1070,21 +1076,24 @@
/* Check if clock ID is valid and return an error if it is not */
status = pm_clock_id_is_valid(clock_id);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
- if (enable)
+ if (enable) {
api_id = PM_CLOCK_ENABLE;
- else
+ } else {
api_id = PM_CLOCK_DISABLE;
+ }
/* Send request to the PMU */
PM_PACK_PAYLOAD2(payload, api_id, clock_id);
status = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
/* If action fails due to the lack of permissions filter the error */
- if (status == PM_RET_ERROR_ACCESS)
+ if (status == PM_RET_ERROR_ACCESS) {
status = PM_RET_SUCCESS;
+ }
return status;
}
@@ -1105,8 +1114,9 @@
/* First try to handle it as a PLL */
pll = pm_clock_get_pll(clock_id);
- if (pll)
+ if (pll) {
return pm_clock_pll_enable(pll);
+ }
/* It's an on-chip clock, PMU should configure clock's gate */
return pm_clock_gate(clock_id, 1);
@@ -1128,8 +1138,9 @@
/* First try to handle it as a PLL */
pll = pm_clock_get_pll(clock_id);
- if (pll)
+ if (pll) {
return pm_clock_pll_disable(pll);
+ }
/* It's an on-chip clock, PMU should configure clock's gate */
return pm_clock_gate(clock_id, 0);
@@ -1159,8 +1170,9 @@
/* Check if clock ID is a valid on-chip clock */
status = pm_clock_id_is_valid(clock_id);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
/* Send request to the PMU */
PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETSTATE, clock_id);
@@ -1190,13 +1202,15 @@
/* Get PLL node ID using PLL clock ID */
status = pm_clock_get_pll_node_id(clock_id, &nid);
- if (status == PM_RET_SUCCESS)
+ if (status == PM_RET_SUCCESS) {
return pm_pll_set_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
+ }
/* Check if clock ID is a valid on-chip clock */
status = pm_clock_id_is_valid(clock_id);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
if (div0 == (divider & div0)) {
div_id = PM_CLOCK_DIV0_ID;
@@ -1233,21 +1247,24 @@
/* Get PLL node ID using PLL clock ID */
status = pm_clock_get_pll_node_id(clock_id, &nid);
- if (status == PM_RET_SUCCESS)
+ if (status == PM_RET_SUCCESS) {
return pm_pll_get_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
+ }
/* Check if clock ID is a valid on-chip clock */
status = pm_clock_id_is_valid(clock_id);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
if (pm_clock_has_div(clock_id, PM_CLOCK_DIV0_ID)) {
/* Send request to the PMU to get div0 */
PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
PM_CLOCK_DIV0_ID);
status = pm_ipi_send_sync(primary_proc, payload, &val, 1);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
*divider = val;
}
@@ -1256,8 +1273,9 @@
PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
PM_CLOCK_DIV1_ID);
status = pm_ipi_send_sync(primary_proc, payload, &val, 1);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
*divider |= val << 16;
}
@@ -1313,13 +1331,15 @@
/* First try to handle it as a PLL */
pll = pm_clock_get_pll_by_related_clk(clock_id);
- if (pll)
+ if (pll) {
return pm_clock_pll_set_parent(pll, clock_id, parent_index);
+ }
/* Check if clock ID is a valid on-chip clock */
status = pm_clock_id_is_valid(clock_id);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
/* Send request to the PMU */
PM_PACK_PAYLOAD3(payload, PM_CLOCK_SETPARENT, clock_id, parent_index);
@@ -1345,13 +1365,15 @@
/* First try to handle it as a PLL */
pll = pm_clock_get_pll_by_related_clk(clock_id);
- if (pll)
+ if (pll) {
return pm_clock_pll_get_parent(pll, clock_id, parent_index);
+ }
/* Check if clock ID is a valid on-chip clock */
status = pm_clock_id_is_valid(clock_id);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
/* Send request to the PMU */
PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETPARENT, clock_id);
@@ -1522,6 +1544,7 @@
default:
data[0] = PM_RET_ERROR_ARGS;
WARN("Unimplemented query service call: 0x%x\n", qid);
+ break;
}
}
@@ -1614,12 +1637,14 @@
uint32_t payload[PAYLOAD_ARG_CNT];
/* Check if given node ID is a PLL node */
- if (nid < NODE_APLL || nid > NODE_IOPLL)
+ if (nid < NODE_APLL || nid > NODE_IOPLL) {
return PM_RET_ERROR_ARGS;
+ }
/* Check if parameter ID is valid and return an error if it's not */
- if (param_id >= PM_PLL_PARAM_MAX)
+ if (param_id >= PM_PLL_PARAM_MAX) {
return PM_RET_ERROR_ARGS;
+ }
/* Send request to the PMU */
PM_PACK_PAYLOAD4(payload, PM_PLL_SET_PARAMETER, nid, param_id, value);
@@ -1642,12 +1667,14 @@
uint32_t payload[PAYLOAD_ARG_CNT];
/* Check if given node ID is a PLL node */
- if (nid < NODE_APLL || nid > NODE_IOPLL)
+ if (nid < NODE_APLL || nid > NODE_IOPLL) {
return PM_RET_ERROR_ARGS;
+ }
/* Check if parameter ID is valid and return an error if it's not */
- if (param_id >= PM_PLL_PARAM_MAX)
+ if (param_id >= PM_PLL_PARAM_MAX) {
return PM_RET_ERROR_ARGS;
+ }
/* Send request to the PMU */
PM_PACK_PAYLOAD3(payload, PM_PLL_GET_PARAMETER, nid, param_id);
@@ -1672,12 +1699,14 @@
uint32_t payload[PAYLOAD_ARG_CNT];
/* Check if given node ID is a PLL node */
- if (nid < NODE_APLL || nid > NODE_IOPLL)
+ if (nid < NODE_APLL || nid > NODE_IOPLL) {
return PM_RET_ERROR_ARGS;
+ }
/* Check if PLL mode is valid */
- if (mode >= PM_PLL_MODE_MAX)
+ if (mode >= PM_PLL_MODE_MAX) {
return PM_RET_ERROR_ARGS;
+ }
/* Send request to the PMU */
PM_PACK_PAYLOAD3(payload, PM_PLL_SET_MODE, nid, mode);
@@ -1697,8 +1726,9 @@
uint32_t payload[PAYLOAD_ARG_CNT];
/* Check if given node ID is a PLL node */
- if (nid < NODE_APLL || nid > NODE_IOPLL)
+ if (nid < NODE_APLL || nid > NODE_IOPLL) {
return PM_RET_ERROR_ARGS;
+ }
/* Send request to the PMU */
PM_PACK_PAYLOAD2(payload, PM_PLL_GET_MODE, nid);
@@ -1733,8 +1763,9 @@
if (((ZYNQMP_CSU_BASEADDR & address) != ZYNQMP_CSU_BASEADDR) &&
((CSUDMA_BASE & address) != CSUDMA_BASE) &&
((RSA_CORE_BASE & address) != RSA_CORE_BASE) &&
- ((PMU_GLOBAL_BASE & address) != PMU_GLOBAL_BASE))
+ ((PMU_GLOBAL_BASE & address) != PMU_GLOBAL_BASE)) {
return PM_RET_ERROR_ACCESS;
+ }
switch (register_access_id) {
case CONFIG_REG_WRITE:
@@ -1746,6 +1777,7 @@
default:
ret = PM_RET_ERROR_ARGS;
WARN("Unimplemented register_access call\n\r");
+ break;
}
return ret;
}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c
index 163e891..1f54430 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.c
@@ -188,8 +188,9 @@
* If NODE_EXTERN could not be set as wake source, proceed with
* standard suspend (no one will wake the system otherwise)
*/
- if (ret == PM_RET_SUCCESS)
+ if (ret == PM_RET_SUCCESS) {
return;
+ }
}
zeromem(&pm_wakeup_nodes_set, sizeof(pm_wakeup_nodes_set));
@@ -198,8 +199,9 @@
uint32_t base_irq = reg_num << ISENABLER_SHIFT;
uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2));
- if (!reg)
+ if (!reg) {
continue;
+ }
while (reg) {
enum pm_node_id node;
@@ -208,8 +210,9 @@
idx = __builtin_ctz(lowest_set);
irq = base_irq + idx;
- if (irq > IRQ_MAX)
+ if (irq > IRQ_MAX) {
break;
+ }
node = irq_to_pm_node(irq);
reg &= ~lowest_set;
@@ -231,8 +234,9 @@
*/
const struct pm_proc *pm_get_proc(unsigned int cpuid)
{
- if (cpuid < ARRAY_SIZE(pm_procs_all))
+ if (cpuid < ARRAY_SIZE(pm_procs_all)) {
return &pm_procs_all[cpuid];
+ }
return NULL;
}
@@ -246,8 +250,9 @@
const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid)
{
for (size_t i = 0; i < ARRAY_SIZE(pm_procs_all); i++) {
- if (nid == pm_procs_all[i].node_id)
+ if (nid == pm_procs_all[i].node_id) {
return &pm_procs_all[i];
+ }
}
return NULL;
}
@@ -261,8 +266,9 @@
static unsigned int pm_get_cpuid(enum pm_node_id nid)
{
for (size_t i = 0; i < ARRAY_SIZE(pm_procs_all); i++) {
- if (pm_procs_all[i].node_id == nid)
+ if (pm_procs_all[i].node_id == nid) {
return i;
+ }
}
return UNDEFINED_CPUID;
}
@@ -280,8 +286,9 @@
{
bakery_lock_get(&pm_client_secure_lock);
- if (state == PM_STATE_SUSPEND_TO_RAM)
+ if (state == PM_STATE_SUSPEND_TO_RAM) {
pm_client_set_wakeup_sources();
+ }
/* Set powerdown request */
mmio_write_32(APU_PWRCTL, mmio_read_32(APU_PWRCTL) | proc->pwrdn_mask);
@@ -320,8 +327,9 @@
{
unsigned int cpuid = pm_get_cpuid(proc->node_id);
- if (cpuid == UNDEFINED_CPUID)
+ if (cpuid == UNDEFINED_CPUID) {
return;
+ }
bakery_lock_get(&pm_client_secure_lock);
@@ -336,8 +344,9 @@
enum pm_ret_status pm_set_suspend_mode(uint32_t mode)
{
if ((mode != PM_SUSPEND_MODE_STD) &&
- (mode != PM_SUSPEND_MODE_POWER_OFF))
+ (mode != PM_SUSPEND_MODE_POWER_OFF)) {
return PM_RET_ERROR_ARGS;
+ }
suspend_mode = mode;
return PM_RET_SUCCESS;
diff --git a/plat/xilinx/zynqmp/sip_svc_setup.c b/plat/xilinx/zynqmp/sip_svc_setup.c
index 114da33..4a6095c 100644
--- a/plat/xilinx/zynqmp/sip_svc_setup.c
+++ b/plat/xilinx/zynqmp/sip_svc_setup.c
@@ -13,9 +13,9 @@
#include "pm_svc_main.h"
/* SMC function IDs for SiP Service queries */
-#define ZYNQMP_SIP_SVC_CALL_COUNT 0x8200ff00
-#define ZYNQMP_SIP_SVC_UID 0x8200ff01
-#define ZYNQMP_SIP_SVC_VERSION 0x8200ff03
+#define ZYNQMP_SIP_SVC_CALL_COUNT U(0x8200ff00)
+#define ZYNQMP_SIP_SVC_UID U(0x8200ff01)
+#define ZYNQMP_SIP_SVC_VERSION U(0x8200ff03)
/* SiP Service Calls version numbers */
#define SIP_SVC_VERSION_MAJOR 0
@@ -100,6 +100,6 @@
sip_svc,
OEN_SIP_START,
OEN_SIP_END,
- SMC_TYPE_FAST,
+ (uint8_t)SMC_TYPE_FAST,
sip_svc_setup,
sip_svc_smc_handler);
diff --git a/plat/xilinx/zynqmp/zynqmp_ipi.c b/plat/xilinx/zynqmp/zynqmp_ipi.c
index f57369f..4ea3c6a 100644
--- a/plat/xilinx/zynqmp/zynqmp_ipi.c
+++ b/plat/xilinx/zynqmp/zynqmp_ipi.c
@@ -25,67 +25,67 @@
/* APU IPI */
{
.ipi_bit_mask = 0x1,
- .ipi_reg_base = 0xFF300000,
+ .ipi_reg_base = 0xFF300000U,
.secure_only = 0,
},
/* RPU0 IPI */
{
.ipi_bit_mask = 0x100,
- .ipi_reg_base = 0xFF310000,
+ .ipi_reg_base = 0xFF310000U,
.secure_only = 0,
},
/* RPU1 IPI */
{
.ipi_bit_mask = 0x200,
- .ipi_reg_base = 0xFF320000,
+ .ipi_reg_base = 0xFF320000U,
.secure_only = 0,
},
/* PMU0 IPI */
{
.ipi_bit_mask = 0x10000,
- .ipi_reg_base = 0xFF330000,
+ .ipi_reg_base = 0xFF330000U,
.secure_only = IPI_SECURE_MASK,
},
/* PMU1 IPI */
{
.ipi_bit_mask = 0x20000,
- .ipi_reg_base = 0xFF331000,
+ .ipi_reg_base = 0xFF331000U,
.secure_only = 0,
},
/* PMU2 IPI */
{
.ipi_bit_mask = 0x40000,
- .ipi_reg_base = 0xFF332000,
+ .ipi_reg_base = 0xFF332000U,
.secure_only = IPI_SECURE_MASK,
},
/* PMU3 IPI */
{
.ipi_bit_mask = 0x80000,
- .ipi_reg_base = 0xFF333000,
+ .ipi_reg_base = 0xFF333000U,
.secure_only = IPI_SECURE_MASK,
},
/* PL0 IPI */
{
.ipi_bit_mask = 0x1000000,
- .ipi_reg_base = 0xFF340000,
+ .ipi_reg_base = 0xFF340000U,
.secure_only = 0,
},
/* PL1 IPI */
{
.ipi_bit_mask = 0x2000000,
- .ipi_reg_base = 0xFF350000,
+ .ipi_reg_base = 0xFF350000U,
.secure_only = 0,
},
/* PL2 IPI */
{
.ipi_bit_mask = 0x4000000,
- .ipi_reg_base = 0xFF360000,
+ .ipi_reg_base = 0xFF360000U,
.secure_only = 0,
},
/* PL3 IPI */
{
.ipi_bit_mask = 0x8000000,
- .ipi_reg_base = 0xFF370000,
+ .ipi_reg_base = 0xFF370000U,
.secure_only = 0,
},
};
diff --git a/services/std_svc/spm_mm/aarch64/spm_mm_helpers.S b/services/std_svc/spm/common/aarch64/spm_helpers.S
similarity index 96%
rename from services/std_svc/spm_mm/aarch64/spm_mm_helpers.S
rename to services/std_svc/spm/common/aarch64/spm_helpers.S
index 2c3aaf7..95e69fb 100644
--- a/services/std_svc/spm_mm/aarch64/spm_mm_helpers.S
+++ b/services/std_svc/spm/common/aarch64/spm_helpers.S
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <asm_macros.S>
-#include "../spm_mm_private.h"
+#include "spm_common.h"
.global spm_secure_partition_enter
.global spm_secure_partition_exit
diff --git a/services/std_svc/spm/common/include/spm_common.h b/services/std_svc/spm/common/include/spm_common.h
new file mode 100644
index 0000000..68805fc
--- /dev/null
+++ b/services/std_svc/spm/common/include/spm_common.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPM_COMMON_H
+#define SPM_COMMON_H
+
+#include <context.h>
+
+/*******************************************************************************
+ * Constants that allow assembler code to preserve callee-saved registers of the
+ * C runtime context while performing a security state switch.
+ ******************************************************************************/
+#define SP_C_RT_CTX_X19 0x0
+#define SP_C_RT_CTX_X20 0x8
+#define SP_C_RT_CTX_X21 0x10
+#define SP_C_RT_CTX_X22 0x18
+#define SP_C_RT_CTX_X23 0x20
+#define SP_C_RT_CTX_X24 0x28
+#define SP_C_RT_CTX_X25 0x30
+#define SP_C_RT_CTX_X26 0x38
+#define SP_C_RT_CTX_X27 0x40
+#define SP_C_RT_CTX_X28 0x48
+#define SP_C_RT_CTX_X29 0x50
+#define SP_C_RT_CTX_X30 0x58
+
+#define SP_C_RT_CTX_SIZE 0x60
+#define SP_C_RT_CTX_ENTRIES (SP_C_RT_CTX_SIZE >> DWORD_SHIFT)
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+/* Assembly helpers */
+uint64_t spm_secure_partition_enter(uint64_t *c_rt_ctx);
+void __dead2 spm_secure_partition_exit(uint64_t c_rt_ctx, uint64_t ret);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* SPM_COMMON_H */
diff --git a/services/std_svc/spm/common/spm.mk b/services/std_svc/spm/common/spm.mk
new file mode 100644
index 0000000..9aa96be
--- /dev/null
+++ b/services/std_svc/spm/common/spm.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifneq (${ARCH},aarch64)
+ $(error "Error: SPM is only supported on aarch64.")
+endif
+
+INCLUDES += -Iservices/std_svc/spm/common/include
+
+SPM_SOURCES := $(addprefix services/std_svc/spm/common/,\
+ ${ARCH}/spm_helpers.S)
+
+# Let the top-level Makefile know that we intend to include a BL32 image
+NEED_BL32 := yes
diff --git a/services/std_svc/spm/el3_spmc/logical_sp.c b/services/std_svc/spm/el3_spmc/logical_sp.c
new file mode 100644
index 0000000..e080832
--- /dev/null
+++ b/services/std_svc/spm/el3_spmc/logical_sp.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <services/el3_spmc_logical_sp.h>
+#include <services/ffa_svc.h>
+#include "spmc.h"
+
+/*******************************************************************************
+ * Validate any logical partition descriptors before we initialise.
+ * Initialization of said partitions will be taken care of during SPMC boot.
+ ******************************************************************************/
+int el3_sp_desc_validate(void)
+{
+ struct el3_lp_desc *lp_array;
+
+ /*
+ * Assert the number of descriptors is less than maximum allowed.
+ * This constant should be define on a per platform basis.
+ */
+ assert(EL3_LP_DESCS_COUNT <= MAX_EL3_LP_DESCS_COUNT);
+
+ /* Check the array bounds are valid. */
+ assert(EL3_LP_DESCS_END >= EL3_LP_DESCS_START);
+
+ /* If no logical partitions are implemented then simply bail out. */
+ if (EL3_LP_DESCS_COUNT == 0U) {
+ return 0;
+ }
+
+ lp_array = get_el3_lp_array();
+
+ for (unsigned int index = 0; index < EL3_LP_DESCS_COUNT; index++) {
+ struct el3_lp_desc *lp_desc = &lp_array[index];
+
+ /* Validate our logical partition descriptors. */
+ if (lp_desc == NULL) {
+ ERROR("Invalid Logical SP Descriptor\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Ensure the ID follows the convention to indidate it resides
+ * in the secure world.
+ */
+ if (!ffa_is_secure_world_id(lp_desc->sp_id)) {
+ ERROR("Invalid Logical SP ID (0x%x)\n",
+ lp_desc->sp_id);
+ return -EINVAL;
+ }
+
+ /* Ensure we don't conflict with the SPMC partition ID. */
+ if (lp_desc->sp_id == FFA_SPMC_ID) {
+ ERROR("Logical SP ID clashes with SPMC ID(0x%x)\n",
+ lp_desc->sp_id);
+ return -EINVAL;
+ }
+
+ /* Ensure the UUID is not the NULL UUID. */
+ if (lp_desc->uuid[0] == 0 && lp_desc->uuid[1] == 0 &&
+ lp_desc->uuid[2] == 0 && lp_desc->uuid[3] == 0) {
+ ERROR("Invalid UUID for Logical SP (0x%x)\n",
+ lp_desc->sp_id);
+ return -EINVAL;
+ }
+
+ /* Ensure init function callback is registered. */
+ if (lp_desc->init == NULL) {
+ ERROR("Missing init function for Logical SP(0x%x)\n",
+ lp_desc->sp_id);
+ return -EINVAL;
+ }
+
+ /* Ensure that LP only supports receiving direct requests. */
+ if (lp_desc->properties &
+ ~(FFA_PARTITION_DIRECT_REQ_RECV)) {
+ ERROR("Invalid partition properties (0x%x)\n",
+ lp_desc->properties);
+ return -EINVAL;
+ }
+
+ /* Ensure direct request function callback is registered. */
+ if (lp_desc->direct_req == NULL) {
+ ERROR("No Direct Req handler for Logical SP (0x%x)\n",
+ lp_desc->sp_id);
+ return -EINVAL;
+ }
+
+ /* Ensure that all partition IDs are unique. */
+ for (unsigned int inner_idx = index + 1;
+ inner_idx < EL3_LP_DESCS_COUNT; inner_idx++) {
+ if (lp_desc->sp_id == lp_array[inner_idx].sp_id) {
+ ERROR("Duplicate SP ID Detected (0x%x)\n",
+ lp_desc->sp_id);
+ return -EINVAL;
+ }
+ }
+ }
+ return 0;
+}
diff --git a/services/std_svc/spm/el3_spmc/spmc.h b/services/std_svc/spm/el3_spmc/spmc.h
new file mode 100644
index 0000000..0915d0b
--- /dev/null
+++ b/services/std_svc/spm/el3_spmc/spmc.h
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPMC_H
+#define SPMC_H
+
+#include <stdint.h>
+
+#include <lib/psci/psci.h>
+#include <lib/spinlock.h>
+#include <services/el3_spmc_logical_sp.h>
+#include "spm_common.h"
+
+/*
+ * Ranges of FF-A IDs for Normal world and Secure world components. The
+ * convention matches that used by other SPMCs i.e. Hafnium and OP-TEE.
+ */
+#define FFA_NWD_ID_BASE 0x0
+#define FFA_NWD_ID_LIMIT 0x7FFF
+#define FFA_SWD_ID_BASE 0x8000
+#define FFA_SWD_ID_LIMIT SPMD_DIRECT_MSG_ENDPOINT_ID - 1
+#define FFA_SWD_ID_MASK 0x8000
+
+/* ID 0 is reserved for the normal world entity, (Hypervisor or OS Kernel). */
+#define FFA_NWD_ID U(0)
+/* First ID is reserved for the SPMC */
+#define FFA_SPMC_ID U(FFA_SWD_ID_BASE)
+/* SP IDs are allocated after the SPMC ID */
+#define FFA_SP_ID_BASE (FFA_SPMC_ID + 1)
+/* Align with Hafnium implementation */
+#define INV_SP_ID 0x7FFF
+
+/* FF-A warm boot types. */
+#define FFA_WB_TYPE_S2RAM 0
+#define FFA_WB_TYPE_NOTS2RAM 1
+
+/*
+ * Runtime states of an execution context as per the FF-A v1.1 specification.
+ */
+enum sp_runtime_states {
+ RT_STATE_WAITING,
+ RT_STATE_RUNNING,
+ RT_STATE_PREEMPTED,
+ RT_STATE_BLOCKED
+};
+
+/*
+ * Runtime model of an execution context as per the FF-A v1.1 specification. Its
+ * value is valid only if the execution context is not in the waiting state.
+ */
+enum sp_runtime_model {
+ RT_MODEL_DIR_REQ,
+ RT_MODEL_RUN,
+ RT_MODEL_INIT,
+ RT_MODEL_INTR
+};
+
+enum sp_runtime_el {
+ EL1 = 0,
+ S_EL0,
+ S_EL1
+};
+
+enum sp_execution_state {
+ SP_STATE_AARCH64 = 0,
+ SP_STATE_AARCH32
+};
+
+enum mailbox_state {
+ /* There is no message in the mailbox. */
+ MAILBOX_STATE_EMPTY,
+
+ /* There is a message that has been populated in the mailbox. */
+ MAILBOX_STATE_FULL,
+};
+
+struct mailbox {
+ enum mailbox_state state;
+
+ /* RX/TX Buffers. */
+ void *rx_buffer;
+ const void *tx_buffer;
+
+ /* Size of RX/TX Buffer. */
+ uint32_t rxtx_page_count;
+
+ /* Lock access to mailbox. */
+ spinlock_t lock;
+};
+
+/*
+ * Execution context members for an SP. This is a bit like struct
+ * vcpu in a hypervisor.
+ */
+struct sp_exec_ctx {
+ /*
+ * Store the stack address to restore C runtime context from after
+ * returning from a synchronous entry into the SP.
+ */
+ uint64_t c_rt_ctx;
+
+ /* Space to maintain the architectural state of an SP. */
+ cpu_context_t cpu_ctx;
+
+ /* Track the current runtime state of the SP. */
+ enum sp_runtime_states rt_state;
+
+ /* Track the current runtime model of the SP. */
+ enum sp_runtime_model rt_model;
+};
+
+/*
+ * Structure to describe the cumulative properties of an SP.
+ */
+struct secure_partition_desc {
+ /*
+ * Execution contexts allocated to this endpoint. Ideally,
+ * we need as many contexts as there are physical cpus only
+ * for a S-EL1 SP which is MP-pinned.
+ */
+ struct sp_exec_ctx ec[PLATFORM_CORE_COUNT];
+
+ /* ID of the Secure Partition. */
+ uint16_t sp_id;
+
+ /* Runtime EL. */
+ enum sp_runtime_el runtime_el;
+
+ /* Partition UUID. */
+ uint32_t uuid[4];
+
+ /* Partition Properties. */
+ uint32_t properties;
+
+ /* Supported FF-A Version. */
+ uint32_t ffa_version;
+
+ /* Execution State. */
+ enum sp_execution_state execution_state;
+
+ /* Mailbox tracking. */
+ struct mailbox mailbox;
+
+ /* Secondary entrypoint. Only valid for a S-EL1 SP. */
+ uintptr_t secondary_ep;
+};
+
+/*
+ * This define identifies the only SP that will be initialised and participate
+ * in FF-A communication. The implementation leaves the door open for more SPs
+ * to be managed in future but for now it is reasonable to assume that either a
+ * single S-EL0 or a single S-EL1 SP will be supported. This define will be used
+ * to identify which SP descriptor to initialise and manage during SP runtime.
+ */
+#define ACTIVE_SP_DESC_INDEX 0
+
+/*
+ * Structure to describe the cumulative properties of the Hypervisor and
+ * NS-Endpoints.
+ */
+struct ns_endpoint_desc {
+ /*
+ * ID of the NS-Endpoint or Hypervisor.
+ */
+ uint16_t ns_ep_id;
+
+ /*
+ * Mailbox tracking.
+ */
+ struct mailbox mailbox;
+
+ /*
+ * Supported FF-A Version
+ */
+ uint32_t ffa_version;
+};
+
+/* Setup Function for different SP types. */
+void spmc_sp_common_setup(struct secure_partition_desc *sp,
+ entry_point_info_t *ep_info);
+void spmc_el1_sp_setup(struct secure_partition_desc *sp,
+ entry_point_info_t *ep_info);
+void spmc_sp_common_ep_commit(struct secure_partition_desc *sp,
+ entry_point_info_t *ep_info);
+
+/*
+ * Helper function to perform a synchronous entry into a SP.
+ */
+uint64_t spmc_sp_synchronous_entry(struct sp_exec_ctx *ec);
+
+/*
+ * Helper function to obtain the descriptor of the current SP on a physical cpu.
+ */
+struct secure_partition_desc *spmc_get_current_sp_ctx(void);
+
+/*
+ * Helper function to obtain the execution context of an SP on a
+ * physical cpu.
+ */
+struct sp_exec_ctx *spmc_get_sp_ec(struct secure_partition_desc *sp);
+
+/*
+ * Helper function to obtain the index of the execution context of an SP on a
+ * physical cpu.
+ */
+unsigned int get_ec_index(struct secure_partition_desc *sp);
+
+uint64_t spmc_ffa_error_return(void *handle, int error_code);
+
+/*
+ * Ensure a partition ID does not clash and follows the secure world convention.
+ */
+bool is_ffa_secure_id_valid(uint16_t partition_id);
+
+/*
+ * Helper function to obtain the array storing the EL3
+ * Logical Partition descriptors.
+ */
+struct el3_lp_desc *get_el3_lp_array(void);
+
+#endif /* SPMC_H */
diff --git a/services/std_svc/spm/el3_spmc/spmc.mk b/services/std_svc/spm/el3_spmc/spmc.mk
new file mode 100644
index 0000000..8067c74
--- /dev/null
+++ b/services/std_svc/spm/el3_spmc/spmc.mk
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifneq (${ARCH},aarch64)
+ $(error "Error: SPMC is only supported on aarch64.")
+endif
+
+SPMC_SOURCES := $(addprefix services/std_svc/spm/el3_spmc/, \
+ spmc_main.c \
+ spmc_setup.c \
+ logical_sp.c)
+
+# Specify platform specific logical partition implementation.
+SPMC_LP_SOURCES := $(addprefix ${PLAT_DIR}/, \
+ ${PLAT}_el3_spmc_logical_sp.c)
+
+
+SPMC_SOURCES += $(SPMC_LP_SOURCES)
+
+# Let the top-level Makefile know that we intend to include a BL32 image
+NEED_BL32 := yes
diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c
new file mode 100644
index 0000000..35def25
--- /dev/null
+++ b/services/std_svc/spm/el3_spmc/spmc_main.c
@@ -0,0 +1,892 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <bl31/ehf.h>
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <common/runtime_svc.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/smccc.h>
+#include <lib/utils.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <libfdt.h>
+#include <plat/common/platform.h>
+#include <services/el3_spmc_logical_sp.h>
+#include <services/ffa_svc.h>
+#include <services/spmc_svc.h>
+#include <services/spmd_svc.h>
+#include "spmc.h"
+
+#include <platform_def.h>
+
+/*
+ * Allocate a secure partition descriptor to describe each SP in the system that
+ * does not reside at EL3.
+ */
+static struct secure_partition_desc sp_desc[SECURE_PARTITION_COUNT];
+
+/*
+ * Allocate an NS endpoint descriptor to describe each VM and the Hypervisor in
+ * the system that interacts with a SP. It is used to track the Hypervisor
+ * buffer pair, version and ID for now. It could be extended to track VM
+ * properties when the SPMC supports indirect messaging.
+ */
+static struct ns_endpoint_desc ns_ep_desc[NS_PARTITION_COUNT];
+
+/*
+ * Helper function to obtain the array storing the EL3
+ * Logical Partition descriptors.
+ */
+struct el3_lp_desc *get_el3_lp_array(void)
+{
+ return (struct el3_lp_desc *) EL3_LP_DESCS_START;
+}
+
+/*
+ * Helper function to obtain the descriptor of the last SP to whom control was
+ * handed to on this physical cpu. Currently, we assume there is only one SP.
+ * TODO: Expand to track multiple partitions when required.
+ */
+struct secure_partition_desc *spmc_get_current_sp_ctx(void)
+{
+ return &(sp_desc[ACTIVE_SP_DESC_INDEX]);
+}
+
+/*
+ * Helper function to obtain the execution context of an SP on the
+ * current physical cpu.
+ */
+struct sp_exec_ctx *spmc_get_sp_ec(struct secure_partition_desc *sp)
+{
+ return &(sp->ec[get_ec_index(sp)]);
+}
+
+/* Helper function to get pointer to SP context from its ID. */
+struct secure_partition_desc *spmc_get_sp_ctx(uint16_t id)
+{
+ /* Check for SWd Partitions. */
+ for (unsigned int i = 0U; i < SECURE_PARTITION_COUNT; i++) {
+ if (sp_desc[i].sp_id == id) {
+ return &(sp_desc[i]);
+ }
+ }
+ return NULL;
+}
+
+/******************************************************************************
+ * This function returns to the place where spmc_sp_synchronous_entry() was
+ * called originally.
+ ******************************************************************************/
+__dead2 void spmc_sp_synchronous_exit(struct sp_exec_ctx *ec, uint64_t rc)
+{
+ /*
+ * The SPM must have initiated the original request through a
+ * synchronous entry into the secure partition. Jump back to the
+ * original C runtime context with the value of rc in x0;
+ */
+ spm_secure_partition_exit(ec->c_rt_ctx, rc);
+
+ panic();
+}
+
+/*******************************************************************************
+ * Return FFA_ERROR with specified error code.
+ ******************************************************************************/
+uint64_t spmc_ffa_error_return(void *handle, int error_code)
+{
+ SMC_RET8(handle, FFA_ERROR,
+ FFA_TARGET_INFO_MBZ, error_code,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ);
+}
+
+/******************************************************************************
+ * Helper function to validate a secure partition ID to ensure it does not
+ * conflict with any other FF-A component and follows the convention to
+ * indicate it resides within the secure world.
+ ******************************************************************************/
+bool is_ffa_secure_id_valid(uint16_t partition_id)
+{
+ struct el3_lp_desc *el3_lp_descs = get_el3_lp_array();
+
+ /* Ensure the ID is not the invalid partition ID. */
+ if (partition_id == INV_SP_ID) {
+ return false;
+ }
+
+ /* Ensure the ID is not the SPMD ID. */
+ if (partition_id == SPMD_DIRECT_MSG_ENDPOINT_ID) {
+ return false;
+ }
+
+ /*
+ * Ensure the ID follows the convention to indicate it resides
+ * in the secure world.
+ */
+ if (!ffa_is_secure_world_id(partition_id)) {
+ return false;
+ }
+
+ /* Ensure we don't conflict with the SPMC partition ID. */
+ if (partition_id == FFA_SPMC_ID) {
+ return false;
+ }
+
+ /* Ensure we do not already have an SP context with this ID. */
+ if (spmc_get_sp_ctx(partition_id)) {
+ return false;
+ }
+
+ /* Ensure we don't clash with any Logical SP's. */
+ for (unsigned int i = 0U; i < EL3_LP_DESCS_COUNT; i++) {
+ if (el3_lp_descs[i].sp_id == partition_id) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/*******************************************************************************
+ * This function either forwards the request to the other world or returns
+ * with an ERET depending on the source of the call.
+ * We can assume that the destination is for an entity at a lower exception
+ * level as any messages destined for a logical SP resident in EL3 will have
+ * already been taken care of by the SPMC before entering this function.
+ ******************************************************************************/
+static uint64_t spmc_smc_return(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *handle,
+ void *cookie,
+ uint64_t flags,
+ uint16_t dst_id)
+{
+ /* If the destination is in the normal world always go via the SPMD. */
+ if (ffa_is_normal_world_id(dst_id)) {
+ return spmd_smc_handler(smc_fid, x1, x2, x3, x4,
+ cookie, handle, flags);
+ }
+ /*
+ * If the caller is secure and we want to return to the secure world,
+ * ERET directly.
+ */
+ else if (secure_origin && ffa_is_secure_world_id(dst_id)) {
+ SMC_RET5(handle, smc_fid, x1, x2, x3, x4);
+ }
+ /* If we originated in the normal world then switch contexts. */
+ else if (!secure_origin && ffa_is_secure_world_id(dst_id)) {
+ return spmd_smc_switch_state(smc_fid, secure_origin, x1, x2,
+ x3, x4, handle);
+ } else {
+ /* Unknown State. */
+ panic();
+ }
+
+ /* Shouldn't be Reached. */
+ return 0;
+}
+
+/*******************************************************************************
+ * FF-A ABI Handlers.
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Helper function to validate arg2 as part of a direct message.
+ ******************************************************************************/
+static inline bool direct_msg_validate_arg2(uint64_t x2)
+{
+ /*
+ * We currently only support partition messages, therefore ensure x2 is
+ * not set.
+ */
+ if (x2 != (uint64_t) 0) {
+ VERBOSE("Arg2 MBZ for partition messages (0x%lx).\n", x2);
+ return false;
+ }
+ return true;
+}
+
+/*******************************************************************************
+ * Handle direct request messages and route to the appropriate destination.
+ ******************************************************************************/
+static uint64_t direct_req_smc_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ uint16_t dst_id = ffa_endpoint_destination(x1);
+ struct el3_lp_desc *el3_lp_descs;
+ struct secure_partition_desc *sp;
+ unsigned int idx;
+
+ /* Check if arg2 has been populated correctly based on message type. */
+ if (!direct_msg_validate_arg2(x2)) {
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ el3_lp_descs = get_el3_lp_array();
+
+ /* Check if the request is destined for a Logical Partition. */
+ for (unsigned int i = 0U; i < MAX_EL3_LP_DESCS_COUNT; i++) {
+ if (el3_lp_descs[i].sp_id == dst_id) {
+ return el3_lp_descs[i].direct_req(
+ smc_fid, secure_origin, x1, x2, x3, x4,
+ cookie, handle, flags);
+ }
+ }
+
+ /*
+ * If the request was not targeted to a LSP and from the secure world
+ * then it is invalid since a SP cannot call into the Normal world and
+ * there is no other SP to call into. If there are other SPs in future
+ * then the partition runtime model would need to be validated as well.
+ */
+ if (secure_origin) {
+ VERBOSE("Direct request not supported to the Normal World.\n");
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /* Check if the SP ID is valid. */
+ sp = spmc_get_sp_ctx(dst_id);
+ if (sp == NULL) {
+ VERBOSE("Direct request to unknown partition ID (0x%x).\n",
+ dst_id);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /*
+ * Check that the target execution context is in a waiting state before
+ * forwarding the direct request to it.
+ */
+ idx = get_ec_index(sp);
+ if (sp->ec[idx].rt_state != RT_STATE_WAITING) {
+ VERBOSE("SP context on core%u is not waiting (%u).\n",
+ idx, sp->ec[idx].rt_model);
+ return spmc_ffa_error_return(handle, FFA_ERROR_BUSY);
+ }
+
+ /*
+ * Everything checks out so forward the request to the SP after updating
+ * its state and runtime model.
+ */
+ sp->ec[idx].rt_state = RT_STATE_RUNNING;
+ sp->ec[idx].rt_model = RT_MODEL_DIR_REQ;
+ return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4,
+ handle, cookie, flags, dst_id);
+}
+
+/*******************************************************************************
+ * Handle direct response messages and route to the appropriate destination.
+ ******************************************************************************/
+static uint64_t direct_resp_smc_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ uint16_t dst_id = ffa_endpoint_destination(x1);
+ struct secure_partition_desc *sp;
+ unsigned int idx;
+
+ /* Check if arg2 has been populated correctly based on message type. */
+ if (!direct_msg_validate_arg2(x2)) {
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /* Check that the response did not originate from the Normal world. */
+ if (!secure_origin) {
+ VERBOSE("Direct Response not supported from Normal World.\n");
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /*
+ * Check that the response is either targeted to the Normal world or the
+ * SPMC e.g. a PM response.
+ */
+ if ((dst_id != FFA_SPMC_ID) && ffa_is_secure_world_id(dst_id)) {
+ VERBOSE("Direct response to invalid partition ID (0x%x).\n",
+ dst_id);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /* Obtain the SP descriptor and update its runtime state. */
+ sp = spmc_get_sp_ctx(ffa_endpoint_source(x1));
+ if (sp == NULL) {
+ VERBOSE("Direct response to unknown partition ID (0x%x).\n",
+ dst_id);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /* Sanity check state is being tracked correctly in the SPMC. */
+ idx = get_ec_index(sp);
+ assert(sp->ec[idx].rt_state == RT_STATE_RUNNING);
+
+ /* Ensure SP execution context was in the right runtime model. */
+ if (sp->ec[idx].rt_model != RT_MODEL_DIR_REQ) {
+ VERBOSE("SP context on core%u not handling direct req (%u).\n",
+ idx, sp->ec[idx].rt_model);
+ return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+ }
+
+ /* Update the state of the SP execution context. */
+ sp->ec[idx].rt_state = RT_STATE_WAITING;
+
+ /*
+ * If the receiver is not the SPMC then forward the response to the
+ * Normal world.
+ */
+ if (dst_id == FFA_SPMC_ID) {
+ spmc_sp_synchronous_exit(&sp->ec[idx], x4);
+ /* Should not get here. */
+ panic();
+ }
+
+ return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4,
+ handle, cookie, flags, dst_id);
+}
+
+/*******************************************************************************
+ * This function handles the FFA_MSG_WAIT SMC to allow an SP to relinquish its
+ * cycles.
+ ******************************************************************************/
+static uint64_t msg_wait_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ struct secure_partition_desc *sp;
+ unsigned int idx;
+
+ /*
+ * Check that the response did not originate from the Normal world as
+ * only the secure world can call this ABI.
+ */
+ if (!secure_origin) {
+ VERBOSE("Normal world cannot call FFA_MSG_WAIT.\n");
+ return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+ }
+
+ /* Get the descriptor of the SP that invoked FFA_MSG_WAIT. */
+ sp = spmc_get_current_sp_ctx();
+ if (sp == NULL) {
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /*
+ * Get the execution context of the SP that invoked FFA_MSG_WAIT.
+ */
+ idx = get_ec_index(sp);
+
+ /* Ensure SP execution context was in the right runtime model. */
+ if (sp->ec[idx].rt_model == RT_MODEL_DIR_REQ) {
+ return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+ }
+
+ /* Sanity check the state is being tracked correctly in the SPMC. */
+ assert(sp->ec[idx].rt_state == RT_STATE_RUNNING);
+
+ /*
+ * Perform a synchronous exit if the partition was initialising. The
+ * state is updated after the exit.
+ */
+ if (sp->ec[idx].rt_model == RT_MODEL_INIT) {
+ spmc_sp_synchronous_exit(&sp->ec[idx], x4);
+ /* Should not get here */
+ panic();
+ }
+
+ /* Update the state of the SP execution context. */
+ sp->ec[idx].rt_state = RT_STATE_WAITING;
+
+ /* Resume normal world if a secure interrupt was handled. */
+ if (sp->ec[idx].rt_model == RT_MODEL_INTR) {
+ /* FFA_MSG_WAIT can only be called from the secure world. */
+ unsigned int secure_state_in = SECURE;
+ unsigned int secure_state_out = NON_SECURE;
+
+ cm_el1_sysregs_context_save(secure_state_in);
+ cm_el1_sysregs_context_restore(secure_state_out);
+ cm_set_next_eret_context(secure_state_out);
+ SMC_RET0(cm_get_context(secure_state_out));
+ }
+
+ /* Forward the response to the Normal world. */
+ return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4,
+ handle, cookie, flags, FFA_NWD_ID);
+}
+
+static uint64_t ffa_error_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ struct secure_partition_desc *sp;
+ unsigned int idx;
+
+ /* Check that the response did not originate from the Normal world. */
+ if (!secure_origin) {
+ return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+ }
+
+ /* Get the descriptor of the SP that invoked FFA_ERROR. */
+ sp = spmc_get_current_sp_ctx();
+ if (sp == NULL) {
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /* Get the execution context of the SP that invoked FFA_ERROR. */
+ idx = get_ec_index(sp);
+
+ /*
+ * We only expect FFA_ERROR to be received during SP initialisation
+ * otherwise this is an invalid call.
+ */
+ if (sp->ec[idx].rt_model == RT_MODEL_INIT) {
+ ERROR("SP 0x%x failed to initialize.\n", sp->sp_id);
+ spmc_sp_synchronous_exit(&sp->ec[idx], x2);
+ /* Should not get here. */
+ panic();
+ }
+
+ return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+}
+
+/*******************************************************************************
+ * This function will parse the Secure Partition Manifest. From manifest, it
+ * will fetch details for preparing Secure partition image context and secure
+ * partition image boot arguments if any.
+ ******************************************************************************/
+static int sp_manifest_parse(void *sp_manifest, int offset,
+ struct secure_partition_desc *sp,
+ entry_point_info_t *ep_info)
+{
+ int32_t ret, node;
+ uint32_t config_32;
+
+ /*
+ * Look for the mandatory fields that are expected to be present in
+ * the SP manifests.
+ */
+ node = fdt_path_offset(sp_manifest, "/");
+ if (node < 0) {
+ ERROR("Did not find root node.\n");
+ return node;
+ }
+
+ ret = fdt_read_uint32_array(sp_manifest, node, "uuid",
+ ARRAY_SIZE(sp->uuid), sp->uuid);
+ if (ret != 0) {
+ ERROR("Missing Secure Partition UUID.\n");
+ return ret;
+ }
+
+ ret = fdt_read_uint32(sp_manifest, node, "exception-level", &config_32);
+ if (ret != 0) {
+ ERROR("Missing SP Exception Level information.\n");
+ return ret;
+ }
+
+ sp->runtime_el = config_32;
+
+ ret = fdt_read_uint32(sp_manifest, node, "ffa-version", &config_32);
+ if (ret != 0) {
+ ERROR("Missing Secure Partition FF-A Version.\n");
+ return ret;
+ }
+
+ sp->ffa_version = config_32;
+
+ ret = fdt_read_uint32(sp_manifest, node, "execution-state", &config_32);
+ if (ret != 0) {
+ ERROR("Missing Secure Partition Execution State.\n");
+ return ret;
+ }
+
+ sp->execution_state = config_32;
+
+ ret = fdt_read_uint32(sp_manifest, node,
+ "execution-ctx-count", &config_32);
+
+ if (ret != 0) {
+ ERROR("Missing SP Execution Context Count.\n");
+ return ret;
+ }
+
+ /*
+ * Ensure this field is set correctly in the manifest however
+ * since this is currently a hardcoded value for S-EL1 partitions
+ * we don't need to save it here, just validate.
+ */
+ if (config_32 != PLATFORM_CORE_COUNT) {
+ ERROR("SP Execution Context Count (%u) must be %u.\n",
+ config_32, PLATFORM_CORE_COUNT);
+ return -EINVAL;
+ }
+
+ /*
+ * Look for the optional fields that are expected to be present in
+ * an SP manifest.
+ */
+ ret = fdt_read_uint32(sp_manifest, node, "id", &config_32);
+ if (ret != 0) {
+ WARN("Missing Secure Partition ID.\n");
+ } else {
+ if (!is_ffa_secure_id_valid(config_32)) {
+ ERROR("Invalid Secure Partition ID (0x%x).\n",
+ config_32);
+ return -EINVAL;
+ }
+ sp->sp_id = config_32;
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * This function gets the Secure Partition Manifest base and maps the manifest
+ * region.
+ * Currently only one Secure Partition manifest is considered which is used to
+ * prepare the context for the single Secure Partition.
+ ******************************************************************************/
+static int find_and_prepare_sp_context(void)
+{
+ void *sp_manifest;
+ uintptr_t manifest_base;
+ uintptr_t manifest_base_align;
+ entry_point_info_t *next_image_ep_info;
+ int32_t ret;
+ struct secure_partition_desc *sp;
+
+ next_image_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
+ if (next_image_ep_info == NULL) {
+ WARN("No Secure Partition image provided by BL2.\n");
+ return -ENOENT;
+ }
+
+ sp_manifest = (void *)next_image_ep_info->args.arg0;
+ if (sp_manifest == NULL) {
+ WARN("Secure Partition manifest absent.\n");
+ return -ENOENT;
+ }
+
+ manifest_base = (uintptr_t)sp_manifest;
+ manifest_base_align = page_align(manifest_base, DOWN);
+
+ /*
+ * Map the secure partition manifest region in the EL3 translation
+ * regime.
+ * Map an area equal to (2 * PAGE_SIZE) for now. During manifest base
+ * alignment the region of 1 PAGE_SIZE from manifest align base may
+ * not completely accommodate the secure partition manifest region.
+ */
+ ret = mmap_add_dynamic_region((unsigned long long)manifest_base_align,
+ manifest_base_align,
+ PAGE_SIZE * 2,
+ MT_RO_DATA);
+ if (ret != 0) {
+ ERROR("Error while mapping SP manifest (%d).\n", ret);
+ return ret;
+ }
+
+ ret = fdt_node_offset_by_compatible(sp_manifest, -1,
+ "arm,ffa-manifest-1.0");
+ if (ret < 0) {
+ ERROR("Error happened in SP manifest reading.\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Store the size of the manifest so that it can be used later to pass
+ * the manifest as boot information later.
+ */
+ next_image_ep_info->args.arg1 = fdt_totalsize(sp_manifest);
+ INFO("Manifest size = %lu bytes.\n", next_image_ep_info->args.arg1);
+
+ /*
+ * Select an SP descriptor for initialising the partition's execution
+ * context on the primary CPU.
+ */
+ sp = spmc_get_current_sp_ctx();
+
+ /* Initialize entry point information for the SP */
+ SET_PARAM_HEAD(next_image_ep_info, PARAM_EP, VERSION_1,
+ SECURE | EP_ST_ENABLE);
+
+ /* Parse the SP manifest. */
+ ret = sp_manifest_parse(sp_manifest, ret, sp, next_image_ep_info);
+ if (ret != 0) {
+ ERROR("Error in Secure Partition manifest parsing.\n");
+ return ret;
+ }
+
+ /* Check that the runtime EL in the manifest was correct. */
+ if (sp->runtime_el != S_EL1) {
+ ERROR("Unexpected runtime EL: %d\n", sp->runtime_el);
+ return -EINVAL;
+ }
+
+ /* Perform any common initialisation. */
+ spmc_sp_common_setup(sp, next_image_ep_info);
+
+ /* Perform any initialisation specific to S-EL1 SPs. */
+ spmc_el1_sp_setup(sp, next_image_ep_info);
+
+ /* Initialize the SP context with the required ep info. */
+ spmc_sp_common_ep_commit(sp, next_image_ep_info);
+
+ return 0;
+}
+
+/*******************************************************************************
+ * This function takes an SP context pointer and performs a synchronous entry
+ * into it.
+ ******************************************************************************/
+static int32_t logical_sp_init(void)
+{
+ int32_t rc = 0;
+ struct el3_lp_desc *el3_lp_descs;
+
+ /* Perform initial validation of the Logical Partitions. */
+ rc = el3_sp_desc_validate();
+ if (rc != 0) {
+ ERROR("Logical Partition validation failed!\n");
+ return rc;
+ }
+
+ el3_lp_descs = get_el3_lp_array();
+
+ INFO("Logical Secure Partition init start.\n");
+ for (unsigned int i = 0U; i < EL3_LP_DESCS_COUNT; i++) {
+ rc = el3_lp_descs[i].init();
+ if (rc != 0) {
+ ERROR("Logical SP (0x%x) Failed to Initialize\n",
+ el3_lp_descs[i].sp_id);
+ return rc;
+ }
+ VERBOSE("Logical SP (0x%x) Initialized\n",
+ el3_lp_descs[i].sp_id);
+ }
+
+ INFO("Logical Secure Partition init completed.\n");
+
+ return rc;
+}
+
+uint64_t spmc_sp_synchronous_entry(struct sp_exec_ctx *ec)
+{
+ uint64_t rc;
+
+ assert(ec != NULL);
+
+ /* Assign the context of the SP to this CPU */
+ cm_set_context(&(ec->cpu_ctx), SECURE);
+
+ /* Restore the context assigned above */
+ cm_el1_sysregs_context_restore(SECURE);
+ cm_set_next_eret_context(SECURE);
+
+ /* Invalidate TLBs at EL1. */
+ tlbivmalle1();
+ dsbish();
+
+ /* Enter Secure Partition */
+ rc = spm_secure_partition_enter(&ec->c_rt_ctx);
+
+ /* Save secure state */
+ cm_el1_sysregs_context_save(SECURE);
+
+ return rc;
+}
+
+/*******************************************************************************
+ * SPMC Helper Functions.
+ ******************************************************************************/
+static int32_t sp_init(void)
+{
+ uint64_t rc;
+ struct secure_partition_desc *sp;
+ struct sp_exec_ctx *ec;
+
+ sp = spmc_get_current_sp_ctx();
+ ec = spmc_get_sp_ec(sp);
+ ec->rt_model = RT_MODEL_INIT;
+ ec->rt_state = RT_STATE_RUNNING;
+
+ INFO("Secure Partition (0x%x) init start.\n", sp->sp_id);
+
+ rc = spmc_sp_synchronous_entry(ec);
+ if (rc != 0) {
+ /* Indicate SP init was not successful. */
+ ERROR("SP (0x%x) failed to initialize (%lu).\n",
+ sp->sp_id, rc);
+ return 0;
+ }
+
+ ec->rt_state = RT_STATE_WAITING;
+ INFO("Secure Partition initialized.\n");
+
+ return 1;
+}
+
+static void initalize_sp_descs(void)
+{
+ struct secure_partition_desc *sp;
+
+ for (unsigned int i = 0U; i < SECURE_PARTITION_COUNT; i++) {
+ sp = &sp_desc[i];
+ sp->sp_id = INV_SP_ID;
+ sp->mailbox.rx_buffer = NULL;
+ sp->mailbox.tx_buffer = NULL;
+ sp->mailbox.state = MAILBOX_STATE_EMPTY;
+ sp->secondary_ep = 0;
+ }
+}
+
+static void initalize_ns_ep_descs(void)
+{
+ struct ns_endpoint_desc *ns_ep;
+
+ for (unsigned int i = 0U; i < NS_PARTITION_COUNT; i++) {
+ ns_ep = &ns_ep_desc[i];
+ /*
+ * Clashes with the Hypervisor ID but will not be a
+ * problem in practice.
+ */
+ ns_ep->ns_ep_id = 0;
+ ns_ep->ffa_version = 0;
+ ns_ep->mailbox.rx_buffer = NULL;
+ ns_ep->mailbox.tx_buffer = NULL;
+ ns_ep->mailbox.state = MAILBOX_STATE_EMPTY;
+ }
+}
+
+/*******************************************************************************
+ * Initialize SPMC attributes for the SPMD.
+ ******************************************************************************/
+void spmc_populate_attrs(spmc_manifest_attribute_t *spmc_attrs)
+{
+ spmc_attrs->major_version = FFA_VERSION_MAJOR;
+ spmc_attrs->minor_version = FFA_VERSION_MINOR;
+ spmc_attrs->exec_state = MODE_RW_64;
+ spmc_attrs->spmc_id = FFA_SPMC_ID;
+}
+
+/*******************************************************************************
+ * Initialize contexts of all Secure Partitions.
+ ******************************************************************************/
+int32_t spmc_setup(void)
+{
+ int32_t ret;
+
+ /* Initialize endpoint descriptors */
+ initalize_sp_descs();
+ initalize_ns_ep_descs();
+
+ /* Setup logical SPs. */
+ ret = logical_sp_init();
+ if (ret != 0) {
+ ERROR("Failed to initialize Logical Partitions.\n");
+ return ret;
+ }
+
+ /* Perform physical SP setup. */
+
+ /* Disable MMU at EL1 (initialized by BL2) */
+ disable_mmu_icache_el1();
+
+ /* Initialize context of the SP */
+ INFO("Secure Partition context setup start.\n");
+
+ ret = find_and_prepare_sp_context();
+ if (ret != 0) {
+ ERROR("Error in SP finding and context preparation.\n");
+ return ret;
+ }
+
+ /* Register init function for deferred init. */
+ bl31_register_bl32_init(&sp_init);
+
+ INFO("Secure Partition setup done.\n");
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Secure Partition Manager SMC handler.
+ ******************************************************************************/
+uint64_t spmc_smc_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ switch (smc_fid) {
+
+ case FFA_MSG_SEND_DIRECT_REQ_SMC32:
+ case FFA_MSG_SEND_DIRECT_REQ_SMC64:
+ return direct_req_smc_handler(smc_fid, secure_origin, x1, x2,
+ x3, x4, cookie, handle, flags);
+
+ case FFA_MSG_SEND_DIRECT_RESP_SMC32:
+ case FFA_MSG_SEND_DIRECT_RESP_SMC64:
+ return direct_resp_smc_handler(smc_fid, secure_origin, x1, x2,
+ x3, x4, cookie, handle, flags);
+
+ case FFA_MSG_WAIT:
+ return msg_wait_handler(smc_fid, secure_origin, x1, x2, x3, x4,
+ cookie, handle, flags);
+
+ case FFA_ERROR:
+ return ffa_error_handler(smc_fid, secure_origin, x1, x2, x3, x4,
+ cookie, handle, flags);
+
+ default:
+ WARN("Unsupported FF-A call 0x%08x.\n", smc_fid);
+ break;
+ }
+ return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+}
diff --git a/services/std_svc/spm/el3_spmc/spmc_setup.c b/services/std_svc/spm/el3_spmc/spmc_setup.c
new file mode 100644
index 0000000..7b23c9e
--- /dev/null
+++ b/services/std_svc/spm/el3_spmc/spmc_setup.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <context.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/utils.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/common_def.h>
+#include <plat/common/platform.h>
+#include <services/ffa_svc.h>
+#include "spm_common.h"
+#include "spmc.h"
+
+#include <platform_def.h>
+
+/*
+ * We are assuming that the index of the execution
+ * context used is the linear index of the current physical cpu.
+ */
+unsigned int get_ec_index(struct secure_partition_desc *sp)
+{
+ return plat_my_core_pos();
+}
+
+/* S-EL1 partition specific initialisation. */
+void spmc_el1_sp_setup(struct secure_partition_desc *sp,
+ entry_point_info_t *ep_info)
+{
+ /* Sanity check input arguments. */
+ assert(sp != NULL);
+ assert(ep_info != NULL);
+
+ /* Initialise the SPSR for S-EL1 SPs. */
+ ep_info->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS);
+
+ /*
+ * Check whether setup is being performed for the primary or a secondary
+ * execution context. In the latter case, indicate to the SP that this
+ * is a warm boot.
+ * TODO: This check would need to be reworked if the same entry point is
+ * used for both primary and secondary initialisation.
+ */
+ if (sp->secondary_ep != 0U) {
+ /*
+ * Sanity check that the secondary entry point is still what was
+ * originally set.
+ */
+ assert(sp->secondary_ep == ep_info->pc);
+ ep_info->args.arg0 = FFA_WB_TYPE_S2RAM;
+ }
+}
+
+/* Common initialisation for all SPs. */
+void spmc_sp_common_setup(struct secure_partition_desc *sp,
+ entry_point_info_t *ep_info)
+{
+ uint16_t sp_id;
+
+ /* Assign FF-A Partition ID if not already assigned. */
+ if (sp->sp_id == INV_SP_ID) {
+ sp_id = FFA_SP_ID_BASE + ACTIVE_SP_DESC_INDEX;
+ /*
+ * Ensure we don't clash with previously assigned partition
+ * IDs.
+ */
+ while (!is_ffa_secure_id_valid(sp_id)) {
+ sp_id++;
+
+ if (sp_id == FFA_SWD_ID_LIMIT) {
+ ERROR("Unable to determine valid SP ID.\n");
+ panic();
+ }
+ }
+ sp->sp_id = sp_id;
+ }
+
+ /*
+ * We currently only support S-EL1 partitions so ensure this is the
+ * case.
+ */
+ assert(sp->runtime_el == S_EL1);
+
+ /*
+ * Clear the general purpose registers. These should be populated as
+ * required.
+ */
+ zeromem(&ep_info->args, sizeof(ep_info->args));
+}
+
+/*
+ * Initialise the SP context now we have populated the common and EL specific
+ * entrypoint information.
+ */
+void spmc_sp_common_ep_commit(struct secure_partition_desc *sp,
+ entry_point_info_t *ep_info)
+{
+ cpu_context_t *cpu_ctx;
+
+ cpu_ctx = &(spmc_get_sp_ec(sp)->cpu_ctx);
+ print_entry_point_info(ep_info);
+ cm_setup_context(cpu_ctx, ep_info);
+}
diff --git a/services/std_svc/spm_mm/aarch64/spm_mm_shim_exceptions.S b/services/std_svc/spm/spm_mm/aarch64/spm_mm_shim_exceptions.S
similarity index 97%
rename from services/std_svc/spm_mm/aarch64/spm_mm_shim_exceptions.S
rename to services/std_svc/spm/spm_mm/aarch64/spm_mm_shim_exceptions.S
index be4084c..836f75c 100644
--- a/services/std_svc/spm_mm/aarch64/spm_mm_shim_exceptions.S
+++ b/services/std_svc/spm/spm_mm/aarch64/spm_mm_shim_exceptions.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/services/std_svc/spm_mm/spm_mm.mk b/services/std_svc/spm/spm_mm/spm_mm.mk
similarity index 78%
rename from services/std_svc/spm_mm/spm_mm.mk
rename to services/std_svc/spm/spm_mm/spm_mm.mk
index a87bdd8..78ef0c9 100644
--- a/services/std_svc/spm_mm/spm_mm.mk
+++ b/services/std_svc/spm/spm_mm/spm_mm.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -17,11 +17,10 @@
$(error "Error: SPM_MM is not compatible with ENABLE_SME_FOR_NS")
endif
-SPM_SOURCES := $(addprefix services/std_svc/spm_mm/, \
- ${ARCH}/spm_mm_helpers.S \
+SPM_MM_SOURCES := $(addprefix services/std_svc/spm/spm_mm/, \
${ARCH}/spm_mm_shim_exceptions.S \
- spm_mm_main.c \
- spm_mm_setup.c \
+ spm_mm_main.c \
+ spm_mm_setup.c \
spm_mm_xlat.c)
diff --git a/services/std_svc/spm_mm/spm_mm_main.c b/services/std_svc/spm/spm_mm/spm_mm_main.c
similarity index 98%
rename from services/std_svc/spm_mm/spm_mm_main.c
rename to services/std_svc/spm/spm_mm/spm_mm_main.c
index 14c0038..e71e65b 100644
--- a/services/std_svc/spm_mm/spm_mm_main.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -22,6 +22,7 @@
#include <services/spm_mm_svc.h>
#include <smccc_helpers.h>
+#include "spm_common.h"
#include "spm_mm_private.h"
/*******************************************************************************
diff --git a/services/std_svc/spm_mm/spm_mm_private.h b/services/std_svc/spm/spm_mm/spm_mm_private.h
similarity index 88%
rename from services/std_svc/spm_mm/spm_mm_private.h
rename to services/std_svc/spm/spm_mm/spm_mm_private.h
index 45b4789..0eff1c0 100644
--- a/services/std_svc/spm_mm/spm_mm_private.h
+++ b/services/std_svc/spm/spm_mm/spm_mm_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,6 +8,7 @@
#define SPM_MM_PRIVATE_H
#include <context.h>
+#include "spm_common.h"
/*******************************************************************************
* Constants that allow assembler code to preserve callee-saved registers of the
@@ -51,9 +52,6 @@
spinlock_t state_lock;
} sp_context_t;
-/* Assembly helpers */
-uint64_t spm_secure_partition_enter(uint64_t *c_rt_ctx);
-void __dead2 spm_secure_partition_exit(uint64_t c_rt_ctx, uint64_t ret);
void spm_sp_setup(sp_context_t *sp_ctx);
diff --git a/services/std_svc/spm_mm/spm_mm_setup.c b/services/std_svc/spm/spm_mm/spm_mm_setup.c
similarity index 98%
rename from services/std_svc/spm_mm/spm_mm_setup.c
rename to services/std_svc/spm/spm_mm/spm_mm_setup.c
index 9d681c2..04dc212 100644
--- a/services/std_svc/spm_mm/spm_mm_setup.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -19,6 +19,7 @@
#include <plat/common/platform.h>
#include <services/spm_mm_partition.h>
+#include "spm_common.h"
#include "spm_mm_private.h"
#include "spm_mm_shim_private.h"
diff --git a/services/std_svc/spm_mm/spm_mm_shim_private.h b/services/std_svc/spm/spm_mm/spm_mm_shim_private.h
similarity index 90%
rename from services/std_svc/spm_mm/spm_mm_shim_private.h
rename to services/std_svc/spm/spm_mm/spm_mm_shim_private.h
index 0c8d894..f69c748 100644
--- a/services/std_svc/spm_mm/spm_mm_shim_private.h
+++ b/services/std_svc/spm/spm_mm/spm_mm_shim_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/services/std_svc/spm_mm/spm_mm_xlat.c b/services/std_svc/spm/spm_mm/spm_mm_xlat.c
similarity index 98%
rename from services/std_svc/spm_mm/spm_mm_xlat.c
rename to services/std_svc/spm/spm_mm/spm_mm_xlat.c
index eae597c..6261016 100644
--- a/services/std_svc/spm_mm/spm_mm_xlat.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_xlat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 27a8382..5b131cd 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -24,6 +24,7 @@
#include <plat/common/platform.h>
#include <platform_def.h>
#include <services/ffa_svc.h>
+#include <services/spmc_svc.h>
#include <services/spmd_svc.h>
#include <smccc_helpers.h>
#include "spmd_private.h"
@@ -34,7 +35,8 @@
static spmd_spm_core_context_t spm_core_context[PLATFORM_CORE_COUNT];
/*******************************************************************************
- * SPM Core attribute information read from its manifest.
+ * SPM Core attribute information is read from its manifest if the SPMC is not
+ * at EL3. Else, it is populated from the SPMC directly.
******************************************************************************/
static spmc_manifest_attribute_t spmc_attrs;
@@ -88,7 +90,9 @@
uint64_t x2,
uint64_t x3,
uint64_t x4,
- void *handle);
+ void *cookie,
+ void *handle,
+ uint64_t flags);
/******************************************************************************
* Builds an SPMD to SPMC direct message request.
@@ -385,8 +389,23 @@
******************************************************************************/
int spmd_setup(void)
{
- void *spmc_manifest;
int rc;
+ void *spmc_manifest;
+
+ /*
+ * If the SPMC is at EL3, then just initialise it directly. The
+ * shenanigans of when it is at a lower EL are not needed.
+ */
+ if (is_spmc_at_el3()) {
+ /* Allow the SPMC to populate its attributes directly. */
+ spmc_populate_attrs(&spmc_attrs);
+
+ rc = spmc_setup();
+ if (rc != 0) {
+ ERROR("SPMC initialisation failed 0x%x.\n", rc);
+ }
+ return rc;
+ }
spmc_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
if (spmc_ep_info == NULL) {
@@ -417,15 +436,15 @@
}
/*******************************************************************************
- * Forward SMC to the other security state
+ * Forward FF-A SMCs to the other security state.
******************************************************************************/
-static uint64_t spmd_smc_forward(uint32_t smc_fid,
- bool secure_origin,
- uint64_t x1,
- uint64_t x2,
- uint64_t x3,
- uint64_t x4,
- void *handle)
+uint64_t spmd_smc_switch_state(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *handle)
{
unsigned int secure_state_in = (secure_origin) ? SECURE : NON_SECURE;
unsigned int secure_state_out = (!secure_origin) ? SECURE : NON_SECURE;
@@ -458,6 +477,28 @@
}
/*******************************************************************************
+ * Forward SMCs to the other security state.
+ ******************************************************************************/
+static uint64_t spmd_smc_forward(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ if (is_spmc_at_el3() && !secure_origin) {
+ return spmc_smc_handler(smc_fid, secure_origin, x1, x2, x3, x4,
+ cookie, handle, flags);
+ }
+ return spmd_smc_switch_state(smc_fid, secure_origin, x1, x2, x3, x4,
+ handle);
+
+}
+
+/*******************************************************************************
* Return FFA_ERROR with specified error code
******************************************************************************/
static uint64_t spmd_ffa_error_return(void *handle, int error_code)
@@ -484,6 +525,10 @@
*****************************************************************************/
static bool spmd_is_spmc_message(unsigned int ep)
{
+ if (is_spmc_at_el3()) {
+ return false;
+ }
+
return ((ffa_endpoint_destination(ep) == SPMD_DIRECT_MSG_ENDPOINT_ID)
&& (ffa_endpoint_source(ep) == spmc_attrs.spmc_id));
}
@@ -502,6 +547,35 @@
}
/*******************************************************************************
+ * This function forwards FF-A SMCs to either the main SPMD handler or the
+ * SPMC at EL3, depending on the origin security state, if enabled.
+ ******************************************************************************/
+uint64_t spmd_ffa_smc_handler(uint32_t smc_fid,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ if (is_spmc_at_el3()) {
+ /*
+ * If we have an SPMC at EL3 allow handling of the SMC first.
+ * The SPMC will call back through to SPMD handler if required.
+ */
+ if (is_caller_secure(flags)) {
+ return spmc_smc_handler(smc_fid,
+ is_caller_secure(flags),
+ x1, x2, x3, x4, cookie,
+ handle, flags);
+ }
+ }
+ return spmd_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+ handle, flags);
+}
+
+/*******************************************************************************
* This function handles all SMCs in the range reserved for FFA. Each call is
* either forwarded to the other security state or handled by the SPM dispatcher
******************************************************************************/
@@ -542,7 +616,8 @@
}
return spmd_smc_forward(smc_fid, secure_origin,
- x1, x2, x3, x4, handle);
+ x1, x2, x3, x4, cookie,
+ handle, flags);
break; /* not reached */
case FFA_VERSION:
@@ -553,9 +628,11 @@
* If caller is non secure and SPMC was initialized,
* return SPMC's version.
* Sanity check to "input_version".
+ * If the EL3 SPMC is enabled, ignore the SPMC state as
+ * this is not used.
*/
if ((input_version & FFA_VERSION_BIT31_MASK) ||
- (ctx->state == SPMC_STATE_RESET)) {
+ (!is_spmc_at_el3() && (ctx->state == SPMC_STATE_RESET))) {
ret = FFA_ERROR_NOT_SUPPORTED;
} else if (!secure_origin) {
gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx);
@@ -610,7 +687,8 @@
*/
return spmd_smc_forward(ret, true, FFA_PARAM_MBZ,
FFA_PARAM_MBZ, FFA_PARAM_MBZ,
- FFA_PARAM_MBZ, gpregs);
+ FFA_PARAM_MBZ, cookie, gpregs,
+ flags);
} else {
ret = MAKE_FFA_VERSION(FFA_VERSION_MAJOR,
FFA_VERSION_MINOR);
@@ -630,7 +708,8 @@
/* Forward SMC from Normal world to the SPM Core */
if (!secure_origin) {
return spmd_smc_forward(smc_fid, secure_origin,
- x1, x2, x3, x4, handle);
+ x1, x2, x3, x4, cookie,
+ handle, flags);
}
/*
@@ -726,7 +805,8 @@
} else {
/* Forward direct message to the other world */
return spmd_smc_forward(smc_fid, secure_origin,
- x1, x2, x3, x4, handle);
+ x1, x2, x3, x4, cookie,
+ handle, flags);
}
break; /* Not reached */
@@ -736,7 +816,8 @@
} else {
/* Forward direct message to the other world */
return spmd_smc_forward(smc_fid, secure_origin,
- x1, x2, x3, x4, handle);
+ x1, x2, x3, x4, cookie,
+ handle, flags);
}
break; /* Not reached */
@@ -755,6 +836,7 @@
case FFA_NOTIFICATION_INFO_GET:
case FFA_NOTIFICATION_INFO_GET_SMC64:
case FFA_MSG_SEND2:
+ case FFA_RX_ACQUIRE:
#endif
case FFA_MSG_RUN:
/*
@@ -791,7 +873,8 @@
*/
return spmd_smc_forward(smc_fid, secure_origin,
- x1, x2, x3, x4, handle);
+ x1, x2, x3, x4, cookie,
+ handle, flags);
break; /* not reached */
case FFA_MSG_WAIT:
@@ -814,7 +897,8 @@
}
return spmd_smc_forward(smc_fid, secure_origin,
- x1, x2, x3, x4, handle);
+ x1, x2, x3, x4, cookie,
+ handle, flags);
break; /* not reached */
case FFA_NORMAL_WORLD_RESUME:
diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h
index 4cd6a74..4c298c9 100644
--- a/services/std_svc/spmd/spmd_private.h
+++ b/services/std_svc/spmd/spmd_private.h
@@ -58,12 +58,6 @@
*/
#define FFA_NS_ENDPOINT_ID U(0)
-/* Mask and shift to check valid secure FF-A Endpoint ID. */
-#define SPMC_SECURE_ID_MASK U(1)
-#define SPMC_SECURE_ID_SHIFT U(15)
-
-#define SPMD_DIRECT_MSG_ENDPOINT_ID U(FFA_ENDPOINT_ID_MAX - 1)
-
/* Define SPMD target function IDs for framework messages to the SPMC */
#define SPMD_FWK_MSG_BIT BIT(31)
#define SPMD_FWK_MSG_PSCI U(0)
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index bfe26ca..b1e3db9 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -17,6 +17,7 @@
#include <services/rmmd_svc.h>
#include <services/sdei.h>
#include <services/spm_mm_svc.h>
+#include <services/spmc_svc.h>
#include <services/spmd_svc.h>
#include <services/std_svc.h>
#include <services/trng_svc.h>
@@ -147,8 +148,8 @@
* dispatcher and return its return value
*/
if (is_ffa_fid(smc_fid)) {
- return spmd_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
- handle, flags);
+ return spmd_ffa_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+ handle, flags);
}
#endif
diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py
old mode 100755
new mode 100644
index 82d5c1b..f4045d3
--- a/tools/sptool/sp_mk_generator.py
+++ b/tools/sptool/sp_mk_generator.py
@@ -46,112 +46,187 @@
}
"""
-
-import getopt
import json
import os
import re
import sys
import uuid
+from spactions import SpSetupActions
-with open(sys.argv[2],'r') as in_file:
- data = json.load(in_file)
-json_file = os.path.abspath(sys.argv[2])
-json_dir = os.path.dirname(json_file)
-gen_file = os.path.abspath(sys.argv[1])
-out_dir = os.path.abspath(sys.argv[3])
-dtb_dir = out_dir + "/fdts/"
MAX_SP = 8
-dualroot = sys.argv[4].lower() == "dualroot"
-split = int(MAX_SP / 2)
-print(dtb_dir)
-platform_count = 1
-sip_count = 1
+UUID_LEN = 4
-with open(gen_file, 'w') as out_file:
- for idx, key in enumerate(data.keys()):
+# Some helper functions to access args propagated to the action functions in
+# SpSetupActions framework.
+def check_sp_mk_gen(args :dict):
+ if "sp_gen_mk" not in args.keys():
+ raise Exception(f"Path to file sp_gen.mk needs to be in 'args'.")
- pkg_num = idx + 1
+def check_out_dir(args :dict):
+ if "out_dir" not in args.keys() or not os.path.isdir(args["out_dir"]):
+ raise Exception("Define output folder with \'out_dir\' key.")
- if (pkg_num > MAX_SP):
- print("WARNING: Too many secure partitions\n")
- exit(-1)
+def check_sp_layout_dir(args :dict):
+ if "sp_layout_dir" not in args.keys() or not os.path.isdir(args["sp_layout_dir"]):
+ raise Exception("Define output folder with \'sp_layout_dir\' key.")
- if dualroot:
- owner = data[key].get('owner')
- if owner == "Plat":
- if (platform_count > split):
- print("WARNING: Maximum Secure partitions by Plat " +
- "have been exceeded (" + str(split) + ")\n")
- exit(-1)
- pkg_num = split + platform_count
- platform_count += 1
- elif (sip_count > split):
- print("WARNING: Maximum Secure partitions by SiP " +
- "have been exceeded (" + str(split) + ")\n")
- exit(-1)
- else:
- pkg_num = sip_count
- sip_count += 1
+def write_to_sp_mk_gen(content, args :dict):
+ check_sp_mk_gen(args)
+ with open(args["sp_gen_mk"], "a") as f:
+ f.write(f"{content}\n")
- """
- Append FDT_SOURCES
- """
- dts = os.path.join(json_dir, data[key]['pm'])
- dtb = dtb_dir + os.path.basename(data[key]['pm'][:-1] + "b")
- out_file.write("FDT_SOURCES += " + dts + "\n")
+def get_sp_manifest_full_path(sp_node, args :dict):
+ check_sp_layout_dir(args)
+ return os.path.join(args["sp_layout_dir"], get_file_from_layout(sp_node["pm"]))
- """
- Update SPTOOL_ARGS
- """
- dst = out_dir + "/" + key + ".pkg"
- src = [ json_dir + "/" + data[key]['image'] , dtb ]
- out_file.write("SPTOOL_ARGS += -i " + ":".join(src) + " -o " + dst + "\n")
+def get_sp_img_full_path(sp_node, args :dict):
+ check_sp_layout_dir(args)
+ return os.path.join(args["sp_layout_dir"], get_file_from_layout(sp_node["image"]))
- if "uuid" in data[key]:
- """
- Extract the UUID from the JSON file if the SP entry has a 'uuid' field
- """
- uuid_std = uuid.UUID(data[key]['uuid'])
- else:
- """
- Extract uuid from partition manifest
- """
- pm_file = open(dts)
- for line in pm_file:
- if "uuid" in line:
- # re.findall returns a list of string tuples.
- # uuid_hex is the first item in this list representing the four
- # uuid hex integers from the manifest uuid field. The heading
- # '0x' of the hexadecimal representation is stripped out.
- # e.g. uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>;
- # uuid_hex = ('1e67b5b4', 'e14f904a', '13fb1fb8', 'cbdae1da')
- uuid_hex = re.findall(r'0x([0-9a-f]+) 0x([0-9a-f]+) 0x([0-9a-f]+) 0x([0-9a-f]+)', line)[0];
+def get_sp_pkg(sp, args :dict):
+ check_out_dir(args)
+ return os.path.join(args["out_dir"], f"{sp}.pkg")
+
+def is_line_in_sp_gen(line, args :dict):
+ with open(args["sp_gen_mk"], "r") as f:
+ sppkg_rule = [l for l in f if line in l]
+ return len(sppkg_rule) is not 0
+
+def get_file_from_layout(node):
+ ''' Helper to fetch a file path from sp_layout.json. '''
+ if type(node) is dict and "file" in node.keys():
+ return node["file"]
+ return node
- # uuid_hex is a list of four hex string values
- if len(uuid_hex) != 4:
- print("ERROR: malformed UUID")
- exit(-1)
+def get_offset_from_layout(node):
+ ''' Helper to fetch an offset from sp_layout.json. '''
+ if type(node) is dict and "offset" in node.keys():
+ return int(node["offset"], 0)
+ return None
- # The uuid field in SP manifest is the little endian representation
- # mapped to arguments as described in SMCCC section 5.3.
- # Convert each unsigned integer value to a big endian representation
- # required by fiptool.
- y=list(map(bytearray.fromhex, uuid_hex))
- z=(int.from_bytes(y[0], byteorder='little', signed=False),
- int.from_bytes(y[1], byteorder='little', signed=False),
- int.from_bytes(y[2], byteorder='little', signed=False),
- int.from_bytes(y[3], byteorder='little', signed=False))
- uuid_std = uuid.UUID(f'{z[0]:08x}{z[1]:08x}{z[2]:08x}{z[3]:08x}')
+def get_image_offset(node):
+ ''' Helper to fetch image offset from sp_layout.json '''
+ return get_offset_from_layout(node["image"])
+
+def get_pm_offset(node):
+ ''' Helper to fetch pm offset from sp_layout.json '''
+ return get_offset_from_layout(node["pm"])
+
+@SpSetupActions.sp_action(global_action=True)
+def check_max_sps(sp_layout, _, args :dict):
+ ''' Check validate the maximum number of SPs is respected. '''
+ if len(sp_layout.keys()) > MAX_SP:
+ raise Exception(f"Too many SPs in SP layout file. Max: {MAX_SP}")
+ return args
+
+@SpSetupActions.sp_action
+def gen_fdt_sources(sp_layout, sp, args :dict):
+ ''' Generate FDT_SOURCES values for a given SP. '''
+ manifest_path = get_sp_manifest_full_path(sp_layout[sp], args)
+ write_to_sp_mk_gen(f"FDT_SOURCES += {manifest_path}", args)
+ return args
- """
- Append FIP_ARGS
- """
- out_file.write("FIP_ARGS += --blob uuid=" + str(uuid_std) + ",file=" + dst + "\n")
+@SpSetupActions.sp_action
+def gen_sptool_args(sp_layout, sp, args :dict):
+ ''' Generate Sp Pkgs rules. '''
+ sp_pkg = get_sp_pkg(sp, args)
+ sp_dtb_name = os.path.basename(get_file_from_layout(sp_layout[sp]["pm"]))[:-1] + "b"
+ sp_dtb = os.path.join(args["out_dir"], f"fdts/{sp_dtb_name}")
- """
- Append CRT_ARGS
- """
+ # Do not generate rule if already there.
+ if is_line_in_sp_gen(f'{sp_pkg}:', args):
+ return args
+ write_to_sp_mk_gen(f"SP_PKGS += {sp_pkg}\n", args)
+
+ sptool_args = f" -i {get_sp_img_full_path(sp_layout[sp], args)}:{sp_dtb}"
+ pm_offset = get_pm_offset(sp_layout[sp])
+ sptool_args += f" --pm-offset {pm_offset}" if pm_offset is not None else ""
+ image_offset = get_image_offset(sp_layout[sp])
+ sptool_args += f" --img-offset {image_offset}" if image_offset is not None else ""
+ sptool_args += f" -o {sp_pkg}"
+ sppkg_rule = f'''
+{sp_pkg}:
+\t$(Q)echo Generating {sp_pkg}
+\t$(Q)$(PYTHON) $(SPTOOL) {sptool_args}
+'''
+ write_to_sp_mk_gen(sppkg_rule, args)
+ return args
+
+@SpSetupActions.sp_action(global_action=True, exec_order=1)
+def check_dualroot(sp_layout, _, args :dict):
+ ''' Validate the amount of SPs from SiP and Platform owners. '''
+ if not args.get("dualroot"):
+ return args
+ args["split"] = int(MAX_SP / 2)
+ owners = [sp_layout[sp].get("owner") for sp in sp_layout]
+ args["plat_max_count"] = owners.count("Plat")
+ # If it is owned by the platform owner, it is assigned to the SiP.
+ args["sip_max_count"] = len(sp_layout.keys()) - args["plat_max_count"]
+ if args["sip_max_count"] > args["split"] or args["sip_max_count"] > args["split"]:
+ print(f"WARN: SiP Secure Partitions should not be more than {args['split']}")
+ # Counters for gen_crt_args.
+ args["sip_count"] = 1
+ args["plat_count"] = 1
+ return args
+
+@SpSetupActions.sp_action
+def gen_crt_args(sp_layout, sp, args :dict):
+ ''' Append CRT_ARGS. '''
+ # If "dualroot" is configured, 'sp_pkg_idx' depends on whether the SP is owned
+ # by the "SiP" or the "Plat".
+ if args.get("dualroot"):
+ # If the owner is not specified as "Plat", default to "SiP".
+ if sp_layout[sp].get("owner") == "Plat":
+ if args["plat_count"] > args["plat_max_count"]:
+ raise ValueError("plat_count can't surpass plat_max_count in args.")
+ sp_pkg_idx = args["plat_count"] + args["split"]
+ args["plat_count"] += 1
+ else:
+ if args["sip_count"] > args["sip_max_count"]:
+ raise ValueError("sip_count can't surpass sip_max_count in args.")
+ sp_pkg_idx = args["sip_count"]
+ args["sip_count"] += 1
+ else:
+ sp_pkg_idx = [k for k in sp_layout.keys()].index(sp) + 1
+ write_to_sp_mk_gen(f"CRT_ARGS += --sp-pkg{sp_pkg_idx} {get_sp_pkg(sp, args)}\n", args)
+ return args
+
+@SpSetupActions.sp_action
+def gen_fiptool_args(sp_layout, sp, args :dict):
+ ''' Generate arguments for the FIP Tool. '''
+ if "uuid" in sp_layout[sp]:
+ # Extract the UUID from the JSON file if the SP entry has a 'uuid' field
+ uuid_std = uuid.UUID(data[key]['uuid'])
+ else:
+ with open(get_sp_manifest_full_path(sp_layout[sp], args), "r") as pm_f:
+ uuid_lines = [l for l in pm_f if 'uuid' in l]
+ assert(len(uuid_lines) is 1)
+ # The uuid field in SP manifest is the little endian representation
+ # mapped to arguments as described in SMCCC section 5.3.
+ # Convert each unsigned integer value to a big endian representation
+ # required by fiptool.
+ uuid_parsed = re.findall("0x([0-9a-f]+)", uuid_lines[0])
+ y = list(map(bytearray.fromhex, uuid_parsed))
+ z = [int.from_bytes(i, byteorder='little', signed=False) for i in y]
+ uuid_std = uuid.UUID(f'{z[0]:08x}{z[1]:08x}{z[2]:08x}{z[3]:08x}')
+ write_to_sp_mk_gen(f"FIP_ARGS += --blob uuid={str(uuid_std)},file={get_sp_pkg(sp, args)}\n", args)
+ return args
+
+def init_sp_actions(sys):
+ sp_layout_file = os.path.abspath(sys.argv[2])
+ with open(sp_layout_file) as json_file:
+ sp_layout = json.load(json_file)
+ # Initialize arguments for the SP actions framework
+ args = {}
+ args["sp_gen_mk"] = os.path.abspath(sys.argv[1])
+ args["sp_layout_dir"] = os.path.dirname(sp_layout_file)
+ args["out_dir"] = os.path.abspath(sys.argv[3])
+ args["dualroot"] = sys.argv[4] == "dualroot"
+ #Clear content of file "sp_gen.mk".
+ with open(args["sp_gen_mk"], "w"):
+ None
+ return args, sp_layout
- out_file.write("CRT_ARGS += --sp-pkg" + str(pkg_num) + " " + dst + "\n")
- out_file.write("\n")
+if __name__ == "__main__":
+ args, sp_layout = init_sp_actions(sys)
+ SpSetupActions.run_actions(sp_layout, args)
diff --git a/tools/sptool/spactions.py b/tools/sptool/spactions.py
new file mode 100644
index 0000000..ff28ebb
--- /dev/null
+++ b/tools/sptool/spactions.py
@@ -0,0 +1,155 @@
+#!/usr/bin/python3
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+'''
+This is a python module for defining and executing SP setup actions, targeting
+a system deploying an SPM implementation.
+Each action consists of a function, that processes the SP layout json file and
+other provided arguments.
+At the core of this is the SpSetupActions which provides a means to register
+the functions into a table of actions, and execute them all when invoking
+SpSetupActions.run_actions.
+Registering the function is done by using the decorator '@SpSetupActions.sp_action'
+at function definition.
+
+Functions can be called:
+- once only, or per SP defined in the SP layout file;
+- following an order, from lowest to highest of their execution order.
+More information in the doc comments below.
+'''
+import bisect
+
+DEFAULT_ACTION_ORDER = 100
+
+class _ConfiguredAction:
+ """
+ Wraps action function with its configuration.
+ """
+ def __init__(self, action, exec_order=DEFAULT_ACTION_ORDER, global_action=True, log_calls = False):
+ self.exec_order = exec_order
+ self.__name__ = action.__name__
+ def logged_action(action):
+ def inner_logged_action(sp_layout, sp, args :dict):
+ print(f"Calling {action.__name__} -> {sp}")
+ return action(sp_layout, sp, args)
+ return inner_logged_action
+ self.action = logged_action(action) if log_calls is True else action
+ self.global_action = global_action
+
+ def __lt__(self, other):
+ """
+ To allow for ordered inserts in a list of actions.
+ """
+ return self.exec_order < other.exec_order
+
+ def __call__(self, sp_layout, sp, args :dict):
+ """
+ Calls action function.
+ """
+ return self.action(sp_layout, sp, args)
+
+ def __repr__(self) -> str:
+ """
+ Pretty format to show debug information about the action.
+ """
+ return f"func: {self.__name__}; global:{self.global_action}; exec_order: {self.exec_order}"
+
+class SpSetupActions:
+ actions = []
+
+ def sp_action(in_action = None, global_action = False, log_calls=False, exec_order=DEFAULT_ACTION_ORDER):
+ """
+ Function decorator that registers and configures action.
+
+ :param in_action - function to register
+ :param global_action - make the function global, i.e. make it be
+ only called once.
+ :param log_calls - at every call to action, a useful log will be printed.
+ :param exec_order - action's calling order.
+ """
+ def append_action(action):
+ action = _ConfiguredAction(action, exec_order, global_action, log_calls)
+ bisect.insort(SpSetupActions.actions, action)
+ return action
+ if in_action is not None:
+ return append_action(in_action)
+ return append_action
+
+ def run_actions(sp_layout: dict, args: dict, verbose=False):
+ """
+ Executes all actions in accordance to their registering configuration:
+ - If set as "global" it will be called once.
+ - Actions are called respecting the order established by their "exec_order" field.
+
+ :param sp_layout - dictionary containing the SP layout information.
+ :param args - arguments to be propagated through the call of actions.
+ :param verbose - prints actions information in order of execution.
+ """
+ args["called"] = [] # for debug purposes
+ def append_called(action, sp, args :dict):
+ args["called"].append(f"{action.__name__} -> {sp}")
+ return args
+
+ for action in SpSetupActions.actions:
+ if verbose:
+ print(f"Calling {action}")
+ if action.global_action:
+ scope = "global"
+ args = action(sp_layout, scope, args)
+ args = append_called(action, scope, args)
+ else:
+ # Functions that are not global called for each SP defined in
+ # the SP layout.
+ for sp in sp_layout.keys():
+ args = action(sp_layout, sp, args)
+ args = append_called(action, sp, args)
+
+if __name__ == "__main__":
+ # Executing this module will have the following test code/playground executed
+ sp_layout = {
+ "partition1" : {
+ "boot-info": True,
+ "image": {
+ "file": "partition.bin",
+ "offset":"0x2000"
+ },
+ "pm": {
+ "file": "cactus.dts",
+ "offset":"0x1000"
+ },
+ "owner": "SiP"
+ },
+ "partition2" : {
+ "image": "partition.bin",
+ "pm": "cactus-secondary.dts",
+ "owner": "Plat"
+ },
+ "partition3" : {
+ "image": "partition.bin",
+ "pm": "cactus-tertiary.dts",
+ "owner": "Plat"
+ },
+ "partition4" : {
+ "image": "ivy.bin",
+ "pm": "ivy.dts",
+ "owner": "Plat"
+ }
+ }
+
+ #Example of how to use this module
+ @SpSetupActions.sp_action(global_action=True)
+ def my_action1(sp_layout, _, args :dict):
+ print(f"inside function my_action1{sp_layout}\n\n args:{args})")
+ return args # Always return args in action function.
+ @SpSetupActions.sp_action(exec_order=1)
+ def my_action2(sp_layout, sp_name, args :dict):
+ print(f"inside function my_action2; SP: {sp_name} {sp_layout} args:{args}")
+ return args
+
+ # Example arguments to be propagated through the functions.
+ # 'args' can be extended in the action functions.
+ args = dict()
+ args["arg1"] = 0xEEE
+ args["arg2"] = 0xFF
+ SpSetupActions.run_actions(sp_layout, args)
diff --git a/tools/sptool/sptool.c b/tools/sptool/sptool.c
deleted file mode 100644
index 38baa2c..0000000
--- a/tools/sptool/sptool.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "sptool.h"
-
-#define PAGE_SIZE 4096
-
-/*
- * Entry describing Secure Partition package.
- */
-struct sp_pkg_info {
- /* Location of the files in the host's RAM. */
- void *img_data, *pm_data;
-
- /* Size of the files. */
- uint32_t img_size, pm_size;
-
- /* Location of the binary files inside the package output file */
- uint32_t img_offset, pm_offset;
-};
-
-/*
- * List of input provided by user
- */
-struct arg_list {
- char *usr_input;
- struct arg_list *next;
-};
-
-/* Align an address to a power-of-two boundary. */
-static unsigned int align_to(unsigned int address, unsigned int boundary)
-{
- unsigned int mask = boundary - 1U;
-
- if ((address & mask) != 0U)
- return (address + boundary) & ~mask;
- else
- return address;
-}
-
-/* Allocate a memory area of 'size' bytes and zero it. */
-static void *xzalloc(size_t size, const char *msg)
-{
- void *d;
-
- d = malloc(size);
- if (d == NULL) {
- fprintf(stderr, "error: malloc: %s\n", msg);
- exit(1);
- }
-
- memset(d, 0, size);
-
- return d;
-}
-
-/*
- * Write 'size' bytes from 'buf' into the specified file stream.
- * Exit the program on error.
- */
-static void xfwrite(void *buf, size_t size, FILE *fp)
-{
- if (fwrite(buf, 1, size, fp) != size) {
- fprintf(stderr, "error: Failed to write to output file.\n");
- exit(1);
- }
-}
-
-/*
- * Set the file position indicator for the specified file stream.
- * Exit the program on error.
- */
-static void xfseek(FILE *fp, long offset, int whence)
-{
- if (fseek(fp, offset, whence) != 0) {
- fprintf(stderr, "error: Failed to set file to offset 0x%lx (%d).\n",
- offset, whence);
- perror(NULL);
- exit(1);
- }
-}
-
-/*
- * Free SP package structure
- */
-static void cleanup(struct sp_pkg_info *sp)
-{
-
- if (sp != NULL) {
- if (sp->img_data != NULL) {
- free(sp->img_data);
- }
-
- if (sp->pm_data != NULL) {
- free(sp->pm_data);
- }
-
- free(sp);
-
- }
-}
-
-/*
- * Free argument list structure
- */
-static void freelist(struct arg_list *head)
-{
- struct arg_list *tmp;
-
- while (head != NULL) {
- tmp = head;
- head = head->next;
- free(tmp);
- }
-}
-
-/*
- * Append user inputs in argument list structure
- */
-static void append_user_input(struct arg_list **head, char *args)
-{
- struct arg_list *tmp = *head;
-
- if (tmp == NULL) {
- tmp = xzalloc(sizeof(struct arg_list),
- "Failed to allocate arg_list struct");
- tmp->usr_input = args;
- *head = tmp;
- } else {
- while (tmp->next != NULL) {
- tmp = tmp->next;
- }
- tmp->next = xzalloc(sizeof(struct arg_list),
- "Failed to allocate arg_list struct");
- tmp = tmp->next;
- tmp->usr_input = args;
- }
-}
-
-/*
- * Allocate a buffer big enough to store the content of the specified file and
- * load the file into it. Fill 'size' with the file size. Exit the program on
- * error.
- */
-static void load_file(const char *path, void **ptr, uint32_t *size)
-{
- FILE *f = fopen(path, "rb");
- if (f == NULL) {
- fprintf(stderr, "error: %s couldn't be opened.\n", path);
- exit(1);
- }
-
- xfseek(f, 0, SEEK_END);
- *size = ftell(f);
- if (*size == 0) {
- fprintf(stderr, "error: Size of %s is 0\n", path);
- exit(1);
- }
-
- rewind(f);
-
- *ptr = malloc(*size);
- if (*ptr == NULL) {
- fprintf(stderr, "error: Not enough memory to load %s\n", path);
- exit(1);
- }
-
- if (fread(*ptr, *size, 1, f) != 1) {
- fprintf(stderr, "error: Couldn't read %s\n", path);
- exit(1);
- }
-
- fclose(f);
-}
-
-/*
- * Parse the string containing input payloads and fill in the
- * SP Package data structure.
- */
-static void load_sp_pm(char *path, struct sp_pkg_info **sp_out)
-{
- struct sp_pkg_info *sp_pkg;
-
- char *split_mark = strstr(path, ":");
-
- *split_mark = '\0';
-
- char *sp_path = path;
- char *pm_path = split_mark + 1;
-
- sp_pkg = xzalloc(sizeof(struct sp_pkg_info),
- "Failed to allocate sp_pkg_info struct");
-
- load_file(pm_path, &sp_pkg->pm_data, &sp_pkg->pm_size);
- printf("\nLoaded SP Manifest file %s (%u bytes)\n", pm_path, sp_pkg->pm_size);
-
- load_file(sp_path, &sp_pkg->img_data, &sp_pkg->img_size);
- printf("Loaded SP Image file %s (%u bytes)\n", sp_path, sp_pkg->img_size);
-
- *sp_out = sp_pkg;
-}
-
-/*
- * Write SP package data structure into output file.
- */
-static void output_write(const char *path, struct sp_pkg_info *sp, bool header)
-{
- struct sp_pkg_header sp_header_info;
- unsigned int file_ptr = 0;
-
- FILE *f = fopen(path, "wb");
- if (f == NULL) {
- fprintf(stderr, "error: Failed to open %s\n", path);
- exit(1);
- }
-
- /* Reserve Header size */
- if (header) {
- file_ptr = sizeof(struct sp_pkg_header);
- }
-
- /* Save partition manifest */
- xfseek(f, file_ptr, SEEK_SET);
- printf("Writing SP Manifest at offset 0x%x (%u bytes)\n",
- file_ptr, sp->pm_size);
-
- sp->pm_offset = file_ptr;
- xfwrite(sp->pm_data, sp->pm_size, f);
-
- /* Save partition image aligned to Page size */
- file_ptr = align_to((sp->pm_offset + sp->pm_size), PAGE_SIZE);
- xfseek(f, file_ptr, SEEK_SET);
- printf("Writing SP Image at offset 0x%x (%u bytes)\n",
- file_ptr, sp->img_size);
-
- sp->img_offset = file_ptr;
- xfwrite(sp->img_data, sp->img_size, f);
-
- /* Finally, write header, if needed */
- if (header) {
- sp_header_info.magic = SECURE_PARTITION_MAGIC;
- sp_header_info.version = 0x1;
- sp_header_info.img_offset = sp->img_offset;
- sp_header_info.img_size = sp->img_size;
- sp_header_info.pm_offset = sp->pm_offset;
- sp_header_info.pm_size = sp->pm_size;
-
- xfseek(f, 0, SEEK_SET);
-
- printf("Writing package header\n");
-
- xfwrite(&sp_header_info, sizeof(struct sp_pkg_header), f);
- }
-
- /* All information has been written now */
- printf("\nsptool: Built Secure Partition blob %s\n", path);
-
- fclose(f);
-}
-
-static void usage(void)
-{
- printf("usage: sptool ");
-#ifdef VERSION
- printf(VERSION);
-#else
- /* If built from sptool directory, VERSION is not set. */
- printf("version unknown");
-#endif
- printf(" [<args>]\n\n");
-
- printf("This tool takes as input set of image binary files and the\n"
- "partition manifest blobs as input and generates set of\n"
- "output package files\n"
- "Usage example: sptool -i sp1.bin:sp1.dtb -o sp1.pkg\n"
- " -i sp2.bin:sp2.dtb -o sp2.pkg ...\n\n");
- printf("Commands supported:\n");
- printf(" -o <path> Set output file path.\n");
- printf(" -i <sp_path:pm_path> Add Secure Partition image and\n"
- " Manifest blob (specified in two paths\n"
- " separated by a colon).\n");
- printf(" -n Generate package without header\n");
- printf(" -h Show this message.\n");
- exit(1);
-}
-
-int main(int argc, char *argv[])
-{
- struct sp_pkg_info *sp_pkg = NULL;
- struct arg_list *in_head = NULL;
- struct arg_list *out_head = NULL;
- struct arg_list *in_list = NULL;
- struct arg_list *out_list = NULL;
- unsigned int match_counter = 0;
- bool need_header = true;
-
- int ch;
-
- if (argc <= 1) {
- fprintf(stderr, "error: File paths must be provided.\n\n");
- usage();
- return 1;
- }
-
- while ((ch = getopt(argc, argv, "hni:o:")) != -1) {
- switch (ch) {
- case 'i':
- append_user_input(&in_head, optarg);
- match_counter++;
- break;
- case 'o':
- append_user_input(&out_head, optarg);
- match_counter--;
- break;
- case 'n':
- need_header = false;
- break;
- case 'h':
- default:
- usage();
- }
- }
-
- if (match_counter) {
- fprintf(stderr, "error: Input/Output count mismatch.\n\n");
- freelist(in_head);
- freelist(out_head);
- usage();
- return 1;
- }
-
- in_list = in_head;
- out_list = out_head;
- while (in_list != NULL) {
- load_sp_pm(in_list->usr_input, &sp_pkg);
- output_write(out_list->usr_input, sp_pkg, need_header);
- in_list = in_list->next;
- out_list = out_list->next;
- }
-
- argc -= optind;
- argv += optind;
-
- cleanup(sp_pkg);
- freelist(in_head);
- freelist(out_head);
-
- return 0;
-}
diff --git a/tools/sptool/sptool.py b/tools/sptool/sptool.py
new file mode 100755
index 0000000..ae7df92
--- /dev/null
+++ b/tools/sptool/sptool.py
@@ -0,0 +1,145 @@
+#!/usr/bin/python3
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+#
+# Copyright 2022 The Hafnium Authors.
+#
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://opensource.org/licenses/BSD-3-Clause.
+
+"""
+Script which generates a Secure Partition package.
+https://trustedfirmware-a.readthedocs.io/en/latest/components/secure-partition-manager.html#secure-partition-packages
+"""
+
+import argparse
+from collections import namedtuple
+import sys
+from shutil import copyfileobj
+import os
+
+HF_PAGE_SIZE = 0x1000 # bytes
+HEADER_ELEMENT_BYTES = 4 # bytes
+MANIFEST_IMAGE_SPLITTER=':'
+PM_OFFSET_DEFAULT = "0x1000"
+IMG_OFFSET_DEFAULT = "0x4000"
+
+def split_dtb_bin(i : str):
+ return i.split(MANIFEST_IMAGE_SPLITTER)
+
+def align_to_page(n):
+ return HF_PAGE_SIZE * \
+ (round(n / HF_PAGE_SIZE) + \
+ (1 if n % HF_PAGE_SIZE else 0))
+
+def to_bytes(value):
+ return int(value).to_bytes(HEADER_ELEMENT_BYTES, 'little')
+
+class SpPkg:
+ def __init__(self, pm_path : str, img_path : str, pm_offset: int,
+ img_offset: int):
+ if not os.path.isfile(pm_path) or not os.path.isfile(img_path):
+ raise Exception(f"Parameters should be path. \
+ manifest: {pm_path}; img: {img_path}")
+ self.pm_path = pm_path
+ self.img_path = img_path
+ self._SpPkgHeader = namedtuple("SpPkgHeader",
+ ("magic", "version",
+ "pm_offset", "pm_size",
+ "img_offset", "img_size"))
+
+ if pm_offset >= img_offset:
+ raise ValueError("pm_offset must be smaller than img_offset")
+
+ is_hfpage_aligned = lambda val : val % HF_PAGE_SIZE == 0
+ if not is_hfpage_aligned(pm_offset) or not is_hfpage_aligned(img_offset):
+ raise ValueError(f"Offsets provided need to be page aligned: pm-{pm_offset}, img-{img_offset}")
+
+ if img_offset - pm_offset < self.pm_size:
+ raise ValueError(f"pm_offset and img_offset do not fit the specified file:{pm_path})")
+
+ self.pm_offset = pm_offset
+ self.img_offset = img_offset
+
+ def __str__(self):
+ return \
+ f'''--SP package Info--
+ header:{self.header}
+ pm: {self.pm_path}
+ img: {self.img_path}
+ '''
+
+ @property
+ def magic(self):
+ return "SPKG".encode()
+
+ @property
+ def version(self):
+ return 0x2
+
+ @property
+ def pm_size(self):
+ return os.path.getsize(self.pm_path)
+
+ @property
+ def img_size(self):
+ return os.path.getsize(self.img_path)
+
+ @property
+ def header(self):
+ return self._SpPkgHeader(
+ self.magic,
+ self.version,
+ self.pm_offset,
+ self.pm_size,
+ self.img_offset,
+ self.img_size)
+
+ @property
+ def header_size(self):
+ return len(self._SpPkgHeader._fields)
+
+ def generate(self, f_out : str):
+ with open(f_out, "wb+") as output:
+ for h in self.header:
+ to_write = h if type(h) is bytes else to_bytes(h)
+ output.write(to_write)
+ output.seek(self.pm_offset)
+ with open(self.pm_path, "rb") as pm:
+ copyfileobj(pm, output)
+ output.seek(self.img_offset)
+ with open(self.img_path, "rb") as img:
+ copyfileobj(img, output)
+
+def Main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-i", required=True,
+ help="path to partition's image and manifest separated by a colon.")
+ parser.add_argument("--pm-offset", required=False, default=PM_OFFSET_DEFAULT,
+ help="set partitition manifest offset.")
+ parser.add_argument("--img-offset", required=False, default=IMG_OFFSET_DEFAULT,
+ help="set partition image offset.")
+ parser.add_argument("-o", required=True, help="set output file path.")
+ parser.add_argument("-v", required=False, action="store_true",
+ help="print package information.")
+ args = parser.parse_args()
+
+ if not os.path.exists(os.path.dirname(args.o)):
+ raise Exception("Provide a valid output file path!\n")
+
+ image_path, manifest_path = split_dtb_bin(args.i)
+ pm_offset = int(args.pm_offset, 0)
+ img_offset = int(args.img_offset, 0)
+ pkg = SpPkg(manifest_path, image_path, pm_offset, img_offset)
+ pkg.generate(args.o)
+
+ if args.v is True:
+ print(pkg)
+
+ return 0
+
+if __name__ == "__main__":
+ sys.exit(Main())