aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile27
-rw-r--r--bl1/aarch64/bl1_context_mgmt.c4
-rw-r--r--bl1/bl1_main.c8
-rw-r--r--bl1/tbbr/tbbr_img_desc.c3
-rw-r--r--bl2/bl2.ld.S12
-rw-r--r--bl2/bl2_image_load_v2.c17
-rw-r--r--bl31/aarch64/bl31_entrypoint.S14
-rw-r--r--bl31/aarch64/crash_reporting.S7
-rw-r--r--bl31/aarch64/runtime_exceptions.S5
-rw-r--r--bl31/bl31.ld.S3
-rw-r--r--bl31/bl31.mk1
-rw-r--r--bl31/bl31_context_mgmt.c3
-rw-r--r--common/backtrace/backtrace.c49
-rw-r--r--common/bl_common.c2
-rw-r--r--common/desc_image_load.c28
-rw-r--r--common/fdt_wrappers.c79
-rw-r--r--docs/about/maintainers.rst8
-rw-r--r--docs/change-log-upcoming.rst2
-rw-r--r--docs/components/exception-handling.rst4
-rw-r--r--docs/components/fconf.rst85
-rw-r--r--docs/components/index.rst1
-rw-r--r--docs/design/trusted-board-boot-build.rst21
-rw-r--r--docs/getting_started/build-options.rst16
-rw-r--r--docs/getting_started/docs-build.rst21
-rw-r--r--docs/getting_started/porting-guide.rst15
-rw-r--r--docs/global_substitutions.txt2
-rw-r--r--docs/glossary.rst6
-rw-r--r--docs/plat/arm/arm-build-options.rst16
-rw-r--r--docs/plat/meson-axg.rst27
-rw-r--r--docs/plat/qemu.rst10
-rw-r--r--docs/process/coding-guidelines.rst515
-rw-r--r--docs/process/coding-style.rst468
-rw-r--r--docs/process/contributing.rst4
-rw-r--r--docs/process/index.rst1
-rw-r--r--docs/process/security-hardening.rst26
-rw-r--r--docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml52
-rw-r--r--docs/resources/diagrams/plantuml/fconf_bl2_populate.puml41
-rw-r--r--drivers/arm/ccn/ccn.c3
-rw-r--r--drivers/arm/css/mhu/css_mhu_doorbell.c10
-rw-r--r--drivers/arm/css/scp/css_pm_scmi.c140
-rw-r--r--drivers/arm/gic/v2/gicv2_helpers.c3
-rw-r--r--drivers/auth/auth_mod.c8
-rw-r--r--drivers/auth/img_parser_mod.c3
-rw-r--r--drivers/console/multi_console.c8
-rw-r--r--include/arch/aarch64/arch_helpers.h14
-rw-r--r--include/common/fdt_wrappers.h6
-rw-r--r--include/drivers/arm/css/css_mhu_doorbell.h12
-rw-r--r--include/drivers/arm/css/scmi.h4
-rw-r--r--include/drivers/io/io_storage.h4
-rw-r--r--include/lib/fconf/fconf.h61
-rw-r--r--include/lib/fconf/fconf_dyn_cfg_getter.h24
-rw-r--r--include/lib/fconf/fconf_tbbr_getter.h27
-rw-r--r--include/plat/arm/common/arm_def.h36
-rw-r--r--include/plat/arm/common/arm_dyn_cfg_helpers.h7
-rw-r--r--include/plat/arm/common/arm_fconf_getter.h24
-rw-r--r--include/plat/arm/common/arm_fconf_io_storage.h19
-rw-r--r--include/plat/arm/common/plat_arm.h26
-rw-r--r--include/plat/arm/css/common/css_def.h6
-rw-r--r--include/plat/arm/css/common/css_pm.h13
-rw-r--r--include/plat/common/platform.h11
-rw-r--r--include/services/spci_svc.h139
-rw-r--r--include/services/spm_core_manifest.h55
-rw-r--r--include/services/spmd_svc.h25
-rw-r--r--include/tools_share/sptool.h26
-rw-r--r--include/tools_share/uuid.h7
-rw-r--r--lib/cpus/errata_report.c3
-rw-r--r--lib/debugfs/devfip.c6
-rw-r--r--lib/el3_runtime/aarch32/context_mgmt.c4
-rw-r--r--lib/el3_runtime/aarch64/context_mgmt.c2
-rw-r--r--lib/el3_runtime/aarch64/cpu_data.S5
-rw-r--r--lib/fconf/fconf.c85
-rw-r--r--lib/fconf/fconf.mk12
-rw-r--r--lib/fconf/fconf_dyn_cfg_getter.c95
-rw-r--r--lib/fconf/fconf_tbbr_getter.c75
-rw-r--r--lib/optee/optee_utils.c5
-rw-r--r--lib/romlib/jmptbl.i3
-rw-r--r--lib/utils/mem_region.c6
-rw-r--r--make_helpers/defaults.mk3
-rw-r--r--plat/amlogic/axg/axg_bl31_setup.c170
-rw-r--r--plat/amlogic/axg/axg_common.c115
-rw-r--r--plat/amlogic/axg/axg_def.h129
-rw-r--r--plat/amlogic/axg/axg_pm.c166
-rw-r--r--plat/amlogic/axg/include/platform_def.h66
-rw-r--r--plat/amlogic/axg/platform.mk95
-rw-r--r--plat/arm/board/a5ds/fdts/a5ds_fw_config.dts35
-rw-r--r--plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts18
-rw-r--r--plat/arm/board/a5ds/platform.mk9
-rw-r--r--plat/arm/board/common/board_arm_trusted_boot.c204
-rw-r--r--plat/arm/board/common/board_common.mk85
-rw-r--r--plat/arm/board/common/rotpk/arm_dev_rotpk.S26
-rw-r--r--plat/arm/board/fvp/fdts/fvp_fw_config.dts96
-rw-r--r--plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts19
-rw-r--r--plat/arm/board/fvp/fvp_bl2_setup.c4
-rw-r--r--plat/arm/board/fvp/fvp_common.c3
-rw-r--r--plat/arm/board/fvp/fvp_err.c3
-rw-r--r--plat/arm/board/fvp/fvp_io_storage.c18
-rw-r--r--plat/arm/board/fvp/fvp_pm.c4
-rw-r--r--plat/arm/board/fvp/fvp_trusted_boot.c23
-rw-r--r--plat/arm/board/fvp/include/platform_def.h6
-rw-r--r--plat/arm/board/fvp/jmptbl.i5
-rw-r--r--plat/arm/board/fvp/platform.mk25
-rw-r--r--plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts35
-rw-r--r--plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts18
-rw-r--r--plat/arm/board/fvp_ve/platform.mk9
-rw-r--r--plat/arm/board/juno/fdts/juno_fw_config.dts (renamed from plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts)33
-rw-r--r--plat/arm/board/juno/include/platform_def.h6
-rw-r--r--plat/arm/board/juno/jmptbl.i5
-rw-r--r--plat/arm/board/juno/juno_bl1_setup.c12
-rw-r--r--plat/arm/board/juno/juno_err.c3
-rw-r--r--plat/arm/board/juno/juno_topology.c4
-rw-r--r--plat/arm/board/juno/juno_trusted_boot.c126
-rw-r--r--plat/arm/board/juno/platform.mk11
-rw-r--r--plat/arm/board/n1sdp/include/platform_def.h6
-rw-r--r--plat/arm/board/n1sdp/n1sdp_bl31_setup.c4
-rw-r--r--plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts22
-rw-r--r--plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts (renamed from plat/arm/board/juno/fdts/juno_tb_fw_config.dts)7
-rw-r--r--plat/arm/board/rddaniel/include/platform_def.h40
-rw-r--r--plat/arm/board/rddaniel/platform.mk43
-rw-r--r--plat/arm/board/rddaniel/rddaniel_err.c17
-rw-r--r--plat/arm/board/rddaniel/rddaniel_plat.c30
-rw-r--r--plat/arm/board/rddaniel/rddaniel_security.c12
-rw-r--r--plat/arm/board/rddaniel/rddaniel_topology.c62
-rw-r--r--plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts3
-rw-r--r--plat/arm/board/rde1edge/include/platform_def.h8
-rw-r--r--plat/arm/board/rde1edge/platform.mk10
-rw-r--r--plat/arm/board/rde1edge/rde1edge_plat.c13
-rw-r--r--plat/arm/board/rde1edge/rde1edge_topology.c9
-rw-r--r--plat/arm/board/rde1edge/rde1edge_trusted_boot.c26
-rw-r--r--plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts3
-rw-r--r--plat/arm/board/rdn1edge/include/platform_def.h15
-rw-r--r--plat/arm/board/rdn1edge/platform.mk14
-rw-r--r--plat/arm/board/rdn1edge/rdn1edge_plat.c81
-rw-r--r--plat/arm/board/rdn1edge/rdn1edge_topology.c26
-rw-r--r--plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c26
-rw-r--r--plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts3
-rw-r--r--plat/arm/board/sgi575/include/platform_def.h8
-rw-r--r--plat/arm/board/sgi575/platform.mk10
-rw-r--r--plat/arm/board/sgi575/sgi575_plat.c14
-rw-r--r--plat/arm/board/sgi575/sgi575_trusted_boot.c26
-rw-r--r--plat/arm/board/sgm775/platform.mk7
-rw-r--r--plat/arm/board/sgm775/sgm775_trusted_boot.c26
-rw-r--r--plat/arm/common/aarch32/arm_bl2_mem_params_desc.c3
-rw-r--r--plat/arm/common/aarch64/arm_bl2_mem_params_desc.c3
-rw-r--r--plat/arm/common/aarch64/execution_state_switch.c3
-rw-r--r--plat/arm/common/arm_bl1_setup.c17
-rw-r--r--plat/arm/common/arm_bl2_setup.c13
-rw-r--r--plat/arm/common/arm_bl31_setup.c14
-rw-r--r--plat/arm/common/arm_common.c1
-rw-r--r--plat/arm/common/arm_common.mk40
-rw-r--r--plat/arm/common/arm_dyn_cfg.c149
-rw-r--r--plat/arm/common/arm_dyn_cfg_helpers.c166
-rw-r--r--plat/arm/common/arm_fconf_io_storage.c143
-rw-r--r--plat/arm/common/arm_io_storage.c35
-rw-r--r--plat/arm/common/arm_nor_psci_mem_protect.c3
-rw-r--r--plat/arm/common/arm_pm.c3
-rw-r--r--plat/arm/common/fconf/arm_fconf_io.c143
-rw-r--r--plat/arm/common/sp_min/arm_sp_min_setup.c3
-rw-r--r--plat/arm/css/common/css_pm.c4
-rw-r--r--plat/arm/css/sgi/aarch64/sgi_helper.S24
-rw-r--r--plat/arm/css/sgi/include/sgi_base_platform_def.h44
-rw-r--r--plat/arm/css/sgi/include/sgi_plat.h13
-rw-r--r--plat/arm/css/sgi/include/sgi_variant.h12
-rw-r--r--plat/arm/css/sgi/sgi-common.mk4
-rw-r--r--plat/arm/css/sgi/sgi_bl31_setup.c62
-rw-r--r--plat/arm/css/sgi/sgi_image_load.c9
-rw-r--r--plat/arm/css/sgm/include/sgm_base_platform_def.h6
-rw-r--r--plat/arm/css/sgm/sgm_bl31_setup.c4
-rw-r--r--plat/common/plat_bl_common.c3
-rw-r--r--plat/common/plat_spmd_manifest.c124
-rw-r--r--plat/intel/soc/agilex/bl31_plat_setup.c35
-rw-r--r--plat/intel/soc/common/include/socfpga_mailbox.h35
-rw-r--r--plat/intel/soc/common/include/socfpga_sip_svc.h1
-rw-r--r--plat/intel/soc/common/soc/socfpga_mailbox.c49
-rw-r--r--plat/intel/soc/common/socfpga_psci.c7
-rw-r--r--plat/intel/soc/common/socfpga_sip_svc.c113
-rw-r--r--plat/intel/soc/stratix10/bl31_plat_setup.c3
-rw-r--r--plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c4
-rw-r--r--plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h30
-rw-r--r--plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h17
-rw-r--r--plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c13
-rw-r--r--plat/nvidia/tegra/common/tegra_bl31_setup.c32
-rw-r--r--plat/nvidia/tegra/common/tegra_common.mk1
-rw-r--r--plat/nvidia/tegra/common/tegra_pm.c100
-rw-r--r--plat/nvidia/tegra/common/tegra_sip_calls.c27
-rw-r--r--plat/nvidia/tegra/include/t132/tegra_def.h7
-rw-r--r--plat/nvidia/tegra/include/t186/tegra_def.h7
-rw-r--r--plat/nvidia/tegra/include/t194/tegra_def.h6
-rw-r--r--plat/nvidia/tegra/include/t210/tegra_def.h7
-rw-r--r--plat/nvidia/tegra/include/tegra_private.h8
-rw-r--r--plat/nvidia/tegra/soc/t132/plat_psci_handlers.c52
-rw-r--r--plat/nvidia/tegra/soc/t132/plat_setup.c33
-rw-r--r--plat/nvidia/tegra/soc/t132/platform_t132.mk2
-rw-r--r--plat/nvidia/tegra/soc/t186/plat_memctrl.c88
-rw-r--r--plat/nvidia/tegra/soc/t186/plat_psci_handlers.c12
-rw-r--r--plat/nvidia/tegra/soc/t186/plat_setup.c9
-rw-r--r--plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h460
-rw-r--r--plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c12
-rw-r--r--plat/nvidia/tegra/soc/t194/drivers/se/se.c17
-rw-r--r--plat/nvidia/tegra/soc/t194/drivers/se/se_private.h4
-rw-r--r--plat/nvidia/tegra/soc/t194/plat_psci_handlers.c77
-rw-r--r--plat/nvidia/tegra/soc/t194/plat_sip_calls.c21
-rw-r--r--plat/nvidia/tegra/soc/t210/plat_psci_handlers.c23
-rw-r--r--plat/nvidia/tegra/soc/t210/plat_setup.c20
-rw-r--r--plat/nvidia/tegra/soc/t210/platform_t210.mk2
-rw-r--r--plat/qemu/qemu/platform.mk1
-rw-r--r--plat/socionext/synquacer/include/platform_def.h3
-rw-r--r--plat/xilinx/versal/pm_service/pm_svc_main.c4
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_svc_main.c2
-rw-r--r--services/std_svc/spmd/aarch64/spmd_helpers.S73
-rw-r--r--services/std_svc/spmd/spmd.mk21
-rw-r--r--services/std_svc/spmd/spmd_main.c487
-rw-r--r--services/std_svc/spmd/spmd_private.h78
-rw-r--r--services/std_svc/std_svc_setup.c20
-rw-r--r--tools/sptool/sptool.c292
214 files changed, 6189 insertions, 1959 deletions
diff --git a/Makefile b/Makefile
index 183f20ddf4..7e416784b0 100644
--- a/Makefile
+++ b/Makefile
@@ -418,11 +418,20 @@ ifdef EL3_PAYLOAD_BASE
$(warning "SPD and EL3_PAYLOAD_BASE are incompatible build options.")
$(warning "The SPD and its BL32 companion will be present but ignored.")
endif
- # We expect to locate an spd.mk under the specified SPD directory
- SPD_MAKE := $(wildcard services/spd/${SPD}/${SPD}.mk)
+ ifeq (${SPD},spmd)
+ # SPMD is located in std_svc directory
+ SPD_DIR := std_svc
+ else
+ # All other SPDs in spd directory
+ SPD_DIR := spd
+ endif
+
+ # We expect to locate an spd.mk under the specified SPD directory
+ SPD_MAKE := $(wildcard services/${SPD_DIR}/${SPD}/${SPD}.mk)
+
ifeq (${SPD_MAKE},)
- $(error Error: No services/spd/${SPD}/${SPD}.mk located)
+ $(error Error: No services/${SPD_DIR}/${SPD}/${SPD}.mk located)
endif
$(info Including ${SPD_MAKE})
include ${SPD_MAKE}
@@ -702,6 +711,9 @@ PYTHON ?= python3
PRINT_MEMORY_MAP_PATH ?= tools/memory
PRINT_MEMORY_MAP ?= ${PRINT_MEMORY_MAP_PATH}/print_memory_map.py
+# Variables for use with documentation build using Sphinx tool
+DOCS_PATH ?= docs
+
################################################################################
# Include BL specific makefiles
################################################################################
@@ -774,6 +786,7 @@ $(eval $(call assert_boolean,SPM_MM))
$(eval $(call assert_boolean,TRUSTED_BOARD_BOOT))
$(eval $(call assert_boolean,USE_COHERENT_MEM))
$(eval $(call assert_boolean,USE_DEBUGFS))
+$(eval $(call assert_boolean,USE_FCONF_BASED_IO))
$(eval $(call assert_boolean,USE_ROMLIB))
$(eval $(call assert_boolean,USE_TBBR_DEFS))
$(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
@@ -842,6 +855,7 @@ $(eval $(call add_define,SPM_MM))
$(eval $(call add_define,TRUSTED_BOARD_BOOT))
$(eval $(call add_define,USE_COHERENT_MEM))
$(eval $(call add_define,USE_DEBUGFS))
+$(eval $(call add_define,USE_FCONF_BASED_IO))
$(eval $(call add_define,USE_ROMLIB))
$(eval $(call add_define,USE_TBBR_DEFS))
$(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
@@ -878,7 +892,7 @@ endif
# Build targets
################################################################################
-.PHONY: all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool sptool fip fwu_fip certtool dtbs memmap
+.PHONY: all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool sptool fip fwu_fip certtool dtbs memmap doc
.SUFFIXES:
all: msg_start
@@ -1076,6 +1090,10 @@ romlib.bin: libraries
memmap: all
${Q}${PYTHON} $(PRINT_MEMORY_MAP) $(BUILD_PLAT)
+doc:
+ @echo " BUILD DOCUMENTATION"
+ ${Q}${MAKE} --no-print-directory -C ${DOCS_PATH} html
+
cscope:
@echo " CSCOPE"
${Q}find ${CURDIR} -name "*.[chsS]" > cscope.files
@@ -1116,6 +1134,7 @@ help:
@echo " sptool Build the Secure Partition Package creation tool"
@echo " dtbs Build the Device Tree Blobs (if required for the platform)"
@echo " memmap Print the memory map of the built binaries"
+ @echo " doc Build html based documentation using Sphinx tool"
@echo ""
@echo "Note: most build targets require PLAT to be set to a specific platform."
@echo ""
diff --git a/bl1/aarch64/bl1_context_mgmt.c b/bl1/aarch64/bl1_context_mgmt.c
index 8be8830a38..210c35842d 100644
--- a/bl1/aarch64/bl1_context_mgmt.c
+++ b/bl1/aarch64/bl1_context_mgmt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -69,7 +69,7 @@ void bl1_prepare_next_image(unsigned int image_id)
security_state = GET_SECURITY_STATE(next_bl_ep->h.attr);
/* Setup the Secure/Non-Secure context if not done already. */
- if (!cm_get_context(security_state))
+ if (cm_get_context(security_state) == NULL)
cm_set_context(&bl1_cpu_context[security_state], security_state);
/* Prepare the SPSR for the next BL image. */
diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c
index cd6fe7d5e8..bff8d22f51 100644
--- a/bl1/bl1_main.c
+++ b/bl1/bl1_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -26,7 +26,7 @@
/* BL1 Service UUID */
DEFINE_SVC_UUID2(bl1_svc_uid,
- 0xd46739fd, 0xcb72, 0x9a4d, 0xb5, 0x75,
+ U(0xd46739fd), 0xcb72, 0x9a4d, 0xb5, 0x75,
0x67, 0x15, 0xd6, 0xf4, 0xbb, 0x4a);
static void bl1_load_bl2(void);
@@ -172,7 +172,7 @@ static void bl1_load_bl2(void)
/* Get the image descriptor */
image_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
- assert(image_desc);
+ assert(image_desc != NULL);
/* Get the image info */
image_info = &image_desc->image_info;
@@ -276,7 +276,7 @@ register_t bl1_smc_wrapper(uint32_t smc_fid,
{
register_t x1, x2, x3, x4;
- assert(handle);
+ assert(handle != NULL);
get_smc_params_from_ctx(handle, x1, x2, x3, x4);
return bl1_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
diff --git a/bl1/tbbr/tbbr_img_desc.c b/bl1/tbbr/tbbr_img_desc.c
index e8df73d471..48367126c2 100644
--- a/bl1/tbbr/tbbr_img_desc.c
+++ b/bl1/tbbr/tbbr_img_desc.c
@@ -1,12 +1,11 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <platform_def.h>
-#include <bl1/bl1.h>
#include <bl1/tbbr/tbbr_img_desc.h>
#include <common/bl_common.h>
diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S
index 6230562edb..c1338e22d3 100644
--- a/bl2/bl2.ld.S
+++ b/bl2/bl2.ld.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -46,6 +46,11 @@ SECTIONS
__RODATA_START__ = .;
*(SORT_BY_ALIGNMENT(.rodata*))
+ . = ALIGN(8);
+ __FCONF_POPULATOR_START__ = .;
+ KEEP(*(.fconf_populator))
+ __FCONF_POPULATOR_END__ = .;
+
/* Ensure 8-byte alignment for descriptors and ensure inclusion */
. = ALIGN(8);
__PARSER_LIB_DESCS_START__ = .;
@@ -62,6 +67,11 @@ SECTIONS
*(SORT_BY_ALIGNMENT(.text*))
*(SORT_BY_ALIGNMENT(.rodata*))
+ . = ALIGN(8);
+ __FCONF_POPULATOR_START__ = .;
+ KEEP(*(.fconf_populator))
+ __FCONF_POPULATOR_END__ = .;
+
/* Ensure 8-byte alignment for descriptors and ensure inclusion */
. = ALIGN(8);
__PARSER_LIB_DESCS_START__ = .;
diff --git a/bl2/bl2_image_load_v2.c b/bl2/bl2_image_load_v2.c
index dd53e1d2b4..81d4b2bcc8 100644
--- a/bl2/bl2_image_load_v2.c
+++ b/bl2/bl2_image_load_v2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -35,13 +35,13 @@ struct entry_point_info *bl2_load_images(void)
* Get information about the images to load.
*/
bl2_load_info = plat_get_bl_image_load_info();
- assert(bl2_load_info);
- assert(bl2_load_info->head);
+ assert(bl2_load_info != NULL);
+ assert(bl2_load_info->head != NULL);
assert(bl2_load_info->h.type == PARAM_BL_LOAD_INFO);
assert(bl2_load_info->h.version >= VERSION_2);
bl2_node_info = bl2_load_info->head;
- while (bl2_node_info) {
+ while (bl2_node_info != NULL) {
/*
* Perform platform setup before loading the image,
* if indicated in the image attributes AND if NOT
@@ -68,7 +68,8 @@ struct entry_point_info *bl2_load_images(void)
err = load_auth_image(bl2_node_info->image_id,
bl2_node_info->image_info);
if (err) {
- ERROR("BL2: Failed to load image (%i)\n", err);
+ ERROR("BL2: Failed to load image id %d (%i)\n",
+ bl2_node_info->image_id, err);
plat_error_handler(err);
}
} else {
@@ -90,11 +91,11 @@ struct entry_point_info *bl2_load_images(void)
* Get information to pass to the next image.
*/
bl2_to_next_bl_params = plat_get_next_bl_params();
- assert(bl2_to_next_bl_params);
- assert(bl2_to_next_bl_params->head);
+ assert(bl2_to_next_bl_params != NULL);
+ assert(bl2_to_next_bl_params->head != NULL);
assert(bl2_to_next_bl_params->h.type == PARAM_BL_PARAMS);
assert(bl2_to_next_bl_params->h.version >= VERSION_2);
- assert(bl2_to_next_bl_params->head->ep_info);
+ assert(bl2_to_next_bl_params->head->ep_info != NULL);
/* Populate arg0 for the next BL image if not already provided */
if (bl2_to_next_bl_params->head->ep_info->args.arg0 == (u_register_t)0)
diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S
index 665a05e889..2d672dd12d 100644
--- a/bl31/aarch64/bl31_entrypoint.S
+++ b/bl31/aarch64/bl31_entrypoint.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -110,13 +110,17 @@ func bl31_entrypoint
* caches and participate in coherency.
* --------------------------------------------------------------------
*/
- adr x0, __DATA_START__
- adr x1, __DATA_END__
+ adrp x0, __DATA_START__
+ add x0, x0, :lo12:__DATA_START__
+ adrp x1, __DATA_END__
+ add x1, x1, :lo12:__DATA_END__
sub x1, x1, x0
bl clean_dcache_range
- adr x0, __BSS_START__
- adr x1, __BSS_END__
+ adrp x0, __BSS_START__
+ add x0, x0, :lo12:__BSS_START__
+ adrp x1, __BSS_END__
+ add x1, x1, :lo12:__BSS_END__
sub x1, x1, x0
bl clean_dcache_range
diff --git a/bl31/aarch64/crash_reporting.S b/bl31/aarch64/crash_reporting.S
index f2c12961d5..97db2a1679 100644
--- a/bl31/aarch64/crash_reporting.S
+++ b/bl31/aarch64/crash_reporting.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -244,6 +244,11 @@ func do_crash_reporting
mrs x0, tpidr_el3
/* report x30 first from the crash buf */
ldr x4, [x0, #REGSZ * 7]
+
+#if ENABLE_PAUTH
+ /* Demangle address */
+ xpaci x4
+#endif
bl asm_print_hex
bl asm_print_newline
/* Load the crash buf address */
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 7f739a9aa8..5b37388686 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -414,7 +414,8 @@ smc_handler64:
orr x16, x16, x15, lsl #FUNCID_OEN_WIDTH
/* Load descriptor index from array of indices */
- adr x14, rt_svc_descs_indices
+ adrp x14, rt_svc_descs_indices
+ add x14, x14, :lo12:rt_svc_descs_indices
ldrb w15, [x14, x16]
/* Any index greater than 127 is invalid. Check bit 7. */
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index c7185a893a..4a1c5f3101 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -208,6 +208,7 @@ SECTIONS
* Define a linker symbol to mark end of the RW memory area for this
* image.
*/
+ . = ALIGN(PAGE_SIZE);
__RW_END__ = .;
__BL31_END__ = .;
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 58909e84a2..0948e94e09 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -31,6 +31,7 @@ BL31_SOURCES += bl31/bl31_main.c \
services/arm_arch_svc/arm_arch_svc_setup.c \
services/std_svc/std_svc_setup.c \
${PSCI_LIB_SOURCES} \
+ ${SPMD_SOURCES} \
${SPM_SOURCES}
diff --git a/bl31/bl31_context_mgmt.c b/bl31/bl31_context_mgmt.c
index d41979fa7d..9175ee35d3 100644
--- a/bl31/bl31_context_mgmt.c
+++ b/bl31/bl31_context_mgmt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,7 +11,6 @@
#include <context.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/el3_runtime/cpu_data.h>
-#include <plat/common/platform.h>
/*******************************************************************************
* This function returns a pointer to the most recent 'cpu_context' structure
diff --git a/common/backtrace/backtrace.c b/common/backtrace/backtrace.c
index 506d4a4822..907117f367 100644
--- a/common/backtrace/backtrace.c
+++ b/common/backtrace/backtrace.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -37,47 +37,6 @@ struct frame_record {
uintptr_t return_addr;
};
-/*
- * Strip the Pointer Authentication Code (PAC) from the address to retrieve the
- * original one.
- *
- * The PAC field is stored on the high bits of the address and defined as:
- * - PAC field = Xn[54:bottom_PAC_bit], when address tagging is used.
- * - PAC field = Xn[63:56, 54:bottom_PAC_bit], without address tagging.
- *
- * With bottom_PAC_bit = 64 - TCR_ELx.TnSZ
- */
-#if ENABLE_PAUTH
-static uintptr_t demangle_address(uintptr_t addr)
-{
- unsigned int el, t0sz, bottom_pac_bit;
- uint64_t tcr, pac_mask;
-
- /*
- * Different virtual address space size can be defined for each EL.
- * Ensure that we use the proper one by reading the corresponding
- * TCR_ELx register.
- */
- el = get_current_el();
-
- if (el == 3U) {
- tcr = read_tcr_el3();
- } else if (el == 2U) {
- tcr = read_tcr_el2();
- } else {
- tcr = read_tcr_el1();
- }
-
- /* T0SZ = TCR_ELx[5:0] */
- t0sz = tcr & 0x1f;
- bottom_pac_bit = 64 - t0sz;
- pac_mask = (1ULL << bottom_pac_bit) - 1;
-
- /* demangle the address with the computed mask */
- return (addr & pac_mask);
-}
-#endif /* ENABLE_PAUTH */
-
static const char *get_el_str(unsigned int el)
{
if (el == 3U) {
@@ -104,9 +63,8 @@ static bool is_address_readable(uintptr_t addr)
* stack contains a PAC. It must be stripped to retrieve the return
* address.
*/
- addr = demangle_address(addr);
+ xpaci(addr);
#endif
-
if (el == 3U) {
ats1e3r(addr);
} else if (el == 2U) {
@@ -257,9 +215,8 @@ static void unwind_stack(struct frame_record *fr, uintptr_t current_pc,
* the stack contains a PAC. It must be stripped to retrieve the
* return address.
*/
- call_site = demangle_address(call_site);
+ xpaci(call_site);
#endif
-
/*
* If the address is invalid it means that the frame record is
* probably corrupted.
diff --git a/common/bl_common.c b/common/bl_common.c
index b74225b13f..2fcb5385d9 100644
--- a/common/bl_common.c
+++ b/common/bl_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/common/desc_image_load.c b/common/desc_image_load.c
index f2e8f60546..07692260ec 100644
--- a/common/desc_image_load.c
+++ b/common/desc_image_load.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -215,6 +215,9 @@ void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params)
bl_params_node_t *params_node;
unsigned int fw_config_id;
uintptr_t hw_config_base = 0, fw_config_base;
+#if defined(SPD_spmd)
+ uint32_t fw_config_size = 0;
+#endif
bl_mem_params_node_t *mem_params;
assert(bl2_to_next_bl_params != NULL);
@@ -249,10 +252,14 @@ void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params)
if (fw_config_id != INVALID_IMAGE_ID) {
mem_params = get_bl_mem_params_node(fw_config_id);
- if (mem_params != NULL)
+ if (mem_params != NULL) {
fw_config_base = mem_params->image_info.image_base;
+#if defined(SPD_spmd)
+ fw_config_size =
+ mem_params->image_info.image_size;
+#endif
+ }
}
-
/*
* Pass hw and tb_fw config addresses to next images. NOTE - for
* EL3 runtime images (BL31 for AArch64 and BL32 for AArch32),
@@ -273,6 +280,11 @@ void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params)
if (params_node->ep_info->args.arg1 == 0U)
params_node->ep_info->args.arg1 =
hw_config_base;
+#if defined(SPD_spmd)
+ if (params_node->ep_info->args.arg2 == 0U)
+ params_node->ep_info->args.arg2 =
+ fw_config_size;
+#endif
}
}
}
@@ -301,9 +313,9 @@ void bl31_params_parse_helper(u_register_t param,
image_info_t *bl33_image_info;
} *v1 = (void *)(uintptr_t)param;
assert(v1->h.type == PARAM_BL31);
- if (bl32_ep_info_out)
+ if (bl32_ep_info_out != NULL)
*bl32_ep_info_out = *v1->bl32_ep_info;
- if (bl33_ep_info_out)
+ if (bl33_ep_info_out != NULL)
*bl33_ep_info_out = *v1->bl33_ep_info;
return;
}
@@ -311,12 +323,12 @@ void bl31_params_parse_helper(u_register_t param,
assert(v2->h.version == PARAM_VERSION_2);
assert(v2->h.type == PARAM_BL_PARAMS);
- for (node = v2->head; node; node = node->next_params_info) {
+ for (node = v2->head; node != NULL; node = node->next_params_info) {
if (node->image_id == BL32_IMAGE_ID)
- if (bl32_ep_info_out)
+ if (bl32_ep_info_out != NULL)
*bl32_ep_info_out = *node->ep_info;
if (node->image_id == BL33_IMAGE_ID)
- if (bl33_ep_info_out)
+ if (bl33_ep_info_out != NULL)
*bl33_ep_info_out = *node->ep_info;
}
}
diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c
index e67fdb0054..ca5b4556d3 100644
--- a/common/fdt_wrappers.c
+++ b/common/fdt_wrappers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -103,6 +103,41 @@ int fdtw_read_array(const void *dtb, int node, const char *prop,
}
/*
+ * Read bytes from a given property of the given node. Any number of
+ * bytes of the property can be read. The fdt pointer is updated.
+ * Returns 0 on success, and -1 on error.
+ */
+int fdtw_read_bytes(const void *dtb, int node, const char *prop,
+ unsigned int length, void *value)
+{
+ const void *ptr;
+ int value_len;
+
+ assert(dtb != NULL);
+ assert(prop != NULL);
+ assert(value != NULL);
+ assert(node >= 0);
+
+ /* Access property and obtain its length (in bytes) */
+ ptr = fdt_getprop_namelen(dtb, node, prop, (int)strlen(prop),
+ &value_len);
+ if (ptr == NULL) {
+ WARN("Couldn't find property %s in dtb\n", prop);
+ return -1;
+ }
+
+ /* Verify that property length is not less than number of bytes */
+ if ((unsigned int)value_len < length) {
+ WARN("Property length mismatch\n");
+ return -1;
+ }
+
+ (void)memcpy(value, ptr, length);
+
+ return 0;
+}
+
+/*
* Read string from a given property of the given node. Up to 'size - 1'
* characters are read, and a NUL terminator is added. Returns 0 on success,
* and -1 upon error.
@@ -167,3 +202,45 @@ int fdtw_write_inplace_cells(void *dtb, int node, const char *prop,
return 0;
}
+
+/*
+ * Write bytes in place to a given property of the given node.
+ * Any number of bytes of the property can be written.
+ * Returns 0 on success, and < 0 on error.
+ */
+int fdtw_write_inplace_bytes(void *dtb, int node, const char *prop,
+ unsigned int length, const void *data)
+{
+ const void *ptr;
+ int namelen, value_len, err;
+
+ assert(dtb != NULL);
+ assert(prop != NULL);
+ assert(data != NULL);
+ assert(node >= 0);
+
+ namelen = (int)strlen(prop);
+
+ /* Access property and obtain its length in bytes */
+ ptr = fdt_getprop_namelen(dtb, node, prop, namelen, &value_len);
+ if (ptr == NULL) {
+ WARN("Couldn't find property %s in dtb\n", prop);
+ return -1;
+ }
+
+ /* Verify that property length is not less than number of bytes */
+ if ((unsigned int)value_len < length) {
+ WARN("Property length mismatch\n");
+ return -1;
+ }
+
+ /* Set property value in place */
+ err = fdt_setprop_inplace_namelen_partial(dtb, node, prop,
+ namelen, 0,
+ data, (int)length);
+ if (err != 0) {
+ WARN("Set property %s failed with error %d\n", prop, err);
+ }
+
+ return err;
+}
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index d9d7f84fdd..802dafcd87 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -64,6 +64,14 @@ Amlogic Meson S905X2 (G12A) platform port
:F: drivers/amlogic/g12a
:F: plat/amlogic/g12a/
+Amlogic Meson A113D (AXG) platform port
+-----------------------------------------
+:M: Carlo Caione <ccaione@baylibre.com>
+:G: `carlocaione`_
+:F: docs/plat/meson-axg.rst
+:F: drivers/amlogic/axg
+:F: plat/amlogic/axg/
+
Armv7-A architecture port
-------------------------
:M: Etienne Carriere <etienne.carriere@linaro.org>
diff --git a/docs/change-log-upcoming.rst b/docs/change-log-upcoming.rst
index 3d7d5094d2..14280cbf7a 100644
--- a/docs/change-log-upcoming.rst
+++ b/docs/change-log-upcoming.rst
@@ -23,7 +23,7 @@ New Features
- Example: "Add support for Branch Target Identification (BTI)"
- Build System
- - Example: "Add support for default stack-protector flag"
+ - Add support for documentation build as a target in Makefile
- CPU Support
- Example: "cortex-a55: Workaround for erratum 1221012"
diff --git a/docs/components/exception-handling.rst b/docs/components/exception-handling.rst
index 3f386854f9..e330a62a46 100644
--- a/docs/components/exception-handling.rst
+++ b/docs/components/exception-handling.rst
@@ -467,7 +467,7 @@ SMCs from Non-secure world are synchronous exceptions, and are mechanisms for
Non-secure world to request Secure services. They're broadly classified as
*Fast* or *Yielding* (see `SMCCC`__).
-.. __: `http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html`
+.. __: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
- *Fast* SMCs are atomic from the caller's point of view. I.e., they return
to the caller only when the Secure world has finished serving the request.
@@ -621,6 +621,6 @@ The |EHF| has the following limitations:
--------------
-*Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.*
.. _SDEI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
diff --git a/docs/components/fconf.rst b/docs/components/fconf.rst
new file mode 100644
index 0000000000..cec3cebe4a
--- /dev/null
+++ b/docs/components/fconf.rst
@@ -0,0 +1,85 @@
+Firmware Configuration Framework
+================================
+
+This document provides an overview of the |FCONF| framework.
+
+Introduction
+~~~~~~~~~~~~
+
+The Firmware CONfiguration Framework (|FCONF|) is an abstraction layer for
+platform specific data, allowing a "property" to be queried and a value
+retrieved without the requesting entity knowing what backing store is being used
+to hold the data.
+
+It is used to bridge new and old ways of providing platform-specific data.
+Today, information like the Chain of Trust is held within several, nested
+platform-defined tables. In the future, it may be provided as part of a device
+blob, along with the rest of the information about images to load.
+Introducing this abstraction layer will make migration easier and will preserve
+functionality for platforms that cannot / don't want to use device tree.
+
+Accessing properties
+~~~~~~~~~~~~~~~~~~~~
+
+Properties defined in the |FCONF| are grouped around namespaces and
+sub-namespaces: a.b.property.
+Examples namespace can be:
+
+- (|TBBR|) Chain of Trust data: tbbr.cot.trusted_boot_fw_cert
+- (|TBBR|) dynamic configuration info: tbbr.dyn_config.disable_auth
+- Arm io policies: arm.io_policies.bl2_image
+
+Properties can be accessed with the ``FCONF_GET_PROPERTY(a,b,property)`` macro.
+
+Defining properties
+~~~~~~~~~~~~~~~~~~~
+
+Properties composing the |FCONF| have to be stored in C structures. If another
+backing store is wanted to be used, the platform has to provide a ``populate()``
+function to fill the corresponding C structure.
+
+The ``populate()`` function must be registered to the |FCONF| framework with
+the ``FCONF_REGISTER_POPULATOR()`` macro. This ensures that the function would
+be called inside the generic ``fconf_populate()`` function during
+initialization.
+
+::
+
+ int fconf_populate_tbbr_dyn_config(uintptr_t config)
+ {
+ /* read dtb and fill tbbr_dyn_config struct */
+ }
+
+ FCONF_REGISTER_POPULATOR(fconf_populate_tbbr_dyn_config);
+
+Then, a wrapper has to be provided to match the ``FCONF_GET_PROPERTY()`` macro:
+
+::
+
+ /* generic getter */
+ #define FCONF_GET_PROPERTY(a,b,property) a##__##b##_getter(property)
+
+ /* my specific getter */
+ #define tbbr__dyn_config_getter(id) tbbr_dyn_config.id
+
+This second level wrapper can be used to remap the ``FCONF_GET_PROPERTY()`` to
+anything appropriate: structure, array, function, etc..
+
+Loading the property device tree
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``fconf_load_config()`` must be called to load the device tree containing
+the properties' values. This must be done after the io layer is initialized, as
+the |DTB| is stored on an external device (FIP).
+
+.. uml:: ../resources/diagrams/plantuml/fconf_bl1_load_config.puml
+
+Populating the properties
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Once a valid device tree is available, the ``fconf_populate(config)`` function
+can be used to fill the C data structure with the data from the config |DTB|.
+This function will call all the ``populate()`` callbacks which have been
+registered with ``FCONF_REGISTER_POPULATOR()``.
+
+.. uml:: ../resources/diagrams/plantuml/fconf_bl2_populate.puml
diff --git a/docs/components/index.rst b/docs/components/index.rst
index f1904c0049..6a6b1b0d54 100644
--- a/docs/components/index.rst
+++ b/docs/components/index.rst
@@ -9,6 +9,7 @@ Components
spd/index
arm-sip-service
exception-handling
+ fconf
firmware-update
platform-interrupt-controller-API
ras
diff --git a/docs/design/trusted-board-boot-build.rst b/docs/design/trusted-board-boot-build.rst
index 2025243164..f5c8bc98c8 100644
--- a/docs/design/trusted-board-boot-build.rst
+++ b/docs/design/trusted-board-boot-build.rst
@@ -33,7 +33,7 @@ images with support for these features:
- ``GENERATE_COT=1``
In the case of Arm platforms, the location of the ROTPK hash must also be
- specified at build time. Two locations are currently supported (see
+ specified at build time. The following locations are currently supported (see
``ARM_ROTPK_LOCATION`` build option):
- ``ARM_ROTPK_LOCATION=regs``: the ROTPK hash is obtained from the Trusted
@@ -41,17 +41,16 @@ images with support for these features:
registers are read-only. On FVP Base and Cortex models, the registers
are read-only, but the value can be specified using the command line
option ``bp.trusted_key_storage.public_key`` when launching the model.
- On both Juno and FVP models, the default value corresponds to an
- ECDSA-SECP256R1 public key hash, whose private part is not currently
- available.
+ On Juno board, the default value corresponds to an ECDSA-SECP256R1 public
+ key hash, whose private part is not currently available.
- - ``ARM_ROTPK_LOCATION=devel_rsa``: use the ROTPK hash that is hardcoded
- in the Arm platform port. The private/public RSA key pair may be
- found in ``plat/arm/board/common/rotpk``.
+ - ``ARM_ROTPK_LOCATION=devel_rsa``: use the default hash located in
+ plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin. Enforce generation
+ of the new hash if ROT_KEY is specified.
- - ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the ROTPK hash that is hardcoded
- in the Arm platform port. The private/public ECDSA key pair may be
- found in ``plat/arm/board/common/rotpk``.
+ - ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the default hash located in
+ plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin. Enforce generation
+ of the new hash if ROT_KEY is specified.
Example of command line using RSA development keys:
@@ -108,7 +107,7 @@ images with support for these features:
--------------
-*Copyright (c) 2019, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
.. _mbed TLS Repository: https://github.com/ARMmbed/mbedtls.git
.. _mbed TLS Security Center: https://tls.mbed.org/security
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 2f44fe817e..8854a7989e 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -189,7 +189,7 @@ Common build options
that is only required for the assertion and does not fit in the assertion
itself.
-- ``ENABLE_BACKTRACE``: This option controls whether to enables backtrace
+- ``ENABLE_BACKTRACE``: This option controls whether to enable backtrace
dumps or not. It is supported in both AArch64 and AArch32. However, in
AArch32 the format of the frame records are not defined in the AAPCS and they
are defined by the implementation. This implementation of backtrace only
@@ -310,8 +310,8 @@ Common build options
EL1 for handling. The default value of this option is ``0``, which means the
Group 0 interrupts are assumed to be handled by Secure EL1.
- .. __: `platform-interrupt-controller-API.rst`
- .. __: `interrupt-framework-design.rst`
+ .. __: platform-interrupt-controller-API.rst
+ .. __: interrupt-framework-design.rst
- ``HANDLE_EA_EL3_FIRST``: When set to ``1``, External Aborts and SError
Interrupts will be always trapped in EL3 i.e. in BL31 at runtime. When set to
@@ -468,7 +468,8 @@ Common build options
entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default value is 0.
- ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
- file that contains the ROT private key in PEM format. If ``SAVE_KEYS=1``, this
+ file that contains the ROT private key in PEM format and enforces public key
+ hash generation. If ``SAVE_KEYS=1``, this
file name will be used to save the key.
- ``SAVE_KEYS``: This option is used when ``GENERATE_COT=1``. It tells the
@@ -577,6 +578,11 @@ Common build options
exposing a virtual filesystem interface through BL31 as a SiP SMC function.
Default is 0.
+- ``USE_FCONF_BASED_IO``: This flag determines whether to use IO based on the
+ firmware configuration framework. This allows moving the io_policies into a
+ configuration device tree, instead of static structure in the code base.
+
+
- ``USE_ROMLIB``: This flag determines whether library at ROM will be used.
This feature creates a library of functions to be placed in ROM and thus
reduces SRAM usage. Refer to :ref:`Library at ROM` for further details. Default
@@ -657,4 +663,4 @@ commands can be used:
--------------
-*Copyright (c) 2019, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/docs/getting_started/docs-build.rst b/docs/getting_started/docs-build.rst
index c5625e98db..91b1b3a397 100644
--- a/docs/getting_started/docs-build.rst
+++ b/docs/getting_started/docs-build.rst
@@ -56,21 +56,28 @@ as root or using ``sudo``.
Building rendered documentation
-------------------------------
-From the ``docs`` directory of the project, run the following commands. It is
-important to note that you will not get the correct result if the commands are
-run from the project root directory, as that would invoke the top-level Makefile
-for |TF-A| itself.
+Documents can be built into HTML-formatted pages from project root directory by
+running the following command.
.. code:: shell
- make clean
- make html
+ make doc
Output from the build process will be placed in:
::
- <tf-a root>/docs/build/html/
+ docs/build/html/
+
+We also support building documentation in other formats. From the ``docs``
+directory of the project, run the following command to see the supported
+formats. It is important to note that you will not get the correct result if
+the command is run from the project root directory, as that would invoke the
+top-level Makefile for |TF-A| itself.
+
+.. code:: shell
+
+ make help
--------------
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index bb14717523..e8357b385e 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -2763,6 +2763,19 @@ build system.
to ``no``. If any of the options ``EL3_PAYLOAD_BASE`` or ``PRELOADED_BL33_BASE``
are used, this flag will be set to ``no`` automatically.
+Platform include paths
+----------------------
+
+Platforms are allowed to add more include paths to be passed to the compiler.
+The ``PLAT_INCLUDES`` variable is used for this purpose. This is needed in
+particular for the file ``platform_def.h``.
+
+Example:
+
+.. code:: c
+
+ PLAT_INCLUDES += -Iinclude/plat/myplat/include
+
C Library
---------
@@ -2844,7 +2857,7 @@ amount of open resources per driver.
--------------
-*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.*
.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
.. _Arm Generic Interrupt Controller version 2.0 (GICv2): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0048b/index.html
diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt
index 491b160e65..4dda1dcd4d 100644
--- a/docs/global_substitutions.txt
+++ b/docs/global_substitutions.txt
@@ -6,11 +6,13 @@
.. |COT| replace:: :term:`COT`
.. |CSS| replace:: :term:`CSS`
.. |CVE| replace:: :term:`CVE`
+.. |DTB| replace:: :term:`DTB`
.. |DS-5| replace:: :term:`DS-5`
.. |DSU| replace:: :term:`DSU`
.. |DT| replace:: :term:`DT`
.. |EL| replace:: :term:`EL`
.. |EHF| replace:: :term:`EHF`
+.. |FCONF| replace:: :term:`FCONF`
.. |FDT| replace:: :term:`FDT`
.. |FIP| replace:: :term:`FIP`
.. |FVP| replace:: :term:`FVP`
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 2f19df59c7..3da30b02a1 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -42,12 +42,18 @@ You can find additional definitions in the `Arm Glossary`_.
DT
Device Tree
+ DTB
+ Device Tree Blob
+
EL
Exception Level
EHF
Exception Handling Framework
+ FCONF
+ Firmware Configuration Framework
+
FDT
Flattened Device Tree
diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
index d24ad231d8..9622de65df 100644
--- a/docs/plat/arm/arm-build-options.rst
+++ b/docs/plat/arm/arm-build-options.rst
@@ -57,8 +57,7 @@ Arm Platform Build Options
``ARM_ROTPK_LOCATION`` are:
- ``regs`` : return the ROTPK hash stored in the Trusted root-key storage
- registers. The private key corresponding to this ROTPK hash is not
- currently available.
+ registers.
- ``devel_rsa`` : return a development public key hash embedded in the BL1
and BL2 binaries. This hash has been obtained from the RSA public key
``arm_rotpk_rsa.der``, located in ``plat/arm/board/common/rotpk``. To use
@@ -70,6 +69,12 @@ Arm Platform Build Options
use this option, ``arm_rotprivk_ecdsa.pem`` must be specified as
``ROT_KEY`` when creating the certificates.
+- ``ARM_ROTPK_HASH``: used when ``ARM_ROTPK_LOCATION=devel_*``. Specifies the
+ location of the ROTPK hash. Not expected to be a build option. This defaults to
+ ``plat/arm/board/common/rotpk/*_sha256.bin`` depending on the specified algorithm.
+ Providing ``ROT_KEY`` enforces generation of the hash from the ``ROT_KEY`` and
+ overwrites the default hash file.
+
- ``ARM_TSP_RAM_LOCATION``: location of the TSP binary. Options:
- ``tsram`` : Trusted SRAM (default option when TBB is not enabled)
@@ -109,6 +114,11 @@ Arm CSS Platform-Specific Build Options
management operations and for SCP RAM Firmware transfer. If this option
is set to 1, then SCMI/SDS drivers will be used. Default is 0.
+ - ``CSS_SGI_CHIP_COUNT``: Configures the number of chips on a SGI/RD platform
+ which supports multi-chip operation. If ``CSS_SGI_CHIP_COUNT`` is set to any
+ valid value greater than 1, the platform code performs required configuration
+ to support multi-chip operation.
+
--------------
-*Copyright (c) 2019, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/docs/plat/meson-axg.rst b/docs/plat/meson-axg.rst
new file mode 100644
index 0000000000..1e4b2c207b
--- /dev/null
+++ b/docs/plat/meson-axg.rst
@@ -0,0 +1,27 @@
+Amlogic Meson A113D (AXG)
+===========================
+
+The Amlogic Meson A113D is a SoC with a quad core Arm Cortex-A53 running at
+~1.2GHz. It also contains a Cortex-M3 used as SCP.
+
+This port is a minimal implementation of BL31 capable of booting mainline U-Boot
+and Linux:
+
+- SCPI support.
+- Basic PSCI support (CPU_ON, CPU_OFF, SYSTEM_RESET, SYSTEM_OFF). Note that CPU0
+ can't be turned off, so there is a workaround to hide this from the caller.
+- GICv2 driver set up.
+- Basic SIP services (read efuse data, enable/disable JTAG).
+
+In order to build it:
+
+.. code:: shell
+
+ CROSS_COMPILE=aarch64-none-elf- make DEBUG=1 PLAT=axg [SPD=opteed]
+ [AML_USE_ATOS=1 when using ATOS as BL32]
+
+This port has been tested on a A113D board. After building it, follow the
+instructions in the `U-Boot repository`_, replacing the mentioned **bl31.img**
+by the one built from this port.
+
+.. _U-Boot repository: https://github.com/u-boot/u-boot/blob/master/board/amlogic/s400/README
diff --git a/docs/plat/qemu.rst b/docs/plat/qemu.rst
index a4c5bec715..88196bc93c 100644
--- a/docs/plat/qemu.rst
+++ b/docs/plat/qemu.rst
@@ -14,7 +14,7 @@ If ``ARM_LINUX_KERNEL_AS_BL33`` is set to 1 then this FDT will be passed to BL33
via register x0, as expected by a Linux kernel. This allows a Linux kernel image
to be booted directly as BL33 rather than using a bootloader.
-An ARM64 defconfig v4.5 Linux kernel is known to boot, FDT doesn't need to be
+An ARM64 defconfig v5.5 Linux kernel is known to boot, FDT doesn't need to be
provided as it's generated by QEMU.
Current limitations:
@@ -24,7 +24,7 @@ Current limitations:
- No instructions for how to load a BL32 (Secure Payload)
``QEMU_EFI.fd`` can be dowloaded from
-http://snapshots.linaro.org/components/kernel/leg-virt-tianocore-edk2-upstream/latest/QEMU-KERNEL-AARCH64/RELEASE_GCC49/QEMU_EFI.fd
+http://snapshots.linaro.org/components/kernel/leg-virt-tianocore-edk2-upstream/latest/QEMU-KERNEL-AARCH64/RELEASE_GCC5/QEMU_EFI.fd
Boot binaries, except BL1, are primarily loaded via semi-hosting so all
binaries has to reside in the same directory as QEMU is started from. This
@@ -33,7 +33,7 @@ is conveniently achieved with symlinks the local names as:
- ``bl2.bin`` -> BL2
- ``bl31.bin`` -> BL31
- ``bl33.bin`` -> BL33 (``QEMU_EFI.fd``)
-- ``Image`` -> linux/Image
+- ``Image`` -> linux/arch/arm64/boot/Image
To build:
@@ -41,12 +41,12 @@ To build:
make CROSS_COMPILE=aarch64-none-elf- PLAT=qemu
-To start (QEMU v2.6.0):
+To start (QEMU v4.1.0):
.. code:: shell
qemu-system-aarch64 -nographic -machine virt,secure=on -cpu cortex-a57 \
-kernel Image \
- -append console=ttyAMA0,38400 keep_bootcon root=/dev/vda2 \
+ -append "console=ttyAMA0,38400 keep_bootcon root=/dev/vda2" \
-initrd rootfs-arm64.cpio.gz -smp 2 -m 1024 -bios bl1.bin \
-d unimp -semihosting-config enable,target=native
diff --git a/docs/process/coding-guidelines.rst b/docs/process/coding-guidelines.rst
index cb8b892455..f7d53a97eb 100644
--- a/docs/process/coding-guidelines.rst
+++ b/docs/process/coding-guidelines.rst
@@ -1,232 +1,126 @@
-Coding Style & Guidelines
-=========================
+Coding Guidelines
+=================
-The following sections contain TF coding guidelines. They are continually
-evolving and should not be considered "set in stone". Feel free to question them
-and provide feedback.
+This document provides some additional guidelines to consider when writing
+|TF-A| code. These are not intended to be strictly-enforced rules like the
+contents of the :ref:`Coding Style`.
-Some of the guidelines may also apply to other codebases.
+Automatic Editor Configuration
+------------------------------
-.. note::
- The existing TF codebase does not necessarily comply with all the
- below guidelines but the intent is for it to do so eventually.
-
-Checkpatch overrides
---------------------
-
-Some checkpatch warnings in the TF codebase are deliberately ignored. These
-include:
-
-- ``**WARNING: line over 80 characters**``: Although the codebase should
- generally conform to the 80 character limit this is overly restrictive in some
- cases.
-
-- ``**WARNING: Use of volatile is usually wrong``: see
- `Why the “volatile” type class should not be used`_ . Although this document
- contains some very useful information, there are several legitimate uses of
- the volatile keyword within the TF codebase.
-
-Headers and inclusion
----------------------
-
-Header guards
-^^^^^^^^^^^^^
-
-For a header file called "some_driver.h" the style used by the Trusted Firmware
-is:
-
-.. code:: c
-
- #ifndef SOME_DRIVER_H
- #define SOME_DRIVER_H
-
- <header content>
-
- #endif /* SOME_DRIVER_H */
+Many of the rules given below (such as indentation size, use of tabs, and
+newlines) can be set automatically using the `EditorConfig`_ configuration file
+in the root of the repository: ``.editorconfig``. With a supported editor, the
+rules set out in this file can be automatically applied when you are editing
+files in the |TF-A| repository.
-Include statement ordering
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-All header files that are included by a source file must use the following,
-grouped ordering. This is to improve readability (by making it easier to quickly
-read through the list of headers) and maintainability.
-
-#. *System* includes: Header files from the standard *C* library, such as
- ``stddef.h`` and ``string.h``.
-
-#. *Project* includes: Header files under the ``include/`` directory within TF
- are *project* includes.
-
-#. *Platform* includes: Header files relating to a single, specific platform,
- and which are located under the ``plat/<platform_name>`` directory within TF,
- are *platform* includes.
-
-Within each group, ``#include`` statements must be in alphabetical order,
-taking both the file and directory names into account.
-
-Groups must be separated by a single blank line for clarity.
-
-The example below illustrates the ordering rules using some contrived header
-file names; this type of name reuse should be otherwise avoided.
-
-.. code:: c
-
- #include <string.h>
-
- #include <a_dir/example/a_header.h>
- #include <a_dir/example/b_header.h>
- #include <a_dir/test/a_header.h>
- #include <b_dir/example/a_header.h>
-
- #include "./a_header.h"
-
-Include statement variants
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Two variants of the ``#include`` directive are acceptable in the TF codebase.
-Correct use of the two styles improves readability by suggesting the location
-of the included header and reducing ambiguity in cases where generic and
-platform-specific headers share a name.
-
-For header files that are in the same directory as the source file that is
-including them, use the ``"..."`` variant.
-
-For header files that are **not** in the same directory as the source file that
-is including them, use the ``<...>`` variant.
-
-Example (bl1_fwu.c):
-
-.. code:: c
+Several editors include built-in support for EditorConfig files, and many others
+support its functionality through plugins.
- #include <assert.h>
- #include <errno.h>
- #include <string.h>
+Use of the EditorConfig file is suggested but is not required.
- #include "bl1_private.h"
-Platform include paths
-^^^^^^^^^^^^^^^^^^^^^^
-
-Platforms are allowed to add more include paths to be passed to the compiler.
-The ``PLAT_INCLUDES`` variable is used for this purpose. This is needed in
-particular for the file ``platform_def.h``.
-
-Example:
-
-.. code:: c
-
- PLAT_INCLUDES += -Iinclude/plat/myplat/include
+Automatic Compliance Checking
+-----------------------------
-Types and typedefs
-------------------
+To assist with coding style compliance, the project Makefile contains two
+targets which both utilise the `checkpatch.pl` script that ships with the Linux
+source tree. The project also defines certain *checkpatch* options in the
+``.checkpatch.conf`` file in the top-level directory.
-Use of built-in *C* and *libc* data types
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. note::
+ Checkpatch errors will gate upstream merging of pull requests.
+ Checkpatch warnings will not gate merging but should be reviewed and fixed if
+ possible.
-The TF codebase should be kept as portable as possible, especially since both
-64-bit and 32-bit platforms are supported. To help with this, the following data
-type usage guidelines should be followed:
+To check the entire source tree, you must first download copies of
+``checkpatch.pl``, ``spelling.txt`` and ``const_structs.checkpatch`` available
+in the `Linux master tree`_ *scripts* directory, then set the ``CHECKPATCH``
+environment variable to point to ``checkpatch.pl`` (with the other 2 files in
+the same directory) and build the `checkcodebase` target:
-- Where possible, use the built-in *C* data types for variable storage (for
- example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99*
- types. Most code is typically only concerned with the minimum size of the
- data stored, which the built-in *C* types guarantee.
-
-- Avoid using the exact-size standard *C99* types in general (for example,
- ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the
- compiler from making optimizations. There are legitimate uses for them,
- for example to represent data of a known structure. When using them in struct
- definitions, consider how padding in the struct will work across architectures.
- For example, extra padding may be introduced in AArch32 systems if a struct
- member crosses a 32-bit boundary.
+.. code:: shell
-- Use ``int`` as the default integer type - it's likely to be the fastest on all
- systems. Also this can be assumed to be 32-bit as a consequence of the
- `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call
- Standard for the Arm 64-bit Architecture`_ .
+ make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkcodebase
-- Avoid use of ``short`` as this may end up being slower than ``int`` in some
- systems. If a variable must be exactly 16-bit, use ``int16_t`` or
- ``uint16_t``.
+To just check the style on the files that differ between your local branch and
+the remote master, use:
-- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given
- that `int` is 32-bit on Arm platforms, there is no use for it. For integers of
- at least 64-bit, use ``long long``.
+.. code:: shell
-- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data.
+ make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkpatch
-- Use ``unsigned`` for integers that can never be negative (counts,
- indices, sizes, etc). TF intends to comply with MISRA "essential type" coding
- rules (10.X), where signed and unsigned types are considered different
- essential types. Choosing the correct type will aid this. MISRA static
- analysers will pick up any implicit signed/unsigned conversions that may lead
- to unexpected behaviour.
+If you wish to check your patch against something other than the remote master,
+set the ``BASE_COMMIT`` variable to your desired branch. By default,
+``BASE_COMMIT`` is set to ``origin/master``.
-- For pointer types:
+Ignored Checkpatch Warnings
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
- - If an argument in a function declaration is pointing to a known type then
- simply use a pointer to that type (for example: ``struct my_struct *``).
+Some checkpatch warnings in the TF codebase are deliberately ignored. These
+include:
- - If a variable (including an argument in a function declaration) is pointing
- to a general, memory-mapped address, an array of pointers or another
- structure that is likely to require pointer arithmetic then use
- ``uintptr_t``. This will reduce the amount of casting required in the code.
- Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it
- may work but is less portable.
+- ``**WARNING: line over 80 characters**``: Although the codebase should
+ generally conform to the 80 character limit this is overly restrictive in some
+ cases.
- - For other pointer arguments in a function declaration, use ``void *``. This
- includes pointers to types that are abstracted away from the known API and
- pointers to arbitrary data. This allows the calling function to pass a
- pointer argument to the function without any explicit casting (the cast to
- ``void *`` is implicit). The function implementation can then do the
- appropriate casting to a specific type.
+- ``**WARNING: Use of volatile is usually wrong``: see
+ `Why the “volatile” type class should not be used`_ . Although this document
+ contains some very useful information, there are several legimate uses of the
+ volatile keyword within the TF codebase.
- - Use ``ptrdiff_t`` to compare the difference between 2 pointers.
+Performance considerations
+--------------------------
-- Use ``size_t`` when storing the ``sizeof()`` something.
+Avoid printf and use logging macros
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that
- can also return an error code; the signed type allows for a negative return
- code in case of error. This practice should be used sparingly.
+``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``)
+which wrap ``tf_log`` and which allow the logging call to be compiled-out
+depending on the ``make`` command. Use these macros to avoid print statements
+being compiled unconditionally into the binary.
-- Use ``u_register_t`` when it's important to store the contents of a register
- in its native size (32-bit in AArch32 and 64-bit in AArch64). This is not a
- standard *C99* type but is widely available in libc implementations,
- including the FreeBSD version included with the TF codebase. Where possible,
- cast the variable to a more appropriate type before interpreting the data. For
- example, the following struct in ``ep_info.h`` could use this type to minimize
- the storage required for the set of registers:
+Each logging macro has a numerical log level:
.. code:: c
- typedef struct aapcs64_params {
- u_register_t arg0;
- u_register_t arg1;
- u_register_t arg2;
- u_register_t arg3;
- u_register_t arg4;
- u_register_t arg5;
- u_register_t arg6;
- u_register_t arg7;
- } aapcs64_params_t;
+ #define LOG_LEVEL_NONE 0
+ #define LOG_LEVEL_ERROR 10
+ #define LOG_LEVEL_NOTICE 20
+ #define LOG_LEVEL_WARNING 30
+ #define LOG_LEVEL_INFO 40
+ #define LOG_LEVEL_VERBOSE 50
-If some code wants to operate on ``arg0`` and knows that it represents a 32-bit
-unsigned integer on all systems, cast it to ``unsigned int``.
+By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will
+be compiled into debug builds and all statements with a log level
+``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be
+overridden from the command line or by the platform makefile (although it may be
+necessary to clean the build directory first). For example, to enable
+``VERBOSE`` logging on FVP:
-These guidelines should be updated if additional types are needed.
+``make PLAT=fvp LOG_LEVEL=50 all``
-Avoid anonymous typedefs of structs/enums in headers
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Use const data where possible
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-For example, the following definition:
+For example, the following code:
.. code:: c
- typedef struct {
+ struct my_struct {
int arg1;
int arg2;
- } my_struct_t;
+ };
+ void init(struct my_struct *ptr);
+
+ void main(void)
+ {
+ struct my_struct x;
+ x.arg1 = 1;
+ x.arg2 = 2;
+ init(&x);
+ }
is better written as:
@@ -237,31 +131,18 @@ is better written as:
int arg2;
};
-This allows function declarations in other header files that depend on the
-struct/enum to forward declare the struct/enum instead of including the
-entire header:
-
-.. code:: c
-
- #include <my_struct.h>
- void my_func(my_struct_t *arg);
-
-instead of:
-
-.. code:: c
-
- struct my_struct;
- void my_func(struct my_struct *arg);
-
-Some TF definitions use both a struct/enum name **and** a typedef name. This
-is discouraged for new definitions as it makes it difficult for TF to comply
-with MISRA rule 8.3, which states that "All declarations of an object or
-function shall use the same names and type qualifiers".
+ void init(const struct my_struct *ptr);
-The Linux coding standards also discourage new typedefs and checkpatch emits
-a warning for this.
+ void main(void)
+ {
+ const struct my_struct x = { 1, 2 };
+ init(&x);
+ }
-Existing typedefs will be retained for compatibility.
+This allows the linker to put the data in a read-only data section instead of a
+writeable data section, which may result in a smaller and faster binary. Note
+that this may require dependent functions (``init()`` in the above example) to
+have ``const`` arguments, assuming they don't need to modify the data.
Libc functions that are banned or to be used with caution
---------------------------------------------------------
@@ -410,14 +291,14 @@ error. This situation should be handled in one of the following ways:
then emit an ``ERROR`` message and call the platform-specific function
``plat_error_handler()``.
-Cases 1 and 2 are subtly different. A platform may implement ``plat_panic_handler``
-and ``plat_error_handler`` in the same way (for example, by waiting for a secure
-watchdog to time-out or by invoking an interface on the platform's power
-controller to reset the platform). However, ``plat_error_handler`` may take
-additional action for some errors (for example, it may set a flag so the
-platform resets into a different mode). Also, ``plat_panic_handler()`` may
-implement additional debug functionality (for example, invoking a hardware
-breakpoint).
+Cases 1 and 2 are subtly different. A platform may implement
+``plat_panic_handler`` and ``plat_error_handler`` in the same way (for example,
+by waiting for a secure watchdog to time-out or by invoking an interface on the
+platform's power controller to reset the platform). However,
+``plat_error_handler`` may take additional action for some errors (for example,
+it may set a flag so the platform resets into a different mode). Also,
+``plat_panic_handler()`` may implement additional debug functionality (for
+example, invoking a hardware breakpoint).
Examples of unexpected unrecoverable errors:
@@ -456,131 +337,115 @@ Examples:
- Secure world is waiting for a hardware response that is critical for continued
operation.
-Security considerations
------------------------
-
-Part of the security of a platform is handling errors correctly, as described in
-the previous section. There are several other security considerations covered in
-this section.
-
-Do not leak secrets to the normal world
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The secure world **must not** leak secrets to the normal world, for example in
-response to an SMC.
-
-Handling Denial of Service attacks
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Use of built-in *C* and *libc* data types
+-----------------------------------------
-The secure world **should never** crash or become unusable due to receiving too
-many normal world requests (a *Denial of Service* or *DoS* attack). It should
-have a mechanism for throttling or ignoring normal world requests.
+The |TF-A| codebase should be kept as portable as possible, especially since
+both 64-bit and 32-bit platforms are supported. To help with this, the following
+data type usage guidelines should be followed:
-Performance considerations
---------------------------
+- Where possible, use the built-in *C* data types for variable storage (for
+ example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99*
+ types. Most code is typically only concerned with the minimum size of the
+ data stored, which the built-in *C* types guarantee.
-Avoid printf and use logging macros
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+- Avoid using the exact-size standard *C99* types in general (for example,
+ ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the
+ compiler from making optimizations. There are legitimate uses for them,
+ for example to represent data of a known structure. When using them in struct
+ definitions, consider how padding in the struct will work across architectures.
+ For example, extra padding may be introduced in |AArch32| systems if a struct
+ member crosses a 32-bit boundary.
-``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``)
-which wrap ``tf_log`` and which allow the logging call to be compiled-out
-depending on the ``make`` command. Use these macros to avoid print statements
-being compiled unconditionally into the binary.
+- Use ``int`` as the default integer type - it's likely to be the fastest on all
+ systems. Also this can be assumed to be 32-bit as a consequence of the
+ `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call
+ Standard for the Arm 64-bit Architecture`_ .
-Each logging macro has a numerical log level:
+- Avoid use of ``short`` as this may end up being slower than ``int`` in some
+ systems. If a variable must be exactly 16-bit, use ``int16_t`` or
+ ``uint16_t``.
-.. code:: c
+- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given
+ that `int` is 32-bit on Arm platforms, there is no use for it. For integers of
+ at least 64-bit, use ``long long``.
- #define LOG_LEVEL_NONE 0
- #define LOG_LEVEL_ERROR 10
- #define LOG_LEVEL_NOTICE 20
- #define LOG_LEVEL_WARNING 30
- #define LOG_LEVEL_INFO 40
- #define LOG_LEVEL_VERBOSE 50
+- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data.
+- Use ``unsigned`` for integers that can never be negative (counts,
+ indices, sizes, etc). TF intends to comply with MISRA "essential type" coding
+ rules (10.X), where signed and unsigned types are considered different
+ essential types. Choosing the correct type will aid this. MISRA static
+ analysers will pick up any implicit signed/unsigned conversions that may lead
+ to unexpected behaviour.
-By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will
-be compiled into debug builds and all statements with a log level
-``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be
-overridden from the command line or by the platform makefile (although it may be
-necessary to clean the build directory first). For example, to enable
-``VERBOSE`` logging on FVP:
+- For pointer types:
-``make PLAT=fvp LOG_LEVEL=50 all``
+ - If an argument in a function declaration is pointing to a known type then
+ simply use a pointer to that type (for example: ``struct my_struct *``).
-Use const data where possible
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ - If a variable (including an argument in a function declaration) is pointing
+ to a general, memory-mapped address, an array of pointers or another
+ structure that is likely to require pointer arithmetic then use
+ ``uintptr_t``. This will reduce the amount of casting required in the code.
+ Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it
+ may work but is less portable.
-For example, the following code:
+ - For other pointer arguments in a function declaration, use ``void *``. This
+ includes pointers to types that are abstracted away from the known API and
+ pointers to arbitrary data. This allows the calling function to pass a
+ pointer argument to the function without any explicit casting (the cast to
+ ``void *`` is implicit). The function implementation can then do the
+ appropriate casting to a specific type.
-.. code:: c
+ - Avoid pointer arithmetic generally (as this violates MISRA C 2012 rule
+ 18.4) and especially on void pointers (as this is only supported via
+ language extensions and is considered non-standard). In TF-A, setting the
+ ``W`` build flag to ``W=3`` enables the *-Wpointer-arith* compiler flag and
+ this will emit warnings where pointer arithmetic is used.
- struct my_struct {
- int arg1;
- int arg2;
- };
+ - Use ``ptrdiff_t`` to compare the difference between 2 pointers.
- void init(struct my_struct *ptr);
+- Use ``size_t`` when storing the ``sizeof()`` something.
- void main(void)
- {
- struct my_struct x;
- x.arg1 = 1;
- x.arg2 = 2;
- init(&x);
- }
+- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that
+ can also return an error code; the signed type allows for a negative return
+ code in case of error. This practice should be used sparingly.
-is better written as:
+- Use ``u_register_t`` when it's important to store the contents of a register
+ in its native size (32-bit in |AArch32| and 64-bit in |AArch64|). This is not a
+ standard *C99* type but is widely available in libc implementations,
+ including the FreeBSD version included with the TF codebase. Where possible,
+ cast the variable to a more appropriate type before interpreting the data. For
+ example, the following struct in ``ep_info.h`` could use this type to minimize
+ the storage required for the set of registers:
.. code:: c
- struct my_struct {
- int arg1;
- int arg2;
- };
-
- void init(const struct my_struct *ptr);
-
- void main(void)
- {
- const struct my_struct x = { 1, 2 };
- init(&x);
- }
-
-This allows the linker to put the data in a read-only data section instead of a
-writeable data section, which may result in a smaller and faster binary. Note
-that this may require dependent functions (``init()`` in the above example) to
-have ``const`` arguments, assuming they don't need to modify the data.
-
-Library and driver code
------------------------
-
-TF library code (under ``lib/`` and ``include/lib``) is any code that provides a
-reusable interface to other code, potentially even to code outside of TF.
-
-In some systems drivers must conform to a specific driver framework to provide
-services to the rest of the system. TF has no driver framework and the
-distinction between a driver and library is somewhat subjective.
+ typedef struct aapcs64_params {
+ u_register_t arg0;
+ u_register_t arg1;
+ u_register_t arg2;
+ u_register_t arg3;
+ u_register_t arg4;
+ u_register_t arg5;
+ u_register_t arg6;
+ u_register_t arg7;
+ } aapcs64_params_t;
-A driver (under ``drivers/`` and ``include/drivers/``) is defined as code that
-interfaces with hardware via a memory mapped interface.
+If some code wants to operate on ``arg0`` and knows that it represents a 32-bit
+unsigned integer on all systems, cast it to ``unsigned int``.
-Some drivers (for example, the Arm CCI driver in ``include/drivers/arm/cci.h``)
-provide a general purpose API to that specific hardware. Other drivers (for
-example, the Arm PL011 console driver in ``drivers/arm/pl011/pl011_console.S``)
-provide a specific hardware implementation of a more abstract library API. In
-the latter case there may potentially be multiple drivers for the same hardware
-device.
+These guidelines should be updated if additional types are needed.
-Neither libraries nor drivers should depend on platform-specific code. If they
-require platform-specific data (for example, a base address) to operate then
-they should provide an initialization function that takes the platform-specific
-data as arguments.
+--------------
-TF common code (under ``common/`` and ``include/common/``) is code that is re-used
-by other generic (non-platform-specific) TF code. It is effectively internal
-library code.
+*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.*
+.. _`Linux master tree`: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/
+.. _`Procedure Call Standard for the Arm Architecture`: https://developer.arm.com/docs/ihi0042/latest/
+.. _`Procedure Call Standard for the Arm 64-bit Architecture`: https://developer.arm.com/docs/ihi0055/latest/
+.. _`EditorConfig`: http://editorconfig.org/
.. _`Why the “volatile” type class should not be used`: https://www.kernel.org/doc/html/latest/process/volatile-considered-harmful.html
-.. _`Procedure Call Standard for the Arm Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf
-.. _`Procedure Call Standard for the Arm 64-bit Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
+.. _`MISRA C:2012 Guidelines`: https://www.misra.org.uk/Activities/MISRAC/tabid/160/Default.aspx
+.. _`a spreadsheet`: https://developer.trustedfirmware.org/file/download/lamajxif3w7c4mpjeoo5/PHID-FILE-fp7c7acszn6vliqomyhn/MISRA-and-TF-Analysis-v1.3.ods
diff --git a/docs/process/coding-style.rst b/docs/process/coding-style.rst
new file mode 100644
index 0000000000..fd1984d303
--- /dev/null
+++ b/docs/process/coding-style.rst
@@ -0,0 +1,468 @@
+Coding Style
+============
+
+The following sections outline the |TF-A| coding style for *C* code. The style
+is based on the `Linux kernel coding style`_, with a few modifications.
+
+The style should not be considered *set in stone*. Feel free to provide feedback
+and suggestions.
+
+.. note::
+ You will almost certainly find code in the |TF-A| repository that does not
+ follow the style. The intent is for all code to do so eventually.
+
+File Encoding
+-------------
+
+The source code must use the **UTF-8** character encoding. Comments and
+documentation may use non-ASCII characters when required (e.g. Greek letters
+used for units) but code itself is still limited to ASCII characters.
+
+Newlines must be in **Unix** style, which means that only the Line Feed (``LF``)
+character is used to break a line and reset to the first column.
+
+Language
+--------
+
+The primary language for comments and naming must be International English. In
+cases where there is a conflict between the American English and British English
+spellings of a word, the American English spelling is used.
+
+Exceptions are made when referring directly to something that does not use
+international style, such as the name of a company. In these cases the existing
+name should be used as-is.
+
+C Language Standard
+-------------------
+
+The C language mode used for TF-A is *GNU99*. This is the "GNU dialect of ISO
+C99", which implies the *ISO C99* standard with GNU extensions.
+
+Both GCC and Clang compiler toolchains have support for *GNU99* mode, though
+Clang does lack support for a small number of GNU extensions. These
+missing extensions are rarely used, however, and should not pose a problem.
+
+MISRA Compliance
+----------------
+
+TF-A attempts to comply with the `MISRA C:2012 Guidelines`_. Coverity
+Static Analysis is used to regularly generate a report of current MISRA defects
+and to prevent the addition of new ones.
+
+It is not possible for the project to follow all MISRA guidelines. We maintain
+`a spreadsheet`_ that lists all rules and directives and whether we aim to
+comply with them or not. A rationale is given for each deviation.
+
+.. note::
+ Enforcing a rule does not mean that the codebase is free of defects
+ of that rule, only that they would ideally be removed.
+
+.. note::
+ Third-party libraries are not considered in our MISRA analysis and we do not
+ intend to modify them to make them MISRA compliant.
+
+Indentation
+-----------
+
+Use **tabs** for indentation. The use of spaces for indentation is forbidden
+except in the case where a term is being indented to a boundary that cannot be
+achieved using tabs alone.
+
+Tab spacing should be set to **8 characters**.
+
+Trailing whitespace is not allowed and must be trimmed.
+
+Spacing
+-------
+
+Single spacing should be used around most operators, including:
+
+- Arithmetic operators (``+``, ``-``, ``/``, ``*``)
+- Assignment operators (``=``, ``+=``, etc)
+- Boolean operators (``&&``, ``||``)
+- Comparison operators (``<``, ``>``, ``==``, etc)
+
+A space should also be used to separate parentheses and braces when they are not
+already separated by a newline, such as for the ``if`` statement in the
+following example:
+
+.. code:: c
+
+ int function_foo(bool bar)
+ {
+ if (bar) {
+ function_baz();
+ }
+ }
+
+Note that there is no space between the name of a function and the following
+parentheses.
+
+Control statements (``if``, ``for``, ``switch``, ``while``, etc) must be
+separated from the following open paranthesis by a single space. The previous
+example illustrates this for an ``if`` statement.
+
+Line Length
+-----------
+
+Line length *should* be at most **80 characters**. This limit does not include
+non-printing characters such as the line feed.
+
+This rule is a *should*, not a must, and it is acceptable to exceed the limit
+**slightly** where the readability of the code would otherwise be significantly
+reduced. Use your judgement in these cases.
+
+Blank Lines
+-----------
+
+Functions are usually separated by a single blank line. In certain cases it is
+acceptable to use additional blank lines for clarity, if required.
+
+The file must end with a single newline character. Many editors have the option
+to insert this automatically and to trim multiple blank lines at the end of the
+file.
+
+Braces
+------
+
+Opening Brace Placement
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Braces follow the **Kernighan and Ritchie (K&R)** style, where the opening brace
+is **not** placed on a new line.
+
+Example for a ``while`` loop:
+
+.. code:: c
+
+ while (condition) {
+ foo();
+ bar();
+ }
+
+This style applies to all blocks except for functions which, following the Linux
+style, **do** place the opening brace on a new line.
+
+Example for a function:
+
+.. code:: c
+
+ int my_function(void)
+ {
+ int a;
+
+ a = 1;
+ return a;
+ }
+
+Conditional Statement Bodies
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Where conditional statements (such as ``if``, ``for``, ``while`` and ``do``) are
+used, braces must be placed around the statements that form the body of the
+conditional. This is the case regardless of the number of statements in the
+body.
+
+.. note::
+ This is a notable departure from the Linux coding style that has been
+ adopted to follow MISRA guidelines more closely and to help prevent errors.
+
+For example, use the following style:
+
+.. code:: c
+
+ if (condition) {
+ foo++;
+ }
+
+instead of omitting the optional braces around a single statement:
+
+.. code:: c
+
+ /* This is violating MISRA C 2012: Rule 15.6 */
+ if (condition)
+ foo++;
+
+The reason for this is to prevent accidental changes to control flow when
+modifying the body of the conditional. For example, at a quick glance it is easy
+to think that the value of ``bar`` is only incremented if ``condition``
+evaluates to ``true`` but this is not the case - ``bar`` will always be
+incremented regardless of the condition evaluation. If the developer forgets to
+add braces around the conditional body when adding the ``bar++;`` statement then
+the program execution will not proceed as intended.
+
+.. code:: c
+
+ /* This is violating MISRA C 2012: Rule 15.6 */
+ if (condition)
+ foo++;
+ bar++;
+
+Naming
+------
+
+Functions
+^^^^^^^^^
+
+Use lowercase for function names, separating multiple words with an underscore
+character (``_``). This is sometimes referred to as *Snake Case*. An example is
+given below:
+
+.. code:: c
+
+ void bl2_arch_setup(void)
+ {
+ ...
+ }
+
+Local Variables and Parameters
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Local variables and function parameters use the same format as function names:
+lowercase with underscore separation between multiple words. An example is
+given below:
+
+.. code:: c
+
+ static void set_scr_el3_from_rm(uint32_t type,
+ uint32_t interrupt_type_flags,
+ uint32_t security_state)
+ {
+ uint32_t flag, bit_pos;
+
+ ...
+
+ }
+
+Preprocessor Macros
+^^^^^^^^^^^^^^^^^^^
+
+Identifiers that are defined using preprocessor macros are written in all
+uppercase text.
+
+.. code:: c
+
+ #define BUFFER_SIZE_BYTES 64
+
+Function Attributes
+-------------------
+
+Place any function attributes after the function type and before the function
+name.
+
+.. code:: c
+
+ void __init plat_arm_interconnect_init(void);
+
+Alignment
+---------
+
+Alignment should be performed primarily with tabs, adding spaces if required to
+achieve a granularity that is smaller than the tab size. For example, with a tab
+size of eight columns it would be necessary to use one tab character and two
+spaces to indent text by ten columns.
+
+Switch Statement Alignment
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When using ``switch`` statements, align each ``case`` statement with the
+``switch`` so that they are in the same column.
+
+.. code:: c
+
+ switch (condition) {
+ case A:
+ foo();
+ case B:
+ bar();
+ default:
+ baz();
+ }
+
+Pointer Alignment
+^^^^^^^^^^^^^^^^^
+
+The reference and dereference operators (ampersand and *pointer star*) must be
+aligned with the name of the object on which they are operating, as opposed to
+the type of the object.
+
+.. code:: c
+
+ uint8_t *foo;
+
+ foo = &bar;
+
+
+Comments
+--------
+
+The general rule for comments is that the double-slash style of comment (``//``)
+is not allowed. Examples of the allowed comment formats are shown below:
+
+.. code:: c
+
+ /*
+ * This example illustrates the first allowed style for multi-line comments.
+ *
+ * Blank lines within multi-lines are allowed when they add clarity or when
+ * they separate multiple contexts.
+ *
+ */
+
+.. code:: c
+
+ /**************************************************************************
+ * This is the second allowed style for multi-line comments.
+ *
+ * In this style, the first and last lines use asterisks that run the full
+ * width of the comment at its widest point.
+ *
+ * This style can be used for additional emphasis.
+ *
+ *************************************************************************/
+
+.. code:: c
+
+ /* Single line comments can use this format */
+
+.. code:: c
+
+ /***************************************************************************
+ * This alternative single-line comment style can also be used for emphasis.
+ **************************************************************************/
+
+Headers and inclusion
+---------------------
+
+Header guards
+^^^^^^^^^^^^^
+
+For a header file called "some_driver.h" the style used by |TF-A| is:
+
+.. code:: c
+
+ #ifndef SOME_DRIVER_H
+ #define SOME_DRIVER_H
+
+ <header content>
+
+ #endif /* SOME_DRIVER_H */
+
+Include statement ordering
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+All header files that are included by a source file must use the following,
+grouped ordering. This is to improve readability (by making it easier to quickly
+read through the list of headers) and maintainability.
+
+#. *System* includes: Header files from the standard *C* library, such as
+ ``stddef.h`` and ``string.h``.
+
+#. *Project* includes: Header files under the ``include/`` directory within
+ |TF-A| are *project* includes.
+
+#. *Platform* includes: Header files relating to a single, specific platform,
+ and which are located under the ``plat/<platform_name>`` directory within
+ |TF-A|, are *platform* includes.
+
+Within each group, ``#include`` statements must be in alphabetical order,
+taking both the file and directory names into account.
+
+Groups must be separated by a single blank line for clarity.
+
+The example below illustrates the ordering rules using some contrived header
+file names; this type of name reuse should be otherwise avoided.
+
+.. code:: c
+
+ #include <string.h>
+
+ #include <a_dir/example/a_header.h>
+ #include <a_dir/example/b_header.h>
+ #include <a_dir/test/a_header.h>
+ #include <b_dir/example/a_header.h>
+
+ #include "a_header.h"
+
+Include statement variants
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Two variants of the ``#include`` directive are acceptable in the |TF-A|
+codebase. Correct use of the two styles improves readability by suggesting the
+location of the included header and reducing ambiguity in cases where generic
+and platform-specific headers share a name.
+
+For header files that are in the same directory as the source file that is
+including them, use the ``"..."`` variant.
+
+For header files that are **not** in the same directory as the source file that
+is including them, use the ``<...>`` variant.
+
+Example (bl1_fwu.c):
+
+.. code:: c
+
+ #include <assert.h>
+ #include <errno.h>
+ #include <string.h>
+
+ #include "bl1_private.h"
+
+Typedefs
+--------
+
+Avoid anonymous typedefs of structs/enums in headers
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For example, the following definition:
+
+.. code:: c
+
+ typedef struct {
+ int arg1;
+ int arg2;
+ } my_struct_t;
+
+
+is better written as:
+
+.. code:: c
+
+ struct my_struct {
+ int arg1;
+ int arg2;
+ };
+
+This allows function declarations in other header files that depend on the
+struct/enum to forward declare the struct/enum instead of including the
+entire header:
+
+.. code:: c
+
+ struct my_struct;
+ void my_func(struct my_struct *arg);
+
+instead of:
+
+.. code:: c
+
+ #include <my_struct.h>
+ void my_func(my_struct_t *arg);
+
+Some TF definitions use both a struct/enum name **and** a typedef name. This
+is discouraged for new definitions as it makes it difficult for TF to comply
+with MISRA rule 8.3, which states that "All declarations of an object or
+function shall use the same names and type qualifiers".
+
+The Linux coding standards also discourage new typedefs and checkpatch emits
+a warning for this.
+
+Existing typedefs will be retained for compatibility.
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
+
+.. _`Linux kernel coding style`: https://www.kernel.org/doc/html/latest/process/coding-style.html
+.. _`MISRA C:2012 Guidelines`: https://www.misra.org.uk/Activities/MISRAC/tabid/160/Default.aspx
+.. _`a spreadsheet`: https://developer.trustedfirmware.org/file/download/lamajxif3w7c4mpjeoo5/PHID-FILE-fp7c7acszn6vliqomyhn/MISRA-and-TF-Analysis-v1.3.ods
diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst
index f569fcbe7a..68c494baad 100644
--- a/docs/process/contributing.rst
+++ b/docs/process/contributing.rst
@@ -23,7 +23,7 @@ Making Changes
- Make commits of logical units. See these general `Git guidelines`_ for
contributing to a project.
-- Follow the :ref:`Coding Style & Guidelines`.
+- Follow the :ref:`Coding Style` and :ref:`Coding Guidelines`.
- Use the checkpatch.pl script provided with the Linux source tree. A
Makefile target is provided for convenience.
@@ -128,7 +128,7 @@ Binary Components
--------------
-*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.*
.. _developer.trustedfirmware.org: https://developer.trustedfirmware.org
.. _issue: https://developer.trustedfirmware.org/project/board/1/
diff --git a/docs/process/index.rst b/docs/process/index.rst
index 9c12de82fc..1cb5354056 100644
--- a/docs/process/index.rst
+++ b/docs/process/index.rst
@@ -8,6 +8,7 @@ Processes & Policies
security
platform-compatibility-policy
+ coding-style
coding-guidelines
contributing
faq
diff --git a/docs/process/security-hardening.rst b/docs/process/security-hardening.rst
index a18a792038..43a5721251 100644
--- a/docs/process/security-hardening.rst
+++ b/docs/process/security-hardening.rst
@@ -1,10 +1,30 @@
-Security hardening
-==================
+Secure Development Guidelines
+=============================
This page contains guidance on what to check for additional security measures,
including build options that can be modified to improve security or catch issues
early in development.
+Security considerations
+-----------------------
+
+Part of the security of a platform is handling errors correctly, as described in
+the previous section. There are several other security considerations covered in
+this section.
+
+Do not leak secrets to the normal world
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The secure world **must not** leak secrets to the normal world, for example in
+response to an SMC.
+
+Handling Denial of Service attacks
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The secure world **should never** crash or become unusable due to receiving too
+many normal world requests (a *Denial of Service* or *DoS* attack). It should
+have a mechanism for throttling or ignoring normal world requests.
+
Build options
-------------
@@ -53,4 +73,4 @@ Several build options can be used to check for security issues. Refer to the
--------------
-*Copyright (c) 2019, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml b/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml
new file mode 100644
index 0000000000..c36e544230
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml
@@ -0,0 +1,52 @@
+@startuml
+
+box "BL1 common code"
+ participant bl1_main
+ participant bl_common
+end box
+
+box "arm platform code" #LightBlue
+ participant fvp_bl1_setup
+ participant arm_bl1_setup
+ participant arm_io_storage
+end box
+
+box "platform common code"
+ participant plat_bl1_common
+ participant fconf
+end box
+
+bl1_main -> fvp_bl1_setup : bl1_platform_setup()
+fvp_bl1_setup -> arm_bl1_setup : arm_bl1_platform_setup()
+arm_bl1_setup -> arm_io_storage : plat_arm_io_setup()
+note over arm_io_storage : register and setup fip
+arm_bl1_setup -> fconf : fconf_load_config()
+activate fconf
+ note over fconf
+ create and populate an
+ image_desc_t for TB_FW_CONFIG
+ end note
+ fconf -> bl_common : load_auth_image(TB_FW_CONFIG_ID, &image_info)
+ activate bl_common
+ note over bl_common
+ load and auth image from fip
+ with info from plat_io_policy
+ end note
+ bl_common -> arm_io_storage
+ arm_io_storage -> fconf: FCONF_GET_PROPERTY(arm, arm_io_policies, tb_fw_cfg)
+ note over fconf: use staticaly defined policies in bl1
+ fconf <- bl_common : image_info
+ deactivate bl_common
+ note over fconf : get tb_fw_config_dtb from image_info
+ fconf -> plat_bl1_common : bl1_plat_get_image_desc(BL2_IMAGE_ID)
+ fconf <- plat_bl1_common : BL2_IMAGE_DESC
+ note over fconf
+ set ep_info.args.arg0 of BL2_IMAGE_DESC
+ to TB_FW_CONFIG base address
+ end note
+arm_bl1_setup <- fconf
+deactivate fconf
+
+== load & auth, prepare and jump to BL2 ==
+
+@enduml
diff --git a/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml b/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml
new file mode 100644
index 0000000000..98a3ff19b3
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml
@@ -0,0 +1,41 @@
+@startuml
+
+box "BL2 common code"
+ participant bl2_entrypoint
+ participant bl2_main
+end box
+
+box "platform common code"
+ participant fconf
+ participant fconf_tbbr_getter
+end box
+
+box "arm platform code" #LightBlue
+ participant arm_bl2_setup
+ participant arm_io_storage
+ participant arm_fconf_io
+end box
+
+== bl2 setup ==
+bl2_entrypoint -> bl2_main : bl2_setup()
+bl2_main -> arm_bl2_setup : bl2_early_platform_setup2(\n\t arg0, arg1, arg2, arg3)
+note over arm_bl2_setup
+ arg0 = tb_fw_config
+ arg1 = mem_layout
+end note
+arm_bl2_setup -> arm_bl2_setup : arm_bl2_early_platform_setup(\n\t tb_fw_config, mem_layout)
+activate arm_bl2_setup
+ arm_bl2_setup -> fconf: fconf_polulate(tb_fw_config)
+ activate fconf
+ fconf -> fconf_tbbr_getter: fconf_populate_tbbr_dyn_config(uintptr_t dtb)
+ note over fconf_tbbr_getter: read tbbr propeties from dtb
+ fconf -> arm_fconf_io: fconf_populate_arm_io_policies(uintptr_t dtb)
+ note over arm_fconf_io: read arm io propeties from dtb
+ deactivate fconf
+ arm_bl2_setup -> arm_io_storage : plat_arm_io_setup()
+ note over arm_io_storage: use populated properties
+deactivate arm_bl2_setup
+
+== bl2 main ==
+
+@enduml
diff --git a/drivers/arm/ccn/ccn.c b/drivers/arm/ccn/ccn.c
index d0c5abc7c5..5b13250bc6 100644
--- a/drivers/arm/ccn/ccn.c
+++ b/drivers/arm/ccn/ccn.c
@@ -1,11 +1,10 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
-#include <errno.h>
#include <stdbool.h>
#include <arch.h>
diff --git a/drivers/arm/css/mhu/css_mhu_doorbell.c b/drivers/arm/css/mhu/css_mhu_doorbell.c
index 885874272f..c51f3b1d78 100644
--- a/drivers/arm/css/mhu/css_mhu_doorbell.c
+++ b/drivers/arm/css/mhu/css_mhu_doorbell.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,11 +20,13 @@ void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info)
void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info)
{
+ uintptr_t mhuv2_base = plat_info->db_reg_addr & MHU_V2_FRAME_BASE_MASK;
+
/* wake receiver */
- MHU_V2_ACCESS_REQUEST(MHUV2_BASE_ADDR);
+ MHU_V2_ACCESS_REQUEST(mhuv2_base);
/* wait for receiver to acknowledge its ready */
- while (MHU_V2_IS_ACCESS_READY(MHUV2_BASE_ADDR) == 0)
+ while (MHU_V2_IS_ACCESS_READY(mhuv2_base) == 0)
;
MHU_RING_DOORBELL(plat_info->db_reg_addr,
@@ -32,7 +34,7 @@ void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info)
plat_info->db_preserve_mask);
/* clear the access request for the receiver */
- MHU_V2_CLEAR_REQUEST(MHUV2_BASE_ADDR);
+ MHU_V2_CLEAR_REQUEST(mhuv2_base);
return;
}
diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c
index b945cda788..097d2eb2b6 100644
--- a/drivers/arm/css/scp/css_pm_scmi.c
+++ b/drivers/arm/css/scp/css_pm_scmi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -63,17 +63,45 @@ typedef enum {
} scmi_power_state_t;
/*
- * The global handle for invoking the SCMI driver APIs after the driver
+ * The global handles for invoking the SCMI driver APIs after the driver
* has been initialized.
*/
-static void *scmi_handle;
+static void *scmi_handles[PLAT_ARM_SCMI_CHANNEL_COUNT];
-/* The SCMI channel global object */
-static scmi_channel_t channel;
+/* The global SCMI channels array */
+static scmi_channel_t scmi_channels[PLAT_ARM_SCMI_CHANNEL_COUNT];
+/*
+ * Channel ID for the default SCMI channel.
+ * The default channel is used to issue SYSTEM level SCMI requests and is
+ * initialized to the channel which has the boot cpu as its resource.
+ */
+static uint32_t default_scmi_channel_id;
+
+/*
+ * TODO: Allow use of channel specific lock instead of using a single lock for
+ * all the channels.
+ */
ARM_SCMI_INSTANTIATE_LOCK;
/*
+ * Function to obtain the SCMI Domain ID and SCMI Channel number from the linear
+ * core position. The SCMI Channel number is encoded in the upper 16 bits and
+ * the Domain ID is encoded in the lower 16 bits in each entry of the mapping
+ * array exported by the platform.
+ */
+static void css_scp_core_pos_to_scmi_channel(unsigned int core_pos,
+ unsigned int *scmi_domain_id, unsigned int *scmi_channel_id)
+{
+ unsigned int composite_id;
+
+ composite_id = plat_css_core_pos_to_scmi_dmn_id_map[core_pos];
+
+ *scmi_channel_id = GET_SCMI_CHANNEL_ID(composite_id);
+ *scmi_domain_id = GET_SCMI_DOMAIN_ID(composite_id);
+}
+
+/*
* Helper function to suspend a CPU power domain and its parent power domains
* if applicable.
*/
@@ -87,10 +115,10 @@ void css_scp_suspend(const struct psci_power_state *target_state)
/* Check if power down at system power domain level is requested */
if (css_system_pwr_state(target_state) == ARM_LOCAL_STATE_OFF) {
- /* Issue SCMI command for SYSTEM_SUSPEND */
- ret = scmi_sys_pwr_state_set(scmi_handle,
- SCMI_SYS_PWR_FORCEFUL_REQ,
- SCMI_SYS_PWR_SUSPEND);
+ /* Issue SCMI command for SYSTEM_SUSPEND on all SCMI channels */
+ ret = scmi_sys_pwr_state_set(
+ scmi_handles[default_scmi_channel_id],
+ SCMI_SYS_PWR_FORCEFUL_REQ, SCMI_SYS_PWR_SUSPEND);
if (ret != SCMI_E_SUCCESS) {
ERROR("SCMI system power domain suspend return 0x%x unexpected\n",
ret);
@@ -99,7 +127,7 @@ void css_scp_suspend(const struct psci_power_state *target_state)
return;
}
#if !HW_ASSISTED_COHERENCY
- unsigned int lvl;
+ unsigned int lvl, channel_id, domain_id;
uint32_t scmi_pwr_state = 0;
/*
* If we reach here, then assert that power down at system power domain
@@ -127,9 +155,10 @@ void css_scp_suspend(const struct psci_power_state *target_state)
SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1);
- ret = scmi_pwr_state_set(scmi_handle,
- plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()],
- scmi_pwr_state);
+ css_scp_core_pos_to_scmi_channel(plat_my_core_pos(),
+ &domain_id, &channel_id);
+ ret = scmi_pwr_state_set(scmi_handles[channel_id],
+ domain_id, scmi_pwr_state);
if (ret != SCMI_E_SUCCESS) {
ERROR("SCMI set power state command return 0x%x unexpected\n",
@@ -145,7 +174,7 @@ void css_scp_suspend(const struct psci_power_state *target_state)
*/
void css_scp_off(const struct psci_power_state *target_state)
{
- unsigned int lvl = 0;
+ unsigned int lvl = 0, channel_id, domain_id;
int ret;
uint32_t scmi_pwr_state = 0;
@@ -168,10 +197,10 @@ void css_scp_off(const struct psci_power_state *target_state)
SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1);
- ret = scmi_pwr_state_set(scmi_handle,
- plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()],
- scmi_pwr_state);
-
+ css_scp_core_pos_to_scmi_channel(plat_my_core_pos(),
+ &domain_id, &channel_id);
+ ret = scmi_pwr_state_set(scmi_handles[channel_id],
+ domain_id, scmi_pwr_state);
if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) {
ERROR("SCMI set power state command return 0x%x unexpected\n",
ret);
@@ -185,8 +214,8 @@ void css_scp_off(const struct psci_power_state *target_state)
*/
void css_scp_on(u_register_t mpidr)
{
- unsigned int lvl = 0;
- int core_pos, ret;
+ unsigned int lvl = 0, channel_id, core_pos, domain_id;
+ int ret;
uint32_t scmi_pwr_state = 0;
for (; lvl <= PLAT_MAX_PWR_LVL; lvl++)
@@ -196,13 +225,12 @@ void css_scp_on(u_register_t mpidr)
SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1);
core_pos = plat_core_pos_by_mpidr(mpidr);
- assert((core_pos >= 0) &&
- (((unsigned int)core_pos) < PLATFORM_CORE_COUNT));
-
- ret = scmi_pwr_state_set(scmi_handle,
- plat_css_core_pos_to_scmi_dmn_id_map[core_pos],
- scmi_pwr_state);
+ assert(core_pos >= 0 && (core_pos < PLATFORM_CORE_COUNT));
+ css_scp_core_pos_to_scmi_channel(core_pos, &domain_id,
+ &channel_id);
+ ret = scmi_pwr_state_set(scmi_handles[channel_id],
+ domain_id, scmi_pwr_state);
if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) {
ERROR("SCMI set power state command return 0x%x unexpected\n",
ret);
@@ -216,8 +244,9 @@ void css_scp_on(u_register_t mpidr)
*/
int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level)
{
- int ret, cpu_idx;
+ int ret;
uint32_t scmi_pwr_state = 0, lvl_state;
+ unsigned int channel_id, cpu_idx, domain_id;
/* We don't support get power state at the system power domain level */
if ((power_level > PLAT_MAX_PWR_LVL) ||
@@ -230,9 +259,9 @@ int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level)
cpu_idx = plat_core_pos_by_mpidr(mpidr);
assert(cpu_idx > -1);
- ret = scmi_pwr_state_get(scmi_handle,
- plat_css_core_pos_to_scmi_dmn_id_map[cpu_idx],
- &scmi_pwr_state);
+ css_scp_core_pos_to_scmi_channel(cpu_idx, &domain_id, &channel_id);
+ ret = scmi_pwr_state_get(scmi_handles[channel_id],
+ domain_id, &scmi_pwr_state);
if (ret != SCMI_E_SUCCESS) {
WARN("SCMI get power state command return 0x%x unexpected\n",
@@ -271,7 +300,7 @@ void __dead2 css_scp_system_off(int state)
* Issue SCMI command. First issue a graceful
* request and if that fails force the request.
*/
- ret = scmi_sys_pwr_state_set(scmi_handle,
+ ret = scmi_sys_pwr_state_set(scmi_handles[default_scmi_channel_id],
SCMI_SYS_PWR_FORCEFUL_REQ,
state);
@@ -325,17 +354,28 @@ static int scmi_ap_core_init(scmi_channel_t *ch)
void __init plat_arm_pwrc_setup(void)
{
- channel.info = plat_css_get_scmi_info();
- channel.lock = ARM_SCMI_LOCK_GET_INSTANCE;
- scmi_handle = scmi_init(&channel);
- if (scmi_handle == NULL) {
- ERROR("SCMI Initialization failed\n");
- panic();
- }
- if (scmi_ap_core_init(&channel) < 0) {
- ERROR("SCMI AP core protocol initialization failed\n");
- panic();
+ unsigned int composite_id, idx;
+
+ for (idx = 0; idx < PLAT_ARM_SCMI_CHANNEL_COUNT; idx++) {
+ INFO("Initializing driver on Channel %d\n", idx);
+
+ scmi_channels[idx].info = plat_css_get_scmi_info(idx);
+ scmi_channels[idx].lock = ARM_SCMI_LOCK_GET_INSTANCE;
+ scmi_handles[idx] = scmi_init(&scmi_channels[idx]);
+
+ if (scmi_handles[idx] == NULL) {
+ ERROR("SCMI Initialization failed on channel %d\n", idx);
+ panic();
+ }
+
+ if (scmi_ap_core_init(&scmi_channels[idx]) < 0) {
+ ERROR("SCMI AP core protocol initialization failed\n");
+ panic();
+ }
}
+
+ composite_id = plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()];
+ default_scmi_channel_id = GET_SCMI_CHANNEL_ID(composite_id);
}
/******************************************************************************
@@ -347,6 +387,7 @@ const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops)
{
uint32_t msg_attr;
int ret;
+ void *scmi_handle = scmi_handles[default_scmi_channel_id];
assert(scmi_handle);
@@ -411,14 +452,17 @@ int css_system_reset2(int is_vendor, int reset_type, u_register_t cookie)
#if PROGRAMMABLE_RESET_ADDRESS
void plat_arm_program_trusted_mailbox(uintptr_t address)
{
- int ret;
+ int ret, i;
- assert(scmi_handle);
- ret = scmi_ap_core_set_reset_addr(scmi_handle, address,
- SCMI_AP_CORE_LOCK_ATTR);
- if (ret != SCMI_E_SUCCESS) {
- ERROR("CSS: Failed to program reset address: %d\n", ret);
- panic();
+ for (i = 0; i < PLAT_ARM_SCMI_CHANNEL_COUNT; i++) {
+ assert(scmi_handles[i]);
+
+ ret = scmi_ap_core_set_reset_addr(scmi_handles[i], address,
+ SCMI_AP_CORE_LOCK_ATTR);
+ if (ret != SCMI_E_SUCCESS) {
+ ERROR("CSS: Failed to program reset address: %d\n", ret);
+ panic();
+ }
}
}
#endif
diff --git a/drivers/arm/gic/v2/gicv2_helpers.c b/drivers/arm/gic/v2/gicv2_helpers.c
index 6739a782c1..751316c03a 100644
--- a/drivers/arm/gic/v2/gicv2_helpers.c
+++ b/drivers/arm/gic/v2/gicv2_helpers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,7 +7,6 @@
#include <assert.h>
#include <arch.h>
-#include <arch_helpers.h>
#include <common/debug.h>
#include <common/interrupt_props.h>
#include <drivers/arm/gic_common.h>
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index 3fb2d1a48c..91ee1bea97 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,6 +16,7 @@
#include <drivers/auth/auth_mod.h>
#include <drivers/auth/crypto_mod.h>
#include <drivers/auth/img_parser_mod.h>
+#include <lib/fconf/fconf_tbbr_getter.h>
#include <plat/common/platform.h>
/* ASN.1 tags */
@@ -302,9 +303,8 @@ int auth_mod_get_parent_id(unsigned int img_id, unsigned int *parent_id)
const auth_img_desc_t *img_desc = NULL;
assert(parent_id != NULL);
-
/* Get the image descriptor */
- img_desc = cot_desc_ptr[img_id];
+ img_desc = FCONF_GET_PROPERTY(tbbr, cot, img_id);
/* Check if the image has no parent (ROT) */
if (img_desc->parent == NULL) {
@@ -353,7 +353,7 @@ int auth_mod_verify_img(unsigned int img_id,
int rc, i;
/* Get the image descriptor from the chain of trust */
- img_desc = cot_desc_ptr[img_id];
+ img_desc = FCONF_GET_PROPERTY(tbbr, cot, img_id);
/* Ask the parser to check the image integrity */
rc = img_parser_check_integrity(img_desc->img_type, img_ptr, img_len);
diff --git a/drivers/auth/img_parser_mod.c b/drivers/auth/img_parser_mod.c
index c4688f8675..535695d829 100644
--- a/drivers/auth/img_parser_mod.c
+++ b/drivers/auth/img_parser_mod.c
@@ -1,11 +1,10 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
-#include <errno.h>
#include <limits.h>
#include <stdint.h>
#include <string.h>
diff --git a/drivers/console/multi_console.c b/drivers/console/multi_console.c
index 215f49517a..0665f202f8 100644
--- a/drivers/console/multi_console.c
+++ b/drivers/console/multi_console.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -90,7 +90,7 @@ int console_putc(int c)
console_t *console;
for (console = console_list; console != NULL; console = console->next)
- if ((console->flags & console_state) && console->putc) {
+ if ((console->flags & console_state) && (console->putc != NULL)) {
int ret = do_putc(c, console);
if ((err == ERROR_NO_VALID_CONSOLE) || (ret < err))
err = ret;
@@ -107,7 +107,7 @@ int console_getc(void)
do { /* Keep polling while at least one console works correctly. */
for (console = console_list; console != NULL;
console = console->next)
- if ((console->flags & console_state) && console->getc) {
+ if ((console->flags & console_state) && (console->getc != NULL)) {
int ret = console->getc(console);
if (ret >= 0)
return ret;
@@ -125,7 +125,7 @@ int console_flush(void)
console_t *console;
for (console = console_list; console != NULL; console = console->next)
- if ((console->flags & console_state) && console->flush) {
+ if ((console->flags & console_state) && (console->flush != NULL)) {
int ret = console->flush(console);
if ((err == ERROR_NO_VALID_CONSOLE) || (ret < err))
err = ret;
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index c60f2e8f7f..240c1fbda6 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -69,6 +69,13 @@ static inline void _op(void) \
__asm__ (#_op); \
}
+/* Define function for system instruction with register parameter */
+#define DEFINE_SYSOP_PARAM_FUNC(_op) \
+static inline void _op(uint64_t v) \
+{ \
+ __asm__ (#_op " %0" : : "r" (v)); \
+}
+
/* Define function for system instruction with type specifier */
#define DEFINE_SYSOP_TYPE_FUNC(_op, _type) \
static inline void _op ## _type(void) \
@@ -211,6 +218,11 @@ DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e1r)
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e2r)
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e3r)
+/*******************************************************************************
+ * Strip Pointer Authentication Code
+ ******************************************************************************/
+DEFINE_SYSOP_PARAM_FUNC(xpaci)
+
void flush_dcache_range(uintptr_t addr, size_t size);
void clean_dcache_range(uintptr_t addr, size_t size);
void inv_dcache_range(uintptr_t addr, size_t size);
diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h
index 79d001d285..f467958b7f 100644
--- a/include/common/fdt_wrappers.h
+++ b/include/common/fdt_wrappers.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,5 +20,9 @@ int fdtw_read_string(const void *dtb, int node, const char *prop,
char *str, size_t size);
int fdtw_write_inplace_cells(void *dtb, int node, const char *prop,
unsigned int cells, void *value);
+int fdtw_read_bytes(const void *dtb, int node, const char *prop,
+ unsigned int length, void *value);
+int fdtw_write_inplace_bytes(void *dtb, int node, const char *prop,
+ unsigned int length, const void *data);
#endif /* FDT_WRAPPERS_H */
diff --git a/include/drivers/arm/css/css_mhu_doorbell.h b/include/drivers/arm/css/css_mhu_doorbell.h
index e6f7a1bd1b..88302fd7bb 100644
--- a/include/drivers/arm/css/css_mhu_doorbell.h
+++ b/include/drivers/arm/css/css_mhu_doorbell.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,13 +11,13 @@
#include <lib/mmio.h>
-/* MHUv2 Base Address */
-#define MHUV2_BASE_ADDR PLAT_MHUV2_BASE
+/* MHUv2 Frame Base Mask */
+#define MHU_V2_FRAME_BASE_MASK UL(~0xFFF)
/* MHUv2 Control Registers Offsets */
-#define MHU_V2_MSG_NO_CAP_OFFSET 0xF80
-#define MHU_V2_ACCESS_REQ_OFFSET 0xF88
-#define MHU_V2_ACCESS_READY_OFFSET 0xF8C
+#define MHU_V2_MSG_NO_CAP_OFFSET UL(0xF80)
+#define MHU_V2_ACCESS_REQ_OFFSET UL(0xF88)
+#define MHU_V2_ACCESS_READY_OFFSET UL(0xF8C)
#define SENDER_REG_STAT(_channel) (0x20 * (_channel))
#define SENDER_REG_SET(_channel) ((0x20 * (_channel)) + 0xC)
diff --git a/include/drivers/arm/css/scmi.h b/include/drivers/arm/css/scmi.h
index 1f8dc6ccea..e8a2863a9f 100644
--- a/include/drivers/arm/css/scmi.h
+++ b/include/drivers/arm/css/scmi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -162,7 +162,7 @@ int scmi_ap_core_set_reset_addr(void *p, uint64_t reset_addr, uint32_t attr);
int scmi_ap_core_get_reset_addr(void *p, uint64_t *reset_addr, uint32_t *attr);
/* API to get the platform specific SCMI channel information. */
-scmi_channel_plat_info_t *plat_css_get_scmi_info(void);
+scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id);
/* API to override default PSCI callbacks for platforms that support SCMI. */
const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops);
diff --git a/include/drivers/io/io_storage.h b/include/drivers/io/io_storage.h
index 0e6ffd6193..a301ad5631 100644
--- a/include/drivers/io/io_storage.h
+++ b/include/drivers/io/io_storage.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -53,7 +53,7 @@ typedef struct io_file_spec {
/* UUID specification - used to refer to data accessed using UUIDs (i.e. FIP
* images) */
typedef struct io_uuid_spec {
- const uuid_t uuid;
+ uuid_t uuid;
} io_uuid_spec_t;
/* Block specification - used to refer to data on a device supporting
diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h
new file mode 100644
index 0000000000..f58ff57103
--- /dev/null
+++ b/include/lib/fconf/fconf.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FCONF_H
+#define FCONF_H
+
+#include <stdint.h>
+
+/* Public API */
+#define FCONF_GET_PROPERTY(a, b, c) a##__##b##_getter(c)
+
+#define FCONF_REGISTER_POPULATOR(name, callback) \
+ __attribute__((used, section(".fconf_populator"))) \
+ const struct fconf_populator name##__populator = { \
+ .info = #name, \
+ .populate = callback \
+ };
+
+/*
+ * Populator callback
+ *
+ * This structure are used by the fconf_populate function and should only be
+ * defined by the FCONF_REGISTER_POPULATOR macro.
+ */
+struct fconf_populator {
+ /* Description of the data loaded by the callback */
+ const char *info;
+
+ /* Callback used by fconf_populate function with a provided config dtb.
+ * Return 0 on success, err_code < 0 otherwise.
+ */
+ int (*populate)(uintptr_t config);
+};
+
+/* Load firmware configuration dtb */
+void fconf_load_config(void);
+
+/* Top level populate function
+ *
+ * This function takes a configuration dtb and calls all the registered
+ * populator callback with it.
+ *
+ * Panic on error.
+ */
+void fconf_populate(uintptr_t config);
+
+/* FCONF specific getter */
+#define fconf__dtb_getter(prop) fconf_dtb_info.prop
+
+/* Structure used to locally keep a reference to the config dtb. */
+struct fconf_dtb_info_t {
+ uintptr_t base_addr;
+ size_t size;
+};
+
+extern struct fconf_dtb_info_t fconf_dtb_info;
+
+#endif /* FCONF_H */
diff --git a/include/lib/fconf/fconf_dyn_cfg_getter.h b/include/lib/fconf/fconf_dyn_cfg_getter.h
new file mode 100644
index 0000000000..0fda8c9b20
--- /dev/null
+++ b/include/lib/fconf/fconf_dyn_cfg_getter.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FCONF_DYN_CFG_GETTER_H
+#define FCONF_DYN_CFG_GETTER_H
+
+#include <lib/fconf/fconf.h>
+
+/* Dynamic configuration related getter */
+#define dyn_cfg__dtb_getter(id) dyn_cfg_dtb_info_getter(id)
+
+struct dyn_cfg_dtb_info_t {
+ uintptr_t config_addr;
+ size_t config_max_size;
+ unsigned int config_id;
+};
+
+struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id);
+int fconf_populate_dtb_registry(uintptr_t config);
+
+#endif /* FCONF_DYN_CFG_GETTER_H */
diff --git a/include/lib/fconf/fconf_tbbr_getter.h b/include/lib/fconf/fconf_tbbr_getter.h
new file mode 100644
index 0000000000..eddc0c4b56
--- /dev/null
+++ b/include/lib/fconf/fconf_tbbr_getter.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FCONF_TBBR_GETTER_H
+#define FCONF_TBBR_GETTER_H
+
+#include <lib/fconf/fconf.h>
+
+/* TBBR related getter */
+#define tbbr__cot_getter(id) cot_desc_ptr[id]
+
+#define tbbr__dyn_config_getter(id) tbbr_dyn_config.id
+
+struct tbbr_dyn_config_t {
+ uint32_t disable_auth;
+ void *mbedtls_heap_addr;
+ size_t mbedtls_heap_size;
+};
+
+extern struct tbbr_dyn_config_t tbbr_dyn_config;
+
+int fconf_populate_tbbr_dyn_config(uintptr_t config);
+
+#endif /* FCONF_TBBR_GETTER_H */
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index b419c853e6..7df6b0d888 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,6 +18,12 @@
* Definitions common to all ARM standard platforms
*****************************************************************************/
+/*
+ * Root of trust key hash lengths
+ */
+#define ARM_ROTPK_HEADER_LEN 19
+#define ARM_ROTPK_HASH_LEN 32
+
/* Special value used to verify platform parameters from BL2 to BL31 */
#define ARM_BL31_PLAT_PARAM_VAL ULL(0x0f1e2d3c4b5a6978)
@@ -223,6 +229,14 @@
ARM_EL3_TZC_DRAM1_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
+#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
+
+
/*
* Mapping for the BL1 RW region. This mapping is needed by BL2 in order to
* share the Mbed TLS heap. Since the heap is allocated inside BL1, it resides
@@ -395,13 +409,21 @@
/*******************************************************************************
* BL31 specific defines.
******************************************************************************/
-#if ARM_BL31_IN_DRAM
+#if ARM_BL31_IN_DRAM || SEPARATE_NOBITS_REGION
/*
* Put BL31 at the bottom of TZC secured DRAM
*/
#define BL31_BASE ARM_AP_TZC_DRAM1_BASE
#define BL31_LIMIT (ARM_AP_TZC_DRAM1_BASE + \
PLAT_ARM_MAX_BL31_SIZE)
+/*
+ * For SEPARATE_NOBITS_REGION, BL31 PROGBITS are loaded in TZC secured DRAM.
+ * And BL31 NOBITS are loaded in Trusted SRAM such that BL2 is overwritten.
+ */
+#if SEPARATE_NOBITS_REGION
+#define BL31_NOBITS_BASE BL2_BASE
+#define BL31_NOBITS_LIMIT BL2_LIMIT
+#endif /* SEPARATE_NOBITS_REGION */
#elif (RESET_TO_BL31)
/* Ensure Position Independent support (PIE) is enabled for this config.*/
# if !ENABLE_PIE
@@ -463,6 +485,12 @@
# define BL32_BASE (ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
# define BL32_LIMIT (ARM_AP_TZC_DRAM1_BASE + \
ARM_AP_TZC_DRAM1_SIZE)
+# elif defined(SPD_spmd)
+# 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 PLAT_ARM_TRUSTED_DRAM_BASE
+# define BL32_LIMIT (PLAT_ARM_TRUSTED_DRAM_BASE \
+ + (UL(1) << 21))
# elif ARM_BL31_IN_DRAM
# define TSP_SEC_MEM_BASE (ARM_AP_TZC_DRAM1_BASE + \
PLAT_ARM_MAX_BL31_SIZE)
@@ -497,12 +525,12 @@
/*
* BL32 is mandatory in AArch32. In AArch64, undefine BL32_BASE if there is no
- * SPD and no SPM, as they are the only ones that can be used as BL32.
+ * SPD and no SPM-MM, 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
# undef BL32_BASE
-# endif /* defined(SPD_none) && !SPM_MM*/
+# endif /* defined(SPD_none) && !SPM_MM */
#endif /* defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME */
/*******************************************************************************
diff --git a/include/plat/arm/common/arm_dyn_cfg_helpers.h b/include/plat/arm/common/arm_dyn_cfg_helpers.h
index 3ad6d5468b..2dc94abe32 100644
--- a/include/plat/arm/common/arm_dyn_cfg_helpers.h
+++ b/include/plat/arm/common/arm_dyn_cfg_helpers.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,12 +10,7 @@
#include <stdint.h>
/* Function declarations */
-int arm_dyn_get_config_load_info(void *dtb, int node, unsigned int config_id,
- uint64_t *config_addr, uint32_t *config_size);
int arm_dyn_tb_fw_cfg_init(void *dtb, int *node);
-int arm_dyn_get_disable_auth(void *dtb, int node, uint32_t *disable_auth);
-int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr,
- size_t *heap_size);
int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr,
size_t heap_size);
diff --git a/include/plat/arm/common/arm_fconf_getter.h b/include/plat/arm/common/arm_fconf_getter.h
new file mode 100644
index 0000000000..28913a43f3
--- /dev/null
+++ b/include/plat/arm/common/arm_fconf_getter.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ARM_FCONF_GETTER
+#define ARM_FCONF_GETTER
+
+#include <lib/fconf/fconf.h>
+
+/* ARM io policies */
+#define arm__io_policies_getter(id) &policies[id]
+
+struct plat_io_policy {
+ uintptr_t *dev_handle;
+ uintptr_t image_spec;
+ int (*check)(const uintptr_t spec);
+};
+
+extern struct plat_io_policy policies[];
+int fconf_populate_arm_io_policies(uintptr_t config);
+
+#endif /* ARM_FCONF_GETTER */
diff --git a/include/plat/arm/common/arm_fconf_io_storage.h b/include/plat/arm/common/arm_fconf_io_storage.h
new file mode 100644
index 0000000000..02ee66c350
--- /dev/null
+++ b/include/plat/arm/common/arm_fconf_io_storage.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef ARM_FCONF_IO_STORAGE_H
+#define ARM_FCONF_IO_STORAGE_H
+
+#include <stdint.h>
+
+/* IO devices handle */
+extern uintptr_t memmap_dev_handle;
+extern uintptr_t fip_dev_handle;
+
+/* Function declarations */
+int open_fip(const uintptr_t spec);
+int open_memmap(const uintptr_t spec);
+
+#endif /* ARM_FCONF_IO_STORAGE_H */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 02feec7086..025a64fa28 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -1,11 +1,12 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PLAT_ARM_H
#define PLAT_ARM_H
+#include <stdbool.h>
#include <stdint.h>
#include <drivers/arm/tzc_common.h>
@@ -142,8 +143,13 @@ void arm_setup_romlib(void);
#define STATE_SW_E_PARAM (-2)
#define STATE_SW_E_DENIED (-3)
+/* plat_get_rotpk_info() flags */
+#define ARM_ROTPK_REGS_ID 1
+#define ARM_ROTPK_DEVEL_RSA_ID 2
+#define ARM_ROTPK_DEVEL_ECDSA_ID 3
+
/* IO storage utility functions */
-void arm_io_setup(void);
+int arm_io_setup(void);
/* Security utility functions */
void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions);
@@ -217,11 +223,9 @@ void arm_sp_min_early_platform_setup(void *from_bl2, uintptr_t tos_fw_config,
void arm_sp_min_plat_runtime_setup(void);
/* FIP TOC validity check */
-int arm_io_is_toc_valid(void);
+bool arm_io_is_toc_valid(void);
/* Utility functions for Dynamic Config */
-void arm_load_tb_fw_config(void);
-void arm_bl2_set_tb_cfg_addr(void *dtb);
void arm_bl2_dyn_cfg_init(void);
void arm_bl1_set_mbedtls_heap(void);
int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size);
@@ -251,13 +255,21 @@ void plat_arm_interconnect_init(void);
void plat_arm_interconnect_enter_coherency(void);
void plat_arm_interconnect_exit_coherency(void);
void plat_arm_program_trusted_mailbox(uintptr_t address);
-int plat_arm_bl1_fwu_needed(void);
+bool plat_arm_bl1_fwu_needed(void);
__dead2 void plat_arm_error_handler(int err);
/*
- * Optional function in ARM standard platforms
+ * Optional functions in ARM standard platforms
*/
void plat_arm_override_gicr_frames(const uintptr_t *plat_gicr_frames);
+int arm_get_rotpk_info(void **key_ptr, unsigned int *key_len,
+ unsigned int *flags);
+int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
+ unsigned int *flags);
+int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len,
+ unsigned int *flags);
+int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
+ unsigned int *flags);
#if ARM_PLAT_MT
unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr);
diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h
index 2adf11d66e..7b61484455 100644
--- a/include/plat/arm/css/common/css_def.h
+++ b/include/plat/arm/css/common/css_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -29,6 +29,10 @@
#define SID_REG_BASE 0x2a4a0000
#define SID_SYSTEM_ID_OFFSET 0x40
#define SID_SYSTEM_CFG_OFFSET 0x70
+#define SID_NODE_ID_OFFSET 0x60
+#define SID_CHIP_ID_MASK 0xFF
+#define SID_MULTI_CHIP_MODE_MASK 0x100
+#define SID_MULTI_CHIP_MODE_SHIFT 8
/* The slave_bootsecure controls access to GPU, DMC and CS. */
#define CSS_NIC400_SLAVE_BOOTSECURE 8
diff --git a/include/plat/arm/css/common/css_pm.h b/include/plat/arm/css/common/css_pm.h
index 93f86162e9..e5357f50be 100644
--- a/include/plat/arm/css/common/css_pm.h
+++ b/include/plat/arm/css/common/css_pm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -44,4 +44,15 @@ int css_node_hw_state(u_register_t mpidr, unsigned int power_level);
*/
extern const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[];
+#define SCMI_DOMAIN_ID_MASK U(0xFFFF)
+#define SCMI_CHANNEL_ID_MASK U(0xFFFF)
+#define SCMI_CHANNEL_ID_SHIFT U(16)
+
+#define SET_SCMI_CHANNEL_ID(n) (((n) & SCMI_CHANNEL_ID_MASK) << \
+ SCMI_CHANNEL_ID_SHIFT)
+#define SET_SCMI_DOMAIN_ID(n) ((n) & SCMI_DOMAIN_ID_MASK)
+#define GET_SCMI_CHANNEL_ID(n) (((n) >> SCMI_CHANNEL_ID_SHIFT) & \
+ SCMI_CHANNEL_ID_MASK)
+#define GET_SCMI_DOMAIN_ID(n) ((n) & SCMI_DOMAIN_ID_MASK)
+
#endif /* CSS_PM_H */
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 332cfca8d7..f5bd298c5a 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +10,9 @@
#include <stdint.h>
#include <lib/psci/psci.h>
+#if defined(SPD_spmd)
+ #include <services/spm_core_manifest.h>
+#endif
/*******************************************************************************
* Forward declarations
@@ -272,7 +275,11 @@ const struct spm_mm_boot_info *plat_get_secure_partition_boot_info(
int plat_spm_sp_rd_load(struct sp_res_desc *rd, const void *ptr, size_t size);
int plat_spm_sp_get_next_address(void **sp_base, size_t *sp_size,
void **rd_base, size_t *rd_size);
-
+#if defined(SPD_spmd)
+int plat_spm_core_manifest_load(spmc_manifest_sect_attribute_t *manifest,
+ const void *ptr,
+ size_t size);
+#endif
/*******************************************************************************
* Mandatory BL image load functions(may be overridden).
******************************************************************************/
diff --git a/include/services/spci_svc.h b/include/services/spci_svc.h
new file mode 100644
index 0000000000..49ba408586
--- /dev/null
+++ b/include/services/spci_svc.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPCI_SVC_H
+#define SPCI_SVC_H
+
+#include <lib/smccc.h>
+#include <lib/utils_def.h>
+#include <tools_share/uuid.h>
+
+/* SPCI error codes. */
+#define SPCI_ERROR_NOT_SUPPORTED -1
+#define SPCI_ERROR_INVALID_PARAMETER -2
+#define SPCI_ERROR_NO_MEMORY -3
+#define SPCI_ERROR_BUSY -4
+#define SPCI_ERROR_INTERRUPTED -5
+#define SPCI_ERROR_DENIED -6
+#define SPCI_ERROR_RETRY -7
+
+/* The macros below are used to identify SPCI calls from the SMC function ID */
+#define SPCI_FNUM_MIN_VALUE U(0x60)
+#define SPCI_FNUM_MAX_VALUE U(0x7f)
+#define is_spci_fid(fid) __extension__ ({ \
+ __typeof__(fid) _fid = (fid); \
+ ((GET_SMC_NUM(_fid) >= SPCI_FNUM_MIN_VALUE) && \
+ (GET_SMC_NUM(_fid) <= SPCI_FNUM_MAX_VALUE)); })
+
+/* SPCI_VERSION helpers */
+#define SPCI_VERSION_MAJOR U(0)
+#define SPCI_VERSION_MAJOR_SHIFT 16
+#define SPCI_VERSION_MAJOR_MASK U(0x7FFF)
+#define SPCI_VERSION_MINOR U(9)
+#define SPCI_VERSION_MINOR_SHIFT 0
+#define SPCI_VERSION_MINOR_MASK U(0xFFFF)
+
+#define MAKE_SPCI_VERSION(major, minor) \
+ ((((major) & SPCI_VERSION_MAJOR_MASK) << SPCI_VERSION_MAJOR_SHIFT) | \
+ (((minor) & SPCI_VERSION_MINOR_MASK) << SPCI_VERSION_MINOR_SHIFT))
+#define SPCI_VERSION_COMPILED MAKE_SPCI_VERSION(SPCI_VERSION_MAJOR, \
+ SPCI_VERSION_MINOR)
+
+/* SPCI_MSG_SEND helpers */
+#define SPCI_MSG_SEND_ATTRS_BLK_SHIFT U(0)
+#define SPCI_MSG_SEND_ATTRS_BLK_MASK U(0x1)
+#define SPCI_MSG_SEND_ATTRS_BLK U(0)
+#define SPCI_MSG_SEND_ATTRS_BLK_NOT U(1)
+#define SPCI_MSG_SEND_ATTRS(blk) \
+ (((blk) & SPCI_MSG_SEND_ATTRS_BLK_MASK) \
+ << SPCI_MSG_SEND_ATTRS_BLK_SHIFT)
+
+/* Get SPCI fastcall std FID from function number */
+#define SPCI_FID(smc_cc, func_num) \
+ ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
+ ((smc_cc) << FUNCID_CC_SHIFT) | \
+ (OEN_STD_START << FUNCID_OEN_SHIFT) | \
+ ((func_num) << FUNCID_NUM_SHIFT))
+
+/* SPCI function numbers */
+#define SPCI_FNUM_ERROR U(0x60)
+#define SPCI_FNUM_SUCCESS U(0x61)
+#define SPCI_FNUM_INTERRUPT U(0x62)
+#define SPCI_FNUM_VERSION U(0x63)
+#define SPCI_FNUM_FEATURES U(0x64)
+#define SPCI_FNUM_RX_RELEASE U(0x65)
+#define SPCI_FNUM_RXTX_MAP U(0x66)
+#define SPCI_FNUM_RXTX_UNMAP U(0x67)
+#define SPCI_FNUM_PARTITION_INFO_GET U(0x68)
+#define SPCI_FNUM_ID_GET U(0x69)
+#define SPCI_FNUM_MSG_POLL U(0x6A)
+#define SPCI_FNUM_MSG_WAIT U(0x6B)
+#define SPCI_FNUM_MSG_YIELD U(0x6C)
+#define SPCI_FNUM_MSG_RUN U(0x6D)
+#define SPCI_FNUM_MSG_SEND U(0x6E)
+#define SPCI_FNUM_MSG_SEND_DIRECT_REQ U(0x6F)
+#define SPCI_FNUM_MSG_SEND_DIRECT_RESP U(0x70)
+#define SPCI_FNUM_MEM_DONATE U(0x71)
+#define SPCI_FNUM_MEM_LEND U(0x72)
+#define SPCI_FNUM_MEM_SHARE U(0x73)
+#define SPCI_FNUM_MEM_RETRIEVE_REQ U(0x74)
+#define SPCI_FNUM_MEM_RETRIEVE_RESP U(0x75)
+#define SPCI_FNUM_MEM_RELINQUISH U(0x76)
+#define SPCI_FNUM_MEM_RECLAIM U(0x77)
+
+/* SPCI SMC32 FIDs */
+#define SPCI_ERROR SPCI_FID(SMC_32, SPCI_FNUM_ERROR)
+#define SPCI_SUCCESS_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_SUCCESS)
+#define SPCI_INTERRUPT SPCI_FID(SMC_32, SPCI_FNUM_INTERRUPT)
+#define SPCI_VERSION SPCI_FID(SMC_32, SPCI_FNUM_VERSION)
+#define SPCI_FEATURES SPCI_FID(SMC_32, SPCI_FNUM_FEATURES)
+#define SPCI_RX_RELEASE SPCI_FID(SMC_32, SPCI_FNUM_RX_RELEASE)
+#define SPCI_RXTX_MAP_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_RXTX_MAP)
+#define SPCI_RXTX_UNMAP SPCI_FID(SMC_32, SPCI_FNUM_RXTX_UNMAP)
+#define SPCI_PARTITION_INFO_GET SPCI_FID(SMC_32, SPCI_FNUM_PARTITION_INFO_GET)
+#define SPCI_ID_GET SPCI_FID(SMC_32, SPCI_FNUM_ID_GET)
+#define SPCI_MSG_POLL SPCI_FID(SMC_32, SPCI_FNUM_MSG_POLL)
+#define SPCI_MSG_WAIT SPCI_FID(SMC_32, SPCI_FNUM_MSG_WAIT)
+#define SPCI_MSG_YIELD SPCI_FID(SMC_32, SPCI_FNUM_MSG_YIELD)
+#define SPCI_MSG_RUN SPCI_FID(SMC_32, SPCI_FNUM_MSG_RUN)
+#define SPCI_MSG_SEND SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND)
+#define SPCI_MSG_SEND_DIRECT_REQ_SMC32 \
+ SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND_DIRECT_REQ)
+#define SPCI_MSG_SEND_DIRECT_RESP_SMC32 \
+ SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND_DIRECT_RESP)
+#define SPCI_MEM_DONATE_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_MEM_DONATE)
+#define SPCI_MEM_LEND_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_MEM_LEND)
+#define SPCI_MEM_SHARE_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_MEM_SHARE)
+#define SPCI_MEM_RETRIEVE_REQ_SMC32 \
+ SPCI_FID(SMC_32, SPCI_FNUM_MEM_RETRIEVE_REQ)
+#define SPCI_MEM_RETRIEVE_RESP SPCI_FID(SMC_32, SPCI_FNUM_MEM_RETRIEVE_RESP)
+#define SPCI_MEM_RELINQUISH SPCI_FID(SMC_32, SPCI_FNUM_MEM_RELINQUISH)
+#define SPCI_MEM_RECLAIM SPCI_FID(SMC_32, SPCI_FNUM_MEM_RECLAIM)
+
+/* SPCI SMC64 FIDs */
+#define SPCI_SUCCESS_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_SUCCESS)
+#define SPCI_RXTX_MAP_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_RXTX_MAP)
+#define SPCI_MSG_SEND_DIRECT_REQ_SMC64 \
+ SPCI_FID(SMC_64, SPCI_FNUM_MSG_SEND_DIRECT_REQ)
+#define SPCI_MSG_SEND_DIRECT_RESP_SMC64 \
+ SPCI_FID(SMC_64, SPCI_FNUM_MSG_SEND_DIRECT_RESP)
+#define SPCI_MEM_DONATE_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_MEM_DONATE)
+#define SPCI_MEM_LEND_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_MEM_LEND)
+#define SPCI_MEM_SHARE_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_MEM_SHARE)
+#define SPCI_MEM_RETRIEVE_REQ_SMC64 \
+ SPCI_FID(SMC_64, SPCI_FNUM_MEM_RETRIEVE_REQ)
+
+/*
+ * Reserve a special value for traffic targeted to the Hypervisor or SPM.
+ */
+#define SPCI_TARGET_INFO_MBZ U(0x0)
+
+/*
+ * Reserve a special value for MBZ parameters.
+ */
+#define SPCI_PARAM_MBZ U(0x0)
+
+#endif /* SPCI_SVC_H */
diff --git a/include/services/spm_core_manifest.h b/include/services/spm_core_manifest.h
new file mode 100644
index 0000000000..06ecc1391f
--- /dev/null
+++ b/include/services/spm_core_manifest.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPMC_MANIFEST_H
+#define SPMC_MANIFEST_H
+
+#include <stdint.h>
+
+/*******************************************************************************
+ * Attribute Section
+ ******************************************************************************/
+
+typedef struct spm_core_manifest_sect_attribute {
+ /*
+ * SPCI version (mandatory).
+ */
+ uint32_t major_version;
+ uint32_t minor_version;
+
+ /*
+ * Run-Time Exception Level (mandatory):
+ * - 1: SEL1
+ * - 2: SEL2
+ */
+ uint32_t runtime_el;
+
+ /*
+ * Run-Time Execution state (optional):
+ * - 0: AArch64 (default)
+ * - 1: AArch32
+ */
+ uint32_t exec_state;
+
+ /*
+ * Address of binary image containing SPM core in bytes (optional).
+ */
+ uint64_t load_address;
+
+ /*
+ * Offset from the base of the partition's binary image to the entry
+ * point of the partition.
+ */
+ uint64_t entrypoint;
+
+ /*
+ * Size of binary image containing SPM core in bytes (mandatory).
+ */
+ uint32_t binary_size;
+
+} spmc_manifest_sect_attribute_t;
+
+#endif /* SPMC_MANIFEST_H */
diff --git a/include/services/spmd_svc.h b/include/services/spmd_svc.h
new file mode 100644
index 0000000000..6e4caf266e
--- /dev/null
+++ b/include/services/spmd_svc.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPMD_SVC_H
+#define SPMD_SVC_H
+
+#ifndef __ASSEMBLER__
+#include <services/spci_svc.h>
+#include <stdint.h>
+
+int32_t spmd_setup(void);
+uint64_t spmd_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);
+#endif /* __ASSEMBLER__ */
+
+#endif /* SPMD_SVC_H */
diff --git a/include/tools_share/sptool.h b/include/tools_share/sptool.h
index 67a2cf093c..53668e09c7 100644
--- a/include/tools_share/sptool.h
+++ b/include/tools_share/sptool.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,21 +9,17 @@
#include <stdint.h>
-/* Header for a secure partition package. There is one per package. */
-struct sp_pkg_header {
- uint64_t version;
- uint64_t number_of_sp;
-};
+/* 4 Byte magic name "SPKG" */
+#define SECURE_PARTITION_MAGIC 0x474B5053
-/*
- * Entry descriptor in a secure partition package. Each entry comprises a
- * secure partition and its resource description.
- */
-struct sp_pkg_entry {
- uint64_t sp_offset;
- uint64_t sp_size;
- uint64_t rd_offset;
- uint64_t rd_size;
+/* 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/include/tools_share/uuid.h b/include/tools_share/uuid.h
index 7d00432061..36be9ed378 100644
--- a/include/tools_share/uuid.h
+++ b/include/tools_share/uuid.h
@@ -27,7 +27,7 @@
*/
/*
- * Portions copyright (c) 2014, ARM Limited and Contributors.
+ * Portions copyright (c) 2014-2020, ARM Limited and Contributors.
* All rights reserved.
*/
@@ -56,6 +56,11 @@ struct uuid {
uint8_t node[_UUID_NODE_LEN];
};
+union uuid_helper_t {
+ struct uuid uuid_struct;
+ uint32_t word[4];
+};
+
/* XXX namespace pollution? */
typedef struct uuid uuid_t;
diff --git a/lib/cpus/errata_report.c b/lib/cpus/errata_report.c
index f43b2176db..5d1e3c5cc8 100644
--- a/lib/cpus/errata_report.c
+++ b/lib/cpus/errata_report.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,7 +14,6 @@
#include <lib/cpus/errata_report.h>
#include <lib/el3_runtime/cpu_data.h>
#include <lib/spinlock.h>
-#include <lib/utils.h>
#ifdef IMAGE_BL1
# define BL_STRING "BL1"
diff --git a/lib/debugfs/devfip.c b/lib/debugfs/devfip.c
index 5581b219fa..fc14e707ec 100644
--- a/lib/debugfs/devfip.c
+++ b/lib/debugfs/devfip.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -103,10 +103,6 @@ static int get_entry(chan_t *c, struct fip_entry *entry)
return -1;
}
- if ((entry->size > LONG_MAX) || (entry->offset_address > LONG_MAX)) {
- return -1;
- }
-
if (entry->size == 0) {
return 0;
}
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index 73d1e354d5..2443001b87 100644
--- a/lib/el3_runtime/aarch32/context_mgmt.c
+++ b/lib/el3_runtime/aarch32/context_mgmt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,8 +17,6 @@
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/extensions/amu.h>
#include <lib/utils.h>
-#include <plat/common/platform.h>
-#include <smccc_helpers.h>
/*******************************************************************************
* Context management library initialisation routine. This library is used by
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index dc4717abee..546e39e16c 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -23,8 +23,6 @@
#include <lib/extensions/spe.h>
#include <lib/extensions/sve.h>
#include <lib/utils.h>
-#include <plat/common/platform.h>
-#include <smccc_helpers.h>
/*******************************************************************************
diff --git a/lib/el3_runtime/aarch64/cpu_data.S b/lib/el3_runtime/aarch64/cpu_data.S
index 2edf225596..2392d6b90c 100644
--- a/lib/el3_runtime/aarch64/cpu_data.S
+++ b/lib/el3_runtime/aarch64/cpu_data.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -41,7 +41,8 @@ endfunc init_cpu_data_ptr
func _cpu_data_by_index
mov_imm x1, CPU_DATA_SIZE
mul x0, x0, x1
- adr x1, percpu_data
+ adrp x1, percpu_data
+ add x1, x1, :lo12:percpu_data
add x0, x0, x1
ret
endfunc _cpu_data_by_index
diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c
new file mode 100644
index 0000000000..a6da56b00d
--- /dev/null
+++ b/lib/fconf/fconf.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <lib/fconf/fconf.h>
+#include <libfdt.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+struct fconf_dtb_info_t fconf_dtb_info;
+
+void fconf_load_config(void)
+{
+ int err;
+ /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB */
+ image_info_t arm_tb_fw_info = {
+ .h.type = (uint8_t)PARAM_IMAGE_BINARY,
+ .h.version = (uint8_t)VERSION_2,
+ .h.size = (uint16_t)sizeof(image_info_t),
+ .h.attr = 0,
+ .image_base = ARM_TB_FW_CONFIG_BASE,
+ .image_max_size = (uint32_t)
+ (ARM_TB_FW_CONFIG_LIMIT - ARM_TB_FW_CONFIG_BASE)
+ };
+
+ VERBOSE("FCONF: Loading FW_CONFIG\n");
+ err = load_auth_image(TB_FW_CONFIG_ID, &arm_tb_fw_info);
+ if (err != 0) {
+ /* Return if FW_CONFIG is not loaded */
+ VERBOSE("Failed to load FW_CONFIG\n");
+ return;
+ }
+
+ /* At this point we know that a DTB is indeed available */
+ fconf_dtb_info.base_addr = arm_tb_fw_info.image_base;
+ fconf_dtb_info.size = (size_t)arm_tb_fw_info.image_size;
+
+#if !BL2_AT_EL3
+ image_desc_t *desc;
+
+ /* The BL2 ep_info arg0 is modified to point to FW_CONFIG */
+ desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
+ assert(desc != NULL);
+ desc->ep_info.args.arg0 = arm_tb_fw_info.image_base;
+#endif
+
+ INFO("FCONF: FW_CONFIG loaded at address = 0x%lx\n", arm_tb_fw_info.image_base);
+}
+
+void fconf_populate(uintptr_t config)
+{
+ assert(config != 0UL);
+
+ /* Check if the pointer to DTB is correct */
+ if (fdt_check_header((void *)config) != 0) {
+ ERROR("FCONF: Invalid DTB file passed for FW_CONFIG\n");
+ panic();
+ }
+
+ INFO("FCONF: Reading firmware configuration file from: 0x%lx\n", config);
+
+ /* Go through all registered populate functions */
+ IMPORT_SYM(struct fconf_populator *, __FCONF_POPULATOR_START__, start);
+ IMPORT_SYM(struct fconf_populator *, __FCONF_POPULATOR_END__, end);
+ const struct fconf_populator *populator;
+
+ for (populator = start; populator != end; populator++) {
+ assert((populator->info != NULL) && (populator->populate != NULL));
+
+ INFO("FCONF: Reading firmware configuration information for: %s\n", populator->info);
+ if (populator->populate(config) != 0) {
+ /* TODO: handle property miss */
+ panic();
+ }
+ }
+
+ /* save local pointer to the config dtb */
+ fconf_dtb_info.base_addr = config;
+}
diff --git a/lib/fconf/fconf.mk b/lib/fconf/fconf.mk
new file mode 100644
index 0000000000..7031969497
--- /dev/null
+++ b/lib/fconf/fconf.mk
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Add Firmware Configuration files
+FCONF_SOURCES := lib/fconf/fconf.c \
+ lib/fconf/fconf_dyn_cfg_getter.c
+
+BL1_SOURCES += ${FCONF_SOURCES}
+BL2_SOURCES += ${FCONF_SOURCES}
diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c
new file mode 100644
index 0000000000..d313a56189
--- /dev/null
+++ b/lib/fconf/fconf_dyn_cfg_getter.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+#include <lib/object_pool.h>
+#include <libfdt.h>
+
+/* We currently use TB_FW, SOC_FW, TOS_FW, NS_fw and HW configs */
+#define MAX_DTB_INFO U(5)
+
+static struct dyn_cfg_dtb_info_t dtb_infos[MAX_DTB_INFO];
+static OBJECT_POOL_ARRAY(dtb_info_pool, dtb_infos);
+
+struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id)
+{
+ unsigned int index;
+ struct dyn_cfg_dtb_info_t *info;
+
+ /* Positions index to the proper config-id */
+ for (index = 0; index < MAX_DTB_INFO; index++) {
+ if (dtb_infos[index].config_id == config_id) {
+ info = &dtb_infos[index];
+ break;
+ }
+ }
+
+ if (index == MAX_DTB_INFO) {
+ WARN("FCONF: Invalid config id %u\n", config_id);
+ info = NULL;
+ }
+
+ return info;
+}
+
+int fconf_populate_dtb_registry(uintptr_t config)
+{
+ int rc;
+ int node, child;
+ struct dyn_cfg_dtb_info_t *dtb_info;
+
+ /* As libfdt use void *, we can't avoid this cast */
+ const void *dtb = (void *)config;
+
+ /* Find the node offset point to "arm,dyn_cfg-dtb_registry" compatible property */
+ const char *compatible_str = "arm,dyn_cfg-dtb_registry";
+ node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
+ if (node < 0) {
+ ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
+ return node;
+ }
+
+ fdt_for_each_subnode(child, dtb, node) {
+ dtb_info = pool_alloc(&dtb_info_pool);
+
+ /* Read configuration dtb information */
+ rc = fdtw_read_cells(dtb, child, "load-address", 2, &dtb_info->config_addr);
+ if (rc < 0) {
+ ERROR("FCONF: Incomplete configuration property in dtb-registry.\n");
+ return rc;
+ }
+
+ rc = fdtw_read_cells(dtb, child, "max-size", 1, &dtb_info->config_max_size);
+ if (rc < 0) {
+ ERROR("FCONF: Incomplete configuration property in dtb-registry.\n");
+ return rc;
+ }
+
+ rc = fdtw_read_cells(dtb, child, "id", 1, &dtb_info->config_id);
+ if (rc < 0) {
+ ERROR("FCONF: Incomplete configuration property in dtb-registry.\n");
+ return rc;
+ }
+
+ VERBOSE("FCONF: dyn_cfg.dtb_registry cell found with:\n");
+ VERBOSE("\tload-address = %lx\n", dtb_info->config_addr);
+ VERBOSE("\tmax-size = 0x%zx\n", dtb_info->config_max_size);
+ VERBOSE("\tconfig-id = %u\n", dtb_info->config_id);
+ }
+
+ if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) {
+ ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node);
+ return child;
+ }
+
+ return 0;
+}
+
+FCONF_REGISTER_POPULATOR(dyn_cfg, fconf_populate_dtb_registry);
diff --git a/lib/fconf/fconf_tbbr_getter.c b/lib/fconf/fconf_tbbr_getter.c
new file mode 100644
index 0000000000..c6df9c8765
--- /dev/null
+++ b/lib/fconf/fconf_tbbr_getter.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <lib/fconf/fconf_tbbr_getter.h>
+#include <libfdt.h>
+
+struct tbbr_dyn_config_t tbbr_dyn_config;
+
+int fconf_populate_tbbr_dyn_config(uintptr_t config)
+{
+ int err;
+ int node;
+
+ /* As libfdt use void *, we can't avoid this cast */
+ const void *dtb = (void *)config;
+
+ /* Assert the node offset point to "arm,tb_fw" compatible property */
+ const char *compatible_str = "arm,tb_fw";
+ node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
+ if (node < 0) {
+ ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
+ return node;
+ }
+
+ /* Locate the disable_auth cell and read the value */
+ err = fdtw_read_cells(dtb, node, "disable_auth", 1, &tbbr_dyn_config.disable_auth);
+ if (err < 0) {
+ WARN("FCONF: Read cell failed for `disable_auth`\n");
+ return err;
+ }
+
+ /* Check if the value is boolean */
+ if ((tbbr_dyn_config.disable_auth != 0U) && (tbbr_dyn_config.disable_auth != 1U)) {
+ WARN("Invalid value for `disable_auth` cell %d\n", tbbr_dyn_config.disable_auth);
+ return -1;
+ }
+
+#if defined(DYN_DISABLE_AUTH)
+ if (tbbr_dyn_config.disable_auth == 1)
+ dyn_disable_auth();
+#endif
+
+ /* Retrieve the Mbed TLS heap details from the DTB */
+ err = fdtw_read_cells(dtb, node,
+ "mbedtls_heap_addr", 2, &tbbr_dyn_config.mbedtls_heap_addr);
+ if (err < 0) {
+ ERROR("FCONF: Read cell failed for mbedtls_heap\n");
+ return err;
+ }
+
+ err = fdtw_read_cells(dtb, node,
+ "mbedtls_heap_size", 1, &tbbr_dyn_config.mbedtls_heap_size);
+ if (err < 0) {
+ ERROR("FCONF: Read cell failed for mbedtls_heap\n");
+ return err;
+ }
+
+ VERBOSE("FCONF:tbbr.disable_auth cell found with value = %d\n",
+ tbbr_dyn_config.disable_auth);
+ VERBOSE("FCONF:tbbr.mbedtls_heap_addr cell found with value = %p\n",
+ tbbr_dyn_config.mbedtls_heap_addr);
+ VERBOSE("FCONF:tbbr.mbedtls_heap_size cell found with value = %zu\n",
+ tbbr_dyn_config.mbedtls_heap_size);
+
+ return 0;
+}
+
+FCONF_REGISTER_POPULATOR(tbbr, fconf_populate_tbbr_dyn_config);
diff --git a/lib/optee/optee_utils.c b/lib/optee/optee_utils.c
index 2a407939b2..0ad108242e 100644
--- a/lib/optee/optee_utils.c
+++ b/lib/optee/optee_utils.c
@@ -1,15 +1,12 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
-#include <errno.h>
-#include <arch_helpers.h>
#include <common/debug.h>
-#include <common/desc_image_load.h>
#include <lib/optee_utils.h>
/*
diff --git a/lib/romlib/jmptbl.i b/lib/romlib/jmptbl.i
index a7280d0d66..33710f581c 100644
--- a/lib/romlib/jmptbl.i
+++ b/lib/romlib/jmptbl.i
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -17,6 +17,7 @@ fdt fdt_getprop_namelen
fdt fdt_setprop_inplace
fdt fdt_check_header
fdt fdt_node_offset_by_compatible
+fdt fdt_setprop_inplace_namelen_partial
mbedtls mbedtls_asn1_get_alg
mbedtls mbedtls_asn1_get_alg_null
mbedtls mbedtls_asn1_get_bitstring_null
diff --git a/lib/utils/mem_region.c b/lib/utils/mem_region.c
index 08bccf64ba..6bd78ba824 100644
--- a/lib/utils/mem_region.c
+++ b/lib/utils/mem_region.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -32,7 +32,7 @@ void clear_mem_regions(mem_region_t *tbl, size_t nregions)
{
size_t i;
- assert(tbl);
+ assert(tbl != NULL);
assert(nregions > 0);
for (i = 0; i < nregions; i++) {
@@ -114,7 +114,7 @@ int mem_region_in_array_chk(mem_region_t *tbl, size_t nregions,
uintptr_t region_start, region_end, start, end;
size_t i;
- assert(tbl);
+ assert(tbl != NULL);
assert(nbytes > 0);
assert(!check_uptr_overflow(addr, nbytes-1));
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index fff336cd21..e8e990d451 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -201,6 +201,9 @@ USE_COHERENT_MEM := 1
# Build option to add debugfs support
USE_DEBUGFS := 0
+# Build option to fconf based io
+USE_FCONF_BASED_IO := 0
+
# Build option to choose whether Trusted Firmware uses library at ROM
USE_ROMLIB := 0
diff --git a/plat/amlogic/axg/axg_bl31_setup.c b/plat/amlogic/axg/axg_bl31_setup.c
new file mode 100644
index 0000000000..8cc9d69f41
--- /dev/null
+++ b/plat/amlogic/axg/axg_bl31_setup.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <common/bl_common.h>
+#include <common/interrupt_props.h>
+#include <drivers/arm/gicv2.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_mmu_helpers.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include "aml_private.h"
+
+/*
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL31 from BL2.
+ */
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+static image_info_t bl30_image_info;
+static image_info_t bl301_image_info;
+
+/*******************************************************************************
+ * 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 can have 0x0 as the entrypoint. */
+ if (next_image_info->pc != 0U)
+ return next_image_info;
+
+ return NULL;
+}
+
+/*******************************************************************************
+ * Perform any BL31 early platform setup. Here is an opportunity to copy
+ * parameters passed by the calling EL (S-EL1 in BL2 & S-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.
+ ******************************************************************************/
+struct axg_bl31_param {
+ param_header_t h;
+ image_info_t *bl31_image_info;
+ entry_point_info_t *bl32_ep_info;
+ image_info_t *bl32_image_info;
+ entry_point_info_t *bl33_ep_info;
+ image_info_t *bl33_image_info;
+ image_info_t *scp_image_info[];
+};
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ struct axg_bl31_param *from_bl2;
+
+ /* Initialize the console to provide early debug support */
+ aml_console_init();
+
+ from_bl2 = (struct axg_bl31_param *)arg0;
+
+ /* Check params passed from BL2 are not NULL. */
+ assert(from_bl2 != NULL);
+ assert(from_bl2->h.type == PARAM_BL31);
+ assert(from_bl2->h.version >= VERSION_1);
+
+ /*
+ * Copy BL32 and BL33 entry point information. It is stored in Secure
+ * RAM, in BL2's address space.
+ */
+ bl32_image_ep_info = *from_bl2->bl32_ep_info;
+ bl33_image_ep_info = *from_bl2->bl33_ep_info;
+
+#if AML_USE_ATOS
+ /*
+ * BL2 is unconditionally setting 0 (OPTEE_AARCH64) in arg0 even when
+ * the BL32 image is 32bit (OPTEE_AARCH32). This is causing the boot to
+ * hang when ATOS (32bit Amlogic BL32 binary-only TEE OS) is used.
+ *
+ * Hardcode to OPTEE_AARCH32 / MODE_RW_32.
+ */
+ bl32_image_ep_info.args.arg0 = MODE_RW_32;
+#endif
+
+ if (bl33_image_ep_info.pc == 0U) {
+ ERROR("BL31: BL33 entrypoint not obtained from BL2\n");
+ panic();
+ }
+
+ bl30_image_info = *from_bl2->scp_image_info[0];
+ bl301_image_info = *from_bl2->scp_image_info[1];
+}
+
+void bl31_plat_arch_setup(void)
+{
+ aml_setup_page_tables();
+
+ enable_mmu_el3(0);
+}
+
+static inline bool axg_scp_ready(void)
+{
+ return AML_AO_RTI_SCP_IS_READY(mmio_read_32(AML_AO_RTI_SCP_STAT));
+}
+
+static inline void axg_scp_boot(void)
+{
+ aml_scpi_upload_scp_fw(bl30_image_info.image_base,
+ bl30_image_info.image_size, 0);
+ aml_scpi_upload_scp_fw(bl301_image_info.image_base,
+ bl301_image_info.image_size, 1);
+ while (!axg_scp_ready())
+ ;
+}
+
+/*******************************************************************************
+ * GICv2 driver setup information
+ ******************************************************************************/
+static const interrupt_prop_t axg_interrupt_props[] = {
+ INTR_PROP_DESC(IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL)
+};
+
+static const gicv2_driver_data_t axg_gic_data = {
+ .gicd_base = AML_GICD_BASE,
+ .gicc_base = AML_GICC_BASE,
+ .interrupt_props = axg_interrupt_props,
+ .interrupt_props_num = ARRAY_SIZE(axg_interrupt_props)
+};
+
+void bl31_platform_setup(void)
+{
+ aml_mhu_secure_init();
+
+ gicv2_driver_init(&axg_gic_data);
+ gicv2_distif_init();
+ gicv2_pcpu_distif_init();
+ gicv2_cpuif_enable();
+
+ axg_scp_boot();
+}
diff --git a/plat/amlogic/axg/axg_common.c b/plat/amlogic/axg/axg_common.c
new file mode 100644
index 0000000000..870daf4591
--- /dev/null
+++ b/plat/amlogic/axg/axg_common.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <bl31/interrupt_mgmt.h>
+#include <common/bl_common.h>
+#include <common/ep_info.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <platform_def.h>
+#include <stdint.h>
+
+/*******************************************************************************
+ * Platform memory map regions
+ ******************************************************************************/
+#define MAP_NSDRAM0 MAP_REGION_FLAT(AML_NSDRAM0_BASE, \
+ AML_NSDRAM0_SIZE, \
+ MT_MEMORY | MT_RW | MT_NS)
+
+#define MAP_NS_SHARE_MEM MAP_REGION_FLAT(AML_NS_SHARE_MEM_BASE, \
+ AML_NS_SHARE_MEM_SIZE, \
+ MT_MEMORY | MT_RW | MT_NS)
+
+#define MAP_SEC_SHARE_MEM MAP_REGION_FLAT(AML_SEC_SHARE_MEM_BASE, \
+ AML_SEC_SHARE_MEM_SIZE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
+#define MAP_SEC_DEVICE0 MAP_REGION_FLAT(AML_SEC_DEVICE0_BASE, \
+ AML_SEC_DEVICE0_SIZE, \
+ MT_DEVICE | MT_RW)
+
+#define MAP_GIC_DEVICE MAP_REGION_FLAT(AML_GIC_DEVICE_BASE, \
+ AML_GIC_DEVICE_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_SEC_DEVICE1 MAP_REGION_FLAT(AML_SEC_DEVICE1_BASE, \
+ AML_SEC_DEVICE1_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_SEC_DEVICE2 MAP_REGION_FLAT(AML_SEC_DEVICE2_BASE, \
+ AML_SEC_DEVICE2_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_TZRAM MAP_REGION_FLAT(AML_TZRAM_BASE, \
+ AML_TZRAM_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+static const mmap_region_t axg_mmap[] = {
+ MAP_NSDRAM0,
+ MAP_NS_SHARE_MEM,
+ MAP_SEC_SHARE_MEM,
+ MAP_SEC_DEVICE0,
+ MAP_GIC_DEVICE,
+ MAP_SEC_DEVICE1,
+ MAP_SEC_DEVICE2,
+ MAP_TZRAM,
+ {0}
+};
+
+/*******************************************************************************
+ * Per-image regions
+ ******************************************************************************/
+#define MAP_BL31 MAP_REGION_FLAT(BL31_BASE, \
+ BL31_END - BL31_BASE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
+#define MAP_BL_CODE MAP_REGION_FLAT(BL_CODE_BASE, \
+ BL_CODE_END - BL_CODE_BASE, \
+ MT_CODE | MT_SECURE)
+
+#define MAP_BL_RO_DATA MAP_REGION_FLAT(BL_RO_DATA_BASE, \
+ BL_RO_DATA_END - BL_RO_DATA_BASE, \
+ MT_RO_DATA | MT_SECURE)
+
+#define MAP_BL_COHERENT MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, \
+ BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+/*******************************************************************************
+ * Function that sets up the translation tables.
+ ******************************************************************************/
+void aml_setup_page_tables(void)
+{
+#if IMAGE_BL31
+ const mmap_region_t axg_bl_mmap[] = {
+ MAP_BL31,
+ MAP_BL_CODE,
+ MAP_BL_RO_DATA,
+#if USE_COHERENT_MEM
+ MAP_BL_COHERENT,
+#endif
+ {0}
+ };
+#endif
+
+ mmap_add(axg_bl_mmap);
+
+ mmap_add(axg_mmap);
+
+ init_xlat_tables();
+}
+
+/*******************************************************************************
+ * Function that returns the system counter frequency
+ ******************************************************************************/
+unsigned int plat_get_syscnt_freq2(void)
+{
+ mmio_clrbits_32(AML_SYS_CPU_CFG7, PLAT_SYS_CPU_CFG7);
+ mmio_clrbits_32(AML_AO_TIMESTAMP_CNTL, PLAT_AO_TIMESTAMP_CNTL);
+
+ return AML_OSC24M_CLK_IN_HZ;
+}
diff --git a/plat/amlogic/axg/axg_def.h b/plat/amlogic/axg/axg_def.h
new file mode 100644
index 0000000000..d90681afdb
--- /dev/null
+++ b/plat/amlogic/axg/axg_def.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AXG_DEF_H
+#define AXG_DEF_H
+
+#include <lib/utils_def.h>
+
+/*******************************************************************************
+ * System oscillator
+ ******************************************************************************/
+#define AML_OSC24M_CLK_IN_HZ ULL(24000000) /* 24 MHz */
+
+/*******************************************************************************
+ * Memory regions
+ ******************************************************************************/
+#define AML_NS_SHARE_MEM_BASE UL(0x05000000)
+#define AML_NS_SHARE_MEM_SIZE UL(0x00100000)
+
+#define AML_SEC_SHARE_MEM_BASE UL(0x05200000)
+#define AML_SEC_SHARE_MEM_SIZE UL(0x00100000)
+
+#define AML_GIC_DEVICE_BASE UL(0xFFC00000)
+#define AML_GIC_DEVICE_SIZE UL(0x00008000)
+
+#define AML_NSDRAM0_BASE UL(0x01000000)
+#define AML_NSDRAM0_SIZE UL(0x0F000000)
+
+#define BL31_BASE UL(0x05100000)
+#define BL31_SIZE UL(0x00100000)
+#define BL31_LIMIT (BL31_BASE + BL31_SIZE)
+
+/* Shared memory used for SMC services */
+#define AML_SHARE_MEM_INPUT_BASE UL(0x050FE000)
+#define AML_SHARE_MEM_OUTPUT_BASE UL(0x050FF000)
+
+#define AML_SEC_DEVICE0_BASE UL(0xFFD00000)
+#define AML_SEC_DEVICE0_SIZE UL(0x00026000)
+
+#define AML_SEC_DEVICE1_BASE UL(0xFF800000)
+#define AML_SEC_DEVICE1_SIZE UL(0x0000A000)
+
+#define AML_SEC_DEVICE2_BASE UL(0xFF620000)
+#define AML_SEC_DEVICE2_SIZE UL(0x00028000)
+
+#define AML_TZRAM_BASE UL(0xFFFC0000)
+#define AML_TZRAM_SIZE UL(0x00020000)
+
+/* Mailboxes */
+#define AML_MHU_SECURE_SCP_TO_AP_PAYLOAD UL(0xFFFD3800)
+#define AML_MHU_SECURE_AP_TO_SCP_PAYLOAD UL(0xFFFD3A00)
+#define AML_PSCI_MAILBOX_BASE UL(0xFFFD3F00)
+
+/*******************************************************************************
+ * GIC-400 and interrupt handling related constants
+ ******************************************************************************/
+#define AML_GICD_BASE UL(0xFFC01000)
+#define AML_GICC_BASE UL(0xFFC02000)
+
+#define IRQ_SEC_PHY_TIMER 29
+
+#define IRQ_SEC_SGI_0 8
+#define IRQ_SEC_SGI_1 9
+#define IRQ_SEC_SGI_2 10
+#define IRQ_SEC_SGI_3 11
+#define IRQ_SEC_SGI_4 12
+#define IRQ_SEC_SGI_5 13
+#define IRQ_SEC_SGI_6 14
+#define IRQ_SEC_SGI_7 15
+#define IRQ_SEC_SGI_8 16
+
+/*******************************************************************************
+ * UART definitions
+ ******************************************************************************/
+#define AML_UART0_AO_BASE UL(0xFF803000)
+#define AML_UART0_AO_CLK_IN_HZ AML_OSC24M_CLK_IN_HZ
+#define AML_UART_BAUDRATE U(115200)
+
+/*******************************************************************************
+ * Memory-mapped I/O Registers
+ ******************************************************************************/
+#define AML_AO_TIMESTAMP_CNTL UL(0xFF8000B4)
+
+#define AML_SYS_CPU_CFG7 UL(0xFF634664)
+
+#define AML_AO_RTI_STATUS_REG3 UL(0xFF80001C)
+#define AML_AO_RTI_SCP_STAT UL(0xFF80023C)
+#define AML_AO_RTI_SCP_READY_OFF U(0x14)
+#define AML_A0_RTI_SCP_READY_MASK U(3)
+#define AML_AO_RTI_SCP_IS_READY(v) \
+ ((((v) >> AML_AO_RTI_SCP_READY_OFF) & \
+ AML_A0_RTI_SCP_READY_MASK) == AML_A0_RTI_SCP_READY_MASK)
+
+#define AML_HIU_MAILBOX_SET_0 UL(0xFF63C404)
+#define AML_HIU_MAILBOX_STAT_0 UL(0xFF63C408)
+#define AML_HIU_MAILBOX_CLR_0 UL(0xFF63C40C)
+#define AML_HIU_MAILBOX_SET_3 UL(0xFF63C428)
+#define AML_HIU_MAILBOX_STAT_3 UL(0xFF63C42C)
+#define AML_HIU_MAILBOX_CLR_3 UL(0xFF63C430)
+
+#define AML_SHA_DMA_BASE UL(0xFF63E000)
+#define AML_SHA_DMA_DESC (AML_SHA_DMA_BASE + 0x08)
+#define AML_SHA_DMA_STATUS (AML_SHA_DMA_BASE + 0x28)
+
+/*******************************************************************************
+ * System Monitor Call IDs and arguments
+ ******************************************************************************/
+#define AML_SM_GET_SHARE_MEM_INPUT_BASE U(0x82000020)
+#define AML_SM_GET_SHARE_MEM_OUTPUT_BASE U(0x82000021)
+
+#define AML_SM_EFUSE_READ U(0x82000030)
+#define AML_SM_EFUSE_USER_MAX U(0x82000033)
+
+#define AML_SM_JTAG_ON U(0x82000040)
+#define AML_SM_JTAG_OFF U(0x82000041)
+#define AML_SM_GET_CHIP_ID U(0x82000044)
+
+#define AML_JTAG_STATE_ON U(0)
+#define AML_JTAG_STATE_OFF U(1)
+
+#define AML_JTAG_M3_AO U(0)
+#define AML_JTAG_M3_EE U(1)
+#define AML_JTAG_A53_AO U(2)
+#define AML_JTAG_A53_EE U(3)
+
+#endif /* AXG_DEF_H */
diff --git a/plat/amlogic/axg/axg_pm.c b/plat/amlogic/axg/axg_pm.c
new file mode 100644
index 0000000000..e67f263a4b
--- /dev/null
+++ b/plat/amlogic/axg/axg_pm.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <common/debug.h>
+#include <drivers/arm/gicv2.h>
+#include <drivers/console.h>
+#include <errno.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include "aml_private.h"
+
+#define SCPI_POWER_ON 0
+#define SCPI_POWER_RETENTION 1
+#define SCPI_POWER_OFF 3
+
+#define SCPI_SYSTEM_SHUTDOWN 0
+#define SCPI_SYSTEM_REBOOT 1
+
+static uintptr_t axg_sec_entrypoint;
+
+static void axg_pm_set_reset_addr(u_register_t mpidr, uint64_t value)
+{
+ unsigned int core = plat_calc_core_pos(mpidr);
+ uintptr_t cpu_mailbox_addr = AML_PSCI_MAILBOX_BASE + (core << 4);
+
+ mmio_write_64(cpu_mailbox_addr, value);
+}
+
+static void axg_pm_reset(u_register_t mpidr, uint32_t value)
+{
+ unsigned int core = plat_calc_core_pos(mpidr);
+ uintptr_t cpu_mailbox_addr = AML_PSCI_MAILBOX_BASE + (core << 4) + 8;
+
+ mmio_write_32(cpu_mailbox_addr, value);
+}
+
+static void __dead2 axg_system_reset(void)
+{
+ u_register_t mpidr = read_mpidr_el1();
+ int ret;
+
+ INFO("BL31: PSCI_SYSTEM_RESET\n");
+
+ ret = aml_scpi_sys_power_state(SCPI_SYSTEM_REBOOT);
+ if (ret != 0) {
+ ERROR("BL31: PSCI_SYSTEM_RESET: SCP error: %i\n", ret);
+ panic();
+ }
+
+ axg_pm_reset(mpidr, 0);
+
+ wfi();
+
+ ERROR("BL31: PSCI_SYSTEM_RESET: Operation not handled\n");
+ panic();
+}
+
+static void __dead2 axg_system_off(void)
+{
+ u_register_t mpidr = read_mpidr_el1();
+ int ret;
+
+ INFO("BL31: PSCI_SYSTEM_OFF\n");
+
+ ret = aml_scpi_sys_power_state(SCPI_SYSTEM_SHUTDOWN);
+ if (ret != 0) {
+ ERROR("BL31: PSCI_SYSTEM_OFF: SCP error %i\n", ret);
+ panic();
+ }
+
+ axg_pm_set_reset_addr(mpidr, 0);
+ axg_pm_reset(mpidr, 0);
+
+ dmbsy();
+ wfi();
+
+ ERROR("BL31: PSCI_SYSTEM_OFF: Operation not handled\n");
+ panic();
+}
+
+static int32_t axg_pwr_domain_on(u_register_t mpidr)
+{
+ axg_pm_set_reset_addr(mpidr, axg_sec_entrypoint);
+ aml_scpi_set_css_power_state(mpidr,
+ SCPI_POWER_ON, SCPI_POWER_ON, SCPI_POWER_ON);
+ dmbsy();
+ sev();
+
+ return PSCI_E_SUCCESS;
+}
+
+static void axg_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+ assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
+ PLAT_LOCAL_STATE_OFF);
+
+ gicv2_pcpu_distif_init();
+ gicv2_cpuif_enable();
+
+ axg_pm_set_reset_addr(read_mpidr_el1(), 0);
+}
+
+static void axg_pwr_domain_off(const psci_power_state_t *target_state)
+{
+ u_register_t mpidr = read_mpidr_el1();
+ uint32_t system_state = SCPI_POWER_ON;
+ uint32_t cluster_state = SCPI_POWER_ON;
+
+ assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
+ PLAT_LOCAL_STATE_OFF);
+
+ axg_pm_reset(mpidr, -1);
+
+ gicv2_cpuif_disable();
+
+ if (target_state->pwr_domain_state[MPIDR_AFFLVL2] ==
+ PLAT_LOCAL_STATE_OFF)
+ system_state = SCPI_POWER_OFF;
+
+ if (target_state->pwr_domain_state[MPIDR_AFFLVL1] ==
+ PLAT_LOCAL_STATE_OFF)
+ cluster_state = SCPI_POWER_OFF;
+
+
+ aml_scpi_set_css_power_state(mpidr,
+ SCPI_POWER_OFF, cluster_state,
+ system_state);
+}
+
+static void __dead2 axg_pwr_domain_pwr_down_wfi(const psci_power_state_t
+ *target_state)
+{
+ dsbsy();
+ axg_pm_reset(read_mpidr_el1(), 0);
+
+ for (;;)
+ wfi();
+}
+
+/*******************************************************************************
+ * Platform handlers and setup function.
+ ******************************************************************************/
+static const plat_psci_ops_t axg_ops = {
+ .pwr_domain_on = axg_pwr_domain_on,
+ .pwr_domain_on_finish = axg_pwr_domain_on_finish,
+ .pwr_domain_off = axg_pwr_domain_off,
+ .pwr_domain_pwr_down_wfi = axg_pwr_domain_pwr_down_wfi,
+ .system_off = axg_system_off,
+ .system_reset = axg_system_reset
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+ const plat_psci_ops_t **psci_ops)
+{
+ axg_sec_entrypoint = sec_entrypoint;
+ *psci_ops = &axg_ops;
+ return 0;
+}
diff --git a/plat/amlogic/axg/include/platform_def.h b/plat/amlogic/axg/include/platform_def.h
new file mode 100644
index 0000000000..a47cf7348e
--- /dev/null
+++ b/plat/amlogic/axg/include/platform_def.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include <lib/utils_def.h>
+
+#include "../axg_def.h"
+
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH aarch64
+
+#define PLATFORM_STACK_SIZE UL(0x1000)
+
+#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4)
+#define PLATFORM_CLUSTER_COUNT U(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER
+#define PLATFORM_CORE_COUNT PLATFORM_CLUSTER0_CORE_COUNT
+
+#define AML_PRIMARY_CPU U(0)
+
+#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1
+#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \
+ PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_RET_STATE U(1)
+#define PLAT_MAX_OFF_STATE U(2)
+
+#define PLAT_SYS_CPU_CFG7 (U(1) << 25)
+#define PLAT_AO_TIMESTAMP_CNTL U(0x1ff)
+
+/* Local power state for power domains in Run state. */
+#define PLAT_LOCAL_STATE_RUN U(0)
+/* Local power state for retention. Valid only for CPU power domains */
+#define PLAT_LOCAL_STATE_RET U(1)
+/* Local power state for power-down. Valid for CPU and cluster power domains. */
+#define PLAT_LOCAL_STATE_OFF U(2)
+
+/*
+ * Macros used to parse state information from State-ID if it is using the
+ * recommended encoding for State-ID.
+ */
+#define PLAT_LOCAL_PSTATE_WIDTH U(4)
+#define PLAT_LOCAL_PSTATE_MASK ((U(1) << PLAT_LOCAL_PSTATE_WIDTH) - 1)
+
+/*
+ * Some data must be 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.
+ */
+#define CACHE_WRITEBACK_SHIFT U(6)
+#define CACHE_WRITEBACK_GRANULE (U(1) << CACHE_WRITEBACK_SHIFT)
+
+/* Memory-related defines */
+#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32)
+
+#define MAX_MMAP_REGIONS 16
+#define MAX_XLAT_TABLES 8
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/amlogic/axg/platform.mk b/plat/amlogic/axg/platform.mk
new file mode 100644
index 0000000000..3560b0cd18
--- /dev/null
+++ b/plat/amlogic/axg/platform.mk
@@ -0,0 +1,95 @@
+#
+# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include lib/xlat_tables_v2/xlat_tables.mk
+
+AML_PLAT := plat/amlogic
+AML_PLAT_SOC := ${AML_PLAT}/${PLAT}
+AML_PLAT_COMMON := ${AML_PLAT}/common
+
+DOIMAGEPATH ?= tools/amlogic
+DOIMAGETOOL ?= ${DOIMAGEPATH}/doimage
+
+PLAT_INCLUDES := -Iinclude/drivers/amlogic/ \
+ -I${AML_PLAT_SOC}/include \
+ -I${AML_PLAT_COMMON}/include
+
+GIC_SOURCES := 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
+
+BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \
+ plat/common/plat_psci_common.c \
+ drivers/amlogic/console/aarch64/meson_console.S \
+ ${AML_PLAT_SOC}/${PLAT}_bl31_setup.c \
+ ${AML_PLAT_SOC}/${PLAT}_pm.c \
+ ${AML_PLAT_SOC}/${PLAT}_common.c \
+ ${AML_PLAT_COMMON}/aarch64/aml_helpers.S \
+ ${AML_PLAT_COMMON}/aml_efuse.c \
+ ${AML_PLAT_COMMON}/aml_mhu.c \
+ ${AML_PLAT_COMMON}/aml_scpi.c \
+ ${AML_PLAT_COMMON}/aml_sip_svc.c \
+ ${AML_PLAT_COMMON}/aml_thermal.c \
+ ${AML_PLAT_COMMON}/aml_topology.c \
+ ${AML_PLAT_COMMON}/aml_console.c \
+ drivers/amlogic/crypto/sha_dma.c \
+ ${XLAT_TABLES_LIB_SRCS} \
+ ${GIC_SOURCES}
+
+# Tune compiler for Cortex-A53
+ifeq ($(notdir $(CC)),armclang)
+ TF_CFLAGS_aarch64 += -mcpu=cortex-a53
+else ifneq ($(findstring clang,$(notdir $(CC))),)
+ TF_CFLAGS_aarch64 += -mcpu=cortex-a53
+else
+ TF_CFLAGS_aarch64 += -mtune=cortex-a53
+endif
+
+# Build config flags
+# ------------------
+
+# Enable all errata workarounds for Cortex-A53
+ERRATA_A53_855873 := 1
+ERRATA_A53_819472 := 1
+ERRATA_A53_824069 := 1
+ERRATA_A53_827319 := 1
+
+WORKAROUND_CVE_2017_5715 := 0
+
+# Have different sections for code and rodata
+SEPARATE_CODE_AND_RODATA := 1
+
+# Use Coherent memory
+USE_COHERENT_MEM := 1
+
+AML_USE_ATOS := 0
+$(eval $(call assert_boolean,AML_USE_ATOS))
+$(eval $(call add_define,AML_USE_ATOS))
+
+# Verify build config
+# -------------------
+
+ifneq (${RESET_TO_BL31}, 0)
+ $(error Error: ${PLAT} needs RESET_TO_BL31=0)
+endif
+
+ifeq (${ARCH},aarch32)
+ $(error Error: AArch32 not supported on ${PLAT})
+endif
+
+all: ${BUILD_PLAT}/bl31.img
+distclean realclean clean: cleanimage
+
+cleanimage:
+ ${Q}${MAKE} -C ${DOIMAGEPATH} clean
+
+${DOIMAGETOOL}:
+ ${Q}${MAKE} -C ${DOIMAGEPATH}
+
+${BUILD_PLAT}/bl31.img: ${BUILD_PLAT}/bl31.bin ${DOIMAGETOOL}
+ ${DOIMAGETOOL} ${BUILD_PLAT}/bl31.bin ${BUILD_PLAT}/bl31.img
+
diff --git a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts
new file mode 100644
index 0000000000..2f2d265c59
--- /dev/null
+++ b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <export/common/tbbr/tbbr_img_def_exp.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "arm,dyn_cfg-dtb_registry";
+
+ /* tb_fw_config is temporarily contained in this dtb */
+ tb_fw-config {
+ load-address = <0x0 0x2001010>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ hw-config {
+ load-address = <0x0 0x83000000>;
+ max-size = <0x01000000>;
+ id = <HW_CONFIG_ID>;
+ };
+ };
+
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+ };
+};
diff --git a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts
deleted file mode 100644
index 7b3aa11448..0000000000
--- a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-
-/ {
- /* Platform Config */
- plat_arm_bl2 {
- compatible = "arm,tb_fw";
- hw_config_addr = <0x0 0x83000000>;
- hw_config_max_size = <0x01000000>;
- /* Disable authentication for development */
- disable_auth = <0x0>;
- };
-};
diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk
index d42b2bfa89..7198842172 100644
--- a/plat/arm/board/a5ds/platform.mk
+++ b/plat/arm/board/a5ds/platform.mk
@@ -1,9 +1,12 @@
#
-# Copyright (c) 2019, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
+# Firmware Configuration Framework sources
+include lib/fconf/fconf.mk
+
# Add `libfdt` and Arm common helpers required for Dynamic Config
include lib/libfdt/libfdt.mk
@@ -67,7 +70,7 @@ BL2_SOURCES += lib/aarch32/arm32_aeabi_divmod.c \
# Add the FDT_SOURCES and options for Dynamic Config (only for Unix env)
ifdef UNIX_MK
-FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_tb_fw_config.dtb
+FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_fw_config.dtb
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config))
@@ -77,7 +80,7 @@ $(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb, \
# Add the HW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config))
-FDT_SOURCES += plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts \
+FDT_SOURCES += plat/arm/board/a5ds/fdts/a5ds_fw_config.dts \
${FVP_HW_CONFIG_DTS}
endif
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index c71e932a0f..3c19230bd6 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,130 +8,61 @@
#include <stdint.h>
#include <string.h>
+#include <common/debug.h>
+#include <drivers/arm/cryptocell/cc_rotpk.h>
+#include <drivers/delay_timer.h>
#include <lib/cassert.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/common_def.h>
#include <plat/common/platform.h>
-#include <tools_share/tbbr_oid.h>
#include <platform_def.h>
+#include <tools_share/tbbr_oid.h>
-/* SHA256 algorithm */
-#define SHA256_BYTES 32
-
-/* ROTPK locations */
-#define ARM_ROTPK_REGS_ID 1
-#define ARM_ROTPK_DEVEL_RSA_ID 2
-#define ARM_ROTPK_DEVEL_ECDSA_ID 3
-
-static const unsigned char rotpk_hash_hdr[] = \
- "\x30\x31\x30\x0D\x06\x09\x60\x86\x48" \
- "\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20";
-static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1;
-static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES];
-/* Use the cryptocell variants if Cryptocell is present */
#if !ARM_CRYPTOCELL_INTEG
#if !ARM_ROTPK_LOCATION_ID
#error "ARM_ROTPK_LOCATION_ID not defined"
#endif
+#endif
/* Weak definition may be overridden in specific platform */
#pragma weak plat_get_nv_ctr
#pragma weak plat_set_nv_ctr
-#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID)
-static const unsigned char arm_devel_rotpk_hash[] = \
- "\xB0\xF3\x82\x09\x12\x97\xD8\x3A" \
- "\x37\x7A\x72\x47\x1B\xEC\x32\x73" \
- "\xE9\x92\x32\xE2\x49\x59\xF6\x5E" \
- "\x8B\x4A\x4A\x46\xD8\x22\x9A\xDA";
-#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
-static const unsigned char arm_devel_rotpk_hash[] = \
- "\x2E\x40\xBF\x6E\xF9\x12\xBB\x98" \
- "\x31\x71\x09\x0E\x1E\x15\x3D\x0B" \
- "\xFD\xD1\xCC\x69\x4A\x98\xEB\x8B" \
- "\xA0\xB0\x20\x86\x4E\x6C\x07\x17";
-#endif
+extern unsigned char arm_rotpk_header[], arm_rotpk_hash_end[];
+
+static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
/*
- * 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
- * }
+ * Return the ROTPK hash stored in dedicated registers.
*/
-int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
unsigned int *flags)
{
uint8_t *dst;
+ uint32_t *src, tmp;
+ unsigned int words, i;
assert(key_ptr != NULL);
assert(key_len != NULL);
assert(flags != NULL);
/* Copy the DER header */
- memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
- dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len];
-#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \
- || (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
- memcpy(dst, arm_devel_rotpk_hash, SHA256_BYTES);
-#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
- uint32_t *src, tmp;
- unsigned int words, i;
+ memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
+ dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
+
+ words = ARM_ROTPK_HASH_LEN >> 2;
- /*
- * Append the hash from Trusted Root-Key Storage registers. The hash has
- * not been written linearly into the registers, so we have to do a bit
- * of byte swapping:
- *
- * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C
- * +---------------------------------------------------------------+
- * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 |
- * +---------------------------------------------------------------+
- * | ... ... | | ... ... |
- * | +--------------------+ | +-------+
- * | | | |
- * +----------------------------+ +----------------------------+
- * | | | |
- * +-------+ | +--------------------+ |
- * | | | |
- * v v v v
- * +---------------------------------------------------------------+
- * | | |
- * +---------------------------------------------------------------+
- * 0 15 16 31
- *
- * Additionally, we have to access the registers in 32-bit words
- */
- words = SHA256_BYTES >> 3;
-
- /* Swap bytes 0-15 (first four registers) */
src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
for (i = 0 ; i < words ; i++) {
tmp = src[words - 1 - i];
/* Words are read in little endian */
- *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
- *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
- *dst++ = (uint8_t)((tmp >> 8) & 0xFF);
*dst++ = (uint8_t)(tmp & 0xFF);
- }
-
- /* Swap bytes 16-31 (last four registers) */
- src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + SHA256_BYTES / 2);
- for (i = 0 ; i < words ; i++) {
- tmp = src[words - 1 - i];
- *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
- *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
- *dst++ = (uint8_t)(tmp & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
}
-#endif /* (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \
- || (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) */
*key_ptr = (void *)rotpk_hash_der;
*key_len = (unsigned int)sizeof(rotpk_hash_der);
@@ -139,6 +70,65 @@ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
return 0;
}
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
+ (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
+/*
+ * Return development ROTPK hash generated from ROT_KEY.
+ */
+int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ *key_ptr = arm_rotpk_header;
+ *key_len = arm_rotpk_hash_end - arm_rotpk_header;
+ *flags = ROTPK_IS_HASH;
+ return 0;
+}
+#endif
+
+#if ARM_CRYPTOCELL_INTEG
+/*
+ * Return ROTPK hash from CryptoCell.
+ */
+int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ unsigned char *dst;
+
+ assert(key_ptr != NULL);
+ assert(key_len != NULL);
+ assert(flags != NULL);
+
+ /* Copy the DER header */
+ memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
+ dst = &rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
+ *key_ptr = rotpk_hash_der;
+ *key_len = sizeof(rotpk_hash_der);
+ return cc_get_rotpk_hash(dst, ARM_ROTPK_HASH_LEN, flags);
+}
+#endif
+
+/*
+ * Wraper function for most Arm platforms to get ROTPK hash.
+ */
+int arm_get_rotpk_info(void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+#if ARM_CRYPTOCELL_INTEG
+ return arm_get_rotpk_info_cc(key_ptr, key_len, flags);
+#else
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
+ (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
+ return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
+#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
+ return arm_get_rotpk_info_regs(key_ptr, key_len, flags);
+#else
+ return 1;
+#endif
+
+#endif /* ARM_CRYPTOCELL_INTEG */
+}
+
/*
* Return the non-volatile counter value stored in the platform. The cookie
* will contain the OID of the counter in the certificate.
@@ -179,37 +169,3 @@ int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
{
return 1;
}
-#else /* ARM_CRYPTOCELL_INTEG */
-
-#include <drivers/arm/cryptocell/cc_rotpk.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)
-{
- unsigned char *dst;
-
- assert(key_ptr != NULL);
- assert(key_len != NULL);
- assert(flags != NULL);
-
- /* Copy the DER header */
- memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
- dst = &rotpk_hash_der[rotpk_hash_hdr_len];
- *key_ptr = rotpk_hash_der;
- *key_len = sizeof(rotpk_hash_der);
- return cc_get_rotpk_hash(dst, SHA256_BYTES, flags);
-}
-#endif /* ARM_CRYPTOCELL_INTEG */
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index b98dfd48b2..459156b2a5 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -12,31 +12,60 @@ BL1_SOURCES += drivers/cfi/v2m/v2m_flash.c
BL2_SOURCES += drivers/cfi/v2m/v2m_flash.c
ifneq (${TRUSTED_BOARD_BOOT},0)
- ifneq (${ARM_CRYPTOCELL_INTEG}, 1)
- # ROTPK hash location
- ifeq (${ARM_ROTPK_LOCATION}, regs)
- ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID
- else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa)
- KEY_ALG := rsa
- ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID
- else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa)
- KEY_ALG := ecdsa
- ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID
- else
- $(error "Unsupported ARM_ROTPK_LOCATION value")
- endif
- $(eval $(call add_define,ARM_ROTPK_LOCATION_ID))
-
- # Certificate NV-Counters. Use values corresponding to tied off values in
- # ARM development platforms
- TFW_NVCTR_VAL ?= 31
- NTFW_NVCTR_VAL ?= 223
- else
- # Certificate NV-Counters when CryptoCell is integrated. For development
- # platforms we set the counter to first valid value.
- TFW_NVCTR_VAL ?= 0
- NTFW_NVCTR_VAL ?= 0
- endif
- BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c
- BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c
+ifneq (${ARM_CRYPTOCELL_INTEG}, 1)
+# ROTPK hash location
+ifeq (${ARM_ROTPK_LOCATION}, regs)
+ ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID
+else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa)
+ CRYPTO_ALG=rsa
+ ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID
+ ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin
+$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"'))
+$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH)
+$(warning Development keys support for FVP is deprecated. Use `regs` \
+option instead)
+else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa)
+ CRYPTO_ALG=ec
+ ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID
+ ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin
+$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"'))
+$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH)
+$(warning Development keys support for FVP is deprecated. Use `regs` \
+option instead)
+else
+ $(error "Unsupported ARM_ROTPK_LOCATION value")
+endif
+
+$(eval $(call add_define,ARM_ROTPK_LOCATION_ID))
+
+# Force generation of the new hash if ROT_KEY is specified
+ifdef ROT_KEY
+ HASH_PREREQUISITES = $(ROT_KEY) FORCE
+FORCE:
+else
+ HASH_PREREQUISITES = $(ROT_KEY)
+endif
+
+$(ARM_ROTPK_HASH) : $(HASH_PREREQUISITES)
+ifndef ROT_KEY
+ $(error Cannot generate hash: no ROT_KEY defined)
+endif
+ openssl ${CRYPTO_ALG} -in $< -pubout -outform DER | openssl dgst \
+ -sha256 -binary > $@
+
+# Certificate NV-Counters. Use values corresponding to tied off values in
+# ARM development platforms
+TFW_NVCTR_VAL ?= 31
+NTFW_NVCTR_VAL ?= 223
+else
+# Certificate NV-Counters when CryptoCell is integrated. For development
+# platforms we set the counter to first valid value.
+TFW_NVCTR_VAL ?= 0
+NTFW_NVCTR_VAL ?= 0
+endif
+BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c \
+ plat/arm/board/common/rotpk/arm_dev_rotpk.S
+BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c \
+ plat/arm/board/common/rotpk/arm_dev_rotpk.S
+
endif
diff --git a/plat/arm/board/common/rotpk/arm_dev_rotpk.S b/plat/arm/board/common/rotpk/arm_dev_rotpk.S
new file mode 100644
index 0000000000..80f2192e4d
--- /dev/null
+++ b/plat/arm/board/common/rotpk/arm_dev_rotpk.S
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "plat/arm/common/arm_def.h"
+
+ .global arm_rotpk_header
+ .global arm_rotpk_header_end
+ .section .rodata.arm_rotpk_hash, "a"
+
+arm_rotpk_header:
+ .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+ .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+arm_rotpk_header_len:
+
+#ifdef ARM_ROTPK_HASH
+ .global arm_rotpk_hash_end
+ .incbin ARM_ROTPK_HASH
+arm_rotpk_hash_end:
+#endif
+
+.if ARM_ROTPK_HEADER_LEN != arm_rotpk_header_len - arm_rotpk_header
+.error "Invalid ROTPK header length."
+.endif
diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
new file mode 100644
index 0000000000..d0f60331d4
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <export/common/tbbr/tbbr_img_def_exp.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "arm,dyn_cfg-dtb_registry";
+
+ /* tb_fw_config is temporarily contained on this dtb */
+ tb_fw-config {
+ load-address = <0x0 0x4001010>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ hw-config {
+ load-address = <0x0 0x82000000>;
+ max-size = <0x01000000>;
+ id = <HW_CONFIG_ID>;
+ };
+
+ /*
+ * Load SoC and TOS firmware configs at the base of
+ * non shared SRAM. The runtime checks ensure we don't
+ * overlap BL2, BL31 or BL32. The NT firmware config
+ * is loaded at base of DRAM.
+ */
+ soc_fw-config {
+ load-address = <0x0 0x04001000>;
+ max-size = <0x200>;
+ id = <SOC_FW_CONFIG_ID>;
+ };
+
+ tos_fw-config {
+ load-address = <0x0 0x04001200>;
+ max-size = <0x200>;
+ id = <TOS_FW_CONFIG_ID>;
+ };
+
+ nt_fw-config {
+ load-address = <0x0 0x80000000>;
+ max-size = <0x200>;
+ id = <NT_FW_CONFIG_ID>;
+ };
+ };
+
+ 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>;
+ };
+
+ arm-io_policies {
+ fip-handles {
+ compatible = "arm,io-fip-handle";
+ scp_bl2_uuid = <0x3dfd6697 0x49e8be89 0xa1785dae 0x13826040>;
+ bl31_uuid = <0x6d08d447 0x4698fe4c 0x5029959b 0x005abdcb>;
+ bl32_uuid = <0x89e1d005 0x4713dc53 0xa502b8d 0x383e7a4b>;
+ bl32_extra1_uuid = <0x9bc2700b 0x40785a2a 0x560a659f 0x88827382>;
+ bl32_extra2_uuid = <0xb17ba88e 0x4d3fa2cf 0xbbe7fd85 0xd92002a5>;
+ bl33_uuid = <0xa7eed0d6 0x4bd5eafc 0x34998297 0xe4b634f2>;
+ hw_cfg_uuid = <0xd9f1b808 0x4993cfc9 0xbc6f62a9 0xcc65726b>;
+ soc_fw_cfg_uuid = <0x4b817999 0x46fb7603 0x268d8e8c 0xe059787f>;
+ tos_fw_cfg_uuid = <0x1a7c2526 0x477fc6db 0xc4c4968d 0x218024b0>;
+ nt_fw_cfg_uuid = <0x1598da28 0x447ee893 0xaf1a66ac 0xf9501580>;
+ t_key_cert_uuid = <0x90e87e82 0x11e460f8 0x7a77b4a1 0x4cf9b421>;
+ scp_fw_key_uuid = <0xa1214202 0x11e460f8 0x3cf39b8d 0x14a0150e>;
+ soc_fw_key_uuid = <0xccbeb88a 0x11e460f9 0x48ebd09a 0xf8dcd822>;
+ tos_fw_key_cert_uuid = <0x3d67794 0x11e460fb 0x10b7dd85 0x4ee8c5b>;
+ nt_fw_key_cert_uuid = <0x2a83d58a 0x11e460fb 0x30dfaf8a 0x5998c4bb>;
+ scp_fw_content_cert_uuid = <0x046fbe44 0x11e4635e 0xd8738bb2 0x5696aeea>;
+ soc_fw_content_cert_uuid = <0x200cb2e2 0x11e4635e 0xccabe89c 0x66b62bf9>;
+ tos_fw_content_cert_uuid = <0x11449fa4 0x11e4635e 0x53f2887 0x3df32a72>;
+ nt_fw_content_cert_uuid = <0xf3c1c48e 0x11e4635d 0xee87a9a7 0xa73fb240>;
+ };
+ };
+};
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
new file mode 100644
index 0000000000..e1c106f1e3
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/dts-v1/;
+
+/ {
+ compatible = "spci-core-manifest-1.0";
+
+ attribute {
+ maj_ver = <0x0>;
+ min_ver = <0x9>;
+ runtime_el = <0x1>;
+ exec_state = <0x0>;
+ load_address = <0x0 0x6000000>;
+ entrypoint = <0x0 0x6000000>;
+ };
+};
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index 89636d18a3..43b1374811 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -1,12 +1,10 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <drivers/arm/sp804_delay_timer.h>
-#include <drivers/generic_delay_timer.h>
-#include <lib/mmio.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index ffaa93de4d..2c880fc306 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -86,6 +86,9 @@ const mmap_region_t plat_arm_mmap[] = {
#ifdef __aarch64__
ARM_MAP_DRAM2,
#endif
+#if defined(SPD_spmd)
+ ARM_MAP_TRUSTED_DRAM,
+#endif
#ifdef SPD_tspd
ARM_MAP_TSP_SEC_MEM,
#endif
diff --git a/plat/arm/board/fvp/fvp_err.c b/plat/arm/board/fvp/fvp_err.c
index 2437cd4745..62ac882b00 100644
--- a/plat/arm/board/fvp/fvp_err.c
+++ b/plat/arm/board/fvp/fvp_err.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,7 +10,6 @@
#include <drivers/arm/sp805.h>
#include <drivers/cfi/v2m_flash.h>
#include <plat/arm/common/plat_arm.h>
-#include <plat/common/platform.h>
#include <platform_def.h>
/*
diff --git a/plat/arm/board/fvp/fvp_io_storage.c b/plat/arm/board/fvp/fvp_io_storage.c
index 9c4c1d574b..109d321502 100644
--- a/plat/arm/board/fvp/fvp_io_storage.c
+++ b/plat/arm/board/fvp/fvp_io_storage.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -120,18 +120,22 @@ void plat_arm_io_setup(void)
{
int io_result;
- arm_io_setup();
+ io_result = arm_io_setup();
+ if (io_result < 0) {
+ panic();
+ }
/* Register the additional IO devices on this platform */
io_result = register_io_dev_sh(&sh_dev_con);
- assert(io_result == 0);
+ if (io_result < 0) {
+ panic();
+ }
/* Open connections to devices and cache the handles */
io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle);
- assert(io_result == 0);
-
- /* Ignore improbable errors in release builds */
- (void)io_result;
+ if (io_result < 0) {
+ panic();
+ }
}
/*
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index 0a62543fa9..c47d837796 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -1,11 +1,10 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
-#include <errno.h>
#include <arch_helpers.h>
#include <common/debug.h>
@@ -16,7 +15,6 @@
#include <lib/psci/psci.h>
#include <plat/arm/common/arm_config.h>
#include <plat/arm/common/plat_arm.h>
-#include <plat/common/platform.h>
#include <platform_def.h>
#include "fvp_private.h"
diff --git a/plat/arm/board/fvp/fvp_trusted_boot.c b/plat/arm/board/fvp/fvp_trusted_boot.c
index dc50764356..a09b80e10b 100644
--- a/plat/arm/board/fvp/fvp_trusted_boot.c
+++ b/plat/arm/board/fvp/fvp_trusted_boot.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,12 +9,31 @@
#include <string.h>
#include <lib/mmio.h>
-
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
#include <tools_share/tbbr_oid.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(key_ptr, key_len, flags);
+}
+
+/*
* Store a new non-volatile counter value.
*
* On some FVP versions, the non-volatile counters are read-only so this
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index c2b7b98d4d..602ea6defa 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -139,13 +139,13 @@
# if TRUSTED_BOARD_BOOT
# define PLATFORM_STACK_SIZE UL(0x1000)
# else
-# define PLATFORM_STACK_SIZE UL(0x440)
+# define PLATFORM_STACK_SIZE UL(0x500)
# endif
#elif defined(IMAGE_BL2)
# if TRUSTED_BOARD_BOOT
# define PLATFORM_STACK_SIZE UL(0x1000)
# else
-# define PLATFORM_STACK_SIZE UL(0x400)
+# define PLATFORM_STACK_SIZE UL(0x440)
# endif
#elif defined(IMAGE_BL2U)
# define PLATFORM_STACK_SIZE UL(0x400)
diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i
index bfa9b561f0..b1b9ed463e 100644
--- a/plat/arm/board/fvp/jmptbl.i
+++ b/plat/arm/board/fvp/jmptbl.i
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -19,6 +19,9 @@ fdt fdt_getprop_namelen
fdt fdt_setprop_inplace
fdt fdt_check_header
fdt fdt_node_offset_by_compatible
+fdt fdt_setprop_inplace_namelen_partial
+fdt fdt_first_subnode
+fdt fdt_next_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 97a326c092..60374352a8 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -10,6 +10,11 @@ FVP_USE_GIC_DRIVER := FVP_GICV3
# Use the SP804 timer instead of the generic one
FVP_USE_SP804_TIMER := 0
+# Use fconf based io for FVP
+ifeq ($(BL2_AT_EL3), 0)
+USE_FCONF_BASED_IO := 1
+endif
+
# Default cluster count for FVP
FVP_CLUSTER_COUNT := 2
@@ -139,7 +144,6 @@ BL1_SOURCES += drivers/arm/smmu/smmu_v3.c \
plat/arm/board/fvp/fvp_bl1_setup.c \
plat/arm/board/fvp/fvp_err.c \
plat/arm/board/fvp/fvp_io_storage.c \
- plat/arm/board/fvp/fvp_trusted_boot.c \
${FVP_CPU_LIBS} \
${FVP_INTERCONNECT_SOURCES}
@@ -158,7 +162,6 @@ BL2_SOURCES += drivers/arm/sp805/sp805.c \
plat/arm/board/fvp/fvp_bl2_setup.c \
plat/arm/board/fvp/fvp_err.c \
plat/arm/board/fvp/fvp_io_storage.c \
- plat/arm/board/fvp/fvp_trusted_boot.c \
plat/arm/common/arm_nor_psci_mem_protect.c \
${FVP_SECURITY_SOURCES}
@@ -207,12 +210,12 @@ endif
ifdef UNIX_MK
FVP_HW_CONFIG_DTS := fdts/${FVP_DT_PREFIX}.dts
FDT_SOURCES += $(addprefix plat/arm/board/fvp/fdts/, \
- ${PLAT}_tb_fw_config.dts \
+ ${PLAT}_fw_config.dts \
${PLAT}_soc_fw_config.dts \
${PLAT}_nt_fw_config.dts \
)
-FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
FVP_SOC_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_soc_fw_config.dtb
FVP_NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
@@ -224,6 +227,14 @@ FVP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tsp_fw_config.dtb
$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config))
endif
+ifeq (${SPD},spmd)
+FDT_SOURCES += plat/arm/board/fvp/fdts/${PLAT}_spmc_manifest.dts
+FVP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_spmc_manifest.dtb
+
+# Add the TOS_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config))
+endif
+
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config))
# Add the SOC_FW_CONFIG to FIP and specify the same to certtool
@@ -302,8 +313,10 @@ endif
include plat/arm/board/common/board_common.mk
include plat/arm/common/arm_common.mk
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES += plat/arm/board/fvp/fvp_trusted_boot.c
+BL2_SOURCES += plat/arm/board/fvp/fvp_trusted_boot.c
# FVP being a development platform, enable capability to disable Authentication
# dynamically if TRUSTED_BOARD_BOOT is set.
-ifeq (${TRUSTED_BOARD_BOOT}, 1)
- DYN_DISABLE_AUTH := 1
+DYN_DISABLE_AUTH := 1
endif
diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts
new file mode 100644
index 0000000000..147c8f3661
--- /dev/null
+++ b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <export/common/tbbr/tbbr_img_def_exp.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "arm,dyn_cfg-dtb_registry";
+
+ /* tb_fw_config is temporarily contained on this dtb */
+ tb_fw-config {
+ load-address = <0x0 0x80001010>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ hw-config {
+ load-address = <0x0 0x82000000>;
+ max-size = <0x01000000>;
+ id = <HW_CONFIG_ID>;
+ };
+ };
+
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+ };
+};
diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts
deleted file mode 100644
index 9ab2d96566..0000000000
--- a/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-
-/ {
- /* Platform Config */
- plat_arm_bl2 {
- compatible = "arm,tb_fw";
- hw_config_addr = <0x0 0x82000000>;
- hw_config_max_size = <0x01000000>;
- /* Disable authentication for development */
- disable_auth = <0x0>;
- };
-};
diff --git a/plat/arm/board/fvp_ve/platform.mk b/plat/arm/board/fvp_ve/platform.mk
index 4d21f4ba09..7883719b09 100644
--- a/plat/arm/board/fvp_ve/platform.mk
+++ b/plat/arm/board/fvp_ve/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2019, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -72,9 +72,9 @@ BL2_SOURCES += plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c \
# Add the FDT_SOURCES and options for Dynamic Config (only for Unix env)
ifdef UNIX_MK
-FDT_SOURCES += plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts
+FDT_SOURCES += plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts
-FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_tb_fw_config.dtb
+FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_fw_config.dtb
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config))
@@ -116,6 +116,9 @@ else
PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
endif
+# Firmware Configuration Framework sources
+include lib/fconf/fconf.mk
+
# Add `libfdt` and Arm common helpers required for Dynamic Config
include lib/libfdt/libfdt.mk
diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/juno/fdts/juno_fw_config.dts
index ce589385c1..cab6f2bf4c 100644
--- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+++ b/plat/arm/board/juno/fdts/juno_fw_config.dts
@@ -1,32 +1,31 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <export/common/tbbr/tbbr_img_def_exp.h>
+
/dts-v1/;
/ {
- /* Platform Config */
- plat_arm_bl2 {
+ dtb-registry {
+ compatible = "arm,dyn_cfg-dtb_registry";
+
+ /* tb_fw_config is temporarily contained on this dtb */
+ tb_fw-config {
+ load-address = <0x0 0x4001010>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+ };
+
+ tb_fw-config {
+ /* Platform Config */
compatible = "arm,tb_fw";
- hw_config_addr = <0x0 0x82000000>;
- hw_config_max_size = <0x01000000>;
/* Disable authentication for development */
disable_auth = <0x0>;
/*
- * Load SoC and TOS firmware configs at the base of
- * non shared SRAM. The runtime checks ensure we don't
- * overlap BL2, BL31 or BL32. The NT firmware config
- * is loaded at base of DRAM.
- */
- soc_fw_config_addr = <0x0 0x04001000>;
- soc_fw_config_max_size = <0x200>;
- tos_fw_config_addr = <0x0 0x04001200>;
- tos_fw_config_max_size = <0x200>;
- nt_fw_config_addr = <0x0 0x80000000>;
- nt_fw_config_max_size = <0x200>;
- /*
* The following two entries are placeholders for Mbed TLS
* heap information. The default values don't matter since
* they will be overwritten by BL1.
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index 16bb33d7ef..eddd7e5704 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -224,7 +224,6 @@
/* MHU related constants */
#define PLAT_CSS_MHU_BASE UL(0x2b1f0000)
-#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
/*
* Base address of the first memory region used for communication between AP
@@ -301,4 +300,7 @@
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
#endif
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1)
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i
index bfa9b561f0..b1b9ed463e 100644
--- a/plat/arm/board/juno/jmptbl.i
+++ b/plat/arm/board/juno/jmptbl.i
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -19,6 +19,9 @@ fdt fdt_getprop_namelen
fdt fdt_setprop_inplace
fdt fdt_check_header
fdt fdt_node_offset_by_compatible
+fdt fdt_setprop_inplace_namelen_partial
+fdt fdt_first_subnode
+fdt fdt_next_subnode
mbedtls mbedtls_asn1_get_alg
mbedtls mbedtls_asn1_get_alg_null
mbedtls mbedtls_asn1_get_bitstring_null
diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c
index 89398d686d..25a27da07c 100644
--- a/plat/arm/board/juno/juno_bl1_setup.c
+++ b/plat/arm/board/juno/juno_bl1_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -60,17 +60,13 @@ static int is_watchdog_reset(void)
* The following function checks if Firmware update is needed,
* by checking if TOC in FIP image is valid or watchdog reset happened.
******************************************************************************/
-int plat_arm_bl1_fwu_needed(void)
+bool plat_arm_bl1_fwu_needed(void)
{
const int32_t *nv_flags_ptr = (const int32_t *)V2M_SYS_NVFLAGS_ADDR;
/* Check if TOC is invalid or watchdog reset happened. */
- if ((arm_io_is_toc_valid() != 1) ||
- (((*nv_flags_ptr == -EAUTH) || (*nv_flags_ptr == -ENOENT))
- && is_watchdog_reset()))
- return 1;
-
- return 0;
+ return (!arm_io_is_toc_valid() || (((*nv_flags_ptr == -EAUTH) ||
+ (*nv_flags_ptr == -ENOENT)) && is_watchdog_reset()));
}
/*******************************************************************************
diff --git a/plat/arm/board/juno/juno_err.c b/plat/arm/board/juno/juno_err.c
index 961bfda17a..60699cc732 100644
--- a/plat/arm/board/juno/juno_err.c
+++ b/plat/arm/board/juno/juno_err.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,7 +9,6 @@
#include <arch_helpers.h>
#include <drivers/arm/sp805.h>
#include <plat/arm/common/plat_arm.h>
-#include <plat/common/platform.h>
#include <platform_def.h>
/*
diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c
index 052ab9f8a7..075f512c36 100644
--- a/plat/arm/board/juno/juno_topology.c
+++ b/plat/arm/board/juno/juno_topology.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,7 +20,7 @@ static scmi_channel_plat_info_t juno_scmi_plat_info = {
.ring_doorbell = &mhu_ring_doorbell,
};
-scmi_channel_plat_info_t *plat_css_get_scmi_info(void)
+scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
{
return &juno_scmi_plat_info;
}
diff --git a/plat/arm/board/juno/juno_trusted_boot.c b/plat/arm/board/juno/juno_trusted_boot.c
new file mode 100644
index 0000000000..25a74705d9
--- /dev/null
+++ b/plat/arm/board/juno/juno_trusted_boot.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <drivers/arm/cryptocell/cc_rotpk.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/common_def.h>
+#include <plat/common/platform.h>
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
+
+static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
+
+extern unsigned char arm_rotpk_header[];
+
+/*
+ * Return the ROTPK hash stored in the registers of Juno board.
+ */
+static int juno_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ uint8_t *dst;
+ uint32_t *src, tmp;
+ unsigned int words, i;
+
+ assert(key_ptr != NULL);
+ assert(key_len != NULL);
+ assert(flags != NULL);
+
+ /* Copy the DER header */
+ memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
+ dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
+
+
+ /*
+ * Append the hash from Trusted Root-Key Storage registers. The hash has
+ * not been written linearly into the registers, so we have to do a bit
+ * of byte swapping:
+ *
+ * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C
+ * +---------------------------------------------------------------+
+ * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 |
+ * +---------------------------------------------------------------+
+ * | ... ... | | ... ... |
+ * | +--------------------+ | +-------+
+ * | | | |
+ * +----------------------------+ +----------------------------+
+ * | | | |
+ * +-------+ | +--------------------+ |
+ * | | | |
+ * v v v v
+ * +---------------------------------------------------------------+
+ * | | |
+ * +---------------------------------------------------------------+
+ * 0 15 16 31
+ *
+ * Additionally, we have to access the registers in 32-bit words
+ */
+ words = ARM_ROTPK_HASH_LEN >> 3;
+
+ /* Swap bytes 0-15 (first four registers) */
+ src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
+ for (i = 0 ; i < words ; i++) {
+ tmp = src[words - 1 - i];
+ /* Words are read in little endian */
+ *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 8) & 0xFF);
+ *dst++ = (uint8_t)(tmp & 0xFF);
+ }
+
+ /* Swap bytes 16-31 (last four registers) */
+ src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + ARM_ROTPK_HASH_LEN / 2);
+ for (i = 0 ; i < words ; i++) {
+ tmp = src[words - 1 - i];
+ *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 8) & 0xFF);
+ *dst++ = (uint8_t)(tmp & 0xFF);
+ }
+
+ *key_ptr = (void *)rotpk_hash_der;
+ *key_len = (unsigned int)sizeof(rotpk_hash_der);
+ *flags = ROTPK_IS_HASH;
+ return 0;
+}
+
+#endif
+
+/*
+ * 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)
+{
+#if ARM_CRYPTOCELL_INTEG
+ return arm_get_rotpk_info_cc(key_ptr, key_len, flags);
+#else
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
+ (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
+ return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
+#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
+ return juno_get_rotpk_info_regs(key_ptr, key_len, flags);
+#else
+ return 1;
+#endif
+
+#endif /* ARM_CRYPTOCELL_INTEG */
+}
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index bd6bae536d..27650d2668 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -91,6 +91,11 @@ ifeq (${CSS_USE_SCMI_SDS_DRIVER},1)
BL1_SOURCES += drivers/arm/css/sds/sds.c
endif
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES += plat/arm/board/juno/juno_trusted_boot.c
+BL2_SOURCES += plat/arm/board/juno/juno_trusted_boot.c
+endif
+
endif
ifneq (${RESET_TO_BL31},0)
@@ -151,8 +156,8 @@ else
endif
# Add the FDT_SOURCES and options for Dynamic Config
-FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_tb_fw_config.dts
-TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_fw_config.dts
+TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h
index 6a309e8e16..cc07852c27 100644
--- a/plat/arm/board/n1sdp/include/platform_def.h
+++ b/plat/arm/board/n1sdp/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -90,7 +90,6 @@
#define PLAT_ARM_NSTIMER_FRAME_ID 0
#define PLAT_CSS_MHU_BASE 0x45000000
-#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
#define PLAT_MAX_PWR_LVL 2
#define PLAT_ARM_G1S_IRQS ARM_G1S_IRQS, \
@@ -144,4 +143,7 @@
#define SBSA_SECURE_WDOG_BASE UL(0x2A480000)
#define SBSA_SECURE_WDOG_TIMEOUT UL(100)
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1)
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
index b150b89599..136287a8da 100644
--- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -74,7 +74,7 @@ static uintptr_t n1sdp_multichip_gicr_frames[3] = {
0
};
-scmi_channel_plat_info_t *plat_css_get_scmi_info()
+scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
{
return &n1sdp_scmi_plat_info;
}
diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts
new file mode 100644
index 0000000000..4d4580d68b
--- /dev/null
+++ b/plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+/ {
+ /* compatible string */
+ compatible = "arm,rd-daniel";
+
+ /*
+ * Place holder for system-id node with default values. The
+ * value of platform-id and config-id will be set to the
+ * correct values during the BL2 stage of boot.
+ */
+ system-id {
+ platform-id = <0x0>;
+ config-id = <0x0>;
+ multi-chip-mode = <0x0>;
+ };
+};
diff --git a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts
index a8ab6c5f9f..9acec137e7 100644
--- a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts
+++ b/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,8 +9,9 @@
/ {
/* Platform Config */
compatible = "arm,tb_fw";
- /* Disable authentication for development */
- disable_auth = <0x0>;
+ nt_fw_config_addr = <0x0 0xFEF00000>;
+ nt_fw_config_max_size = <0x0100000>;
+
/*
* The following two entries are placeholders for Mbed TLS
* heap information. The default values don't matter since
diff --git a/plat/arm/board/rddaniel/include/platform_def.h b/plat/arm/board/rddaniel/include/platform_def.h
new file mode 100644
index 0000000000..516360278e
--- /dev/null
+++ b/plat/arm/board/rddaniel/include/platform_def.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2020, 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>
+
+#include <sgi_base_platform_def.h>
+
+#define PLAT_ARM_CLUSTER_COUNT U(16)
+#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(1)
+#define CSS_SGI_MAX_PE_PER_CPU U(1)
+
+#define PLAT_CSS_MHU_BASE UL(0x45400000)
+#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
+
+#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2
+#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
+
+/*
+ * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
+ */
+#ifdef __aarch64__
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 42)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 42)
+#else
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
+#endif
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE UL(0x30000000)
+#define PLAT_ARM_GICC_BASE UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE UL(0x30140000)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk
new file mode 100644
index 0000000000..67f57779a2
--- /dev/null
+++ b/plat/arm/board/rddaniel/platform.mk
@@ -0,0 +1,43 @@
+# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include plat/arm/css/sgi/sgi-common.mk
+
+RDDANIEL_BASE = plat/arm/board/rddaniel
+
+PLAT_INCLUDES += -I${RDDANIEL_BASE}/include/
+
+SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_zeus.S
+
+BL1_SOURCES += ${SGI_CPU_SOURCES} \
+ ${RDDANIEL_BASE}/rddaniel_err.c
+
+BL2_SOURCES += ${RDDANIEL_BASE}/rddaniel_plat.c \
+ ${RDDANIEL_BASE}/rddaniel_security.c \
+ ${RDDANIEL_BASE}/rddaniel_err.c \
+ lib/utils/mem_region.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c
+
+BL31_SOURCES += ${SGI_CPU_SOURCES} \
+ ${RDDANIEL_BASE}/rddaniel_plat.c \
+ ${RDDANIEL_BASE}/rddaniel_topology.c \
+ drivers/cfi/v2m/v2m_flash.c \
+ lib/utils/mem_region.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c
+
+# Add the FDT_SOURCES and options for Dynamic Config
+FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_tb_fw_config.dts
+TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
+
+FDT_SOURCES += ${RDDANIEL_BASE}/fdts/${PLAT}_nt_fw_config.dts
+NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
+
+# Add the NT_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+
+override CTX_INCLUDE_AARCH32_REGS := 0
diff --git a/plat/arm/board/rddaniel/rddaniel_err.c b/plat/arm/board/rddaniel/rddaniel_err.c
new file mode 100644
index 0000000000..5e10942199
--- /dev/null
+++ b/plat/arm/board/rddaniel/rddaniel_err.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * rddaniel error handler
+ */
+void __dead2 plat_arm_error_handler(int err)
+{
+ while (1) {
+ wfi();
+ }
+}
diff --git a/plat/arm/board/rddaniel/rddaniel_plat.c b/plat/arm/board/rddaniel/rddaniel_plat.c
new file mode 100644
index 0000000000..ab5251e511
--- /dev/null
+++ b/plat/arm/board/rddaniel/rddaniel_plat.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+#include <sgi_plat.h>
+
+unsigned int plat_arm_sgi_get_platform_id(void)
+{
+ return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
+ & SID_SYSTEM_ID_PART_NUM_MASK;
+}
+
+unsigned int plat_arm_sgi_get_config_id(void)
+{
+ return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
+}
+
+unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+{
+ return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
+ SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
+}
+
+void bl31_platform_setup(void)
+{
+ sgi_bl31_common_platform_setup();
+}
diff --git a/plat/arm/board/rddaniel/rddaniel_security.c b/plat/arm/board/rddaniel/rddaniel_security.c
new file mode 100644
index 0000000000..6aa38c822c
--- /dev/null
+++ b/plat/arm/board/rddaniel/rddaniel_security.c
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+/* Initialize the secure environment */
+void plat_arm_security_setup(void)
+{
+}
diff --git a/plat/arm/board/rddaniel/rddaniel_topology.c b/plat/arm/board/rddaniel/rddaniel_topology.c
new file mode 100644
index 0000000000..55f5e04da5
--- /dev/null
+++ b/plat/arm/board/rddaniel/rddaniel_topology.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+
+/******************************************************************************
+ * The power domain tree descriptor.
+ ******************************************************************************/
+const unsigned char rd_daniel_pd_tree_desc[] = {
+ PLAT_ARM_CLUSTER_COUNT,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER
+};
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return rd_daniel_pd_tree_desc;
+}
+
+/*******************************************************************************
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ ******************************************************************************/
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x8)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x9)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xA)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xB)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xC)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xD)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xE)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xF))
+};
diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts
index 41769217a9..0af821e15d 100644
--- a/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts
+++ b/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,6 +17,7 @@
system-id {
platform-id = <0x0>;
config-id = <0x0>;
+ multi-chip-mode = <0x0>;
};
};
diff --git a/plat/arm/board/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h
index 2be3f8852f..3fb640972a 100644
--- a/plat/arm/board/rde1edge/include/platform_def.h
+++ b/plat/arm/board/rde1edge/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,7 +16,6 @@
#define CSS_SGI_MAX_PE_PER_CPU U(2)
#define PLAT_CSS_MHU_BASE UL(0x45400000)
-#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
/* Base address of DMC-620 instances */
#define RDE1EDGE_DMC620_BASE0 UL(0x4e000000)
@@ -37,4 +36,9 @@
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
#endif
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE UL(0x30000000)
+#define PLAT_ARM_GICC_BASE UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE UL(0x300C0000)
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk
index 43c37ffc11..88aa634b86 100644
--- a/plat/arm/board/rde1edge/platform.mk
+++ b/plat/arm/board/rde1edge/platform.mk
@@ -29,6 +29,11 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \
lib/utils/mem_region.c \
plat/arm/common/arm_nor_psci_mem_protect.c
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES += ${RDE1EDGE_BASE}/rde1edge_trusted_boot.c
+BL2_SOURCES += ${RDE1EDGE_BASE}/rde1edge_trusted_boot.c
+endif
+
# Add the FDT_SOURCES and options for Dynamic Config
FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts
TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
@@ -42,4 +47,9 @@ NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
# Add the NT_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+ifneq ($(CSS_SGI_CHIP_COUNT),1)
+ $(error "Chip count for RDE1Edge should be 1, currently set to \
+ ${CSS_SGI_CHIP_COUNT}.")
+endif
+
override CTX_INCLUDE_AARCH32_REGS := 0
diff --git a/plat/arm/board/rde1edge/rde1edge_plat.c b/plat/arm/board/rde1edge/rde1edge_plat.c
index a1b8d621d6..44d818aecb 100644
--- a/plat/arm/board/rde1edge/rde1edge_plat.c
+++ b/plat/arm/board/rde1edge/rde1edge_plat.c
@@ -1,10 +1,11 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <plat/common/platform.h>
+#include <sgi_plat.h>
unsigned int plat_arm_sgi_get_platform_id(void)
{
@@ -16,3 +17,13 @@ unsigned int plat_arm_sgi_get_config_id(void)
{
return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
}
+
+unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+{
+ return 0;
+}
+
+void bl31_platform_setup(void)
+{
+ sgi_bl31_common_platform_setup();
+}
diff --git a/plat/arm/board/rde1edge/rde1edge_topology.c b/plat/arm/board/rde1edge/rde1edge_topology.c
index 0b56f208ae..a16283e450 100644
--- a/plat/arm/board/rde1edge/rde1edge_topology.c
+++ b/plat/arm/board/rde1edge/rde1edge_topology.c
@@ -7,12 +7,15 @@
#include <plat/arm/common/plat_arm.h>
/******************************************************************************
- * The power domain tree descriptor.
+ * The power domain tree descriptor. RD-E1-Edge platform consists of two
+ * clusters with eight CPUs in each cluster. The CPUs are multi-threaded with
+ * two threads per CPU.
******************************************************************************/
static const unsigned char rde1edge_pd_tree_desc[] = {
+ CSS_SGI_CHIP_COUNT,
PLAT_ARM_CLUSTER_COUNT,
- CSS_SGI_MAX_CPUS_PER_CLUSTER,
- CSS_SGI_MAX_CPUS_PER_CLUSTER
+ CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU
};
/******************************************************************************
diff --git a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c b/plat/arm/board/rde1edge/rde1edge_trusted_boot.c
new file mode 100644
index 0000000000..c271f7f2dc
--- /dev/null
+++ b/plat/arm/board/rde1edge/rde1edge_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * 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(key_ptr, key_len, flags);
+}
diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
index fff5874769..68366c5ca1 100644
--- a/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
+++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,5 +17,6 @@
system-id {
platform-id = <0x0>;
config-id = <0x0>;
+ multi-chip-mode = <0x0>;
};
};
diff --git a/plat/arm/board/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h
index c635faa441..ab63e23ece 100644
--- a/plat/arm/board/rdn1edge/include/platform_def.h
+++ b/plat/arm/board/rdn1edge/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,7 +16,6 @@
#define CSS_SGI_MAX_PE_PER_CPU U(1)
#define PLAT_CSS_MHU_BASE UL(0x45400000)
-#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
/* Base address of DMC-620 instances */
#define RDN1EDGE_DMC620_BASE0 UL(0x4e000000)
@@ -27,15 +26,23 @@
#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
+/* Virtual address used by dynamic mem_protect for chunk_base */
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000)
+
/*
* 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)
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 43)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 43)
#else
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
#endif
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE UL(0x30000000)
+#define PLAT_ARM_GICC_BASE UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE UL(0x300C0000)
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk
index ca1e95eaf0..04f70f3f25 100644
--- a/plat/arm/board/rdn1edge/platform.mk
+++ b/plat/arm/board/rdn1edge/platform.mk
@@ -26,9 +26,18 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \
${RDN1EDGE_BASE}/rdn1edge_plat.c \
${RDN1EDGE_BASE}/rdn1edge_topology.c \
drivers/cfi/v2m/v2m_flash.c \
+ drivers/arm/gic/v3/gic600_multichip.c \
lib/utils/mem_region.c \
plat/arm/common/arm_nor_psci_mem_protect.c
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c
+BL2_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c
+endif
+
+# Enable dynamic addition of MMAP regions in BL31
+BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
+
# Add the FDT_SOURCES and options for Dynamic Config
FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts
TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
@@ -42,4 +51,9 @@ NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
# Add the NT_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),1 2))
+ $(error "Chip count for RDN1Edge platform should either 1 or 2, currently \
+ set to ${CSS_SGI_CHIP_COUNT}.")
+endif
+
override CTX_INCLUDE_AARCH32_REGS := 0
diff --git a/plat/arm/board/rdn1edge/rdn1edge_plat.c b/plat/arm/board/rdn1edge/rdn1edge_plat.c
index 3b7e5ee4e4..f62c6f402b 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_plat.c
+++ b/plat/arm/board/rdn1edge/rdn1edge_plat.c
@@ -1,10 +1,44 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <common/debug.h>
+#include <drivers/arm/gic600_multichip.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
+#include <sgi_base_platform_def.h>
+#include <sgi_plat.h>
+
+#if defined(IMAGE_BL31)
+static const mmap_region_t rdn1edge_dynamic_mmap[] = {
+ ARM_MAP_SHARED_RAM_REMOTE_CHIP(1),
+ CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1),
+ SOC_CSS_MAP_DEVICE_REMOTE_CHIP(1)
+};
+
+static struct gic600_multichip_data rdn1e1_multichip_data __init = {
+ .rt_owner_base = PLAT_ARM_GICD_BASE,
+ .rt_owner = 0,
+ .chip_count = CSS_SGI_CHIP_COUNT,
+ .chip_addrs = {
+ PLAT_ARM_GICD_BASE >> 16,
+ (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16
+ },
+ .spi_ids = {
+ {32, 255},
+ {0, 0}
+ }
+};
+
+static uintptr_t rdn1e1_multichip_gicr_frames[] = {
+ PLAT_ARM_GICR_BASE, /* Chip 0's GICR Base */
+ PLAT_ARM_GICR_BASE +
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1), /* Chip 1's GICR BASE */
+ UL(0) /* Zero Termination */
+};
+#endif /* IMAGE_BL31 */
unsigned int plat_arm_sgi_get_platform_id(void)
{
@@ -16,3 +50,48 @@ unsigned int plat_arm_sgi_get_config_id(void)
{
return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
}
+
+unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+{
+ return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
+ SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
+}
+
+/*
+ * IMAGE_BL31 macro is added to build bl31_platform_setup function only for BL31
+ * because PLAT_XLAT_TABLES_DYNAMIC macro is set to build only for BL31 and not
+ * for other stages.
+ */
+#if defined(IMAGE_BL31)
+void bl31_platform_setup(void)
+{
+ int i, ret;
+
+ if (plat_arm_sgi_get_multi_chip_mode() == 0 && CSS_SGI_CHIP_COUNT > 1) {
+ ERROR("Chip Count is set to %d but multi-chip mode not enabled\n",
+ CSS_SGI_CHIP_COUNT);
+ panic();
+ } else if (plat_arm_sgi_get_multi_chip_mode() == 1 &&
+ CSS_SGI_CHIP_COUNT > 1) {
+ INFO("Enabling support for multi-chip in RD-N1-Edge\n");
+
+ for (i = 0; i < ARRAY_SIZE(rdn1edge_dynamic_mmap); i++) {
+ ret = mmap_add_dynamic_region(
+ rdn1edge_dynamic_mmap[i].base_pa,
+ rdn1edge_dynamic_mmap[i].base_va,
+ rdn1edge_dynamic_mmap[i].size,
+ rdn1edge_dynamic_mmap[i].attr
+ );
+ if (ret != 0) {
+ ERROR("Failed to add dynamic mmap entry\n");
+ panic();
+ }
+ }
+
+ plat_arm_override_gicr_frames(rdn1e1_multichip_gicr_frames);
+ gic600_multichip_init(&rdn1e1_multichip_data);
+ }
+
+ sgi_bl31_common_platform_setup();
+}
+#endif /* IMAGE_BL31 */
diff --git a/plat/arm/board/rdn1edge/rdn1edge_topology.c b/plat/arm/board/rdn1edge/rdn1edge_topology.c
index 687ae35953..5bbea6998c 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_topology.c
+++ b/plat/arm/board/rdn1edge/rdn1edge_topology.c
@@ -5,14 +5,19 @@
*/
#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
/******************************************************************************
* The power domain tree descriptor.
******************************************************************************/
static const unsigned char rdn1edge_pd_tree_desc[] = {
- PLAT_ARM_CLUSTER_COUNT,
+ (PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_COUNT),
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+#if (CSS_SGI_CHIP_COUNT > 1)
CSS_SGI_MAX_CPUS_PER_CLUSTER,
CSS_SGI_MAX_CPUS_PER_CLUSTER
+#endif
};
/*******************************************************************************
@@ -28,5 +33,22 @@ const unsigned char *plat_get_power_domain_tree_desc(void)
* to the SCMI power domain ID implemented by SCP.
******************************************************************************/
const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
- 0, 1, 2, 3, 4, 5, 6, 7
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
+#if (CSS_SGI_CHIP_COUNT > 1)
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)),
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)),
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)),
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x3)),
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x4)),
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x5)),
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x6)),
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x7)),
+#endif
};
diff --git a/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c b/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c
new file mode 100644
index 0000000000..c271f7f2dc
--- /dev/null
+++ b/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * 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(key_ptr, key_len, flags);
+}
diff --git a/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts
index 1e1ea14b0e..260247a0d8 100644
--- a/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts
+++ b/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,5 +17,6 @@
system-id {
platform-id = <0x0>;
config-id = <0x0>;
+ multi-chip-mode = <0x0>;
};
};
diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h
index fd59e5277e..95986cf4a3 100644
--- a/plat/arm/board/sgi575/include/platform_def.h
+++ b/plat/arm/board/sgi575/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,7 +16,6 @@
#define CSS_SGI_MAX_PE_PER_CPU U(1)
#define PLAT_CSS_MHU_BASE UL(0x45000000)
-#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
/* Base address of DMC-620 instances */
#define SGI575_DMC620_BASE0 UL(0x4e000000)
@@ -38,4 +37,9 @@
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
#endif
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE UL(0x30000000)
+#define PLAT_ARM_GICC_BASE UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE UL(0x300C0000)
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk
index ce2717fe02..76cc4e2c2e 100644
--- a/plat/arm/board/sgi575/platform.mk
+++ b/plat/arm/board/sgi575/platform.mk
@@ -29,6 +29,11 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \
lib/utils/mem_region.c \
plat/arm/common/arm_nor_psci_mem_protect.c
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES += ${SGI575_BASE}/sgi575_trusted_boot.c
+BL2_SOURCES += ${SGI575_BASE}/sgi575_trusted_boot.c
+endif
+
# Add the FDT_SOURCES and options for Dynamic Config
FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_tb_fw_config.dts
TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
@@ -41,3 +46,8 @@ NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
# Add the NT_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+
+ifneq ($(CSS_SGI_CHIP_COUNT),1)
+ $(error "Chip count for SGI575 should be 1, currently set to \
+ ${CSS_SGI_CHIP_COUNT}.")
+endif
diff --git a/plat/arm/board/sgi575/sgi575_plat.c b/plat/arm/board/sgi575/sgi575_plat.c
index 0d3fd16ab6..dc294e6a8d 100644
--- a/plat/arm/board/sgi575/sgi575_plat.c
+++ b/plat/arm/board/sgi575/sgi575_plat.c
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <plat/common/platform.h>
-
+#include <sgi_plat.h>
#include <sgi_variant.h>
unsigned int plat_arm_sgi_get_platform_id(void)
@@ -18,3 +18,13 @@ unsigned int plat_arm_sgi_get_config_id(void)
return (mmio_read_32(SSC_VERSION) >> SSC_VERSION_CONFIG_SHIFT)
& SSC_VERSION_CONFIG_MASK;
}
+
+unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+{
+ return 0;
+}
+
+void bl31_platform_setup(void)
+{
+ sgi_bl31_common_platform_setup();
+}
diff --git a/plat/arm/board/sgi575/sgi575_trusted_boot.c b/plat/arm/board/sgi575/sgi575_trusted_boot.c
new file mode 100644
index 0000000000..c271f7f2dc
--- /dev/null
+++ b/plat/arm/board/sgi575/sgi575_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * 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(key_ptr, key_len, flags);
+}
diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk
index 7a843c369c..f096ca53d3 100644
--- a/plat/arm/board/sgm775/platform.mk
+++ b/plat/arm/board/sgm775/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -21,3 +21,8 @@ BL2_SOURCES += lib/utils/mem_region.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_trusted_boot.c b/plat/arm/board/sgm775/sgm775_trusted_boot.c
new file mode 100644
index 0000000000..c271f7f2dc
--- /dev/null
+++ b/plat/arm/board/sgm775/sgm775_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * 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(key_ptr, key_len, flags);
+}
diff --git a/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c
index 7aeeb2aedd..78360b06c2 100644
--- a/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c
+++ b/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,7 +8,6 @@
#include <common/bl_common.h>
#include <common/desc_image_load.h>
-#include <plat/common/platform.h>
/*******************************************************************************
* Following descriptor provides BL image/ep information that gets used
diff --git a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
index 0514b39945..6a8943d5d0 100644
--- a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
+++ b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,7 +8,6 @@
#include <common/bl_common.h>
#include <common/desc_image_load.h>
-#include <plat/common/platform.h>
/*******************************************************************************
* Following descriptor provides BL image/ep information that gets used
diff --git a/plat/arm/common/aarch64/execution_state_switch.c b/plat/arm/common/aarch64/execution_state_switch.c
index 8835fa1352..bed929a9c2 100644
--- a/plat/arm/common/aarch64/execution_state_switch.c
+++ b/plat/arm/common/aarch64/execution_state_switch.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,7 +12,6 @@
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/psci/psci.h>
#include <lib/utils.h>
-#include <plat/arm/common/arm_sip_svc.h>
#include <plat/arm/common/plat_arm.h>
#include <smccc_helpers.h>
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index b19a7c39cf..c2f49c2113 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,6 +11,7 @@
#include <arch.h>
#include <bl1/bl1.h>
#include <common/bl_common.h>
+#include <lib/fconf/fconf.h>
#include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat/arm/common/plat_arm.h>
@@ -143,7 +144,10 @@ void arm_bl1_platform_setup(void)
{
/* Initialise the IO layer and register platform IO devices */
plat_arm_io_setup();
- arm_load_tb_fw_config();
+
+ /* Load fw config */
+ fconf_load_config();
+
#if TRUSTED_BOARD_BOOT
/* Share the Mbed TLS heap info with other images */
arm_bl1_set_mbedtls_heap();
@@ -184,9 +188,9 @@ void bl1_plat_prepare_exit(entry_point_info_t *ep_info)
* On Arm platforms, the FWU process is triggered when the FIP image has
* been tampered with.
*/
-int plat_arm_bl1_fwu_needed(void)
+bool plat_arm_bl1_fwu_needed(void)
{
- return (arm_io_is_toc_valid() != 1);
+ return !arm_io_is_toc_valid();
}
/*******************************************************************************
@@ -195,8 +199,5 @@ int plat_arm_bl1_fwu_needed(void)
******************************************************************************/
unsigned int bl1_plat_get_next_image_id(void)
{
- if (plat_arm_bl1_fwu_needed() != 0)
- return NS_BL1U_IMAGE_ID;
-
- return BL2_IMAGE_ID;
+ return plat_arm_bl1_fwu_needed() ? NS_BL1U_IMAGE_ID : BL2_IMAGE_ID;
}
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index cdf87ca552..dd392085df 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,6 +14,7 @@
#include <common/debug.h>
#include <common/desc_image_load.h>
#include <drivers/generic_delay_timer.h>
+#include <lib/fconf/fconf.h>
#ifdef SPD_opteed
#include <lib/optee_utils.h>
#endif
@@ -58,11 +59,13 @@ void arm_bl2_early_platform_setup(uintptr_t tb_fw_config,
/* Setup the BL2 memory layout */
bl2_tzram_layout = *mem_layout;
+ /* Fill the properties struct with the info from the config dtb */
+ if (tb_fw_config != 0U) {
+ fconf_populate(tb_fw_config);
+ }
+
/* Initialise the IO layer and register platform IO devices */
plat_arm_io_setup();
-
- if (tb_fw_config != 0U)
- arm_bl2_set_tb_cfg_addr((void *)tb_fw_config);
}
void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
@@ -150,7 +153,7 @@ int arm_bl2_handle_post_image_load(unsigned int image_id)
bl_mem_params_node_t *pager_mem_params = NULL;
bl_mem_params_node_t *paged_mem_params = NULL;
#endif
- assert(bl_mem_params);
+ assert(bl_mem_params != NULL);
switch (image_id) {
#ifdef __aarch64__
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index 939885f984..c135d7f2d6 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,7 +14,6 @@
#include <lib/debugfs.h>
#include <lib/extensions/ras.h>
#include <lib/mmio.h>
-#include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
@@ -56,6 +55,14 @@ IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_INIT_CODE_END);
MT_CODE | MT_SECURE)
#endif
+#if SEPARATE_NOBITS_REGION
+#define MAP_BL31_NOBITS MAP_REGION_FLAT( \
+ BL31_NOBITS_BASE, \
+ BL31_NOBITS_LIMIT \
+ - BL31_NOBITS_BASE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
+#endif
/*******************************************************************************
* 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
@@ -295,6 +302,9 @@ void __init arm_bl31_plat_arch_setup(void)
#if RECLAIM_INIT_CODE
MAP_BL_INIT_CODE,
#endif
+#if SEPARATE_NOBITS_REGION
+ MAP_BL31_NOBITS,
+#endif
ARM_MAP_BL_RO,
#if USE_ROMLIB
ARM_MAP_ROMLIB_CODE,
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index 255e6b4210..d1e9620de9 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -16,7 +16,6 @@
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <services/spm_mm_partition.h>
/* Weak definitions may be overridden in specific ARM standard platform */
#pragma weak plat_get_ns_image_entrypoint
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index c8b7ab448a..17058d1a5d 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -125,6 +125,23 @@ ENABLE_PMF := 1
# mapping the former as executable and the latter as execute-never.
SEPARATE_CODE_AND_RODATA := 1
+# On ARM platforms, disable SEPARATE_NOBITS_REGION by default. Both PROGBITS
+# and NOBITS sections of BL31 image are adjacent to each other and loaded
+# into Trusted SRAM.
+SEPARATE_NOBITS_REGION := 0
+
+# In order to support SEPARATE_NOBITS_REGION for Arm platforms, we need to load
+# BL31 PROGBITS into secure DRAM space and BL31 NOBITS into SRAM. Hence mandate
+# the build to require that ARM_BL31_IN_DRAM is enabled as well.
+ifeq ($(SEPARATE_NOBITS_REGION),1)
+ ifneq ($(ARM_BL31_IN_DRAM),1)
+ $(error For SEPARATE_NOBITS_REGION, ARM_BL31_IN_DRAM must be enabled)
+ endif
+ ifneq ($(RECLAIM_INIT_CODE),0)
+ $(error For SEPARATE_NOBITS_REGION, RECLAIM_INIT_CODE cannot be supported)
+ endif
+endif
+
# Disable ARM Cryptocell by default
ARM_CRYPTOCELL_INTEG := 0
$(eval $(call assert_boolean,ARM_CRYPTOCELL_INTEG))
@@ -160,12 +177,20 @@ include lib/xlat_tables_v2/xlat_tables.mk
PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
endif
+ifeq (${USE_FCONF_BASED_IO}, 0)
+ARM_IO_SOURCES += plat/arm/common/arm_io_storage.c
+else
+ARM_IO_SOURCES += plat/arm/common/arm_fconf_io_storage.c \
+ plat/arm/common/fconf/arm_fconf_io.c
+endif
+
BL1_SOURCES += drivers/io/io_fip.c \
drivers/io/io_memmap.c \
drivers/io/io_storage.c \
plat/arm/common/arm_bl1_setup.c \
plat/arm/common/arm_err.c \
- plat/arm/common/arm_io_storage.c
+ ${ARM_IO_SOURCES}
+
ifdef EL3_PAYLOAD_BASE
# Need the plat_arm_program_trusted_mailbox() function to release secondary CPUs from
# their holding pen
@@ -179,7 +204,10 @@ BL2_SOURCES += drivers/delay_timer/delay_timer.c \
drivers/io/io_storage.c \
plat/arm/common/arm_bl2_setup.c \
plat/arm/common/arm_err.c \
- plat/arm/common/arm_io_storage.c
+ ${ARM_IO_SOURCES}
+
+# Firmware Configuration Framework sources
+include lib/fconf/fconf.mk
# Add `libfdt` and Arm common helpers required for Dynamic Config
include lib/libfdt/libfdt.mk
@@ -248,12 +276,20 @@ PLAT_BL_COMMON_SOURCES += plat/arm/common/aarch64/arm_pauth.c \
lib/extensions/pauth/pauth_helpers.S
endif
+ifeq (${SPD},spmd)
+BL31_SOURCES += plat/common/plat_spmd_manifest.c \
+ common/fdt_wrappers.c \
+ ${LIBFDT_SRCS}
+
+endif
+
ifneq (${TRUSTED_BOARD_BOOT},0)
# Include common TBB sources
AUTH_SOURCES := drivers/auth/auth_mod.c \
drivers/auth/crypto_mod.c \
drivers/auth/img_parser_mod.c \
+ lib/fconf/fconf_tbbr_getter.c
# Include the selected chain of trust sources.
ifeq (${COT},tbbr)
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index e6c5a73615..443d40fe8c 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,13 +16,13 @@
#if TRUSTED_BOARD_BOOT
#include <drivers/auth/mbedtls/mbedtls_config.h>
#endif
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+#include <lib/fconf/fconf_tbbr_getter.h>
#include <plat/arm/common/arm_dyn_cfg_helpers.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-/* Variable to store the address to TB_FW_CONFIG passed from BL1 */
-static void *tb_fw_cfg_dtb;
-
#if TRUSTED_BOARD_BOOT
static void *mbedtls_heap_addr;
@@ -57,20 +57,10 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
#elif defined(IMAGE_BL2)
- int err;
-
/* If in BL2, retrieve the already allocated heap's info from DTB */
- if (tb_fw_cfg_dtb != NULL) {
- err = arm_get_dtb_mbedtls_heap_info(tb_fw_cfg_dtb, heap_addr,
- heap_size);
- if (err < 0) {
- ERROR("BL2: unable to retrieve shared Mbed TLS heap information from DTB\n");
- panic();
- }
- } else {
- ERROR("BL2: DTB missing, cannot get Mbed TLS heap\n");
- panic();
- }
+ *heap_addr = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_addr);
+ *heap_size = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_size);
+
#endif
return 0;
@@ -83,6 +73,7 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
void arm_bl1_set_mbedtls_heap(void)
{
int err;
+ uintptr_t tb_fw_cfg_dtb;
/*
* If tb_fw_cfg_dtb==NULL then DTB is not present for the current
@@ -96,8 +87,15 @@ void arm_bl1_set_mbedtls_heap(void)
* information, we would need to call plat_get_mbedtls_heap to retrieve
* the default heap's address and size.
*/
- if ((tb_fw_cfg_dtb != NULL) && (mbedtls_heap_addr != NULL)) {
- err = arm_set_dtb_mbedtls_heap_info(tb_fw_cfg_dtb,
+
+ /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB*/
+ tb_fw_cfg_dtb = FCONF_GET_PROPERTY(fconf, dtb, base_addr);
+
+ if ((tb_fw_cfg_dtb != 0UL) && (mbedtls_heap_addr != NULL)) {
+ /* As libfdt use void *, we can't avoid this cast */
+ void *dtb = (void *)tb_fw_cfg_dtb;
+
+ err = arm_set_dtb_mbedtls_heap_info(dtb,
mbedtls_heap_addr, mbedtls_heap_size);
if (err < 0) {
ERROR("BL1: unable to write shared Mbed TLS heap information to DTB\n");
@@ -108,111 +106,34 @@ void arm_bl1_set_mbedtls_heap(void)
* images. It's critical because BL2 won't be able to proceed
* without the heap info.
*/
- flush_dcache_range((uintptr_t)tb_fw_cfg_dtb,
- fdt_totalsize(tb_fw_cfg_dtb));
+ flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize(dtb));
}
}
#endif /* TRUSTED_BOARD_BOOT */
/*
- * Helper function to load TB_FW_CONFIG and populate the load information to
- * arg0 of BL2 entrypoint info.
- */
-void arm_load_tb_fw_config(void)
-{
- int err;
- uintptr_t config_base = 0UL;
- image_desc_t *desc;
-
- image_desc_t arm_tb_fw_info = {
- .image_id = TB_FW_CONFIG_ID,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = ARM_TB_FW_CONFIG_BASE,
- .image_info.image_max_size =
- ARM_TB_FW_CONFIG_LIMIT - ARM_TB_FW_CONFIG_BASE
- };
-
- VERBOSE("BL1: Loading TB_FW_CONFIG\n");
- err = load_auth_image(TB_FW_CONFIG_ID, &arm_tb_fw_info.image_info);
- if (err != 0) {
- /* Return if TB_FW_CONFIG is not loaded */
- VERBOSE("Failed to load TB_FW_CONFIG\n");
- return;
- }
-
- /* At this point we know that a DTB is indeed available */
- config_base = arm_tb_fw_info.image_info.image_base;
- tb_fw_cfg_dtb = (void *)config_base;
-
- /* The BL2 ep_info arg0 is modified to point to TB_FW_CONFIG */
- desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
- assert(desc != NULL);
- desc->ep_info.args.arg0 = config_base;
-
- INFO("BL1: TB_FW_CONFIG loaded at address = 0x%lx\n", config_base);
-
-#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH)
- int tb_fw_node;
- uint32_t disable_auth = 0;
-
- err = arm_dyn_tb_fw_cfg_init((void *)config_base, &tb_fw_node);
- if (err < 0) {
- ERROR("Invalid TB_FW_CONFIG loaded\n");
- panic();
- }
-
- err = arm_dyn_get_disable_auth((void *)config_base, tb_fw_node, &disable_auth);
- if (err < 0)
- return;
-
- if (disable_auth == 1)
- dyn_disable_auth();
-#endif
-}
-
-/*
- * BL2 utility function to set the address of TB_FW_CONFIG passed from BL1.
- */
-void arm_bl2_set_tb_cfg_addr(void *dtb)
-{
- assert(dtb != NULL);
- tb_fw_cfg_dtb = dtb;
-}
-
-/*
* BL2 utility function to initialize dynamic configuration specified by
* TB_FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if
* specified in TB_FW_CONFIG.
*/
void arm_bl2_dyn_cfg_init(void)
{
- int err = 0, tb_fw_node;
unsigned int i;
bl_mem_params_node_t *cfg_mem_params = NULL;
- uint64_t image_base;
- uint32_t image_size;
+ uintptr_t image_base;
+ size_t image_size;
const unsigned int config_ids[] = {
HW_CONFIG_ID,
SOC_FW_CONFIG_ID,
NT_FW_CONFIG_ID,
-#ifdef SPD_tspd
- /* Currently tos_fw_config is only present for TSP */
+#if defined(SPD_tspd) || defined(SPD_spmd)
+ /* tos_fw_config is only present for TSPD/SPMD */
TOS_FW_CONFIG_ID
#endif
};
- if (tb_fw_cfg_dtb == NULL) {
- VERBOSE("No TB_FW_CONFIG specified\n");
- return;
- }
-
- err = arm_dyn_tb_fw_cfg_init(tb_fw_cfg_dtb, &tb_fw_node);
- if (err < 0) {
- ERROR("Invalid TB_FW_CONFIG passed from BL1\n");
- panic();
- }
+ const struct dyn_cfg_dtb_info_t *dtb_info;
/* Iterate through all the fw config IDs */
for (i = 0; i < ARRAY_SIZE(config_ids); i++) {
@@ -223,14 +144,16 @@ void arm_bl2_dyn_cfg_init(void)
continue;
}
- err = arm_dyn_get_config_load_info(tb_fw_cfg_dtb, tb_fw_node,
- config_ids[i], &image_base, &image_size);
- if (err < 0) {
+ dtb_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, config_ids[i]);
+ if (dtb_info == NULL) {
VERBOSE("Couldn't find config_id %d load info in TB_FW_CONFIG\n",
config_ids[i]);
continue;
}
+ image_base = dtb_info->config_addr;
+ image_size = dtb_info->config_max_size;
+
/*
* Do some runtime checks on the load addresses of soc_fw_config,
* tos_fw_config, nt_fw_config. This is not a comprehensive check
@@ -262,8 +185,8 @@ void arm_bl2_dyn_cfg_init(void)
}
- cfg_mem_params->image_info.image_base = (uintptr_t)image_base;
- cfg_mem_params->image_info.image_max_size = image_size;
+ cfg_mem_params->image_info.image_base = image_base;
+ cfg_mem_params->image_info.image_max_size = (uint32_t)image_size;
/*
* Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from
@@ -271,16 +194,4 @@ void arm_bl2_dyn_cfg_init(void)
*/
cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
}
-
-#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH)
- uint32_t disable_auth = 0;
-
- err = arm_dyn_get_disable_auth(tb_fw_cfg_dtb, tb_fw_node,
- &disable_auth);
- if (err < 0)
- return;
-
- if (disable_auth == 1)
- dyn_disable_auth();
-#endif
}
diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c
index 36d37f8f66..909c4a671a 100644
--- a/plat/arm/common/arm_dyn_cfg_helpers.c
+++ b/plat/arm/common/arm_dyn_cfg_helpers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,7 +8,6 @@
#include <libfdt.h>
-#include <common/desc_image_load.h>
#include <common/fdt_wrappers.h>
#include <plat/arm/common/arm_dyn_cfg_helpers.h>
#include <plat/arm/common/plat_arm.h>
@@ -16,128 +15,6 @@
#define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr"
#define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size"
-typedef struct config_load_info_prop {
- unsigned int config_id;
- const char *config_addr;
- const char *config_max_size;
-} config_load_info_prop_t;
-
-static const config_load_info_prop_t prop_names[] = {
- {HW_CONFIG_ID, "hw_config_addr", "hw_config_max_size"},
- {SOC_FW_CONFIG_ID, "soc_fw_config_addr", "soc_fw_config_max_size"},
- {TOS_FW_CONFIG_ID, "tos_fw_config_addr", "tos_fw_config_max_size"},
- {NT_FW_CONFIG_ID, "nt_fw_config_addr", "nt_fw_config_max_size"}
-};
-
-/*******************************************************************************
- * Helper to read the load information corresponding to the `config_id` in
- * TB_FW_CONFIG. This function expects the following properties to be defined :
- * <config>_addr size : 2 cells
- * <config>_max_size size : 1 cell
- *
- * Arguments:
- * void *dtb - pointer to the TB_FW_CONFIG in memory
- * int node - The node offset to appropriate node in the
- * DTB.
- * unsigned int config_id - The configuration id
- * uint64_t *config_addr - Returns the `config` load address if read
- * is successful.
- * uint32_t *config_size - Returns the `config` size if read is
- * successful.
- *
- * Returns 0 on success and -1 on error.
- ******************************************************************************/
-int arm_dyn_get_config_load_info(void *dtb, int node, unsigned int config_id,
- uint64_t *config_addr, uint32_t *config_size)
-{
- int err;
- unsigned int i;
-
- assert(dtb != NULL);
- assert(config_addr != NULL);
- assert(config_size != NULL);
-
- for (i = 0; i < ARRAY_SIZE(prop_names); i++) {
- if (prop_names[i].config_id == config_id)
- break;
- }
-
- if (i == ARRAY_SIZE(prop_names)) {
- WARN("Invalid config id %d\n", config_id);
- return -1;
- }
-
- /* Check if the pointer to DT is correct */
- assert(fdt_check_header(dtb) == 0);
-
- /* Assert the node offset point to "arm,tb_fw" compatible property */
- assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw"));
-
- err = fdtw_read_cells(dtb, node, prop_names[i].config_addr, 2,
- (void *) config_addr);
- if (err < 0) {
- WARN("Read cell failed for %s\n", prop_names[i].config_addr);
- return -1;
- }
-
- err = fdtw_read_cells(dtb, node, prop_names[i].config_max_size, 1,
- (void *) config_size);
- if (err < 0) {
- WARN("Read cell failed for %s\n", prop_names[i].config_max_size);
- return -1;
- }
-
- VERBOSE("Dyn cfg: Read config_id %d load info from TB_FW_CONFIG 0x%llx 0x%x\n",
- config_id, (unsigned long long)*config_addr, *config_size);
-
- return 0;
-}
-
-/*******************************************************************************
- * Helper to read the `disable_auth` property in config DTB. This function
- * expects the following properties to be present in the config DTB.
- * name : disable_auth size : 1 cell
- *
- * Arguments:
- * void *dtb - pointer to the TB_FW_CONFIG in memory
- * int node - The node offset to appropriate node in the
- * DTB.
- * uint64_t *disable_auth - The value of `disable_auth` property on
- * successful read. Must be 0 or 1.
- *
- * Returns 0 on success and -1 on error.
- ******************************************************************************/
-int arm_dyn_get_disable_auth(void *dtb, int node, uint32_t *disable_auth)
-{
- int err;
-
- assert(dtb != NULL);
- assert(disable_auth != NULL);
-
- /* Check if the pointer to DT is correct */
- assert(fdt_check_header(dtb) == 0);
-
- /* Assert the node offset point to "arm,tb_fw" compatible property */
- assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw"));
-
- /* Locate the disable_auth cell and read the value */
- err = fdtw_read_cells(dtb, node, "disable_auth", 1, disable_auth);
- if (err < 0) {
- WARN("Read cell failed for `disable_auth`\n");
- return -1;
- }
-
- /* Check if the value is boolean */
- if ((*disable_auth != 0U) && (*disable_auth != 1U)) {
- WARN("Invalid value for `disable_auth` cell %d\n", *disable_auth);
- return -1;
- }
-
- VERBOSE("Dyn cfg: `disable_auth` cell found with value = %d\n",
- *disable_auth);
- return 0;
-}
-
/*******************************************************************************
* Validate the tb_fw_config is a valid DTB file and returns the node offset
* to "arm,tb_fw" property.
@@ -170,47 +47,6 @@ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node)
}
/*
- * Reads and returns the Mbed TLS shared heap information from the DTB.
- * This function is supposed to be called *only* when a DTB is present.
- * This function is supposed to be called only by BL2.
- *
- * Returns:
- * 0 = success
- * -1 = error. In this case the values of heap_addr, heap_size should be
- * considered as garbage by the caller.
- */
-int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr,
- size_t *heap_size)
-{
- int err, dtb_root;
-
- /* Verify the DTB is valid and get the root node */
- err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root);
- if (err < 0) {
- ERROR("Invalid TB_FW_CONFIG. Cannot retrieve Mbed TLS heap information from DTB\n");
- return -1;
- }
-
- /* Retrieve the Mbed TLS heap details from the DTB */
- err = fdtw_read_cells(dtb, dtb_root,
- DTB_PROP_MBEDTLS_HEAP_ADDR, 2, heap_addr);
- if (err < 0) {
- ERROR("Error while reading %s from DTB\n",
- DTB_PROP_MBEDTLS_HEAP_ADDR);
- return -1;
- }
- err = fdtw_read_cells(dtb, dtb_root,
- DTB_PROP_MBEDTLS_HEAP_SIZE, 1, heap_size);
- if (err < 0) {
- ERROR("Error while reading %s from DTB\n",
- DTB_PROP_MBEDTLS_HEAP_SIZE);
- return -1;
- }
- return 0;
-}
-
-
-/*
* This function writes the Mbed TLS heap address and size in the DTB. When it
* is called, it is guaranteed that a DTB is available. However it is not
* guaranteed that the shared Mbed TLS heap implementation is used. Thus we
diff --git a/plat/arm/common/arm_fconf_io_storage.c b/plat/arm/common/arm_fconf_io_storage.c
new file mode 100644
index 0000000000..341622a0bb
--- /dev/null
+++ b/plat/arm/common/arm_fconf_io_storage.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2015-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <drivers/io/io_driver.h>
+#include <drivers/io/io_fip.h>
+#include <drivers/io/io_memmap.h>
+#include <drivers/io/io_storage.h>
+#include <lib/utils.h>
+#include <tools_share/firmware_image_package.h>
+
+#include <plat/arm/common/arm_fconf_getter.h>
+#include <plat/arm/common/arm_fconf_io_storage.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+/* IO devices */
+static const io_dev_connector_t *fip_dev_con;
+uintptr_t fip_dev_handle;
+static const io_dev_connector_t *memmap_dev_con;
+uintptr_t memmap_dev_handle;
+
+/* Weak definitions may be overridden in specific ARM standard platform */
+#pragma weak plat_arm_io_setup
+#pragma weak plat_arm_get_alt_image_source
+
+int open_fip(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ /* See if a Firmware Image Package is available */
+ result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
+ if (result == 0) {
+ result = io_open(fip_dev_handle, spec, &local_image_handle);
+ if (result == 0) {
+ VERBOSE("Using FIP\n");
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+
+int open_memmap(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
+ if (result == 0) {
+ result = io_open(memmap_dev_handle, spec, &local_image_handle);
+ if (result == 0) {
+ VERBOSE("Using Memmap\n");
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+
+int arm_io_setup(void)
+{
+ int io_result;
+
+ io_result = register_io_dev_fip(&fip_dev_con);
+ if (io_result < 0) {
+ return io_result;
+ }
+
+ io_result = register_io_dev_memmap(&memmap_dev_con);
+ if (io_result < 0) {
+ return io_result;
+ }
+
+ /* Open connections to devices and cache the handles */
+ io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
+ &fip_dev_handle);
+ if (io_result < 0) {
+ return io_result;
+ }
+
+ io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
+ &memmap_dev_handle);
+
+ return io_result;
+}
+
+void plat_arm_io_setup(void)
+{
+ int err;
+
+ err = arm_io_setup();
+ if (err < 0) {
+ panic();
+ }
+}
+
+int plat_arm_get_alt_image_source(
+ unsigned int image_id __unused,
+ uintptr_t *dev_handle __unused,
+ uintptr_t *image_spec __unused)
+{
+ /* By default do not try an alternative */
+ return -ENOENT;
+}
+
+/* Return an IO device handle and specification which can be used to access
+ * an image. Use this to enforce platform load policy */
+int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
+ uintptr_t *image_spec)
+{
+ int result;
+ const struct plat_io_policy *policy;
+
+ assert(image_id < MAX_NUMBER_IDS);
+
+ policy = FCONF_GET_PROPERTY(arm, io_policies, image_id);
+ result = policy->check(policy->image_spec);
+ if (result == 0) {
+ *image_spec = policy->image_spec;
+ *dev_handle = *(policy->dev_handle);
+ } else {
+ VERBOSE("Trying alternative IO\n");
+ result = plat_arm_get_alt_image_source(image_id, dev_handle,
+ image_spec);
+ }
+
+ return result;
+}
+
+/*
+ * See if a Firmware Image Package is available,
+ * by checking if TOC is valid or not.
+ */
+bool arm_io_is_toc_valid(void)
+{
+ return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0);
+}
diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c
index fc1eb490e9..f5d8a414d9 100644
--- a/plat/arm/common/arm_io_storage.c
+++ b/plat/arm/common/arm_io_storage.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -292,32 +292,41 @@ static int open_memmap(const uintptr_t spec)
}
-void arm_io_setup(void)
+int arm_io_setup(void)
{
int io_result;
io_result = register_io_dev_fip(&fip_dev_con);
- assert(io_result == 0);
+ if (io_result < 0) {
+ return io_result;
+ }
io_result = register_io_dev_memmap(&memmap_dev_con);
- assert(io_result == 0);
+ if (io_result < 0) {
+ return io_result;
+ }
/* Open connections to devices and cache the handles */
io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
&fip_dev_handle);
- assert(io_result == 0);
+ if (io_result < 0) {
+ return io_result;
+ }
io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
&memmap_dev_handle);
- assert(io_result == 0);
- /* Ignore improbable errors in release builds */
- (void)io_result;
+ return io_result;
}
void plat_arm_io_setup(void)
{
- arm_io_setup();
+ int err;
+
+ err = arm_io_setup();
+ if (err < 0) {
+ panic();
+ }
}
int plat_arm_get_alt_image_source(
@@ -357,12 +366,8 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
* See if a Firmware Image Package is available,
* by checking if TOC is valid or not.
*/
-int arm_io_is_toc_valid(void)
+bool arm_io_is_toc_valid(void)
{
- int result;
-
- result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
-
- return (result == 0);
+ return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0);
}
diff --git a/plat/arm/common/arm_nor_psci_mem_protect.c b/plat/arm/common/arm_nor_psci_mem_protect.c
index b9181eb4cf..1fa234d797 100644
--- a/plat/arm/common/arm_nor_psci_mem_protect.c
+++ b/plat/arm/common/arm_nor_psci_mem_protect.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,7 +9,6 @@
#include <common/debug.h>
#include <drivers/cfi/v2m_flash.h>
#include <lib/psci/psci.h>
-#include <lib/mmio.h>
#include <lib/utils.h>
#include <plat/arm/common/plat_arm.h>
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index c95f4523c6..5434c94571 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -1,11 +1,10 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
-#include <errno.h>
#include <platform_def.h>
diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c
new file mode 100644
index 0000000000..3c0586fd01
--- /dev/null
+++ b/plat/arm/common/fconf/arm_fconf_io.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <drivers/io/io_storage.h>
+#include <lib/object_pool.h>
+#include <libfdt.h>
+#include <tools_share/firmware_image_package.h>
+
+#include <plat/arm/common/arm_fconf_getter.h>
+#include <plat/arm/common/arm_fconf_io_storage.h>
+#include <platform_def.h>
+
+const io_block_spec_t fip_block_spec = {
+ .offset = PLAT_ARM_FIP_BASE,
+ .length = PLAT_ARM_FIP_MAX_SIZE
+};
+
+const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = {
+ [BL2_IMAGE_ID] = {UUID_TRUSTED_BOOT_FIRMWARE_BL2},
+ [TB_FW_CONFIG_ID] = {UUID_TB_FW_CONFIG},
+#if TRUSTED_BOARD_BOOT
+ [TRUSTED_BOOT_FW_CERT_ID] = {UUID_TRUSTED_BOOT_FW_CERT},
+#endif /* TRUSTED_BOARD_BOOT */
+};
+
+/* By default, ARM platforms load images from the FIP */
+struct plat_io_policy policies[MAX_NUMBER_IDS] = {
+ [FIP_IMAGE_ID] = {
+ &memmap_dev_handle,
+ (uintptr_t)&fip_block_spec,
+ open_memmap
+ },
+ [BL2_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[BL2_IMAGE_ID],
+ open_fip
+ },
+ [TB_FW_CONFIG_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[TB_FW_CONFIG_ID],
+ open_fip
+ },
+#if TRUSTED_BOARD_BOOT
+ [TRUSTED_BOOT_FW_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[TRUSTED_BOOT_FW_CERT_ID],
+ open_fip
+ },
+#endif /* TRUSTED_BOARD_BOOT */
+};
+
+#ifdef IMAGE_BL2
+
+#if TRUSTED_BOARD_BOOT
+#define FCONF_ARM_IO_UUID_NUMBER 19
+#else
+#define FCONF_ARM_IO_UUID_NUMBER 10
+#endif
+
+static io_uuid_spec_t fconf_arm_uuids[FCONF_ARM_IO_UUID_NUMBER];
+static OBJECT_POOL_ARRAY(fconf_arm_uuids_pool, fconf_arm_uuids);
+
+struct policies_load_info {
+ unsigned int image_id;
+ const char *name;
+};
+
+/* image id to property name table */
+static const struct policies_load_info load_info[FCONF_ARM_IO_UUID_NUMBER] = {
+ {SCP_BL2_IMAGE_ID, "scp_bl2_uuid"},
+ {BL31_IMAGE_ID, "bl31_uuid"},
+ {BL32_IMAGE_ID, "bl32_uuid"},
+ {BL32_EXTRA1_IMAGE_ID, "bl32_extra1_uuid"},
+ {BL32_EXTRA2_IMAGE_ID, "bl32_extra2_uuid"},
+ {BL33_IMAGE_ID, "bl33_uuid"},
+ {HW_CONFIG_ID, "hw_cfg_uuid"},
+ {SOC_FW_CONFIG_ID, "soc_fw_cfg_uuid"},
+ {TOS_FW_CONFIG_ID, "tos_fw_cfg_uuid"},
+ {NT_FW_CONFIG_ID, "nt_fw_cfg_uuid"},
+#if TRUSTED_BOARD_BOOT
+ {TRUSTED_KEY_CERT_ID, "t_key_cert_uuid"},
+ {SCP_FW_KEY_CERT_ID, "scp_fw_key_uuid"},
+ {SOC_FW_KEY_CERT_ID, "soc_fw_key_uuid"},
+ {TRUSTED_OS_FW_KEY_CERT_ID, "tos_fw_key_cert_uuid"},
+ {NON_TRUSTED_FW_KEY_CERT_ID, "nt_fw_key_cert_uuid"},
+ {SCP_FW_CONTENT_CERT_ID, "scp_fw_content_cert_uuid"},
+ {SOC_FW_CONTENT_CERT_ID, "soc_fw_content_cert_uuid"},
+ {TRUSTED_OS_FW_CONTENT_CERT_ID, "tos_fw_content_cert_uuid"},
+ {NON_TRUSTED_FW_CONTENT_CERT_ID, "nt_fw_content_cert_uuid"},
+#endif /* TRUSTED_BOARD_BOOT */
+};
+
+int fconf_populate_arm_io_policies(uintptr_t config)
+{
+ int err, node;
+ unsigned int i;
+
+ union uuid_helper_t uuid_helper;
+ io_uuid_spec_t *uuid_ptr;
+
+ /* As libfdt uses void *, we can't avoid this cast */
+ const void *dtb = (void *)config;
+
+ /* Assert the node offset point to "arm,io-fip-handle" compatible property */
+ const char *compatible_str = "arm,io-fip-handle";
+ node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
+ if (node < 0) {
+ ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
+ return node;
+ }
+
+ /* Locate the uuid cells and read the value for all the load info uuid */
+ for (i = 0; i < FCONF_ARM_IO_UUID_NUMBER; i++) {
+ uuid_ptr = pool_alloc(&fconf_arm_uuids_pool);
+ err = fdtw_read_array(dtb, node, load_info[i].name, 4, &uuid_helper.word);
+ if (err < 0) {
+ WARN("FCONF: Read cell failed for %s\n", load_info[i].name);
+ return err;
+ }
+
+ VERBOSE("FCONF: arm-io_policies.%s cell found with value = 0x%x 0x%x 0x%x 0x%x\n",
+ load_info[i].name,
+ uuid_helper.word[0], uuid_helper.word[1],
+ uuid_helper.word[2], uuid_helper.word[3]);
+
+ uuid_ptr->uuid = uuid_helper.uuid_struct;
+ policies[load_info[i].image_id].image_spec = (uintptr_t)uuid_ptr;
+ policies[load_info[i].image_id].dev_handle = &fip_dev_handle;
+ policies[load_info[i].image_id].check = open_fip;
+ }
+ return 0;
+}
+
+FCONF_REGISTER_POPULATOR(arm_io, fconf_populate_arm_io_policies);
+
+#endif /* IMAGE_BL2 */
diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c
index bb69914ae3..0cc746b104 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,7 +11,6 @@
#include <bl32/sp_min/platform_sp_min.h>
#include <common/bl_common.h>
#include <common/debug.h>
-#include <drivers/arm/pl011.h>
#include <drivers/console.h>
#include <lib/mmio.h>
#include <plat/arm/common/plat_arm.h>
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index 01c674f82e..af69c6fb46 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -1,11 +1,10 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
-#include <errno.h>
#include <platform_def.h>
@@ -15,7 +14,6 @@
#include <lib/cassert.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/arm/css/common/css_pm.h>
-#include <plat/common/platform.h>
/* Allow CSS platforms to override `plat_arm_psci_pm_ops` */
#pragma weak plat_arm_psci_pm_ops
diff --git a/plat/arm/css/sgi/aarch64/sgi_helper.S b/plat/arm/css/sgi/aarch64/sgi_helper.S
index b80903d061..04bfb77718 100644
--- a/plat/arm/css/sgi/aarch64/sgi_helper.S
+++ b/plat/arm/css/sgi/aarch64/sgi_helper.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,19 +18,22 @@
* unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
*
* Helper function to calculate the core position.
+ * (ChipId * PLAT_ARM_CLUSTER_COUNT *
+ * CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU) +
* (ClusterId * CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU) +
* (CPUId * CSS_SGI_MAX_PE_PER_CPU) +
* ThreadId
*
* which can be simplified as:
*
- * ((ClusterId * CSS_SGI_MAX_CPUS_PER_CLUSTER + CPUId) *
- * CSS_SGI_MAX_PE_PER_CPU) + ThreadId
+ * ((((ChipId * PLAT_ARM_CLUSTER_COUNT) + ClusterId) *
+ * CSS_SGI_MAX_CPUS_PER_CLUSTER) + CPUId) * CSS_SGI_MAX_PE_PER_CPU +
+ * ThreadId
* ------------------------------------------------------
*/
func plat_arm_calc_core_pos
- mov x3, x0
+ mov x4, x0
/*
* The MT bit in MPIDR is always set for SGI platforms
@@ -38,15 +41,18 @@ func plat_arm_calc_core_pos
*/
/* 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
+ ubfx x0, x4, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x1, x4, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x2, x4, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x3, x4, #MPIDR_AFF3_SHIFT, #MPIDR_AFFINITY_BITS
/* Compute linear position */
+ mov x4, #PLAT_ARM_CLUSTER_COUNT
+ madd x2, x3, x4, x2
mov x4, #CSS_SGI_MAX_CPUS_PER_CLUSTER
madd x1, x2, x4, x1
- mov x5, #CSS_SGI_MAX_PE_PER_CPU
- madd x0, x1, x5, x0
+ mov x4, #CSS_SGI_MAX_PE_PER_CPU
+ madd x0, x1, x4, x0
ret
endfunc plat_arm_calc_core_pos
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index e21457304b..4986378e99 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,12 +17,16 @@
#include <plat/arm/soc/common/soc_css_def.h>
#include <plat/common/common_def.h>
-#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \
- CSS_SGI_MAX_CPUS_PER_CLUSTER * \
+#define PLATFORM_CORE_COUNT (CSS_SGI_CHIP_COUNT * \
+ PLAT_ARM_CLUSTER_COUNT * \
+ CSS_SGI_MAX_CPUS_PER_CLUSTER * \
CSS_SGI_MAX_PE_PER_CPU)
#define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00040000 /* 256 KB */
+/* Remote chip address offset (4TB per chip) */
+#define CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) ((ULL(1) << 42) * (n))
+
/*
* PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
* plat_arm_mmap array defined for each BL stage.
@@ -35,14 +39,14 @@
# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
# else
# define PLAT_ARM_MMAP_ENTRIES 8
-# define MAX_XLAT_TABLES 5
+# define MAX_XLAT_TABLES 8
# endif
#elif defined(IMAGE_BL32)
# define PLAT_ARM_MMAP_ENTRIES 8
# define MAX_XLAT_TABLES 5
#elif !USE_ROMLIB
# define PLAT_ARM_MMAP_ENTRIES 11
-# define MAX_XLAT_TABLES 5
+# define MAX_XLAT_TABLES 7
#else
# define PLAT_ARM_MMAP_ENTRIES 12
# define MAX_XLAT_TABLES 6
@@ -129,10 +133,29 @@
CSS_SGI_DEVICE_SIZE, \
MT_DEVICE | MT_RW | MT_SECURE)
-/* GIC related constants */
-#define PLAT_ARM_GICD_BASE 0x30000000
-#define PLAT_ARM_GICC_BASE 0x2C000000
-#define PLAT_ARM_GICR_BASE 0x300C0000
+#define ARM_MAP_SHARED_RAM_REMOTE_CHIP(n) \
+ MAP_REGION_FLAT( \
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + \
+ ARM_SHARED_RAM_BASE, \
+ ARM_SHARED_RAM_SIZE, \
+ MT_MEMORY | MT_RW | MT_SECURE \
+ )
+
+#define CSS_SGI_MAP_DEVICE_REMOTE_CHIP(n) \
+ MAP_REGION_FLAT( \
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + \
+ CSS_SGI_DEVICE_BASE, \
+ CSS_SGI_DEVICE_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE \
+ )
+
+#define SOC_CSS_MAP_DEVICE_REMOTE_CHIP(n) \
+ MAP_REGION_FLAT( \
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + \
+ SOC_CSS_DEVICE_BASE, \
+ SOC_CSS_DEVICE_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE \
+ )
/* Map the secure region for access from S-EL0 */
#define PLAT_ARM_SECURE_MAP_DEVICE MAP_REGION_FLAT( \
@@ -212,4 +235,7 @@
#define SBSA_SECURE_WDOG_BASE UL(0x2A480000)
#define SBSA_SECURE_WDOG_TIMEOUT UL(100)
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT CSS_SGI_CHIP_COUNT
+
#endif /* SGI_BASE_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgi/include/sgi_plat.h b/plat/arm/css/sgi/include/sgi_plat.h
new file mode 100644
index 0000000000..a5fbded3ca
--- /dev/null
+++ b/plat/arm/css/sgi/include/sgi_plat.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGI_PLAT_H
+#define SGI_PLAT_H
+
+/* BL31 platform setup common to all SGI based platforms */
+void sgi_bl31_common_platform_setup(void);
+
+#endif /* SGI_PLAT_H */
diff --git a/plat/arm/css/sgi/include/sgi_variant.h b/plat/arm/css/sgi/include/sgi_variant.h
index c75f2132b9..f4c5300d09 100644
--- a/plat/arm/css/sgi/include/sgi_variant.h
+++ b/plat/arm/css/sgi/include/sgi_variant.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,16 +8,21 @@
#define SGI_VARIANT_H
/* SSC_VERSION values for SGI575 */
-#define SGI575_SSC_VER_PART_NUM 0x0783
+#define SGI575_SSC_VER_PART_NUM 0x0783
/* SID Version values for RD-N1E1-Edge */
#define RD_N1E1_EDGE_SID_VER_PART_NUM 0x0786
#define RD_E1_EDGE_CONFIG_ID 0x2
+/* SID Version values for RD-Daniel */
+#define RD_DANIEL_SID_VER_PART_NUM 0x078a
+
/* Structure containing SGI platform variant information */
typedef struct sgi_platform_info {
unsigned int platform_id; /* Part Number of the platform */
unsigned int config_id; /* Config Id of the platform */
+ unsigned int chip_id; /* Chip Id or Node number */
+ unsigned int multi_chip_mode; /* Multi-chip mode availability */
} sgi_platform_info_t;
extern sgi_platform_info_t sgi_plat_info;
@@ -28,4 +33,7 @@ unsigned int plat_arm_sgi_get_platform_id(void);
/* returns the configuration id of the platform */
unsigned int plat_arm_sgi_get_config_id(void);
+/* returns true if operating in multi-chip configuration */
+unsigned int plat_arm_sgi_get_multi_chip_mode(void);
+
#endif /* SGI_VARIANT_H */
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 71601118f6..40a7fd8a3e 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -16,6 +16,8 @@ EL3_EXCEPTION_HANDLING := 0
HANDLE_EA_EL3_FIRST := 0
+CSS_SGI_CHIP_COUNT := 1
+
INTERCONNECT_SOURCES := ${CSS_ENT_BASE}/sgi_interconnect.c
PLAT_INCLUDES += -I${CSS_ENT_BASE}/include
@@ -52,6 +54,8 @@ endif
$(eval $(call add_define,SGI_PLAT))
+$(eval $(call add_define,CSS_SGI_CHIP_COUNT))
+
override CSS_LOAD_SCP_IMAGES := 0
override NEED_BL2U := no
override ARM_BL31_IN_DRAM := 1
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
index ba050d5f1c..fcb7e1f9fa 100644
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ b/plat/arm/css/sgi/sgi_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -28,18 +28,57 @@ static scmi_channel_plat_info_t sgi575_scmi_plat_info = {
.ring_doorbell = &mhu_ring_doorbell,
};
-static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info = {
+static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info[] = {
+ {
.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
.db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
.db_preserve_mask = 0xfffffffe,
.db_modify_mask = 0x1,
.ring_doorbell = &mhuv2_ring_doorbell,
+ },
+ #if (CSS_SGI_CHIP_COUNT > 1)
+ {
+ .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1),
+ .db_reg_addr = PLAT_CSS_MHU_BASE
+ + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1) + SENDER_REG_SET(0),
+ .db_preserve_mask = 0xfffffffe,
+ .db_modify_mask = 0x1,
+ .ring_doorbell = &mhuv2_ring_doorbell,
+ },
+ #endif
+ #if (CSS_SGI_CHIP_COUNT > 2)
+ {
+ .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2),
+ .db_reg_addr = PLAT_CSS_MHU_BASE +
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2) + SENDER_REG_SET(0),
+ .db_preserve_mask = 0xfffffffe,
+ .db_modify_mask = 0x1,
+ .ring_doorbell = &mhuv2_ring_doorbell,
+ },
+ #endif
+ #if (CSS_SGI_CHIP_COUNT > 3)
+ {
+ .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3),
+ .db_reg_addr = PLAT_CSS_MHU_BASE +
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3) + SENDER_REG_SET(0),
+ .db_preserve_mask = 0xfffffffe,
+ .db_modify_mask = 0x1,
+ .ring_doorbell = &mhuv2_ring_doorbell,
+ },
+ #endif
};
-scmi_channel_plat_info_t *plat_css_get_scmi_info(void)
+scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
{
- if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM)
- return &rd_n1e1_edge_scmi_plat_info;
+ if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM ||
+ sgi_plat_info.platform_id == RD_DANIEL_SID_VER_PART_NUM) {
+ if (channel_id >= sizeof(rd_n1e1_edge_scmi_plat_info))
+ panic();
+ return &rd_n1e1_edge_scmi_plat_info[channel_id];
+ }
else if (sgi_plat_info.platform_id == SGI575_SSC_VER_PART_NUM)
return &sgi575_scmi_plat_info;
else
@@ -51,11 +90,12 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
{
sgi_plat_info.platform_id = plat_arm_sgi_get_platform_id();
sgi_plat_info.config_id = plat_arm_sgi_get_config_id();
+ sgi_plat_info.multi_chip_mode = plat_arm_sgi_get_multi_chip_mode();
arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
}
-void bl31_platform_setup(void)
+void sgi_bl31_common_platform_setup(void)
{
arm_bl31_platform_setup();
@@ -66,9 +106,13 @@ void bl31_platform_setup(void)
const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
{
- /* For RD-E1-Edge platform only CPU ON/OFF is supported */
- if ((sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) &&
- (sgi_plat_info.config_id == RD_E1_EDGE_CONFIG_ID)) {
+ /*
+ * For RD-E1-Edge and RD-Daniel platforms, only CPU power ON/OFF
+ * PSCI platform callbacks are supported.
+ */
+ if (((sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) &&
+ (sgi_plat_info.config_id == RD_E1_EDGE_CONFIG_ID)) ||
+ (sgi_plat_info.platform_id == RD_DANIEL_SID_VER_PART_NUM)) {
ops->cpu_standby = NULL;
ops->system_off = NULL;
ops->system_reset = NULL;
diff --git a/plat/arm/css/sgi/sgi_image_load.c b/plat/arm/css/sgi/sgi_image_load.c
index a2f10dcc7f..09f3b728db 100644
--- a/plat/arm/css/sgi/sgi_image_load.c
+++ b/plat/arm/css/sgi/sgi_image_load.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -62,6 +62,13 @@ static int plat_sgi_append_config_node(void)
return -1;
}
+ platcfg = plat_arm_sgi_get_multi_chip_mode();
+ err = fdt_setprop_u32(fdt, nodeoffset, "multi-chip-mode", platcfg);
+ if (err < 0) {
+ ERROR("Failed to set multi-chip-mode\n");
+ return -1;
+ }
+
flush_dcache_range((uintptr_t)fdt, mem_params->image_info.image_size);
return 0;
diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h
index 24bbed513f..90511ac6a7 100644
--- a/plat/arm/css/sgm/include/sgm_base_platform_def.h
+++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -86,7 +86,6 @@
/* MHU related constants */
#define PLAT_CSS_MHU_BASE 0x2b1f0000
-#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
#define PLAT_ARM_TRUSTED_ROM_BASE 0x00000000
#define PLAT_ARM_TRUSTED_ROM_SIZE 0x00080000
@@ -239,4 +238,7 @@
/* 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/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c
index 7e92ac8350..907e9fdacf 100644
--- a/plat/arm/css/sgm/sgm_bl31_setup.c
+++ b/plat/arm/css/sgm/sgm_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,7 +20,7 @@ static scmi_channel_plat_info_t sgm775_scmi_plat_info = {
.ring_doorbell = &mhu_ring_doorbell,
};
-scmi_channel_plat_info_t *plat_css_get_scmi_info()
+scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
{
return &sgm775_scmi_plat_info;
}
diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c
index b46656c7ac..6070db235f 100644
--- a/plat/common/plat_bl_common.c
+++ b/plat/common/plat_bl_common.c
@@ -1,11 +1,10 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
-#include <errno.h>
#include <arch_helpers.h>
#include <common/bl_common.h>
diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c
new file mode 100644
index 0000000000..4c789795e6
--- /dev/null
+++ b/plat/common/plat_spmd_manifest.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <libfdt.h>
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <errno.h>
+#include <platform_def.h>
+#include <services/spm_core_manifest.h>
+
+/*******************************************************************************
+ * Attribute section handler
+ ******************************************************************************/
+static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr,
+ const void *fdt,
+ int node)
+{
+ int rc = 0;
+
+ assert(attr && fdt);
+
+ rc = fdtw_read_cells(fdt, node, "maj_ver", 1, &attr->major_version);
+ if (rc) {
+ ERROR("Missing SPCI major version in SPM core manifest.\n");
+ return -ENOENT;
+ }
+
+ rc = fdtw_read_cells(fdt, node, "min_ver", 1, &attr->minor_version);
+ if (rc) {
+ ERROR("Missing SPCI minor version in SPM core manifest.\n");
+ return -ENOENT;
+ }
+
+ rc = fdtw_read_cells(fdt, node, "runtime_el", 1, &attr->runtime_el);
+ if (rc) {
+ ERROR("Missing SPM core runtime EL in manifest.\n");
+ return -ENOENT;
+ }
+
+ rc = fdtw_read_cells(fdt, node, "exec_state", 1, &attr->exec_state);
+ if (rc)
+ NOTICE("Execution state not specified in SPM core manifest.\n");
+
+ rc = fdtw_read_cells(fdt, node, "binary_size", 1, &attr->binary_size);
+ if (rc)
+ NOTICE("Binary size not specified in SPM core manifest.\n");
+
+ rc = fdtw_read_cells(fdt, node, "load_address", 2, &attr->load_address);
+ if (rc)
+ NOTICE("Load address not specified in SPM core manifest.\n");
+
+ rc = fdtw_read_cells(fdt, node, "entrypoint", 2, &attr->entrypoint);
+ if (rc)
+ NOTICE("Entrypoint not specified in SPM core manifest.\n");
+
+ VERBOSE("SPM core manifest attribute section:\n");
+ VERBOSE(" version: %x.%x\n", attr->major_version, attr->minor_version);
+ VERBOSE(" runtime_el: 0x%x\n", attr->runtime_el);
+ VERBOSE(" binary_size: 0x%x\n", attr->binary_size);
+ VERBOSE(" load_address: 0x%llx\n", attr->load_address);
+ VERBOSE(" entrypoint: 0x%llx\n", attr->entrypoint);
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Root node handler
+ ******************************************************************************/
+static int manifest_parse_root(spmc_manifest_sect_attribute_t *manifest,
+ const void *fdt,
+ int root)
+{
+ int node;
+ char *str;
+
+ str = "attribute";
+ node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str));
+ if (node < 0) {
+ ERROR("Root node doesn't contain subnode '%s'\n", str);
+ return -ENOENT;
+ }
+
+ return manifest_parse_attribute(manifest, fdt, node);
+}
+
+/*******************************************************************************
+ * Platform handler to parse a SPM core manifest.
+ ******************************************************************************/
+int plat_spm_core_manifest_load(spmc_manifest_sect_attribute_t *manifest,
+ const void *ptr,
+ size_t size)
+{
+ int rc;
+ int root_node;
+
+ assert(manifest != NULL);
+ assert(ptr != NULL);
+
+ INFO("Reading SPM core manifest at address %p\n", ptr);
+
+ rc = fdt_check_header(ptr);
+ if (rc != 0) {
+ ERROR("Wrong format for SPM core manifest (%d).\n", rc);
+ return -EINVAL;
+ }
+
+ INFO("Reading SPM core manifest at address %p\n", ptr);
+
+ root_node = fdt_node_offset_by_compatible(ptr, -1,
+ "arm,spci-core-manifest-1.0");
+ if (root_node < 0) {
+ ERROR("Unrecognized SPM core manifest\n");
+ return -ENOENT;
+ }
+
+ INFO("Reading SPM core manifest at address %p\n", ptr);
+ return manifest_parse_root(manifest, ptr, root_node);
+}
diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c
index 375483dd44..4b11440955 100644
--- a/plat/intel/soc/agilex/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex/bl31_plat_setup.c
@@ -11,8 +11,11 @@
#include <common/bl_common.h>
#include <drivers/arm/gicv2.h>
#include <drivers/ti/uart/uart_16550.h>
+#include <lib/mmio.h>
#include <lib/xlat_tables/xlat_tables.h>
+#include "socfpga_mailbox.h"
+#include "socfpga_private.h"
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
@@ -44,23 +47,33 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
void *from_bl2 = (void *) arg0;
bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
-
assert(params_from_bl2 != NULL);
- assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
- assert(params_from_bl2->h.version >= VERSION_2);
/*
* Copy BL32 (if populated by BL31) and BL33 entry point information.
* They are stored in Secure RAM, in BL31's address space.
*/
- bl_params_node_t *bl_params = params_from_bl2->head;
+ if (params_from_bl2->h.type == PARAM_BL_PARAMS &&
+ params_from_bl2->h.version >= VERSION_2) {
+
+ bl_params_node_t *bl_params = params_from_bl2->head;
+
+ while (bl_params) {
+ if (bl_params->image_id == BL33_IMAGE_ID)
+ bl33_image_ep_info = *bl_params->ep_info;
- while (bl_params) {
- if (bl_params->image_id == BL33_IMAGE_ID)
- bl33_image_ep_info = *bl_params->ep_info;
+ bl_params = bl_params->next_params_info;
+ }
+ } else {
+ struct socfpga_bl31_params *arg_from_bl2 =
+ (struct socfpga_bl31_params *) from_bl2;
- bl_params = bl_params->next_params_info;
+ assert(arg_from_bl2->h.type == PARAM_BL31);
+ assert(arg_from_bl2->h.version >= VERSION_1);
+
+ bl32_image_ep_info = *arg_from_bl2->bl32_ep_info;
+ bl33_image_ep_info = *arg_from_bl2->bl33_ep_info;
}
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
}
@@ -91,6 +104,12 @@ void bl31_platform_setup(void)
gicv2_distif_init();
gicv2_pcpu_distif_init();
gicv2_cpuif_enable();
+
+ /* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */
+ mmio_write_64(PLAT_CPU_RELEASE_ADDR,
+ (uint64_t)plat_secondary_cpus_bl31_entry);
+
+ mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
}
const mmap_region_t plat_agilex_mmap[] = {
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index c4b9e59671..38f46963a4 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -73,6 +73,29 @@
/* Mailbox REBOOT commands */
#define MBOX_CMD_REBOOT_HPS 71
+/* Mailbox RSU commands */
+#define MBOX_GET_SUBPARTITION_TABLE 90
+#define MBOX_RSU_STATUS 91
+#define MBOX_RSU_UPDATE 92
+
+/* Mailbox RSU macros */
+#define RSU_VERSION_ACMF BIT(8)
+#define RSU_VERSION_ACMF_MASK 0xff00
+
+/* HPS stage notify command */
+#define MBOX_HPS_STAGE_NOTIFY 93
+
+/* Execution states for HPS_STAGE_NOTIFY */
+#define HPS_EXECUTION_STATE_FSBL 0
+#define HPS_EXECUTION_STATE_SSBL 1
+#define HPS_EXECUTION_STATE_OS 2
+
+/* Mailbox reconfiguration commands */
+#define MBOX_CONFIG_STATUS 4
+#define MBOX_RECONFIG 6
+#define MBOX_RECONFIG_DATA 8
+#define MBOX_RECONFIG_STATUS 9
+
/* Generic error handling */
#define MBOX_TIMEOUT -2047
#define MBOX_NO_RESPONSE -2
@@ -98,13 +121,6 @@
#define MBOX_CFGSTAT_STATE_ERROR_BOOT_INFO 0xf0000007
#define MBOX_CFGSTAT_STATE_ERROR_QSPI_ERROR 0xf0000008
-/* Mailbox reconfiguration commands */
-#define MBOX_CONFIG_STATUS 4
-#define MBOX_RECONFIG 6
-#define MBOX_RECONFIG_DATA 8
-#define MBOX_RECONFIG_STATUS 9
-
-
void mailbox_set_int(int interrupt_input);
int mailbox_init(void);
void mailbox_set_qspi_close(void);
@@ -122,4 +138,9 @@ void mailbox_clear_response(void);
uint32_t intel_mailbox_get_config_status(uint32_t cmd);
int intel_mailbox_is_fpga_not_ready(void);
+int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len);
+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);
+
#endif /* SOCFPGA_MBOX_H */
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index 6bb41f31b6..2b1d9837ce 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -28,6 +28,7 @@
#define INTEL_SIP_LEGACY_SMC_ECC_DBE 0xC200000D
#define INTEL_SIP_SMC_RSU_NOTIFY 0xC200000E
#define INTEL_SIP_SMC_RSU_RETRY_COUNTER 0xC200000F
+#define INTEL_SIP_SMC_MBOX_SEND_CMD 0xC200001E
/* FPGA config helpers */
#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x400000
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index 8d7c1d6638..673c2d56e1 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -267,6 +267,55 @@ void mailbox_reset_cold(void)
mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0, 0, 0, NULL, 0);
}
+int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len)
+{
+ return mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_SUBPARTITION_TABLE,
+ NULL, 0, 0, (uint32_t *)resp_buf,
+ resp_buf_len);
+}
+
+struct rsu_status_info {
+ uint64_t current_image;
+ uint64_t fail_image;
+ uint32_t state;
+ uint32_t version;
+ uint32_t error_location;
+ uint32_t error_details;
+ uint32_t retry_counter;
+};
+
+int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len)
+{
+ int ret;
+ struct rsu_status_info *info = (struct rsu_status_info *)resp_buf;
+
+ info->retry_counter = ~0;
+
+ ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_STATUS, NULL, 0, 0,
+ (uint32_t *)resp_buf, resp_buf_len);
+
+ if (ret < 0)
+ return ret;
+
+ if (info->retry_counter != ~0)
+ if (!(info->version & RSU_VERSION_ACMF_MASK))
+ info->version |= RSU_VERSION_ACMF;
+
+ return ret;
+}
+
+int mailbox_rsu_update(uint32_t *flash_offset)
+{
+ return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE,
+ (uint32_t *)flash_offset, 2, 0, NULL, 0);
+}
+
+int mailbox_hps_stage_notify(uint32_t execution_stage)
+{
+ return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HPS_STAGE_NOTIFY,
+ &execution_stage, 1, 0, NULL, 0);
+}
+
int mailbox_init(void)
{
int status = 0;
diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c
index d8a6c19804..d27ab9f966 100644
--- a/plat/intel/soc/common/socfpga_psci.c
+++ b/plat/intel/soc/common/socfpga_psci.c
@@ -130,9 +130,14 @@ static void __dead2 socfpga_system_off(void)
panic();
}
+extern uint64_t intel_rsu_update_address;
+
static void __dead2 socfpga_system_reset(void)
{
- mailbox_reset_cold();
+ if (intel_rsu_update_address)
+ mailbox_rsu_update((uint32_t *)&intel_rsu_update_address);
+ else
+ mailbox_reset_cold();
while (1)
wfi();
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index 41dae9e763..5b600e5ea8 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -252,12 +252,16 @@ static bool is_fpga_config_buffer_full(void)
return true;
}
-static bool is_address_in_ddr_range(uint64_t addr)
+static bool is_address_in_ddr_range(uint64_t addr, uint64_t size)
{
- if (addr >= DRAM_BASE && addr <= DRAM_BASE + DRAM_SIZE)
- return true;
+ if (size > (UINT64_MAX - addr))
+ return false;
+ if (addr < DRAM_BASE)
+ return false;
+ if (addr + size > DRAM_BASE + DRAM_SIZE)
+ return false;
- return false;
+ return true;
}
static uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size)
@@ -266,8 +270,7 @@ static uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size)
intel_fpga_sdm_write_all();
- if (!is_address_in_ddr_range(mem) ||
- !is_address_in_ddr_range(mem + size) ||
+ if (!is_address_in_ddr_range(mem, size) ||
is_fpga_config_buffer_full())
return INTEL_SIP_SMC_STATUS_REJECTED;
@@ -365,6 +368,66 @@ uint32_t intel_secure_reg_update(uint64_t reg_addr, uint32_t mask,
return INTEL_SIP_SMC_STATUS_ERROR;
}
+/* Intel Remote System Update (RSU) services */
+uint64_t intel_rsu_update_address;
+
+static uint32_t intel_rsu_status(uint64_t *respbuf, uint32_t respbuf_sz)
+{
+ if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0)
+ return INTEL_SIP_SMC_STATUS_ERROR;
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static uint32_t intel_rsu_update(uint64_t update_address)
+{
+ intel_rsu_update_address = update_address;
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static uint32_t intel_rsu_notify(uint64_t execution_stage)
+{
+ if (mailbox_hps_stage_notify((uint32_t)execution_stage) < 0)
+ return INTEL_SIP_SMC_STATUS_ERROR;
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static uint32_t intel_rsu_retry_counter(uint32_t *respbuf, uint32_t respbuf_sz,
+ uint32_t *ret_stat)
+{
+ if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0)
+ return INTEL_SIP_SMC_STATUS_ERROR;
+
+ *ret_stat = respbuf[8];
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+/* Mailbox services */
+static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args, int len,
+ int urgent, uint32_t *response,
+ int resp_len, int *mbox_status,
+ int *len_in_resp)
+{
+ *len_in_resp = 0;
+ *mbox_status = 0;
+
+ if (!is_address_in_ddr_range((uint64_t)args, sizeof(uint32_t) * len))
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+
+ int status = mailbox_send_cmd(MBOX_JOB_ID, cmd, args, len, urgent,
+ response, resp_len);
+
+ if (status < 0) {
+ *mbox_status = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *mbox_status = 0;
+ *len_in_resp = status;
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
/*
* This function is responsible for handling all SiP calls from the NS world
*/
@@ -381,7 +444,10 @@ uintptr_t sip_smc_handler(uint32_t smc_fid,
uint32_t val = 0;
uint32_t status = INTEL_SIP_SMC_STATUS_OK;
uint32_t completed_addr[3];
+ uint64_t rsu_respbuf[9];
uint32_t count = 0;
+ u_register_t x5, x6;
+ int mbox_status, len_in_resp;
switch (smc_fid) {
case SIP_SVC_UID:
@@ -446,6 +512,41 @@ uintptr_t sip_smc_handler(uint32_t smc_fid,
(uint32_t)x3, &val);
SMC_RET3(handle, status, val, x1);
+ case INTEL_SIP_SMC_RSU_STATUS:
+ status = intel_rsu_status(rsu_respbuf,
+ ARRAY_SIZE(rsu_respbuf));
+ if (status) {
+ SMC_RET1(handle, status);
+ } else {
+ SMC_RET4(handle, rsu_respbuf[0], rsu_respbuf[1],
+ rsu_respbuf[2], rsu_respbuf[3]);
+ }
+
+ case INTEL_SIP_SMC_RSU_UPDATE:
+ status = intel_rsu_update(x1);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_RSU_NOTIFY:
+ status = intel_rsu_notify(x1);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_RSU_RETRY_COUNTER:
+ status = intel_rsu_retry_counter((uint32_t *)rsu_respbuf,
+ ARRAY_SIZE(rsu_respbuf), &val);
+ if (status) {
+ SMC_RET1(handle, status);
+ } else {
+ SMC_RET2(handle, status, val);
+ }
+
+ case INTEL_SIP_SMC_MBOX_SEND_CMD:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_mbox_send_cmd(x1, (uint32_t *)x2, x3, x4,
+ (uint32_t *)x5, x6, &mbox_status,
+ &len_in_resp);
+ SMC_RET4(handle, status, mbox_status, x5, len_in_resp);
+
default:
return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
cookie, handle, flags);
diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c
index 29f57c467b..4c3123815a 100644
--- a/plat/intel/soc/stratix10/bl31_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl31_plat_setup.c
@@ -16,6 +16,7 @@
#include <plat/common/platform.h>
#include <platform_def.h>
+#include "socfpga_mailbox.h"
#include "socfpga_private.h"
#include "socfpga_reset_manager.h"
#include "socfpga_system_manager.h"
@@ -115,6 +116,8 @@ void bl31_platform_setup(void)
/* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */
mmio_write_64(PLAT_CPU_RELEASE_ADDR,
(uint64_t)plat_secondary_cpus_bl31_entry);
+
+ mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
}
const mmap_region_t plat_stratix10_mmap[] = {
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c
index ae899c424e..eaf96751ce 100644
--- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c
+++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c
@@ -316,7 +316,7 @@ int tegra_bpmp_ipc_enable_clock(uint32_t clk_id)
/* prepare the MRQ_CLK command */
req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_ENABLE, clk_id);
- ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, sizeof(req),
+ ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, (uint32_t)sizeof(req),
NULL, 0);
if (ret != 0) {
ERROR("%s: failed for module %d with error %d\n", __func__,
@@ -339,7 +339,7 @@ int tegra_bpmp_ipc_disable_clock(uint32_t clk_id)
/* prepare the MRQ_CLK command */
req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_DISABLE, clk_id);
- ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, sizeof(req),
+ ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, (uint32_t)sizeof(req),
NULL, 0);
if (ret != 0) {
ERROR("%s: failed for module %d with error %d\n", __func__,
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h
index 7059c37016..d85b906b88 100644
--- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h
+++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h
@@ -1,17 +1,17 @@
/*
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef INTF_H
-#define INTF_H
+#ifndef BPMP_INTF_H
+#define BPMP_INTF_H
/**
* Flags used in IPC req
*/
#define FLAG_DO_ACK (U(1) << 0)
-#define FLAG_RING_DOORBELL (U(1) << 1)
+#define FLAG_RING_DOORBELL (U(1) << 1)
/* Bit 1 is designated for CCPlex in secure world */
#define HSP_MASTER_CCPLEX_BIT (U(1) << 1)
@@ -77,16 +77,16 @@ struct __attribute__((packed)) mrq_reset_request {
*
*/
enum {
- CMD_CLK_GET_RATE = 1,
- CMD_CLK_SET_RATE = 2,
- CMD_CLK_ROUND_RATE = 3,
- CMD_CLK_GET_PARENT = 4,
- CMD_CLK_SET_PARENT = 5,
- CMD_CLK_IS_ENABLED = 6,
- CMD_CLK_ENABLE = 7,
- CMD_CLK_DISABLE = 8,
- CMD_CLK_GET_ALL_INFO = 14,
- CMD_CLK_GET_MAX_CLK_ID = 15,
+ CMD_CLK_GET_RATE = U(1),
+ CMD_CLK_SET_RATE = U(2),
+ CMD_CLK_ROUND_RATE = U(3),
+ CMD_CLK_GET_PARENT = U(4),
+ CMD_CLK_SET_PARENT = U(5),
+ CMD_CLK_IS_ENABLED = U(6),
+ CMD_CLK_ENABLE = U(7),
+ CMD_CLK_DISABLE = U(8),
+ CMD_CLK_GET_ALL_INFO = U(14),
+ CMD_CLK_GET_MAX_CLK_ID = U(15),
CMD_CLK_MAX,
};
@@ -124,4 +124,4 @@ struct mrq_clk_request {
*/
#define make_mrq_clk_cmd(cmd, id) (((cmd) << 24) | (id & 0xFFFFFF))
-#endif /* INTF_H */
+#endif /* BPMP_INTF_H */
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h
index 42e6a1f7cc..1b318213b9 100644
--- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h
+++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2017-2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef IVC_H
-#define IVC_H
+#ifndef BPMP_IVC_H
+#define BPMP_IVC_H
#include <lib/utils_def.h>
#include <stdint.h>
@@ -15,22 +15,21 @@
#define IVC_CHHDR_TX_FIELDS U(16)
#define IVC_CHHDR_RX_FIELDS U(16)
-struct ivc;
struct ivc_channel_header;
-/* callback handler for notify on receiving a response */
-typedef void (* ivc_notify_function)(const struct ivc *);
-
struct ivc {
struct ivc_channel_header *rx_channel;
struct ivc_channel_header *tx_channel;
uint32_t w_pos;
uint32_t r_pos;
- ivc_notify_function notify;
+ void (*notify)(const struct ivc *);
uint32_t nframes;
uint32_t frame_size;
};
+/* callback handler for notify on receiving a response */
+typedef void (* ivc_notify_function)(const struct ivc *);
+
int32_t tegra_ivc_init(struct ivc *ivc, uintptr_t rx_base, uintptr_t tx_base,
uint32_t nframes, uint32_t frame_size,
ivc_notify_function notify);
@@ -48,4 +47,4 @@ bool tegra_ivc_tx_empty(const struct ivc *ivc);
bool tegra_ivc_can_write(const struct ivc *ivc);
bool tegra_ivc_can_read(const struct ivc *ivc);
-#endif /* IVC_H */
+#endif /* BPMP_IVC_H */
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
index 2f31906d83..c2ef981eed 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
+++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,17 +27,6 @@ static uint64_t video_mem_base;
static uint64_t video_mem_size_mb;
/*
- * The following platform setup functions are weakly defined. They
- * provide typical implementations that will be overridden by a SoC.
- */
-#pragma weak plat_memctrl_tzdram_setup
-
-void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
-{
- ; /* do nothing */
-}
-
-/*
* Init Memory controller during boot.
*/
void tegra_memctrl_setup(void)
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index cbe3377b0c..8a49e232db 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -65,35 +65,6 @@ static aapcs64_params_t bl32_args;
extern uint64_t ns_image_entrypoint;
/*******************************************************************************
- * The following platform setup functions are weakly defined. They
- * provide typical implementations that will be overridden by a SoC.
- ******************************************************************************/
-#pragma weak plat_early_platform_setup
-#pragma weak plat_get_bl31_params
-#pragma weak plat_get_bl31_plat_params
-#pragma weak plat_late_platform_setup
-
-void plat_early_platform_setup(void)
-{
- ; /* do nothing */
-}
-
-struct tegra_bl31_params *plat_get_bl31_params(void)
-{
- return NULL;
-}
-
-plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
-{
- return NULL;
-}
-
-void plat_late_platform_setup(void)
-{
- ; /* do nothing */
-}
-
-/*******************************************************************************
* Return a pointer to the 'entry_point_info' structure of the next image for
* security state specified. BL33 corresponds to the non-secure image type
* while BL32 corresponds to the secure image type.
@@ -137,8 +108,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
/*
* For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
* there's no argument to relay from a previous bootloader. Platforms
- * might use custom ways to get arguments, so provide handlers which
- * they can override.
+ * might use custom ways to get arguments.
*/
if (arg_from_bl2 == NULL) {
arg_from_bl2 = plat_get_bl31_params();
diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk
index 34b5638ecd..50c9592f17 100644
--- a/plat/nvidia/tegra/common/tegra_common.mk
+++ b/plat/nvidia/tegra/common/tegra_common.mk
@@ -25,7 +25,6 @@ BL31_SOURCES += drivers/delay_timer/delay_timer.c \
plat/common/aarch64/crash_console_helpers.S \
${TEGRA_GICv2_SOURCES} \
${COMMON_DIR}/aarch64/tegra_helpers.S \
- ${COMMON_DIR}/drivers/pmc/pmc.c \
${COMMON_DIR}/lib/debug/profiler.c \
${COMMON_DIR}/tegra_bl31_setup.c \
${COMMON_DIR}/tegra_delay_timer.c \
diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c
index 39dc42c5ba..1f59f30aad 100644
--- a/plat/nvidia/tegra/common/tegra_pm.c
+++ b/plat/nvidia/tegra/common/tegra_pm.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,97 +28,6 @@
extern uint64_t tegra_bl31_phys_base;
extern uint64_t tegra_sec_entry_point;
-/*
- * The following platform setup functions are weakly defined. They
- * provide typical implementations that will be overridden by a SoC.
- */
-#pragma weak tegra_soc_pwr_domain_suspend_pwrdown_early
-#pragma weak tegra_soc_cpu_standby
-#pragma weak tegra_soc_pwr_domain_suspend
-#pragma weak tegra_soc_pwr_domain_on
-#pragma weak tegra_soc_pwr_domain_off
-#pragma weak tegra_soc_pwr_domain_on_finish
-#pragma weak tegra_soc_pwr_domain_power_down_wfi
-#pragma weak tegra_soc_prepare_system_reset
-#pragma weak tegra_soc_prepare_system_off
-#pragma weak tegra_soc_get_target_pwr_state
-
-int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
-{
- return PSCI_E_NOT_SUPPORTED;
-}
-
-int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
-{
- (void)cpu_state;
- return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
-{
- (void)target_state;
- return PSCI_E_NOT_SUPPORTED;
-}
-
-int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
-{
- (void)mpidr;
- return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
-{
- (void)target_state;
- return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
-{
- (void)target_state;
- return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
-{
- (void)target_state;
- return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_prepare_system_reset(void)
-{
- return PSCI_E_SUCCESS;
-}
-
-__dead2 void tegra_soc_prepare_system_off(void)
-{
- ERROR("Tegra System Off: operation not handled.\n");
- panic();
-}
-
-plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
- const plat_local_state_t *states,
- uint32_t ncpu)
-{
- plat_local_state_t target = PLAT_MAX_OFF_STATE, temp;
- uint32_t num_cpu = ncpu;
- const plat_local_state_t *local_state = states;
-
- (void)lvl;
-
- assert(ncpu != 0U);
-
- do {
- temp = *local_state;
- if ((temp < target)) {
- target = temp;
- }
- --num_cpu;
- local_state++;
- } while (num_cpu != 0U);
-
- return target;
-}
-
/*******************************************************************************
* This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND`
* call to get the `power_state` parameter. This allows the platform to encode
@@ -311,10 +221,10 @@ __dead2 void tegra_system_reset(void)
/* per-SoC system reset handler */
(void)tegra_soc_prepare_system_reset();
- /*
- * Program the PMC in order to restart the system.
- */
- tegra_pmc_system_reset();
+ /* wait for the system to reset */
+ for (;;) {
+ ;
+ }
}
/*******************************************************************************
diff --git a/plat/nvidia/tegra/common/tegra_sip_calls.c b/plat/nvidia/tegra/common/tegra_sip_calls.c
index b8ba09562a..1d48cc01b4 100644
--- a/plat/nvidia/tegra/common/tegra_sip_calls.c
+++ b/plat/nvidia/tegra/common/tegra_sip_calls.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -26,32 +27,6 @@
#define TEGRA_SIP_FIQ_NS_GET_CONTEXT 0x82000006
/*******************************************************************************
- * SoC specific SiP handler
- ******************************************************************************/
-#pragma weak plat_sip_handler
-int32_t plat_sip_handler(uint32_t smc_fid,
- uint64_t x1,
- uint64_t x2,
- uint64_t x3,
- uint64_t x4,
- const void *cookie,
- void *handle,
- uint64_t flags)
-{
- /* unused parameters */
- (void)smc_fid;
- (void)x1;
- (void)x2;
- (void)x3;
- (void)x4;
- (void)cookie;
- (void)handle;
- (void)flags;
-
- return -ENOTSUP;
-}
-
-/*******************************************************************************
* This function is responsible for handling all SiP calls
******************************************************************************/
uintptr_t tegra_sip_handler(uint32_t smc_fid,
diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h
index dfed2aa60c..8e6c1fd2b8 100644
--- a/plat/nvidia/tegra/include/t132/tegra_def.h
+++ b/plat/nvidia/tegra/include/t132/tegra_def.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -110,4 +111,10 @@
#define TEGRA_TZRAM_BASE U(0x7C010000)
#define TEGRA_TZRAM_SIZE U(0x10000)
+/*******************************************************************************
+ * Tegra DRAM memory base address
+ ******************************************************************************/
+#define TEGRA_DRAM_BASE ULL(0x80000000)
+#define TEGRA_DRAM_END ULL(0x27FFFFFFF)
+
#endif /* TEGRA_DEF_H */
diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h
index da050a8952..f2a2334efe 100644
--- a/plat/nvidia/tegra/include/t186/tegra_def.h
+++ b/plat/nvidia/tegra/include/t186/tegra_def.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -279,4 +280,10 @@
#define TEGRA_TZRAM_BASE U(0x30000000)
#define TEGRA_TZRAM_SIZE U(0x40000)
+/*******************************************************************************
+ * Tegra DRAM memory base address
+ ******************************************************************************/
+#define TEGRA_DRAM_BASE ULL(0x80000000)
+#define TEGRA_DRAM_END ULL(0x27FFFFFFF)
+
#endif /* TEGRA_DEF_H */
diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h
index df1d656305..a58ae9d931 100644
--- a/plat/nvidia/tegra/include/t194/tegra_def.h
+++ b/plat/nvidia/tegra/include/t194/tegra_def.h
@@ -257,6 +257,12 @@
#define TEGRA_GPCDMA_RST_CLR_REG_OFFSET U(0x6A0008)
/*******************************************************************************
+ * Tegra DRAM memory base address
+ ******************************************************************************/
+#define TEGRA_DRAM_BASE ULL(0x80000000)
+#define TEGRA_DRAM_END ULL(0xFFFFFFFFF)
+
+/*******************************************************************************
* XUSB STREAMIDs
******************************************************************************/
#define TEGRA_SID_XUSB_HOST U(0x1b)
diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h
index bbcfdc5c12..4a39aa1fb1 100644
--- a/plat/nvidia/tegra/include/t210/tegra_def.h
+++ b/plat/nvidia/tegra/include/t210/tegra_def.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -268,4 +269,10 @@
#define TEGRA_TZRAM_CARVEOUT_BASE U(0x7C04C000)
#define TEGRA_TZRAM_CARVEOUT_SIZE U(0x4000)
+/*******************************************************************************
+ * Tegra DRAM memory base address
+ ******************************************************************************/
+#define TEGRA_DRAM_BASE ULL(0x80000000)
+#define TEGRA_DRAM_END ULL(0x27FFFFFFF)
+
#endif /* TEGRA_DEF_H */
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index 761acdea5e..b419d94e5a 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,12 +19,6 @@
#include <tegra_gic.h>
/*******************************************************************************
- * Tegra DRAM memory base address
- ******************************************************************************/
-#define TEGRA_DRAM_BASE ULL(0x80000000)
-#define TEGRA_DRAM_END ULL(0x27FFFFFFF)
-
-/*******************************************************************************
* Implementation defined ACTLR_EL1 bit definitions
******************************************************************************/
#define ACTLR_EL1_PMSTATE_MASK (ULL(0xF) << 0)
@@ -106,6 +101,7 @@ int32_t tegra_soc_pwr_domain_on(u_register_t mpidr);
int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state);
int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state);
int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state);
+int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state);
int32_t tegra_soc_prepare_system_reset(void);
__dead2 void tegra_soc_prepare_system_off(void);
plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
diff --git a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
index bd3f46fcca..0e2edf0969 100644
--- a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -35,6 +36,30 @@
static int cpu_powergate_mask[PLATFORM_MAX_CPUS_PER_CLUSTER];
+plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
+ const plat_local_state_t *states,
+ uint32_t ncpu)
+{
+ plat_local_state_t target = PLAT_MAX_OFF_STATE, temp;
+ uint32_t num_cpu = ncpu;
+ const plat_local_state_t *local_state = states;
+
+ (void)lvl;
+
+ assert(ncpu != 0U);
+
+ do {
+ temp = *local_state;
+ if ((temp < target)) {
+ target = temp;
+ }
+ --num_cpu;
+ local_state++;
+ } while (num_cpu != 0U);
+
+ return target;
+}
+
int32_t tegra_soc_validate_power_state(unsigned int power_state,
psci_power_state_t *req_state)
{
@@ -112,6 +137,12 @@ int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
return PSCI_E_SUCCESS;
}
+int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
+{
+ (void)cpu_state;
+ return PSCI_E_SUCCESS;
+}
+
int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
{
uint64_t val;
@@ -139,6 +170,16 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
return PSCI_E_SUCCESS;
}
+int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
+{
+ return PSCI_E_NOT_SUPPORTED;
+}
+
+int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
+{
+ return PSCI_E_SUCCESS;
+}
+
int tegra_soc_prepare_system_reset(void)
{
/*
@@ -152,5 +193,16 @@ int tegra_soc_prepare_system_reset(void)
/* Wait 1 ms to make sure clock source/device logic is stabilized. */
mdelay(1);
+ /*
+ * Program the PMC in order to restart the system.
+ */
+ tegra_pmc_system_reset();
+
return PSCI_E_SUCCESS;
}
+
+__dead2 void tegra_soc_prepare_system_off(void)
+{
+ ERROR("Tegra System Off: operation not handled.\n");
+ panic();
+}
diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c
index df62678970..2f54dd5253 100644
--- a/plat/nvidia/tegra/soc/t132/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t132/plat_setup.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -121,3 +122,35 @@ void plat_gic_setup(void)
tegra_gic_setup(NULL, 0);
tegra_gic_init();
}
+
+/*******************************************************************************
+ * Return pointer to the BL31 params from previous bootloader
+ ******************************************************************************/
+struct tegra_bl31_params *plat_get_bl31_params(void)
+{
+ return NULL;
+}
+
+/*******************************************************************************
+ * Return pointer to the BL31 platform params from previous bootloader
+ ******************************************************************************/
+plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
+{
+ return NULL;
+}
+
+/*******************************************************************************
+ * Handler for early platform setup
+ ******************************************************************************/
+void plat_early_platform_setup(void)
+{
+ ; /* do nothing */
+}
+
+/*******************************************************************************
+ * Handler for late platform setup
+ ******************************************************************************/
+void plat_late_platform_setup(void)
+{
+ ; /* do nothing */
+}
diff --git a/plat/nvidia/tegra/soc/t132/platform_t132.mk b/plat/nvidia/tegra/soc/t132/platform_t132.mk
index bb7b7ee661..183e1889cc 100644
--- a/plat/nvidia/tegra/soc/t132/platform_t132.mk
+++ b/plat/nvidia/tegra/soc/t132/platform_t132.mk
@@ -1,5 +1,6 @@
#
# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -23,6 +24,7 @@ BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
lib/cpus/aarch64/denver.S \
${COMMON_DIR}/drivers/flowctrl/flowctrl.c \
${COMMON_DIR}/drivers/memctrl/memctrl_v1.c \
+ ${COMMON_DIR}/drivers/pmc/pmc.c \
${SOC_DIR}/plat_psci_handlers.c \
${SOC_DIR}/plat_sip_calls.c \
${SOC_DIR}/plat_setup.c \
diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
index df943969e2..4ca5e77ad8 100644
--- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c
+++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
@@ -95,71 +95,71 @@ const static uint32_t tegra186_streamid_override_regs[] = {
******************************************************************************/
const static mc_streamid_security_cfg_t tegra186_streamid_sec_cfgs[] = {
mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(AFIR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(AFIW, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(AFIR, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(AFIW, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(XUSB_DEVR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, ENABLE),
+ mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(AXISW, SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
+ mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(GPUSWR2, SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(SDMMCWAA, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(SDMMCWAA, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(GPUSRD, SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+ mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(SCEDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(ISPWA, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(XUSB_HOSTW, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(SDMMCRAA, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(SDMMCRAA, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(VIW, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(AXISR, SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(ISPRA, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+ mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(XUSB_DEVW, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(NVDECSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(MPCOREW, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(MPCOREW, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(BPMPDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+ mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(NVDECSRD1, NON_SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(SCER, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(XUSB_HOSTR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(BPMPR, NON_SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+ mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(GPUSWR, SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, ENABLE),
+ mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(ISPWB, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(GPUSRD2, SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
index 11394c0ce4..2000e53fd6 100644
--- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -83,6 +84,12 @@ int32_t tegra_soc_validate_power_state(uint32_t power_state,
return ret;
}
+int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
+{
+ (void)cpu_state;
+ return PSCI_E_SUCCESS;
+}
+
int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
{
const plat_local_state_t *pwr_domain_state;
@@ -289,6 +296,11 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta
return PSCI_E_SUCCESS;
}
+int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
+{
+ return PSCI_E_NOT_SUPPORTED;
+}
+
int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
{
int32_t ret = PSCI_E_SUCCESS;
diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c
index 1018caa946..7e18b5c421 100644
--- a/plat/nvidia/tegra/soc/t186/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t186/plat_setup.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -193,6 +194,14 @@ void plat_early_platform_setup(void)
}
}
+/*******************************************************************************
+ * Handler for late platform setup
+ ******************************************************************************/
+void plat_late_platform_setup(void)
+{
+ ; /* do nothing */
+}
+
/* Secure IRQs for Tegra186 */
static const interrupt_prop_t tegra186_interrupt_props[] = {
INTR_PROP_DESC(TEGRA186_TOP_WDT_IRQ, GIC_HIGHEST_SEC_PRIORITY,
diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h
index ccc46655ab..9ccb823825 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h
@@ -19,123 +19,124 @@
* occur when there is only new functionality.
*/
enum {
- TEGRA_NVG_VERSION_MAJOR = 6,
- TEGRA_NVG_VERSION_MINOR = 6
+ TEGRA_NVG_VERSION_MAJOR = U(6),
+ TEGRA_NVG_VERSION_MINOR = U(6)
};
typedef enum {
- TEGRA_NVG_CHANNEL_VERSION = 0,
- TEGRA_NVG_CHANNEL_POWER_PERF = 1,
- TEGRA_NVG_CHANNEL_POWER_MODES = 2,
- TEGRA_NVG_CHANNEL_WAKE_TIME = 3,
- TEGRA_NVG_CHANNEL_CSTATE_INFO = 4,
- TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND = 5,
- TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND = 6,
- TEGRA_NVG_CHANNEL_CROSSOVER_CG7_LOWER_BOUND = 8,
- TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_REQUEST = 10,
- TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_VALUE = 11,
- TEGRA_NVG_CHANNEL_NUM_CORES = 20,
- TEGRA_NVG_CHANNEL_UNIQUE_LOGICAL_ID = 21,
- TEGRA_NVG_CHANNEL_LOGICAL_TO_PHYSICAL_MAPPING = 22,
- TEGRA_NVG_CHANNEL_LOGICAL_TO_MPIDR = 23,
- TEGRA_NVG_CHANNEL_SHUTDOWN = 42,
- TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED = 43,
- TEGRA_NVG_CHANNEL_ONLINE_CORE = 44,
- TEGRA_NVG_CHANNEL_CC3_CTRL = 45,
- TEGRA_NVG_CHANNEL_CCPLEX_CACHE_CONTROL = 49,
- TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC = 50,
- TEGRA_NVG_CHANNEL_HSM_ERROR_CTRL = 53,
- TEGRA_NVG_CHANNEL_SECURITY_CONFIG = 54,
- TEGRA_NVG_CHANNEL_DEBUG_CONFIG = 55,
- TEGRA_NVG_CHANNEL_DDA_SNOC_MCF = 56,
- TEGRA_NVG_CHANNEL_DDA_MCF_ORD1 = 57,
- TEGRA_NVG_CHANNEL_DDA_MCF_ORD2 = 58,
- TEGRA_NVG_CHANNEL_DDA_MCF_ORD3 = 59,
- TEGRA_NVG_CHANNEL_DDA_MCF_ISO = 60,
- TEGRA_NVG_CHANNEL_DDA_MCF_SISO = 61,
- TEGRA_NVG_CHANNEL_DDA_MCF_NISO = 62,
- TEGRA_NVG_CHANNEL_DDA_MCF_NISO_REMOTE = 63,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_ISO = 64,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_SISO = 65,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO = 66,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO_REMOTE = 67,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3FILL = 68,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3WR = 69,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_L3RD_DMA = 70,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_MCFRD_DMA = 71,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_GLOBAL = 72,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_LL = 73,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3D = 74,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_RD = 75,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_WR = 76,
- TEGRA_NVG_CHANNEL_DDA_SNOC_GLOBAL_CTRL = 77,
- TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REQ_CTRL = 78,
- TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REPLENTISH_CTRL = 79,
+ TEGRA_NVG_CHANNEL_VERSION = U(0),
+ TEGRA_NVG_CHANNEL_POWER_PERF = U(1),
+ TEGRA_NVG_CHANNEL_POWER_MODES = U(2),
+ TEGRA_NVG_CHANNEL_WAKE_TIME = U(3),
+ TEGRA_NVG_CHANNEL_CSTATE_INFO = U(4),
+ TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND = U(5),
+ TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND = U(6),
+ TEGRA_NVG_CHANNEL_CROSSOVER_CG7_LOWER_BOUND = U(8),
+ TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_REQUEST = U(10),
+ TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_VALUE = U(11),
+ TEGRA_NVG_CHANNEL_NUM_CORES = U(20),
+ TEGRA_NVG_CHANNEL_UNIQUE_LOGICAL_ID = U(21),
+ TEGRA_NVG_CHANNEL_LOGICAL_TO_PHYSICAL_MAPPING = U(22),
+ TEGRA_NVG_CHANNEL_LOGICAL_TO_MPIDR = U(23),
+ TEGRA_NVG_CHANNEL_SHUTDOWN = U(42),
+ TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED = U(43),
+ TEGRA_NVG_CHANNEL_ONLINE_CORE = U(44),
+ TEGRA_NVG_CHANNEL_CC3_CTRL = U(45),
+ TEGRA_NVG_CHANNEL_CCPLEX_CACHE_CONTROL = U(49),
+ TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC = U(50),
+ TEGRA_NVG_CHANNEL_HSM_ERROR_CTRL = U(53),
+ TEGRA_NVG_CHANNEL_SECURITY_CONFIG = U(54),
+ TEGRA_NVG_CHANNEL_DEBUG_CONFIG = U(55),
+ TEGRA_NVG_CHANNEL_DDA_SNOC_MCF = U(56),
+ TEGRA_NVG_CHANNEL_DDA_MCF_ORD1 = U(57),
+ TEGRA_NVG_CHANNEL_DDA_MCF_ORD2 = U(58),
+ TEGRA_NVG_CHANNEL_DDA_MCF_ORD3 = U(59),
+ TEGRA_NVG_CHANNEL_DDA_MCF_ISO = U(60),
+ TEGRA_NVG_CHANNEL_DDA_MCF_SISO = U(61),
+ TEGRA_NVG_CHANNEL_DDA_MCF_NISO = U(62),
+ TEGRA_NVG_CHANNEL_DDA_MCF_NISO_REMOTE = U(63),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_ISO = U(64),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_SISO = U(65),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO = U(66),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO_REMOTE = U(67),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3FILL = U(68),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3WR = U(69),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_L3RD_DMA = U(70),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_MCFRD_DMA = U(71),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_GLOBAL = U(72),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_LL = U(73),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3D = U(74),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_RD = U(75),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_WR = U(76),
+ TEGRA_NVG_CHANNEL_DDA_SNOC_GLOBAL_CTRL = U(77),
+ TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REQ_CTRL = U(78),
+ TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REPLENTISH_CTRL = U(79),
TEGRA_NVG_CHANNEL_LAST_INDEX
} tegra_nvg_channel_id_t;
typedef enum {
- NVG_STAT_QUERY_SC7_ENTRIES = 1,
- NVG_STAT_QUERY_CC6_ENTRIES = 6,
- NVG_STAT_QUERY_CG7_ENTRIES = 7,
- NVG_STAT_QUERY_C6_ENTRIES = 10,
- NVG_STAT_QUERY_C7_ENTRIES = 14,
- NVG_STAT_QUERY_SC7_RESIDENCY_SUM = 32,
- NVG_STAT_QUERY_CC6_RESIDENCY_SUM = 41,
- NVG_STAT_QUERY_CG7_RESIDENCY_SUM = 46,
- NVG_STAT_QUERY_C6_RESIDENCY_SUM = 51,
- NVG_STAT_QUERY_C7_RESIDENCY_SUM = 56,
- NVG_STAT_QUERY_SC7_ENTRY_TIME_SUM = 60,
- NVG_STAT_QUERY_CC6_ENTRY_TIME_SUM = 61,
- NVG_STAT_QUERY_CG7_ENTRY_TIME_SUM = 62,
- NVG_STAT_QUERY_C6_ENTRY_TIME_SUM = 63,
- NVG_STAT_QUERY_C7_ENTRY_TIME_SUM = 64,
- NVG_STAT_QUERY_SC7_EXIT_TIME_SUM = 70,
- NVG_STAT_QUERY_CC6_EXIT_TIME_SUM = 71,
- NVG_STAT_QUERY_CG7_EXIT_TIME_SUM = 72,
- NVG_STAT_QUERY_C6_EXIT_TIME_SUM = 73,
- NVG_STAT_QUERY_C7_EXIT_TIME_SUM = 74,
- NVG_STAT_QUERY_SC7_ENTRY_LAST = 80,
- NVG_STAT_QUERY_CC6_ENTRY_LAST = 81,
- NVG_STAT_QUERY_CG7_ENTRY_LAST = 82,
- NVG_STAT_QUERY_C6_ENTRY_LAST = 83,
- NVG_STAT_QUERY_C7_ENTRY_LAST = 84,
- NVG_STAT_QUERY_SC7_EXIT_LAST = 90,
- NVG_STAT_QUERY_CC6_EXIT_LAST = 91,
- NVG_STAT_QUERY_CG7_EXIT_LAST = 92,
- NVG_STAT_QUERY_C6_EXIT_LAST = 93,
- NVG_STAT_QUERY_C7_EXIT_LAST = 94
+ NVG_STAT_QUERY_SC7_ENTRIES = U(1),
+ NVG_STAT_QUERY_CC6_ENTRIES = U(6),
+ NVG_STAT_QUERY_CG7_ENTRIES = U(7),
+ NVG_STAT_QUERY_C6_ENTRIES = U(10),
+ NVG_STAT_QUERY_C7_ENTRIES = U(14),
+ NVG_STAT_QUERY_SC7_RESIDENCY_SUM = U(32),
+ NVG_STAT_QUERY_CC6_RESIDENCY_SUM = U(41),
+ NVG_STAT_QUERY_CG7_RESIDENCY_SUM = U(46),
+ NVG_STAT_QUERY_C6_RESIDENCY_SUM = U(51),
+ NVG_STAT_QUERY_C7_RESIDENCY_SUM = U(56),
+ NVG_STAT_QUERY_SC7_ENTRY_TIME_SUM = U(60),
+ NVG_STAT_QUERY_CC6_ENTRY_TIME_SUM = U(61),
+ NVG_STAT_QUERY_CG7_ENTRY_TIME_SUM = U(62),
+ NVG_STAT_QUERY_C6_ENTRY_TIME_SUM = U(63),
+ NVG_STAT_QUERY_C7_ENTRY_TIME_SUM = U(64),
+ NVG_STAT_QUERY_SC7_EXIT_TIME_SUM = U(70),
+ NVG_STAT_QUERY_CC6_EXIT_TIME_SUM = U(71),
+ NVG_STAT_QUERY_CG7_EXIT_TIME_SUM = U(72),
+ NVG_STAT_QUERY_C6_EXIT_TIME_SUM = U(73),
+ NVG_STAT_QUERY_C7_EXIT_TIME_SUM = U(74),
+ NVG_STAT_QUERY_SC7_ENTRY_LAST = U(80),
+ NVG_STAT_QUERY_CC6_ENTRY_LAST = U(81),
+ NVG_STAT_QUERY_CG7_ENTRY_LAST = U(82),
+ NVG_STAT_QUERY_C6_ENTRY_LAST = U(83),
+ NVG_STAT_QUERY_C7_ENTRY_LAST = U(84),
+ NVG_STAT_QUERY_SC7_EXIT_LAST = U(90),
+ NVG_STAT_QUERY_CC6_EXIT_LAST = U(91),
+ NVG_STAT_QUERY_CG7_EXIT_LAST = U(92),
+ NVG_STAT_QUERY_C6_EXIT_LAST = U(93),
+ NVG_STAT_QUERY_C7_EXIT_LAST = U(94)
+
} tegra_nvg_stat_query_t;
typedef enum {
- TEGRA_NVG_CORE_C0 = 0,
- TEGRA_NVG_CORE_C1 = 1,
- TEGRA_NVG_CORE_C6 = 6,
- TEGRA_NVG_CORE_C7 = 7,
- TEGRA_NVG_CORE_WARMRSTREQ = 8
+ TEGRA_NVG_CORE_C0 = U(0),
+ TEGRA_NVG_CORE_C1 = U(1),
+ TEGRA_NVG_CORE_C6 = U(6),
+ TEGRA_NVG_CORE_C7 = U(7),
+ TEGRA_NVG_CORE_WARMRSTREQ = U(8)
} tegra_nvg_core_sleep_state_t;
typedef enum {
- TEGRA_NVG_SHUTDOWN = 0U,
- TEGRA_NVG_REBOOT = 1U
+ TEGRA_NVG_SHUTDOWN = U(0),
+ TEGRA_NVG_REBOOT = U(1)
} tegra_nvg_shutdown_reboot_state_t;
typedef enum {
- TEGRA_NVG_CLUSTER_CC0 = 0,
- TEGRA_NVG_CLUSTER_AUTO_CC1 = 1,
- TEGRA_NVG_CLUSTER_CC6 = 6
+ TEGRA_NVG_CLUSTER_CC0 = U(0),
+ TEGRA_NVG_CLUSTER_AUTO_CC1 = U(1),
+ TEGRA_NVG_CLUSTER_CC6 = U(6)
} tegra_nvg_cluster_sleep_state_t;
typedef enum {
- TEGRA_NVG_CG_CG0 = 0,
- TEGRA_NVG_CG_CG7 = 7
+ TEGRA_NVG_CG_CG0 = U(0),
+ TEGRA_NVG_CG_CG7 = U(7)
} tegra_nvg_cluster_group_sleep_state_t;
typedef enum {
- TEGRA_NVG_SYSTEM_SC0 = 0,
- TEGRA_NVG_SYSTEM_SC7 = 7,
- TEGRA_NVG_SYSTEM_SC8 = 8
+ TEGRA_NVG_SYSTEM_SC0 = U(0),
+ TEGRA_NVG_SYSTEM_SC7 = U(7),
+ TEGRA_NVG_SYSTEM_SC8 = U(8)
} tegra_nvg_system_sleep_state_t;
// ---------------------------------------------------------------------------
@@ -145,95 +146,95 @@ typedef enum {
typedef union {
uint64_t flat;
struct nvg_version_channel_t {
- uint32_t minor_version : 32;
- uint32_t major_version : 32;
+ uint32_t minor_version : U(32);
+ uint32_t major_version : U(32);
} bits;
} nvg_version_data_t;
typedef union {
uint64_t flat;
struct nvg_power_perf_channel_t {
- uint32_t perf_per_watt : 1;
- uint32_t reserved_31_1 : 31;
- uint32_t reserved_63_32 : 32;
+ uint32_t perf_per_watt : U(1);
+ uint32_t reserved_31_1 : U(31);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_power_perf_channel_t;
typedef union {
uint64_t flat;
struct nvg_power_modes_channel_t {
- uint32_t low_battery : 1;
- uint32_t reserved_1_1 : 1;
- uint32_t battery_save : 1;
- uint32_t reserved_31_3 : 29;
- uint32_t reserved_63_32 : 32;
+ uint32_t low_battery : U(1);
+ uint32_t reserved_1_1 : U(1);
+ uint32_t battery_save : U(1);
+ uint32_t reserved_31_3 : U(29);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_power_modes_channel_t;
typedef union nvg_channel_1_data_u {
uint64_t flat;
struct nvg_channel_1_data_s {
- uint32_t perf_per_watt_mode : 1;
- uint32_t reserved_31_1 : 31;
- uint32_t reserved_63_32 : 32;
+ uint32_t perf_per_watt_mode : U(1);
+ uint32_t reserved_31_1 : U(31);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_channel_1_data_t;
typedef union {
uint64_t flat;
struct nvg_ccplex_cache_control_channel_t {
- uint32_t gpu_ways : 5;
- uint32_t reserved_7_5 : 3;
- uint32_t gpu_only_ways : 5;
- uint32_t reserved_31_13 : 19;
- uint32_t reserved_63_32 : 32;
+ uint32_t gpu_ways : U(5);
+ uint32_t reserved_7_5 : U(3);
+ uint32_t gpu_only_ways : U(5);
+ uint32_t reserved_31_13 : U(19);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_ccplex_cache_control_channel_t;
typedef union nvg_channel_2_data_u {
uint64_t flat;
struct nvg_channel_2_data_s {
- uint32_t reserved_1_0 : 2;
- uint32_t battery_saver_mode : 1;
- uint32_t reserved_31_3 : 29;
- uint32_t reserved_63_32 : 32;
+ uint32_t reserved_1_0 : U(2);
+ uint32_t battery_saver_mode : U(1);
+ uint32_t reserved_31_3 : U(29);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_channel_2_data_t;
typedef union {
uint64_t flat;
struct nvg_wake_time_channel_t {
- uint32_t wake_time : 32;
- uint32_t reserved_63_32 : 32;
+ uint32_t wake_time : U(32);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_wake_time_channel_t;
typedef union {
uint64_t flat;
struct nvg_cstate_info_channel_t {
- uint32_t cluster_state : 3;
- uint32_t reserved_6_3 : 4;
- uint32_t update_cluster : 1;
- uint32_t cg_cstate : 3;
- uint32_t reserved_14_11 : 4;
- uint32_t update_cg : 1;
- uint32_t system_cstate : 4;
- uint32_t reserved_22_20 : 3;
- uint32_t update_system : 1;
- uint32_t reserved_30_24 : 7;
- uint32_t update_wake_mask : 1;
+ uint32_t cluster_state : U(3);
+ uint32_t reserved_6_3 : U(4);
+ uint32_t update_cluster : U(1);
+ uint32_t cg_cstate : U(3);
+ uint32_t reserved_14_11 : U(4);
+ uint32_t update_cg : U(1);
+ uint32_t system_cstate : U(4);
+ uint32_t reserved_22_20 : U(3);
+ uint32_t update_system : U(1);
+ uint32_t reserved_30_24 : U(7);
+ uint32_t update_wake_mask : U(1);
union {
- uint32_t flat : 32;
+ uint32_t flat : U(32);
struct {
- uint32_t vfiq : 1;
- uint32_t virq : 1;
- uint32_t fiq : 1;
- uint32_t irq : 1;
- uint32_t serror : 1;
- uint32_t reserved_10_5 : 6;
- uint32_t fiqout : 1;
- uint32_t irqout : 1;
- uint32_t reserved_31_13 : 19;
+ uint32_t vfiq : U(1);
+ uint32_t virq : U(1);
+ uint32_t fiq : U(1);
+ uint32_t irq : U(1);
+ uint32_t serror : U(1);
+ uint32_t reserved_10_5 : U(6);
+ uint32_t fiqout : U(1);
+ uint32_t irqout : U(1);
+ uint32_t reserved_31_13 : U(19);
} carmel;
} wake_mask;
} bits;
@@ -242,183 +243,182 @@ typedef union {
typedef union {
uint64_t flat;
struct nvg_lower_bound_channel_t {
- uint32_t crossover_value : 32;
- uint32_t reserved_63_32 : 32;
+ uint32_t crossover_value : U(32);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_lower_bound_channel_t;
typedef union {
uint64_t flat;
struct nvg_cstate_stat_query_channel_t {
- uint32_t unit_id : 4;
- uint32_t reserved_15_4 : 12;
- uint32_t stat_id : 16;
- uint32_t reserved_63_32 : 32;
+ uint32_t unit_id : U(4);
+ uint32_t reserved_15_4 : U(12);
+ uint32_t stat_id : U(16);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_cstate_stat_query_channel_t;
typedef union {
uint64_t flat;
struct nvg_num_cores_channel_t {
- uint32_t num_cores : 4;
- uint32_t reserved_31_4 : 28;
- uint32_t reserved_63_32 : 32;
+ uint32_t num_cores : U(4);
+ uint32_t reserved_31_4 : U(28);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_num_cores_channel_t;
typedef union {
uint64_t flat;
struct nvg_unique_logical_id_channel_t {
- uint32_t unique_core_id : 3;
- uint32_t reserved_31_3 : 29;
- uint32_t reserved_63_32 : 32;
+ uint32_t unique_core_id : U(3);
+ uint32_t reserved_31_3 : U(29);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_unique_logical_id_channel_t;
typedef union {
uint64_t flat;
struct nvg_logical_to_physical_mappings_channel_t {
- uint32_t lcore0_pcore_id : 4;
- uint32_t lcore1_pcore_id : 4;
- uint32_t lcore2_pcore_id : 4;
- uint32_t lcore3_pcore_id : 4;
- uint32_t lcore4_pcore_id : 4;
- uint32_t lcore5_pcore_id : 4;
- uint32_t lcore6_pcore_id : 4;
- uint32_t lcore7_pcore_id : 4;
- uint32_t reserved_63_32 : 32;
+ uint32_t lcore0_pcore_id : U(4);
+ uint32_t lcore1_pcore_id : U(4);
+ uint32_t lcore2_pcore_id : U(4);
+ uint32_t lcore3_pcore_id : U(4);
+ uint32_t lcore4_pcore_id : U(4);
+ uint32_t lcore5_pcore_id : U(4);
+ uint32_t lcore6_pcore_id : U(4);
+ uint32_t lcore7_pcore_id : U(4);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_logical_to_physical_mappings_channel_t;
typedef union {
uint64_t flat;
struct nvg_logical_to_mpidr_channel_write_t {
- uint32_t lcore_id : 3;
- uint32_t reserved_31_3 : 29;
- uint32_t reserved_63_32 : 32;
+ uint32_t lcore_id : U(3);
+ uint32_t reserved_31_3 : U(29);
+ uint32_t reserved_63_32 : U(32);
} write;
struct nvg_logical_to_mpidr_channel_read_t {
- uint32_t mpidr : 32;
- uint32_t reserved_63_32 : 32;
+ uint32_t mpidr : U(32);
+ uint32_t reserved_63_32 : U(32);
} read;
} nvg_logical_to_mpidr_channel_t;
typedef union {
uint64_t flat;
struct nvg_is_sc7_allowed_channel_t {
- uint32_t is_sc7_allowed : 1;
- uint32_t reserved_31_1 : 31;
- uint32_t reserved_63_32 : 32;
+ uint32_t is_sc7_allowed : U(1);
+ uint32_t reserved_31_1 : U(31);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_is_sc7_allowed_channel_t;
typedef union {
uint64_t flat;
struct nvg_core_online_channel_t {
- uint32_t core_id : 4;
- uint32_t reserved_31_4 : 28;
- uint32_t reserved_63_32 : 32;
+ uint32_t core_id : U(4);
+ uint32_t reserved_31_4 : U(28);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_core_online_channel_t;
typedef union {
uint64_t flat;
struct nvg_cc3_control_channel_t {
- uint32_t freq_req : 9;
- uint32_t reserved_30_9 : 22;
- uint32_t enable : 1;
- uint32_t reserved_63_32 : 32;
+ uint32_t freq_req : U(9);
+ uint32_t reserved_30_9 : U(22);
+ uint32_t enable : U(1);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_cc3_control_channel_t;
typedef enum {
- TEGRA_NVG_CHANNEL_UPDATE_GSC_ALL = 0,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_NVDEC = 1,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR1 = 2,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR2 = 3,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECA = 4,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECB = 5,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP = 6,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_APE = 7,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_SPE = 8,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_SCE = 9,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_APR = 10,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_TZRAM = 11,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_TSEC = 12,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_RCE = 13,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_MCE = 14,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_SE_SC7 = 15,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_SPE = 16,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_RCE = 17,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_TZ_TO_BPMP = 18,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR1 = 19,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_NS_TO_BPMP = 20,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_OEM_SC7 = 21,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_SPE_SCE_BPMP = 22,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_SC7_RESUME_FW = 23,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_CAMERA_TASKLIST = 24,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_XUSB = 25,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_CV = 26,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR2 = 27,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_HYPERVISOR_SW = 28,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_SMMU_PAGETABLES = 29,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_30 = 30,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_31 = 31,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM = 32,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_NVLINK = 33,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_SBS = 34,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR = 35,
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_ALL = U(0),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_NVDEC = U(1),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR1 = U(2),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR2 = U(3),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECA = U(4),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECB = U(5),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP = U(6),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_APE = U(7),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_SPE = U(8),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_SCE = U(9),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_APR = U(10),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_TZRAM = U(11),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_TSEC = U(12),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_RCE = U(13),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_MCE = U(14),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_SE_SC7 = U(15),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_SPE = U(16),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_RCE = U(17),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_TZ_TO_BPMP = U(18),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR1 = U(19),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_NS_TO_BPMP = U(20),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_OEM_SC7 = U(21),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_SPE_SCE_BPMP = U(22),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_SC7_RESUME_FW = U(23),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_CAMERA_TASKLIST = U(24),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_XUSB = U(25),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_CV = U(26),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR2 = U(27),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_HYPERVISOR_SW = U(28),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_SMMU_PAGETABLES = U(29),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_30 = U(30),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_31 = U(31),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM = U(32),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_NVLINK = U(33),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_SBS = U(34),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR = U(35),
TEGRA_NVG_CHANNEL_UPDATE_GSC_LAST_INDEX
} tegra_nvg_channel_update_gsc_gsc_enum_t;
typedef union {
uint64_t flat;
struct nvg_update_ccplex_gsc_channel_t {
- uint32_t gsc_enum : 16;
- uint32_t reserved_31_16 : 16;
- uint32_t reserved_63_32 : 32;
+ uint32_t gsc_enum : U(16);
+ uint32_t reserved_31_16 : U(16);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_update_ccplex_gsc_channel_t;
typedef union {
uint64_t flat;
struct nvg_security_config_channel_t {
- uint32_t strict_checking_enabled : 1;
- uint32_t strict_checking_locked : 1;
- uint32_t reserved_31_2 : 30;
- uint32_t reserved_63_32 : 32;
+ uint32_t strict_checking_enabled : U(1);
+ uint32_t strict_checking_locked : U(1);
+ uint32_t reserved_31_2 : U(30);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_security_config_t;
typedef union {
uint64_t flat;
struct nvg_shutdown_channel_t {
- uint32_t reboot : 1;
- uint32_t reserved_31_1 : 31;
- uint32_t reserved_63_32 : 32;
+ uint32_t reboot : U(1);
+ uint32_t reserved_31_1 : U(31);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_shutdown_t;
typedef union {
uint64_t flat;
struct nvg_debug_config_channel_t {
- uint32_t enter_debug_state_on_mca : 1;
- uint32_t reserved_31_1 : 31;
- uint32_t reserved_63_32 : 32;
+ uint32_t enter_debug_state_on_mca : U(1);
+ uint32_t reserved_31_1 : U(31);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_debug_config_t;
typedef union {
uint64_t flat;
struct nvg_hsm_error_ctrl_channel_t {
- uint32_t uncorr : 1;
- uint32_t corr : 1;
- uint32_t reserved_31_2 : 30;
- uint32_t reserved_63_32 : 32;
+ uint32_t uncorr : U(1);
+ uint32_t corr : U(1);
+ uint32_t reserved_31_2 : U(30);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_hsm_error_ctrl_channel_t;
extern nvg_debug_config_t nvg_debug_config;
-#endif
-
+#endif /* T194_NVG_H */
diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
index 1012cdf113..ef740a143a 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
+++ b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
@@ -15,8 +15,8 @@
#include <t194_nvg.h>
#include <tegra_private.h>
-#define ID_AFR0_EL1_CACHE_OPS_SHIFT 12
-#define ID_AFR0_EL1_CACHE_OPS_MASK 0xFU
+#define ID_AFR0_EL1_CACHE_OPS_SHIFT U(12)
+#define ID_AFR0_EL1_CACHE_OPS_MASK U(0xF)
/*
* Reports the major and minor version of this interface.
*
@@ -209,7 +209,7 @@ void nvg_enable_strict_checking_mode(void)
uint64_t params = (uint64_t)(STRICT_CHECKING_ENABLED_SET |
STRICT_CHECKING_LOCKED_SET);
- nvg_set_request_data(TEGRA_NVG_CHANNEL_SECURITY_CONFIG, params);
+ nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SECURITY_CONFIG, params);
}
#endif
@@ -221,7 +221,8 @@ void nvg_enable_strict_checking_mode(void)
void nvg_system_reboot(void)
{
/* issue command for reboot */
- nvg_set_request_data(TEGRA_NVG_CHANNEL_SHUTDOWN, TEGRA_NVG_REBOOT);
+ nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SHUTDOWN,
+ (uint64_t)TEGRA_NVG_REBOOT);
}
/*
@@ -232,5 +233,6 @@ void nvg_system_reboot(void)
void nvg_system_shutdown(void)
{
/* issue command for shutdown */
- nvg_set_request_data(TEGRA_NVG_CHANNEL_SHUTDOWN, TEGRA_NVG_SHUTDOWN);
+ nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SHUTDOWN,
+ (uint64_t)TEGRA_NVG_SHUTDOWN);
}
diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se.c b/plat/nvidia/tegra/soc/t194/drivers/se/se.c
index 3a2e959d0d..a3b3389401 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/se/se.c
+++ b/plat/nvidia/tegra/soc/t194/drivers/se/se.c
@@ -15,6 +15,7 @@
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
#include <lib/psci/psci.h>
+#include <se.h>
#include <tegra_platform.h>
#include "se_private.h"
@@ -54,7 +55,7 @@ static bool tegra_se_is_operation_complete(void)
*/
do {
val = tegra_se_read_32(CTX_SAVE_AUTO_STATUS);
- se_is_busy = !!(val & CTX_SAVE_AUTO_SE_BUSY);
+ se_is_busy = ((val & CTX_SAVE_AUTO_SE_BUSY) != 0U);
/* sleep until SE finishes */
if (se_is_busy) {
@@ -186,7 +187,8 @@ int32_t tegra_se_suspend(void)
assert(tegra_bpmp_ipc_init() == 0);
/* Enable SE clock before SE context save */
- tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE);
+ ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE);
+ assert(ret == 0);
/* save SE registers */
se_regs[0] = mmio_read_32(TEGRA_SE0_BASE + SE0_MUTEX_WATCHDOG_NS_LIMIT);
@@ -201,7 +203,8 @@ int32_t tegra_se_suspend(void)
}
/* Disable SE clock after SE context save */
- tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE);
+ ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE);
+ assert(ret == 0);
return ret;
}
@@ -211,11 +214,14 @@ int32_t tegra_se_suspend(void)
*/
void tegra_se_resume(void)
{
+ int32_t ret = 0;
+
/* initialise communication channel with BPMP */
assert(tegra_bpmp_ipc_init() == 0);
/* Enable SE clock before SE context restore */
- tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE);
+ ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE);
+ assert(ret == 0);
/*
* When TZ takes over after System Resume, TZ should first reconfigure
@@ -229,5 +235,6 @@ void tegra_se_resume(void)
mmio_write_32(TEGRA_PKA1_BASE + PKA1_MUTEX_WATCHDOG_NS_LIMIT, se_regs[3]);
/* Disable SE clock after SE context restore */
- tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE);
+ ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE);
+ assert(ret == 0);
}
diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
index a2c5d1c381..577217b8e7 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
@@ -74,12 +74,12 @@
static inline uint32_t tegra_se_read_32(uint32_t offset)
{
- return mmio_read_32(TEGRA_SE0_BASE + offset);
+ return mmio_read_32((uint32_t)(TEGRA_SE0_BASE + offset));
}
static inline void tegra_se_write_32(uint32_t offset, uint32_t val)
{
- mmio_write_32(TEGRA_SE0_BASE + offset, val);
+ mmio_write_32((uint32_t)(TEGRA_SE0_BASE + offset), val);
}
#endif /* SE_PRIVATE_H */
diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
index cc8be128a7..144e41885d 100644
--- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
@@ -44,14 +44,6 @@ static struct t19x_psci_percpu_data {
uint32_t wake_time;
} __aligned(CACHE_WRITEBACK_GRANULE) t19x_percpu_data[PLATFORM_CORE_COUNT];
-/*
- * tegra_fake_system_suspend acts as a boolean var controlling whether
- * we are going to take fake system suspend code or normal system suspend code
- * path. This variable is set inside the sip call handlers, when the kernel
- * requests an SIP call to set the suspend debug flags.
- */
-bool tegra_fake_system_suspend;
-
int32_t tegra_soc_validate_power_state(uint32_t power_state,
psci_power_state_t *req_state)
{
@@ -171,30 +163,27 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
assert(ret == 0);
}
- if (!tegra_fake_system_suspend) {
-
- /* Prepare for system suspend */
- mce_update_cstate_info(&sc7_cstate_info);
+ /* Prepare for system suspend */
+ mce_update_cstate_info(&sc7_cstate_info);
- do {
- val = (uint32_t)mce_command_handler(
- (uint32_t)MCE_CMD_IS_SC7_ALLOWED,
- (uint32_t)TEGRA_NVG_CORE_C7,
- MCE_CORE_SLEEP_TIME_INFINITE,
- 0U);
- } while (val == 0U);
-
- /* Instruct the MCE to enter system suspend state */
- ret = mce_command_handler(
- (uint64_t)MCE_CMD_ENTER_CSTATE,
- (uint64_t)TEGRA_NVG_CORE_C7,
+ do {
+ val = (uint32_t)mce_command_handler(
+ (uint32_t)MCE_CMD_IS_SC7_ALLOWED,
+ (uint32_t)TEGRA_NVG_CORE_C7,
MCE_CORE_SLEEP_TIME_INFINITE,
0U);
- assert(ret == 0);
-
- /* set system suspend state for house-keeping */
- tegra194_set_system_suspend_entry();
- }
+ } while (val == 0U);
+
+ /* Instruct the MCE to enter system suspend state */
+ ret = mce_command_handler(
+ (uint64_t)MCE_CMD_ENTER_CSTATE,
+ (uint64_t)TEGRA_NVG_CORE_C7,
+ MCE_CORE_SLEEP_TIME_INFINITE,
+ 0U);
+ assert(ret == 0);
+
+ /* set system suspend state for house-keeping */
+ tegra194_set_system_suspend_entry();
} else {
; /* do nothing */
}
@@ -301,7 +290,6 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta
uint8_t stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
TEGRA194_STATE_ID_MASK;
uint64_t val;
- u_register_t ns_sctlr_el1;
if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
/*
@@ -313,35 +301,16 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta
tegra194_get_cpu_reset_handler_size();
memcpy((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE,
(uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE);
-
- /*
- * In fake suspend mode, ensure that the loopback procedure
- * towards system suspend exit is started, instead of calling
- * WFI. This is done by disabling both MMU's of EL1 & El3
- * and calling tegra_secure_entrypoint().
- */
- if (tegra_fake_system_suspend) {
-
- /*
- * Disable EL1's MMU.
- */
- ns_sctlr_el1 = read_sctlr_el1();
- ns_sctlr_el1 &= (~((u_register_t)SCTLR_M_BIT));
- write_sctlr_el1(ns_sctlr_el1);
-
- /*
- * Disable MMU to power up the CPU in a "clean"
- * state
- */
- disable_mmu_el3();
- tegra_secure_entrypoint();
- panic();
- }
}
return PSCI_E_SUCCESS;
}
+int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
+{
+ return PSCI_E_NOT_SUPPORTED;
+}
+
int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
{
uint64_t target_cpu = mpidr & MPIDR_CPU_MASK;
diff --git a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
index 8873358cd7..33694a16da 100644
--- a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,12 +18,9 @@
#include <tegra_platform.h>
#include <stdbool.h>
-extern bool tegra_fake_system_suspend;
-
/*******************************************************************************
* Tegra194 SiP SMCs
******************************************************************************/
-#define TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND 0xC2FFFE03U
/*******************************************************************************
* This function is responsible for handling all T194 SiP calls
@@ -39,25 +36,11 @@ int32_t plat_sip_handler(uint32_t smc_fid,
{
int32_t ret = -ENOTSUP;
+ (void)smc_fid;
(void)x1;
(void)x4;
(void)cookie;
(void)flags;
- if (smc_fid == TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND) {
- /*
- * System suspend mode is set if the platform ATF is
- * running on VDK and there is a debug SIP call. This mode
- * ensures that the debug path is exercised, instead of
- * regular code path to suit the pre-silicon platform needs.
- * This includes replacing the call to WFI, with calls to
- * system suspend exit procedures.
- */
- if (tegra_platform_is_virt_dev_kit()) {
- tegra_fake_system_suspend = true;
- ret = 0;
- }
- }
-
return ret;
}
diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
index 12241c2f3f..4ef9558eec 100644
--- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -184,6 +185,12 @@ plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
return target;
}
+int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
+{
+ (void)cpu_state;
+ return PSCI_E_SUCCESS;
+}
+
int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
{
u_register_t mpidr = read_mpidr();
@@ -412,6 +419,11 @@ int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
return PSCI_E_SUCCESS;
}
+int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
+{
+ return PSCI_E_NOT_SUPPORTED;
+}
+
int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
@@ -567,5 +579,16 @@ int tegra_soc_prepare_system_reset(void)
/* Wait 1 ms to make sure clock source/device logic is stabilized. */
mdelay(1);
+ /*
+ * Program the PMC in order to restart the system.
+ */
+ tegra_pmc_system_reset();
+
return PSCI_E_SUCCESS;
}
+
+__dead2 void tegra_soc_prepare_system_off(void)
+{
+ ERROR("Tegra System Off: operation not handled.\n");
+ panic();
+}
diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c
index bfa818419f..da1f1b33eb 100644
--- a/plat/nvidia/tegra/soc/t210/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t210/plat_setup.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -141,6 +142,22 @@ void plat_enable_console(int32_t id)
}
/*******************************************************************************
+ * Return pointer to the BL31 params from previous bootloader
+ ******************************************************************************/
+struct tegra_bl31_params *plat_get_bl31_params(void)
+{
+ return NULL;
+}
+
+/*******************************************************************************
+ * Return pointer to the BL31 platform params from previous bootloader
+ ******************************************************************************/
+plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
+{
+ return NULL;
+}
+
+/*******************************************************************************
* Handler for early platform setup
******************************************************************************/
void plat_early_platform_setup(void)
@@ -168,6 +185,9 @@ static const interrupt_prop_t tegra210_interrupt_props[] = {
GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
};
+/*******************************************************************************
+ * Handler for late platform setup
+ ******************************************************************************/
void plat_late_platform_setup(void)
{
const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk
index a11aef4dd2..4f2db53864 100644
--- a/plat/nvidia/tegra/soc/t210/platform_t210.mk
+++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk
@@ -1,5 +1,6 @@
#
# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -33,6 +34,7 @@ BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
${COMMON_DIR}/drivers/bpmp/bpmp.c \
${COMMON_DIR}/drivers/flowctrl/flowctrl.c \
${COMMON_DIR}/drivers/memctrl/memctrl_v1.c \
+ ${COMMON_DIR}/drivers/pmc/pmc.c \
${SOC_DIR}/plat_psci_handlers.c \
${SOC_DIR}/plat_setup.c \
${SOC_DIR}/drivers/se/security_engine.c \
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index b95bf5a519..bc10569ba7 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -15,6 +15,7 @@ ifeq (${ARM_ARCH_MAJOR},7)
MARCH32_DIRECTIVE := -mcpu=cortex-a15
$(eval $(call add_define,ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING))
$(eval $(call add_define,ARMV7_SUPPORTS_GENERIC_TIMER))
+$(eval $(call add_define,ARMV7_SUPPORTS_VFP))
# Qemu expects a BL32 boot stage.
NEED_BL32 := yes
endif # ARMv7
diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h
index 7158bfaf3d..b87ac3fd6b 100644
--- a/plat/socionext/synquacer/include/platform_def.h
+++ b/plat/socionext/synquacer/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -80,7 +80,6 @@
#define DRAMINFO_BASE 0x2E00FFC0
#define PLAT_SQ_MHU_BASE 0x45000000
-#define PLAT_MHUV2_BASE 0xFFFFFFFF /* MHUV2 is not supported */
#define PLAT_SQ_SCP_COM_SHARED_MEM_BASE 0x45400000
#define SCPI_CMD_GET_DRAMINFO 0x1
diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c
index a3a9f43165..45b2803704 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, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -165,7 +165,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
{
uint32_t result[4] = {0};
- pm_get_callbackdata(result, sizeof(result));
+ pm_get_callbackdata(result, ARRAY_SIZE(result));
SMC_RET2(handle,
(uint64_t)result[0] | ((uint64_t)result[1] << 32),
(uint64_t)result[2] | ((uint64_t)result[3] << 32));
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index 98dbe7d6e8..3f4f0691e5 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -423,7 +423,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
{
uint32_t result[4] = {0};
- pm_get_callbackdata(result, (sizeof(result)/sizeof(uint32_t)));
+ pm_get_callbackdata(result, ARRAY_SIZE(result));
SMC_RET2(handle,
(uint64_t)result[0] | ((uint64_t)result[1] << 32),
(uint64_t)result[2] | ((uint64_t)result[3] << 32));
diff --git a/services/std_svc/spmd/aarch64/spmd_helpers.S b/services/std_svc/spmd/aarch64/spmd_helpers.S
new file mode 100644
index 0000000000..d7bffca243
--- /dev/null
+++ b/services/std_svc/spmd/aarch64/spmd_helpers.S
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include "../spmd_private.h"
+
+ .global spmd_spm_core_enter
+ .global spmd_spm_core_exit
+
+ /* ---------------------------------------------------------------------
+ * This function is called with SP_EL0 as stack. Here we stash our EL3
+ * callee-saved registers on to the stack as a part of saving the C
+ * runtime and enter the secure payload.
+ * 'x0' contains a pointer to the memory where the address of the C
+ * runtime context is to be saved.
+ * ---------------------------------------------------------------------
+ */
+func spmd_spm_core_enter
+ /* Make space for the registers that we're going to save */
+ mov x3, sp
+ str x3, [x0, #0]
+ sub sp, sp, #SPMD_C_RT_CTX_SIZE
+
+ /* Save callee-saved registers on to the stack */
+ stp x19, x20, [sp, #SPMD_C_RT_CTX_X19]
+ stp x21, x22, [sp, #SPMD_C_RT_CTX_X21]
+ stp x23, x24, [sp, #SPMD_C_RT_CTX_X23]
+ stp x25, x26, [sp, #SPMD_C_RT_CTX_X25]
+ stp x27, x28, [sp, #SPMD_C_RT_CTX_X27]
+ stp x29, x30, [sp, #SPMD_C_RT_CTX_X29]
+
+ /* ---------------------------------------------------------------------
+ * Everything is setup now. el3_exit() will use the secure context to
+ * restore to the general purpose and EL3 system registers to ERET
+ * into the secure payload.
+ * ---------------------------------------------------------------------
+ */
+ b el3_exit
+endfunc spmd_spm_core_enter
+
+ /* ---------------------------------------------------------------------
+ * This function is called with 'x0' pointing to a C runtime context.
+ * It restores the saved registers and jumps to that runtime with 'x0'
+ * as the new SP register. This destroys the C runtime context that had
+ * been built on the stack below the saved context by the caller. Later
+ * the second parameter 'x1' is passed as a return value to the caller.
+ * ---------------------------------------------------------------------
+ */
+func spmd_spm_core_exit
+ /* Restore the previous stack */
+ mov sp, x0
+
+ /* Restore callee-saved registers on to the stack */
+ ldp x19, x20, [x0, #(SPMD_C_RT_CTX_X19 - SPMD_C_RT_CTX_SIZE)]
+ ldp x21, x22, [x0, #(SPMD_C_RT_CTX_X21 - SPMD_C_RT_CTX_SIZE)]
+ ldp x23, x24, [x0, #(SPMD_C_RT_CTX_X23 - SPMD_C_RT_CTX_SIZE)]
+ ldp x25, x26, [x0, #(SPMD_C_RT_CTX_X25 - SPMD_C_RT_CTX_SIZE)]
+ ldp x27, x28, [x0, #(SPMD_C_RT_CTX_X27 - SPMD_C_RT_CTX_SIZE)]
+ ldp x29, x30, [x0, #(SPMD_C_RT_CTX_X29 - SPMD_C_RT_CTX_SIZE)]
+
+ /* ---------------------------------------------------------------------
+ * This should take us back to the instruction after the call to the
+ * last spm_secure_partition_enter().* Place the second parameter to x0
+ * so that the caller will see it as a return value from the original
+ * entry call.
+ * ---------------------------------------------------------------------
+ */
+ mov x0, x1
+ ret
+endfunc spmd_spm_core_exit
diff --git a/services/std_svc/spmd/spmd.mk b/services/std_svc/spmd/spmd.mk
new file mode 100644
index 0000000000..38d43f167d
--- /dev/null
+++ b/services/std_svc/spmd/spmd.mk
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifneq (${ARCH},aarch64)
+ $(error "Error: SPMD is only supported on aarch64.")
+endif
+
+SPMD_SOURCES += $(addprefix services/std_svc/spmd/, \
+ ${ARCH}/spmd_helpers.S \
+ spmd_main.c)
+
+# Let the top-level Makefile know that we intend to include a BL32 image
+NEED_BL32 := yes
+
+# Enable dynamic memory mapping
+# The SPMD component maps the SPMC DTB within BL31 virtual space.
+PLAT_XLAT_TABLES_DYNAMIC := 1
+$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
new file mode 100644
index 0000000000..677f63968d
--- /dev/null
+++ b/services/std_svc/spmd/spmd_main.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/smccc.h>
+#include <lib/spinlock.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 <platform_def.h>
+#include <services/spci_svc.h>
+#include <services/spmd_svc.h>
+#include <smccc_helpers.h>
+#include "spmd_private.h"
+
+/*******************************************************************************
+ * SPM Core context information.
+ ******************************************************************************/
+spmd_spm_core_context_t spm_core_context[PLATFORM_CORE_COUNT];
+
+/*******************************************************************************
+ * SPM Core attribute information read from its manifest.
+ ******************************************************************************/
+spmc_manifest_sect_attribute_t spmc_attrs;
+
+/*******************************************************************************
+ * This function takes an SP context pointer and performs a synchronous entry
+ * into it.
+ ******************************************************************************/
+uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *spmc_ctx)
+{
+ uint64_t rc;
+
+ assert(spmc_ctx != NULL);
+
+ cm_set_context(&(spmc_ctx->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 = spmd_spm_core_enter(&spmc_ctx->c_rt_ctx);
+
+ /* Save secure state */
+ cm_el1_sysregs_context_save(SECURE);
+
+ return rc;
+}
+
+/*******************************************************************************
+ * This function returns to the place where spm_sp_synchronous_entry() was
+ * called originally.
+ ******************************************************************************/
+__dead2 void spmd_spm_core_sync_exit(uint64_t rc)
+{
+ spmd_spm_core_context_t *ctx = &spm_core_context[plat_my_core_pos()];
+
+ /* Get context of the SP in use by this CPU. */
+ assert(cm_get_context(SECURE) == &(ctx->cpu_ctx));
+
+ /*
+ * The SPMD must have initiated the original request through a
+ * synchronous entry into SPMC. Jump back to the original C runtime
+ * context with the value of rc in x0;
+ */
+ spmd_spm_core_exit(ctx->c_rt_ctx, rc);
+
+ panic();
+}
+
+/*******************************************************************************
+ * Jump to the SPM core for the first time.
+ ******************************************************************************/
+static int32_t spmd_init(void)
+{
+ uint64_t rc = 0;
+ spmd_spm_core_context_t *ctx = &spm_core_context[plat_my_core_pos()];
+
+ INFO("SPM Core init start.\n");
+ ctx->state = SPMC_STATE_RESET;
+
+ rc = spmd_spm_core_sync_entry(ctx);
+ if (rc) {
+ ERROR("SPMC initialisation failed 0x%llx\n", rc);
+ panic();
+ }
+
+ ctx->state = SPMC_STATE_IDLE;
+ INFO("SPM Core init end.\n");
+
+ return 1;
+}
+
+/*******************************************************************************
+ * Initialize context of SPM core.
+ ******************************************************************************/
+int32_t spmd_setup(void)
+{
+ int rc;
+ void *rd_base;
+ size_t rd_size;
+ entry_point_info_t *spmc_ep_info;
+ uintptr_t rd_base_align;
+ uintptr_t rd_size_align;
+ uint32_t ep_attr;
+
+ spmc_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
+ if (!spmc_ep_info) {
+ WARN("No SPM core image provided by BL2 boot loader, Booting "
+ "device without SP initialization. SMC`s destined for SPM "
+ "core will return SMC_UNK\n");
+ return 1;
+ }
+
+ /* Under no circumstances will this parameter be 0 */
+ assert(spmc_ep_info->pc != 0U);
+
+ /*
+ * Check if BL32 ep_info has a reference to 'tos_fw_config'. This will
+ * be used as a manifest for the SPM core at the next lower EL/mode.
+ */
+ if (spmc_ep_info->args.arg0 == 0U || spmc_ep_info->args.arg2 == 0U) {
+ ERROR("Invalid or absent SPM core manifest\n");
+ panic();
+ }
+
+ /* Obtain whereabouts of SPM core manifest */
+ rd_base = (void *) spmc_ep_info->args.arg0;
+ rd_size = spmc_ep_info->args.arg2;
+
+ rd_base_align = page_align((uintptr_t) rd_base, DOWN);
+ rd_size_align = page_align((uintptr_t) rd_size, UP);
+
+ /* Map the manifest in the SPMD translation regime first */
+ VERBOSE("SPM core manifest base : 0x%lx\n", rd_base_align);
+ VERBOSE("SPM core manifest size : 0x%lx\n", rd_size_align);
+ rc = mmap_add_dynamic_region((unsigned long long) rd_base_align,
+ (uintptr_t) rd_base_align,
+ rd_size_align,
+ MT_RO_DATA);
+ if (rc < 0) {
+ ERROR("Error while mapping SPM core manifest (%d).\n", rc);
+ panic();
+ }
+
+ /* Load the SPM core manifest */
+ rc = plat_spm_core_manifest_load(&spmc_attrs, rd_base, rd_size);
+ if (rc < 0) {
+ WARN("No or invalid SPM core manifest image provided by BL2 "
+ "boot loader. ");
+ goto error;
+ }
+
+ /*
+ * Ensure that the SPM core version is compatible with the SPM
+ * dispatcher version
+ */
+ if ((spmc_attrs.major_version != SPCI_VERSION_MAJOR) ||
+ (spmc_attrs.minor_version > SPCI_VERSION_MINOR)) {
+ WARN("Unsupported SPCI version (%x.%x) specified in SPM core "
+ "manifest image provided by BL2 boot loader.\n",
+ spmc_attrs.major_version, spmc_attrs.minor_version);
+ goto error;
+ }
+
+ INFO("SPCI version (%x.%x).\n", spmc_attrs.major_version,
+ spmc_attrs.minor_version);
+
+ /* Validate the SPM core runtime EL */
+ if ((spmc_attrs.runtime_el != MODE_EL1) &&
+ (spmc_attrs.runtime_el != MODE_EL2)) {
+ WARN("Unsupported SPM core run time EL%x specified in "
+ "manifest image provided by BL2 boot loader.\n",
+ spmc_attrs.runtime_el);
+ goto error;
+ }
+
+ INFO("SPM core run time EL%x.\n", spmc_attrs.runtime_el);
+
+ /* Validate the SPM core execution state */
+ if ((spmc_attrs.exec_state != MODE_RW_64) &&
+ (spmc_attrs.exec_state != MODE_RW_32)) {
+ WARN("Unsupported SPM core execution state %x specified in "
+ "manifest image provided by BL2 boot loader.\n",
+ spmc_attrs.exec_state);
+ goto error;
+ }
+
+ INFO("SPM core execution state %x.\n", spmc_attrs.exec_state);
+
+ /* Ensure manifest has not requested S-EL2 in AArch32 state */
+ if ((spmc_attrs.exec_state == MODE_RW_32) &&
+ (spmc_attrs.runtime_el == MODE_EL2)) {
+ WARN("Invalid combination of SPM core execution state (%x) "
+ "and run time EL (%x).\n", spmc_attrs.exec_state,
+ spmc_attrs.runtime_el);
+ goto error;
+ }
+
+ /*
+ * Check if S-EL2 is supported on this system if S-EL2
+ * is required for SPM
+ */
+ if (spmc_attrs.runtime_el == MODE_EL2) {
+ uint64_t sel2 = read_id_aa64pfr0_el1();
+
+ sel2 >>= ID_AA64PFR0_SEL2_SHIFT;
+ sel2 &= ID_AA64PFR0_SEL2_MASK;
+
+ if (!sel2) {
+ WARN("SPM core run time EL: S-EL%x is not supported "
+ "but specified in manifest image provided by "
+ "BL2 boot loader.\n", spmc_attrs.runtime_el);
+ goto error;
+ }
+ }
+
+ /* Initialise an entrypoint to set up the CPU context */
+ ep_attr = SECURE | EP_ST_ENABLE;
+ if (read_sctlr_el3() & SCTLR_EE_BIT)
+ ep_attr |= EP_EE_BIG;
+ SET_PARAM_HEAD(spmc_ep_info, PARAM_EP, VERSION_1, ep_attr);
+ assert(spmc_ep_info->pc == BL32_BASE);
+
+ /*
+ * Populate SPSR for SPM core based upon validated parameters from the
+ * manifest
+ */
+ if (spmc_attrs.exec_state == MODE_RW_32) {
+ spmc_ep_info->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
+ SPSR_E_LITTLE,
+ DAIF_FIQ_BIT |
+ DAIF_IRQ_BIT |
+ DAIF_ABT_BIT);
+ } else {
+ spmc_ep_info->spsr = SPSR_64(spmc_attrs.runtime_el,
+ MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS);
+ }
+
+ /* Initialise SPM core context with this entry point information */
+ cm_setup_context(&(spm_core_context[plat_my_core_pos()].cpu_ctx),
+ spmc_ep_info);
+
+ INFO("SPM core setup done.\n");
+
+ /* Register init function for deferred init. */
+ bl31_register_bl32_init(&spmd_init);
+
+ return 0;
+
+error:
+ WARN("Booting device without SPM initialization. "
+ "SPCI SMCs destined for SPM core will return "
+ "ENOTSUPPORTED\n");
+
+ rc = mmap_remove_dynamic_region(rd_base_align, rd_size_align);
+ if (rc < 0) {
+ ERROR("Error while unmapping SPM core manifest (%d).\n",
+ rc);
+ panic();
+ }
+
+ return 1;
+}
+
+/*******************************************************************************
+ * This function handles all SMCs in the range reserved for SPCI. Each call is
+ * either forwarded to the other security state or handled by the SPM dispatcher
+ ******************************************************************************/
+uint64_t spmd_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)
+{
+ uint32_t in_sstate;
+ uint32_t out_sstate;
+ int32_t ret;
+ spmd_spm_core_context_t *ctx = &spm_core_context[plat_my_core_pos()];
+
+ /* Determine which security state this SMC originated from */
+ if (is_caller_secure(flags)) {
+ in_sstate = SECURE;
+ out_sstate = NON_SECURE;
+ } else {
+ in_sstate = NON_SECURE;
+ out_sstate = SECURE;
+ }
+
+ INFO("SPM: 0x%x, 0x%llx, 0x%llx, 0x%llx, 0x%llx, "
+ "0x%llx, 0x%llx, 0x%llx\n",
+ smc_fid, x1, x2, x3, x4, SMC_GET_GP(handle, CTX_GPREG_X5),
+ SMC_GET_GP(handle, CTX_GPREG_X6),
+ SMC_GET_GP(handle, CTX_GPREG_X7));
+
+ switch (smc_fid) {
+ case SPCI_ERROR:
+ /*
+ * Check if this is the first invocation of this interface on
+ * this CPU. If so, then indicate that the SPM core initialised
+ * unsuccessfully.
+ */
+ if ((in_sstate == SECURE) && (ctx->state == SPMC_STATE_RESET))
+ spmd_spm_core_sync_exit(x2);
+
+ /* Save incoming security state */
+ cm_el1_sysregs_context_save(in_sstate);
+
+ /* Restore outgoing security state */
+ cm_el1_sysregs_context_restore(out_sstate);
+ cm_set_next_eret_context(out_sstate);
+
+ SMC_RET8(cm_get_context(out_sstate), smc_fid, x1, x2, x3, x4,
+ SMC_GET_GP(handle, CTX_GPREG_X5),
+ SMC_GET_GP(handle, CTX_GPREG_X6),
+ SMC_GET_GP(handle, CTX_GPREG_X7));
+ break; /* not reached */
+
+ case SPCI_VERSION:
+ /*
+ * TODO: This is an optimization that the version information
+ * provided by the SPM core manifest is returned by the SPM
+ * dispatcher. It might be a better idea to simply forward this
+ * call to the SPM core and wash our hands completely.
+ */
+ ret = MAKE_SPCI_VERSION(spmc_attrs.major_version,
+ spmc_attrs.minor_version);
+ SMC_RET8(handle, SPCI_SUCCESS_SMC32, SPCI_TARGET_INFO_MBZ, ret,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ);
+ break; /* not reached */
+
+ case SPCI_FEATURES:
+ /*
+ * This is an optional interface. Do the minimal checks and
+ * forward to SPM core which will handle it if implemented.
+ */
+
+ /*
+ * Check if w1 holds a valid SPCI fid. This is an
+ * optimization.
+ */
+ if (!is_spci_fid(x1))
+ SMC_RET8(handle, SPCI_ERROR,
+ SPCI_TARGET_INFO_MBZ, SPCI_ERROR_NOT_SUPPORTED,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ);
+
+ /* Forward SMC from Normal world to the SPM core */
+ if (in_sstate == NON_SECURE) {
+ /* Save incoming security state */
+ cm_el1_sysregs_context_save(in_sstate);
+
+ /* Restore outgoing security state */
+ cm_el1_sysregs_context_restore(out_sstate);
+ cm_set_next_eret_context(out_sstate);
+
+ SMC_RET8(cm_get_context(out_sstate), smc_fid,
+ x1, x2, x3, x4,
+ SMC_GET_GP(handle, CTX_GPREG_X5),
+ SMC_GET_GP(handle, CTX_GPREG_X6),
+ SMC_GET_GP(handle, CTX_GPREG_X7));
+ } else {
+ /*
+ * Return success if call was from secure world i.e. all
+ * SPCI functions are supported. This is essentially a
+ * nop.
+ */
+ SMC_RET8(handle, SPCI_SUCCESS_SMC32, x1, x2, x3, x4,
+ SMC_GET_GP(handle, CTX_GPREG_X5),
+ SMC_GET_GP(handle, CTX_GPREG_X6),
+ SMC_GET_GP(handle, CTX_GPREG_X7));
+ }
+ break; /* not reached */
+
+ case SPCI_RX_RELEASE:
+ case SPCI_RXTX_MAP_SMC32:
+ case SPCI_RXTX_MAP_SMC64:
+ case SPCI_RXTX_UNMAP:
+ case SPCI_MSG_RUN:
+ /* This interface must be invoked only by the Normal world */
+ if (in_sstate == SECURE) {
+ SMC_RET8(handle, SPCI_ERROR,
+ SPCI_TARGET_INFO_MBZ, SPCI_ERROR_NOT_SUPPORTED,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ);
+ }
+
+ /* Fall through to forward the call to the other world */
+
+ case SPCI_PARTITION_INFO_GET:
+ case SPCI_MSG_SEND:
+ case SPCI_MSG_SEND_DIRECT_REQ_SMC32:
+ case SPCI_MSG_SEND_DIRECT_REQ_SMC64:
+ case SPCI_MSG_SEND_DIRECT_RESP_SMC32:
+ case SPCI_MSG_SEND_DIRECT_RESP_SMC64:
+ case SPCI_MEM_DONATE_SMC32:
+ case SPCI_MEM_DONATE_SMC64:
+ case SPCI_MEM_LEND_SMC32:
+ case SPCI_MEM_LEND_SMC64:
+ case SPCI_MEM_SHARE_SMC32:
+ case SPCI_MEM_SHARE_SMC64:
+ case SPCI_MEM_RETRIEVE_REQ_SMC32:
+ case SPCI_MEM_RETRIEVE_REQ_SMC64:
+ case SPCI_MEM_RETRIEVE_RESP:
+ case SPCI_MEM_RELINQUISH:
+ case SPCI_MEM_RECLAIM:
+ case SPCI_SUCCESS_SMC32:
+ case SPCI_SUCCESS_SMC64:
+ /*
+ * TODO: Assume that no requests originate from EL3 at the
+ * moment. This will change if a SP service is required in
+ * response to secure interrupts targeted to EL3. Until then
+ * simply forward the call to the Normal world.
+ */
+
+ /* Save incoming security state */
+ cm_el1_sysregs_context_save(in_sstate);
+
+ /* Restore outgoing security state */
+ cm_el1_sysregs_context_restore(out_sstate);
+ cm_set_next_eret_context(out_sstate);
+
+ SMC_RET8(cm_get_context(out_sstate), smc_fid, x1, x2, x3, x4,
+ SMC_GET_GP(handle, CTX_GPREG_X5),
+ SMC_GET_GP(handle, CTX_GPREG_X6),
+ SMC_GET_GP(handle, CTX_GPREG_X7));
+ break; /* not reached */
+
+ case SPCI_MSG_WAIT:
+ /*
+ * Check if this is the first invocation of this interface on
+ * this CPU from the Secure world. If so, then indicate that the
+ * SPM core initialised successfully.
+ */
+ if ((in_sstate == SECURE) && (ctx->state == SPMC_STATE_RESET)) {
+ spmd_spm_core_sync_exit(0);
+ }
+
+ /* Intentional fall-through */
+
+ case SPCI_MSG_YIELD:
+ /* This interface must be invoked only by the Secure world */
+ if (in_sstate == NON_SECURE) {
+ SMC_RET8(handle, SPCI_ERROR,
+ SPCI_TARGET_INFO_MBZ, SPCI_ERROR_NOT_SUPPORTED,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ);
+ }
+
+ /* Save incoming security state */
+ cm_el1_sysregs_context_save(in_sstate);
+
+ /* Restore outgoing security state */
+ cm_el1_sysregs_context_restore(out_sstate);
+ cm_set_next_eret_context(out_sstate);
+
+ SMC_RET8(cm_get_context(out_sstate), smc_fid, x1, x2, x3, x4,
+ SMC_GET_GP(handle, CTX_GPREG_X5),
+ SMC_GET_GP(handle, CTX_GPREG_X6),
+ SMC_GET_GP(handle, CTX_GPREG_X7));
+ break; /* not reached */
+
+ default:
+ WARN("SPM: Unsupported call 0x%08x\n", smc_fid);
+ SMC_RET8(handle, SPCI_ERROR,
+ SPCI_TARGET_INFO_MBZ, SPCI_ERROR_NOT_SUPPORTED,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ);
+ }
+}
diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h
new file mode 100644
index 0000000000..61b479a8bc
--- /dev/null
+++ b/services/std_svc/spmd/spmd_private.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPMD_PRIVATE_H
+#define SPMD_PRIVATE_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 SPMD_C_RT_CTX_X19 0x0
+#define SPMD_C_RT_CTX_X20 0x8
+#define SPMD_C_RT_CTX_X21 0x10
+#define SPMD_C_RT_CTX_X22 0x18
+#define SPMD_C_RT_CTX_X23 0x20
+#define SPMD_C_RT_CTX_X24 0x28
+#define SPMD_C_RT_CTX_X25 0x30
+#define SPMD_C_RT_CTX_X26 0x38
+#define SPMD_C_RT_CTX_X27 0x40
+#define SPMD_C_RT_CTX_X28 0x48
+#define SPMD_C_RT_CTX_X29 0x50
+#define SPMD_C_RT_CTX_X30 0x58
+
+#define SPMD_C_RT_CTX_SIZE 0x60
+#define SPMD_C_RT_CTX_ENTRIES (SPMD_C_RT_CTX_SIZE >> DWORD_SHIFT)
+
+#ifndef __ASSEMBLER__
+#include <services/spci_svc.h>
+#include <stdint.h>
+
+/*
+ * Convert a function no. in a FID to a bit position. All function nos. are
+ * between 0 and 0x1f
+ */
+#define SPCI_FNO_TO_BIT_POS(_fid) (1 << ((_fid) & U(0x1f)))
+
+typedef enum spmc_state {
+ SPMC_STATE_RESET = 0,
+ SPMC_STATE_IDLE
+} spmc_state_t;
+
+/*
+ * Data structure used by the SPM dispatcher (SPMD) in EL3 to track context of
+ * the SPM core (SPMC) at the next lower EL.
+ */
+typedef struct spmd_spm_core_context {
+ uint64_t c_rt_ctx;
+ cpu_context_t cpu_ctx;
+ spmc_state_t state;
+} spmd_spm_core_context_t;
+
+/*
+ * Data structure used by the SPM dispatcher (SPMD) in EL3 to track sequence of
+ * SPCI calls from lower ELs.
+ *
+ * next_smc_bit_map: Per-cpu bit map of SMCs from each world that are expected
+ * next.
+ */
+typedef struct spmd_spci_context {
+ uint32_t next_smc_bit_map[2];
+} spmd_spci_context_t;
+
+/* Functions used to enter/exit a Secure Partition synchronously */
+uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *ctx);
+__dead2 void spmd_spm_core_sync_exit(uint64_t rc);
+
+/* Assembly helpers */
+uint64_t spmd_spm_core_enter(uint64_t *c_rt_ctx);
+void __dead2 spmd_spm_core_exit(uint64_t c_rt_ctx, uint64_t ret);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* SPMD_PRIVATE_H */
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index 7787a2fa23..895fd292fa 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,6 +15,7 @@
#include <lib/runtime_instr.h>
#include <services/sdei.h>
#include <services/spm_mm_svc.h>
+#include <services/spmd_svc.h>
#include <services/std_svc.h>
#include <smccc_helpers.h>
#include <tools_share/uuid.h>
@@ -51,6 +52,12 @@ static int32_t std_svc_setup(void)
}
#endif
+#if defined(SPD_spmd)
+ if (spmd_setup() != 0) {
+ ret = 1;
+ }
+#endif
+
#if SDEI_SUPPORT
/* SDEI initialisation */
sdei_init();
@@ -114,6 +121,17 @@ static uintptr_t std_svc_smc_handler(uint32_t smc_fid,
}
#endif
+#if defined(SPD_spmd)
+ /*
+ * Dispatch SPCI calls to the SPCI SMC handler implemented by the SPM
+ * dispatcher and return its return value
+ */
+ if (is_spci_fid(smc_fid)) {
+ return spmd_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+ handle, flags);
+ }
+#endif
+
#if SDEI_SUPPORT
if (is_sdei_fid(smc_fid)) {
return sdei_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
diff --git a/tools/sptool/sptool.c b/tools/sptool/sptool.c
index a33b664461..38baa2cd99 100644
--- a/tools/sptool/sptool.c
+++ b/tools/sptool/sptool.c
@@ -1,10 +1,11 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * 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>
@@ -16,25 +17,26 @@
#define PAGE_SIZE 4096
/*
- * Linked list of entries describing entries in the secure
- * partition package.
+ * Entry describing Secure Partition package.
*/
-struct sp_entry_info {
+struct sp_pkg_info {
/* Location of the files in the host's RAM. */
- void *sp_data, *rd_data;
+ void *img_data, *pm_data;
/* Size of the files. */
- uint64_t sp_size, rd_size;
+ uint32_t img_size, pm_size;
/* Location of the binary files inside the package output file */
- uint64_t sp_offset, rd_offset;
-
- struct sp_entry_info *next;
+ uint32_t img_offset, pm_offset;
};
-static struct sp_entry_info *sp_info_head;
-
-static uint64_t sp_count;
+/*
+ * 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)
@@ -89,26 +91,61 @@ static void xfseek(FILE *fp, long offset, int whence)
}
}
-static void cleanup(void)
+/*
+ * Free SP package structure
+ */
+static void cleanup(struct sp_pkg_info *sp)
{
- struct sp_entry_info *sp = sp_info_head;
- while (sp != NULL) {
- struct sp_entry_info *next = sp->next;
-
- if (sp->sp_data != NULL)
- free(sp->sp_data);
+ if (sp != NULL) {
+ if (sp->img_data != NULL) {
+ free(sp->img_data);
+ }
- if (sp->rd_data != NULL)
- free(sp->rd_data);
+ if (sp->pm_data != NULL) {
+ free(sp->pm_data);
+ }
free(sp);
- sp = next;
}
+}
- sp_count = 0;
- sp_info_head = NULL;
+/*
+ * 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;
+ }
}
/*
@@ -116,7 +153,7 @@ static void cleanup(void)
* 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, uint64_t *size)
+static void load_file(const char *path, void **ptr, uint32_t *size)
{
FILE *f = fopen(path, "rb");
if (f == NULL) {
@@ -147,59 +184,40 @@ static void load_file(const char *path, void **ptr, uint64_t *size)
fclose(f);
}
-static void load_sp_rd(char *path)
+/*
+ * 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 *rd_path = split_mark + 1;
-
- struct sp_entry_info *sp;
-
- if (sp_info_head == NULL) {
- sp_info_head = xzalloc(sizeof(struct sp_entry_info),
- "Failed to allocate sp_entry_info struct");
-
- sp = sp_info_head;
- } else {
- sp = sp_info_head;
-
- while (sp->next != NULL) {
- sp = sp->next;
- }
-
- sp->next = xzalloc(sizeof(struct sp_entry_info),
- "Failed to allocate sp_entry_info struct");
+ char *pm_path = split_mark + 1;
- sp = sp->next;
- }
+ sp_pkg = xzalloc(sizeof(struct sp_pkg_info),
+ "Failed to allocate sp_pkg_info struct");
- load_file(sp_path, &sp->sp_data, &sp->sp_size);
- printf("Loaded image file %s (%lu bytes)\n", sp_path, sp->sp_size);
+ 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(rd_path, &sp->rd_data, &sp->rd_size);
- printf("Loaded RD file %s (%lu bytes)\n", rd_path, sp->rd_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_count++;
+ *sp_out = sp_pkg;
}
-static void output_write(const char *path)
+/*
+ * Write SP package data structure into output file.
+ */
+static void output_write(const char *path, struct sp_pkg_info *sp, bool header)
{
- struct sp_entry_info *sp;
-
- if (sp_count == 0) {
- fprintf(stderr, "error: At least one SP must be provided.\n");
- exit(1);
- }
-
- /* The layout of the structs is specified in the header file sptool.h */
-
- printf("Writing %lu partitions to output file.\n", sp_count);
-
- unsigned int header_size = (sizeof(struct sp_pkg_header) * 8)
- + (sizeof(struct sp_pkg_entry) * 8 * sp_count);
+ struct sp_pkg_header sp_header_info;
+ unsigned int file_ptr = 0;
FILE *f = fopen(path, "wb");
if (f == NULL) {
@@ -207,70 +225,46 @@ static void output_write(const char *path)
exit(1);
}
- unsigned int file_ptr = align_to(header_size, PAGE_SIZE);
-
- /* First, save all partition images aligned to page boundaries */
-
- sp = sp_info_head;
-
- for (uint64_t i = 0; i < sp_count; i++) {
- xfseek(f, file_ptr, SEEK_SET);
-
- printf("Writing image %lu to offset 0x%x (0x%lx bytes)\n",
- i, file_ptr, sp->sp_size);
-
- sp->sp_offset = file_ptr;
- xfwrite(sp->sp_data, sp->sp_size, f);
- file_ptr = align_to(file_ptr + sp->sp_size, PAGE_SIZE);
- sp = sp->next;
+ /* Reserve Header size */
+ if (header) {
+ file_ptr = sizeof(struct sp_pkg_header);
}
- /* Now, save resource description blobs aligned to 8 bytes */
+ /* 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 = sp_info_head;
-
- for (uint64_t i = 0; i < sp_count; i++) {
- xfseek(f, file_ptr, SEEK_SET);
-
- printf("Writing RD blob %lu to offset 0x%x (0x%lx bytes)\n",
- i, file_ptr, sp->rd_size);
-
- sp->rd_offset = file_ptr;
- xfwrite(sp->rd_data, sp->rd_size, f);
- file_ptr = align_to(file_ptr + sp->rd_size, 8);
- sp = sp->next;
- }
+ sp->pm_offset = file_ptr;
+ xfwrite(sp->pm_data, sp->pm_size, f);
- /* Finally, write header */
+ /* 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);
- uint64_t version = 0x1;
- uint64_t sp_num = sp_count;
+ sp->img_offset = file_ptr;
+ xfwrite(sp->img_data, sp->img_size, f);
- xfseek(f, 0, SEEK_SET);
+ /* 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;
- xfwrite(&version, sizeof(uint64_t), f);
- xfwrite(&sp_num, sizeof(uint64_t), f);
+ xfseek(f, 0, SEEK_SET);
- sp = sp_info_head;
+ printf("Writing package header\n");
- for (unsigned int i = 0; i < sp_count; i++) {
-
- uint64_t sp_offset, sp_size, rd_offset, rd_size;
-
- sp_offset = sp->sp_offset;
- sp_size = align_to(sp->sp_size, PAGE_SIZE);
- rd_offset = sp->rd_offset;
- rd_size = sp->rd_size;
-
- xfwrite(&sp_offset, sizeof(uint64_t), f);
- xfwrite(&sp_size, sizeof(uint64_t), f);
- xfwrite(&rd_offset, sizeof(uint64_t), f);
- xfwrite(&rd_size, sizeof(uint64_t), f);
-
- sp = sp->next;
+ 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);
}
@@ -286,30 +280,51 @@ static void usage(void)
#endif
printf(" [<args>]\n\n");
- printf("This tool takes as inputs several image binary files and the\n"
- "resource description blobs as input and generates a package\n"
- "file that contains them.\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:rd_path> Add Secure Partition image and Resource\n"
- " Description blob (specified in two paths\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;
- const char *outname = NULL;
- while ((ch = getopt(argc, argv, "hi:o:")) != -1) {
+ 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':
- load_sp_rd(optarg);
+ append_user_input(&in_head, optarg);
+ match_counter++;
break;
case 'o':
- outname = optarg;
+ append_user_input(&out_head, optarg);
+ match_counter--;
+ break;
+ case 'n':
+ need_header = false;
break;
case 'h':
default:
@@ -317,18 +332,29 @@ int main(int argc, char *argv[])
}
}
- argc -= optind;
- argv += optind;
-
- if (outname == NULL) {
- fprintf(stderr, "error: An output file path must be provided.\n\n");
+ if (match_counter) {
+ fprintf(stderr, "error: Input/Output count mismatch.\n\n");
+ freelist(in_head);
+ freelist(out_head);
usage();
return 1;
}
- output_write(outname);
+ 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();
+ cleanup(sp_pkg);
+ freelist(in_head);
+ freelist(out_head);
return 0;
}