aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile153
-rw-r--r--bl1/aarch32/bl1_exceptions.S2
-rw-r--r--bl2/aarch32/bl2_el3_entrypoint.S2
-rw-r--r--bl32/tsp/tsp_main.c4
-rw-r--r--docs/about/maintainers.rst15
-rw-r--r--docs/change-log-upcoming.rst2
-rw-r--r--docs/design/auth-framework.rst38
-rw-r--r--docs/design/trusted-board-boot.rst28
-rw-r--r--docs/getting_started/build-options.rst44
-rw-r--r--docs/getting_started/porting-guide.rst29
-rw-r--r--docs/getting_started/tools-build.rst27
-rw-r--r--docs/plat/arm/fvp/index.rst4
-rw-r--r--docs/plat/index.rst3
-rw-r--r--docs/plat/qemu.rst53
-rw-r--r--drivers/allwinner/sunxi_msgbox.c95
-rw-r--r--drivers/amlogic/console/aarch64/meson_console.S18
-rw-r--r--drivers/arm/css/scp/css_pm_scmi.c8
-rw-r--r--drivers/arm/css/scpi/css_scpi.c22
-rw-r--r--drivers/arm/pl011/aarch32/pl011_console.S18
-rw-r--r--drivers/arm/pl011/aarch64/pl011_console.S18
-rw-r--r--drivers/auth/crypto_mod.c32
-rw-r--r--drivers/auth/cryptocell/712/cryptocell_crypto.c2
-rw-r--r--drivers/auth/mbedtls/mbedtls_common.mk12
-rw-r--r--drivers/auth/mbedtls/mbedtls_crypto.c117
-rw-r--r--drivers/cadence/uart/aarch64/cdns_console.S18
-rw-r--r--drivers/console/aarch32/skeleton_console.S8
-rw-r--r--drivers/console/aarch64/skeleton_console.S8
-rw-r--r--drivers/coreboot/cbmem_console/aarch64/cbmem_console.S6
-rw-r--r--drivers/imx/uart/imx_uart.h7
-rw-r--r--drivers/io/io_encrypted.c244
-rw-r--r--drivers/marvell/uart/a3700_console.S18
-rw-r--r--drivers/renesas/rcar/console/rcar_console.S10
-rw-r--r--drivers/renesas/rcar/scif/scif.S6
-rw-r--r--drivers/st/uart/aarch32/stm32_console.S14
-rw-r--r--drivers/ti/uart/aarch32/16550_console.S18
-rw-r--r--drivers/ti/uart/aarch64/16550_console.S18
-rw-r--r--fdts/a5ds.dts19
-rw-r--r--fdts/fvp-base-gicv3-psci-dynamiq-2t.dts191
-rw-r--r--include/arch/aarch32/asm_macros.S15
-rw-r--r--include/arch/aarch32/smccc_macros.S2
-rw-r--r--include/arch/aarch64/arch.h26
-rw-r--r--include/drivers/amlogic/meson_console.h9
-rw-r--r--include/drivers/arm/pl011.h9
-rw-r--r--include/drivers/auth/crypto_mod.h34
-rw-r--r--include/drivers/auth/mbedtls/mbedtls_config.h6
-rw-r--r--include/drivers/cadence/cdns_uart.h9
-rw-r--r--include/drivers/console.h4
-rw-r--r--include/drivers/coreboot/cbmem_console.h4
-rw-r--r--include/drivers/io/io_encrypted.h15
-rw-r--r--include/drivers/io/io_storage.h1
-rw-r--r--include/drivers/marvell/uart/a3700_console.h9
-rw-r--r--include/drivers/renesas/rcar/console/console.h9
-rw-r--r--include/drivers/st/stm32_console.h9
-rw-r--r--include/drivers/ti/uart/uart_16550.h9
-rw-r--r--include/export/common/tbbr/tbbr_img_def_exp.h10
-rw-r--r--include/lib/el3_runtime/aarch64/context.h158
-rw-r--r--include/lib/el3_runtime/context_mgmt.h5
-rw-r--r--include/lib/fconf/fconf.h6
-rw-r--r--include/lib/object_pool.h6
-rw-r--r--include/lib/xlat_tables/xlat_tables_v2.h12
-rw-r--r--include/lib/xlat_tables/xlat_tables_v2_helpers.h62
-rw-r--r--include/plat/arm/board/common/board_css_def.h9
-rw-r--r--include/plat/arm/common/fconf_arm_sp_getter.h30
-rw-r--r--include/plat/arm/common/plat_arm.h8
-rw-r--r--include/plat/arm/css/common/css_def.h3
-rw-r--r--include/plat/common/platform.h13
-rw-r--r--include/services/spm_core_manifest.h7
-rw-r--r--include/services/spmd_svc.h2
-rw-r--r--include/tools_share/firmware_encrypted.h42
-rw-r--r--lib/aarch64/cache_helpers.S6
-rw-r--r--lib/coreboot/coreboot_table.c2
-rw-r--r--lib/cpus/aarch64/denver.S8
-rw-r--r--lib/el3_runtime/aarch64/context.S386
-rw-r--r--lib/el3_runtime/aarch64/context_mgmt.c56
-rw-r--r--lib/xlat_tables_v2/ro_xlat_tables.mk37
-rw-r--r--lib/xlat_tables_v2/xlat_tables.mk6
-rw-r--r--lib/xlat_tables_v2/xlat_tables_context.c78
-rw-r--r--make_helpers/build_macros.mk65
-rw-r--r--make_helpers/defaults.mk33
-rw-r--r--plat/allwinner/common/allwinner-common.mk2
-rw-r--r--plat/allwinner/common/include/platform_def.h14
-rw-r--r--plat/allwinner/common/sunxi_bl31_setup.c2
-rw-r--r--plat/allwinner/common/sunxi_common.c4
-rw-r--r--plat/allwinner/common/sunxi_pm.c210
-rw-r--r--plat/allwinner/sun50i_a64/include/sunxi_mmap.h6
-rw-r--r--plat/allwinner/sun50i_h6/include/sunxi_mmap.h6
-rw-r--r--plat/amlogic/common/aml_console.c4
-rw-r--r--plat/arm/board/fvp/fdts/fvp_fw_config.dts19
-rw-r--r--plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts1
-rw-r--r--plat/arm/board/fvp/fvp_def.h9
-rw-r--r--plat/arm/board/fvp/fvp_security.c4
-rw-r--r--plat/arm/board/fvp/platform.mk13
-rw-r--r--plat/arm/board/juno/include/platform_def.h6
-rw-r--r--plat/arm/board/juno/juno_security.c6
-rw-r--r--plat/arm/board/juno/platform.mk8
-rw-r--r--plat/arm/board/rddaniel/include/platform_def.h15
-rw-r--r--plat/arm/board/rddaniel/platform.mk2
-rw-r--r--plat/arm/board/rddaniel/rddaniel_security.c10
-rw-r--r--plat/arm/board/sgm775/include/platform_def.h5
-rw-r--r--plat/arm/common/arm_bl2_setup.c7
-rw-r--r--plat/arm/common/arm_bl31_setup.c5
-rw-r--r--plat/arm/common/arm_common.c20
-rw-r--r--plat/arm/common/arm_common.mk3
-rw-r--r--plat/arm/common/arm_console.c10
-rw-r--r--plat/arm/common/arm_dyn_cfg.c1
-rw-r--r--plat/arm/common/arm_fconf_io_storage.c1
-rw-r--r--plat/arm/common/arm_image_load.c55
-rw-r--r--plat/arm/common/arm_tzc400.c9
-rw-r--r--plat/arm/common/fconf/arm_fconf_io.c4
-rw-r--r--plat/arm/common/fconf/arm_fconf_sp.c107
-rw-r--r--plat/arm/common/sp_min/arm_sp_min_setup.c4
-rw-r--r--plat/arm/common/tsp/arm_tsp_setup.c10
-rw-r--r--plat/arm/css/sgi/include/sgi_base_platform_def.h3
-rw-r--r--plat/common/plat_bl_common.c27
-rw-r--r--plat/common/plat_spmd_manifest.c7
-rw-r--r--plat/hisilicon/hikey/hikey_bl1_setup.c2
-rw-r--r--plat/hisilicon/hikey/hikey_bl2_setup.c2
-rw-r--r--plat/hisilicon/hikey/hikey_bl31_setup.c2
-rw-r--r--plat/hisilicon/hikey960/hikey960_bl1_setup.c2
-rw-r--r--plat/hisilicon/hikey960/hikey960_bl2_setup.c2
-rw-r--r--plat/hisilicon/hikey960/hikey960_bl31_setup.c2
-rw-r--r--plat/hisilicon/hikey960/hikey960_pm.c2
-rw-r--r--plat/hisilicon/poplar/bl1_plat_setup.c2
-rw-r--r--plat/hisilicon/poplar/bl2_plat_setup.c2
-rw-r--r--plat/hisilicon/poplar/bl31_plat_setup.c2
-rw-r--r--plat/imx/common/aarch32/imx_uart_console.S8
-rw-r--r--plat/imx/common/imx_uart_console.S6
-rw-r--r--plat/imx/common/include/imx8_lpuart.h7
-rw-r--r--plat/imx/common/include/imx_uart.h7
-rw-r--r--plat/imx/common/lpuart_console.S6
-rw-r--r--plat/imx/imx7/common/imx7_bl2_el3_common.c4
-rw-r--r--plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c4
-rw-r--r--plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c2
-rw-r--r--plat/imx/imx8m/include/imx_rdc.h6
-rw-r--r--plat/imx/imx8qm/imx8qm_bl31_setup.c2
-rw-r--r--plat/imx/imx8qx/imx8qx_bl31_setup.c2
-rw-r--r--plat/intel/soc/agilex/bl2_plat_setup.c8
-rw-r--r--plat/intel/soc/agilex/bl31_plat_setup.c2
-rw-r--r--plat/intel/soc/agilex/platform.mk5
-rw-r--r--plat/intel/soc/common/include/platform_def.h12
-rw-r--r--plat/intel/soc/common/include/socfpga_emac.h24
-rw-r--r--plat/intel/soc/common/include/socfpga_mailbox.h8
-rw-r--r--plat/intel/soc/common/include/socfpga_sip_svc.h4
-rw-r--r--plat/intel/soc/common/include/socfpga_system_manager.h5
-rw-r--r--plat/intel/soc/common/soc/socfpga_emac.c38
-rw-r--r--plat/intel/soc/common/soc/socfpga_mailbox.c12
-rw-r--r--plat/intel/soc/common/socfpga_psci.c7
-rw-r--r--plat/intel/soc/common/socfpga_sip_svc.c14
-rw-r--r--plat/intel/soc/stratix10/bl2_plat_setup.c8
-rw-r--r--plat/intel/soc/stratix10/bl31_plat_setup.c2
-rw-r--r--plat/intel/soc/stratix10/platform.mk5
-rw-r--r--plat/layerscape/common/aarch64/ls_console.S18
-rw-r--r--plat/layerscape/common/include/ls_16550.h9
-rw-r--r--plat/layerscape/common/ls_bl1_setup.c2
-rw-r--r--plat/layerscape/common/ls_bl2_setup.c2
-rw-r--r--plat/layerscape/common/ls_bl31_setup.c4
-rw-r--r--plat/layerscape/common/tsp/ls_tsp_setup.c2
-rw-r--r--plat/marvell/common/marvell_console.c47
-rw-r--r--plat/mediatek/mt8173/bl31_plat_setup.c2
-rw-r--r--plat/mediatek/mt8173/drivers/wdt/wdt.c115
-rw-r--r--plat/mediatek/mt8173/drivers/wdt/wdt.h20
-rw-r--r--plat/mediatek/mt8173/include/mt8173_def.h12
-rw-r--r--plat/mediatek/mt8173/include/plat_sip_calls.h3
-rw-r--r--plat/mediatek/mt8173/plat_pm.c9
-rw-r--r--plat/mediatek/mt8173/plat_sip_calls.c4
-rw-r--r--plat/mediatek/mt8173/platform.mk2
-rw-r--r--plat/mediatek/mt8183/bl31_plat_setup.c2
-rw-r--r--plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c10
-rw-r--r--plat/nvidia/tegra/common/aarch64/tegra_helpers.S34
-rw-r--r--plat/nvidia/tegra/common/drivers/spe/shared_console.S16
-rw-r--r--plat/nvidia/tegra/common/tegra_fiq_glue.c12
-rw-r--r--plat/nvidia/tegra/include/drivers/pmc.h33
-rw-r--r--plat/nvidia/tegra/include/drivers/security_engine.h3
-rw-r--r--plat/nvidia/tegra/include/drivers/spe.h7
-rw-r--r--plat/nvidia/tegra/include/t186/tegra_def.h25
-rw-r--r--plat/nvidia/tegra/include/t210/tegra_def.h3
-rw-r--r--plat/nvidia/tegra/soc/t132/plat_setup.c4
-rw-r--r--plat/nvidia/tegra/soc/t186/drivers/se/se.c278
-rw-r--r--plat/nvidia/tegra/soc/t186/drivers/se/se_private.h100
-rw-r--r--plat/nvidia/tegra/soc/t186/plat_memctrl.c21
-rw-r--r--plat/nvidia/tegra/soc/t186/plat_psci_handlers.c35
-rw-r--r--plat/nvidia/tegra/soc/t186/plat_setup.c10
-rw-r--r--plat/nvidia/tegra/soc/t186/platform_t186.mk7
-rw-r--r--plat/nvidia/tegra/soc/t194/plat_memctrl.c422
-rw-r--r--plat/nvidia/tegra/soc/t194/plat_setup.c8
-rw-r--r--plat/nvidia/tegra/soc/t210/drivers/se/se_private.h6
-rw-r--r--plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c124
-rw-r--r--plat/nvidia/tegra/soc/t210/plat_psci_handlers.c9
-rw-r--r--plat/nvidia/tegra/soc/t210/plat_setup.c8
-rw-r--r--plat/nvidia/tegra/soc/t210/plat_sip_calls.c39
-rw-r--r--plat/nvidia/tegra/soc/t210/platform_t210.mk1
-rw-r--r--plat/qemu/common/qemu_console.c4
-rw-r--r--plat/qemu/common/qemu_io_storage.c71
-rw-r--r--plat/qemu/qemu/include/platform_def.h6
-rw-r--r--plat/qemu/qemu/platform.mk13
-rw-r--r--plat/renesas/rcar/rcar_common.c8
-rw-r--r--plat/rockchip/common/bl31_plat_setup.c2
-rw-r--r--plat/rockchip/common/sp_min_plat_setup.c2
-rw-r--r--plat/rpi/common/rpi3_common.c4
-rw-r--r--plat/socionext/synquacer/sq_bl31_setup.c5
-rw-r--r--plat/socionext/uniphier/uniphier_console.S6
-rw-r--r--plat/socionext/uniphier/uniphier_console_setup.c25
-rw-r--r--plat/socionext/uniphier/uniphier_io_storage.c35
-rw-r--r--plat/socionext/uniphier/uniphier_soc_info.c13
-rw-r--r--plat/st/stm32mp1/bl2_plat_setup.c4
-rw-r--r--plat/st/stm32mp1/sp_min/sp_min_setup.c4
-rw-r--r--plat/ti/k3/common/k3_console.c2
-rw-r--r--plat/xilinx/versal/bl31_versal_setup.c4
-rw-r--r--plat/xilinx/zynqmp/bl31_zynqmp_setup.c4
-rw-r--r--plat/xilinx/zynqmp/tsp/tsp_plat_setup.c4
-rw-r--r--services/spd/trusty/trusty.c6
-rw-r--r--services/std_svc/spm_mm/spm_mm_setup.c16
-rw-r--r--services/std_svc/spmd/spmd_main.c372
-rw-r--r--tools/encrypt_fw/Makefile65
-rw-r--r--tools/encrypt_fw/include/cmd_opt.h32
-rw-r--r--tools/encrypt_fw/include/debug.h59
-rw-r--r--tools/encrypt_fw/include/encrypt.h19
-rw-r--r--tools/encrypt_fw/src/cmd_opt.c59
-rw-r--r--tools/encrypt_fw/src/encrypt.c167
-rw-r--r--tools/encrypt_fw/src/main.c224
-rwxr-xr-xtools/memory/print_memory_map.py31
-rwxr-xr-xtools/sptool/sp_mk_generator.py100
222 files changed, 4853 insertions, 1379 deletions
diff --git a/Makefile b/Makefile
index 547b5843f..3d5b39502 100644
--- a/Makefile
+++ b/Makefile
@@ -159,6 +159,14 @@ else
endif
endif
+ifneq (${DECRYPTION_SUPPORT},none)
+ENC_ARGS += -f ${FW_ENC_STATUS}
+ENC_ARGS += -k ${ENC_KEY}
+ENC_ARGS += -n ${ENC_NONCE}
+FIP_DEPS += enctool
+FWU_FIP_DEPS += enctool
+endif
+
################################################################################
# Toolchain
################################################################################
@@ -412,40 +420,48 @@ INCLUDE_TBBR_MK := 1
################################################################################
ifneq (${SPD},none)
-ifeq (${ARCH},aarch32)
+ ifeq (${ARCH},aarch32)
$(error "Error: SPD is incompatible with AArch32.")
-endif
-ifdef EL3_PAYLOAD_BASE
+ endif
+
+ 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
- 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)
+ endif
+ ifeq (${SPD},spmd)
+ $(warning "SPMD is an experimental feature")
+ # SPMD is located in std_svc directory
+ SPD_DIR := std_svc
- ifeq (${SPD_MAKE},)
- $(error Error: No services/${SPD_DIR}/${SPD}/${SPD}.mk located)
+ ifeq ($(SPMD_SPM_AT_SEL2),1)
+ ifeq ($(CTX_INCLUDE_EL2_REGS),0)
+ $(error SPMD with SPM at S-EL2 requires CTX_INCLUDE_EL2_REGS option)
+ endif
endif
- $(info Including ${SPD_MAKE})
- include ${SPD_MAKE}
+ 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_DIR}/${SPD}/${SPD}.mk located)
+ endif
+ $(info Including ${SPD_MAKE})
+ include ${SPD_MAKE}
- # If there's BL32 companion for the chosen SPD, we expect that the SPD's
- # Makefile would set NEED_BL32 to "yes". In this case, the build system
- # supports two mutually exclusive options:
- # * BL32 is built from source: then BL32_SOURCES must contain the list
- # of source files to build BL32
- # * BL32 is a prebuilt binary: then BL32 must point to the image file
- # that will be included in the FIP
- # If both BL32_SOURCES and BL32 are defined, the binary takes precedence
- # over the sources.
+ # If there's BL32 companion for the chosen SPD, we expect that the SPD's
+ # Makefile would set NEED_BL32 to "yes". In this case, the build system
+ # supports two mutually exclusive options:
+ # * BL32 is built from source: then BL32_SOURCES must contain the list
+ # of source files to build BL32
+ # * BL32 is a prebuilt binary: then BL32 must point to the image file
+ # that will be included in the FIP
+ # If both BL32_SOURCES and BL32 are defined, the binary takes precedence
+ # over the sources.
endif
################################################################################
@@ -615,12 +631,26 @@ endif
ifeq ($(MEASURED_BOOT),1)
ifneq (${TRUSTED_BOARD_BOOT},1)
- $(error MEASURED_BOOT requires TRUSTED_BOARD_BOOT=1")
+ $(error MEASURED_BOOT requires TRUSTED_BOARD_BOOT=1)
else
$(info MEASURED_BOOT is an experimental feature)
endif
endif
+ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
+ ifeq (${ALLOW_RO_XLAT_TABLES}, 1)
+ $(error "ALLOW_RO_XLAT_TABLES requires translation tables library v2")
+ endif
+endif
+
+ifneq (${DECRYPTION_SUPPORT},none)
+ ifeq (${TRUSTED_BOARD_BOOT}, 0)
+ $(error TRUSTED_BOARD_BOOT must be enabled for DECRYPTION_SUPPORT to be set)
+ else
+ $(info DECRYPTION_SUPPORT is an experimental feature)
+ endif
+endif
+
################################################################################
# Process platform overrideable behaviour
################################################################################
@@ -694,6 +724,10 @@ include lib/stack_protector/stack_protector.mk
CRTTOOLPATH ?= tools/cert_create
CRTTOOL ?= ${CRTTOOLPATH}/cert_create${BIN_EXT}
+# Variables for use with Firmware Encryption Tool
+ENCTOOLPATH ?= tools/encrypt_fw
+ENCTOOL ?= ${ENCTOOLPATH}/encrypt_fw${BIN_EXT}
+
# Variables for use with Firmware Image Package
FIPTOOLPATH ?= tools/fiptool
FIPTOOL ?= ${FIPTOOLPATH}/fiptool${BIN_EXT}
@@ -701,6 +735,7 @@ FIPTOOL ?= ${FIPTOOLPATH}/fiptool${BIN_EXT}
# Variables for use with sptool
SPTOOLPATH ?= tools/sptool
SPTOOL ?= ${SPTOOLPATH}/sptool${BIN_EXT}
+SP_MK_GEN ?= ${SPTOOLPATH}/sp_mk_generator.py
# Variables for use with ROMLIB
ROMLIBPATH ?= lib/romlib
@@ -747,12 +782,14 @@ endif
# Build options checks
################################################################################
+$(eval $(call assert_boolean,ALLOW_RO_XLAT_TABLES))
$(eval $(call assert_boolean,COLD_BOOT_SINGLE_CPU))
$(eval $(call assert_boolean,CREATE_KEYS))
$(eval $(call assert_boolean,CTX_INCLUDE_AARCH32_REGS))
$(eval $(call assert_boolean,CTX_INCLUDE_FPREGS))
$(eval $(call assert_boolean,CTX_INCLUDE_PAUTH_REGS))
$(eval $(call assert_boolean,CTX_INCLUDE_MTE_REGS))
+$(eval $(call assert_boolean,CTX_INCLUDE_EL2_REGS))
$(eval $(call assert_boolean,DEBUG))
$(eval $(call assert_boolean,DYN_DISABLE_AUTH))
$(eval $(call assert_boolean,EL3_EXCEPTION_HANDLING))
@@ -771,6 +808,7 @@ $(eval $(call assert_boolean,GENERATE_COT))
$(eval $(call assert_boolean,GICV2_G0_FOR_EL3))
$(eval $(call assert_boolean,HANDLE_EA_EL3_FIRST))
$(eval $(call assert_boolean,HW_ASSISTED_COHERENCY))
+$(eval $(call assert_boolean,INVERTED_MEMMAP))
$(eval $(call assert_boolean,MEASURED_BOOT))
$(eval $(call assert_boolean,NS_TIMER_SWITCH))
$(eval $(call assert_boolean,OVERRIDE_LIBC))
@@ -784,6 +822,7 @@ $(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA))
$(eval $(call assert_boolean,SEPARATE_NOBITS_REGION))
$(eval $(call assert_boolean,SPIN_ON_BL1_EXIT))
$(eval $(call assert_boolean,SPM_MM))
+$(eval $(call assert_boolean,SPMD_SPM_AT_SEL2))
$(eval $(call assert_boolean,TRUSTED_BOARD_BOOT))
$(eval $(call assert_boolean,USE_COHERENT_MEM))
$(eval $(call assert_boolean,USE_DEBUGFS))
@@ -795,10 +834,13 @@ $(eval $(call assert_boolean,BL2_AT_EL3))
$(eval $(call assert_boolean,BL2_IN_XIP_MEM))
$(eval $(call assert_boolean,BL2_INV_DCACHE))
$(eval $(call assert_boolean,USE_SPINLOCK_CAS))
+$(eval $(call assert_boolean,ENCRYPT_BL31))
+$(eval $(call assert_boolean,ENCRYPT_BL32))
$(eval $(call assert_numeric,ARM_ARCH_MAJOR))
$(eval $(call assert_numeric,ARM_ARCH_MINOR))
$(eval $(call assert_numeric,BRANCH_PROTECTION))
+$(eval $(call assert_numeric,FW_ENC_STATUS))
ifdef KEY_SIZE
$(eval $(call assert_numeric,KEY_SIZE))
@@ -814,6 +856,7 @@ endif
# platform to overwrite the default options
################################################################################
+$(eval $(call add_define,ALLOW_RO_XLAT_TABLES))
$(eval $(call add_define,ARM_ARCH_MAJOR))
$(eval $(call add_define,ARM_ARCH_MINOR))
$(eval $(call add_define,COLD_BOOT_SINGLE_CPU))
@@ -822,6 +865,8 @@ $(eval $(call add_define,CTX_INCLUDE_FPREGS))
$(eval $(call add_define,CTX_INCLUDE_PAUTH_REGS))
$(eval $(call add_define,EL3_EXCEPTION_HANDLING))
$(eval $(call add_define,CTX_INCLUDE_MTE_REGS))
+$(eval $(call add_define,CTX_INCLUDE_EL2_REGS))
+$(eval $(call add_define,DECRYPTION_SUPPORT_${DECRYPTION_SUPPORT}))
$(eval $(call add_define,ENABLE_AMU))
$(eval $(call add_define,ENABLE_ASSERTIONS))
$(eval $(call add_define,ENABLE_BTI))
@@ -833,6 +878,8 @@ $(eval $(call add_define,ENABLE_PSCI_STAT))
$(eval $(call add_define,ENABLE_RUNTIME_INSTRUMENTATION))
$(eval $(call add_define,ENABLE_SPE_FOR_LOWER_ELS))
$(eval $(call add_define,ENABLE_SVE_FOR_NS))
+$(eval $(call add_define,ENCRYPT_BL31))
+$(eval $(call add_define,ENCRYPT_BL32))
$(eval $(call add_define,ERROR_DEPRECATED))
$(eval $(call add_define,FAULT_INJECTION_SUPPORT))
$(eval $(call add_define,GICV2_G0_FOR_EL3))
@@ -853,6 +900,7 @@ $(eval $(call add_define,RECLAIM_INIT_CODE))
$(eval $(call add_define,SPD_${SPD}))
$(eval $(call add_define,SPIN_ON_BL1_EXIT))
$(eval $(call add_define,SPM_MM))
+$(eval $(call add_define,SPMD_SPM_AT_SEL2))
$(eval $(call add_define,TRUSTED_BOARD_BOOT))
$(eval $(call add_define,USE_COHERENT_MEM))
$(eval $(call add_define,USE_DEBUGFS))
@@ -889,11 +937,22 @@ ifneq ($(findstring armlink,$(notdir $(LD))),)
$(eval $(call add_define,USE_ARM_LINK))
endif
+# Generate and include sp_gen.mk if SPD is spmd and SP_LAYOUT_FILE is defined
+ifdef SP_LAYOUT_FILE
+ifeq (${SPD},spmd)
+ -include $(BUILD_PLAT)/sp_gen.mk
+ FIP_DEPS += sp
+ NEED_SP_PKG := yes
+else
+ $(error "SP_LAYOUT_FILE will be used only if SPD=spmd")
+endif
+endif
+
################################################################################
# Build targets
################################################################################
-.PHONY: all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool sptool fip fwu_fip certtool dtbs memmap doc
+.PHONY: all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool sptool fip sp fwu_fip certtool dtbs memmap doc enctool
.SUFFIXES:
all: msg_start
@@ -941,9 +1000,14 @@ endif
ifeq (${NEED_BL31},yes)
BL31_SOURCES += ${SPD_SOURCES}
+ifneq (${DECRYPTION_SUPPORT},none)
+$(if ${BL31}, $(eval $(call TOOL_ADD_IMG,bl31,--soc-fw,,$(ENCRYPT_BL31))),\
+ $(eval $(call MAKE_BL,31,soc-fw,,$(ENCRYPT_BL31))))
+else
$(if ${BL31}, $(eval $(call TOOL_ADD_IMG,bl31,--soc-fw)),\
$(eval $(call MAKE_BL,31,soc-fw)))
endif
+endif
# If a BL32 image is needed but neither BL32 nor BL32_SOURCES is defined, the
# build system will call TOOL_ADD_IMG to print a warning message and abort the
@@ -952,9 +1016,14 @@ ifeq (${NEED_BL32},yes)
BUILD_BL32 := $(if $(BL32),,$(if $(BL32_SOURCES),1))
+ifneq (${DECRYPTION_SUPPORT},none)
+$(if ${BUILD_BL32}, $(eval $(call MAKE_BL,32,tos-fw,,$(ENCRYPT_BL32))),\
+ $(eval $(call TOOL_ADD_IMG,bl32,--tos-fw,,$(ENCRYPT_BL32))))
+else
$(if ${BUILD_BL32}, $(eval $(call MAKE_BL,32,tos-fw)),\
$(eval $(call TOOL_ADD_IMG,bl32,--tos-fw)))
endif
+endif
# Add the BL33 image if required by the platform
ifeq (${NEED_BL33},yes)
@@ -971,6 +1040,17 @@ ifeq (${NEED_FDT},yes)
$(eval $(call MAKE_DTBS,$(BUILD_PLAT)/fdts,$(FDT_SOURCES)))
endif
+# Add Secure Partition packages
+ifeq (${NEED_SP_PKG},yes)
+$(BUILD_PLAT)/sp_gen.mk: ${SP_MK_GEN} ${SP_LAYOUT_FILE} | ${BUILD_PLAT}
+ ${Q}${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT)
+sp: $(SPTOOL) $(DTBS) $(BUILD_PLAT)/sp_gen.mk
+ ${Q}$(SPTOOL) $(SPTOOL_ARGS)
+ @${ECHO_BLANK_LINE}
+ @echo "Built SP Images successfully"
+ @${ECHO_BLANK_LINE}
+endif
+
locate-checkpatch:
ifndef CHECKPATCH
$(error "Please set CHECKPATCH to point to the Linux checkpatch.pl file, eg: CHECKPATCH=../linux/scripts/checkpatch.pl")
@@ -985,6 +1065,7 @@ clean:
$(call SHELL_REMOVE_DIR,${BUILD_PLAT})
${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
+ ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} clean
${Q}${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
realclean distclean:
@@ -994,6 +1075,7 @@ realclean distclean:
${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
${Q}${MAKE} --no-print-directory -C ${SPTOOLPATH} clean
${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
+ ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} realclean
${Q}${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
checkcodebase: locate-checkpatch
@@ -1089,12 +1171,21 @@ romlib.bin: libraries
# Call print_memory_map tool
memmap: all
- ${Q}${PYTHON} $(PRINT_MEMORY_MAP) $(BUILD_PLAT)
+ ${Q}${PYTHON} ${PRINT_MEMORY_MAP} ${BUILD_PLAT} ${INVERTED_MEMMAP}
doc:
@echo " BUILD DOCUMENTATION"
${Q}${MAKE} --no-print-directory -C ${DOCS_PATH} html
+enctool: ${ENCTOOL}
+
+.PHONY: ${ENCTOOL}
+${ENCTOOL}:
+ ${Q}${MAKE} PLAT=${PLAT} BUILD_INFO=0 --no-print-directory -C ${ENCTOOLPATH}
+ @${ECHO_BLANK_LINE}
+ @echo "Built $@ successfully"
+ @${ECHO_BLANK_LINE}
+
cscope:
@echo " CSCOPE"
${Q}find ${CURDIR} -name "*.[chsS]" > cscope.files
@@ -1131,7 +1222,9 @@ help:
@echo " cscope Generate cscope index"
@echo " distclean Remove all build artifacts for all platforms"
@echo " certtool Build the Certificate generation tool"
+ @echo " enctool Build the Firmware encryption tool"
@echo " fiptool Build the Firmware Image Package (FIP) creation tool"
+ @echo " sp Build the Secure Partition Packages"
@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"
diff --git a/bl1/aarch32/bl1_exceptions.S b/bl1/aarch32/bl1_exceptions.S
index f2af9ab5b..493d2ca4e 100644
--- a/bl1/aarch32/bl1_exceptions.S
+++ b/bl1/aarch32/bl1_exceptions.S
@@ -80,7 +80,7 @@ debug_loop:
add r8, r8, #ENTRY_POINT_INFO_ARGS_OFFSET
ldm r8, {r0, r1, r2, r3}
- eret
+ exception_return
endfunc bl1_aarch32_smc_handler
/* -----------------------------------------------------
diff --git a/bl2/aarch32/bl2_el3_entrypoint.S b/bl2/aarch32/bl2_el3_entrypoint.S
index 9b4da6b13..2e851e61a 100644
--- a/bl2/aarch32/bl2_el3_entrypoint.S
+++ b/bl2/aarch32/bl2_el3_entrypoint.S
@@ -87,5 +87,5 @@ func bl2_run_next_image
add r8, r8, #ENTRY_POINT_INFO_ARGS_OFFSET
ldm r8, {r0, r1, r2, r3}
- eret
+ exception_return
endfunc bl2_run_next_image
diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c
index e1d961cc6..9da2f9af9 100644
--- a/bl32/tsp/tsp_main.c
+++ b/bl32/tsp/tsp_main.c
@@ -273,11 +273,11 @@ tsp_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl,
spin_lock(&console_lock);
INFO("TSP: cpu 0x%lx resumed. maximum off power level %lld\n",
read_mpidr(), max_off_pwrlvl);
- INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu suspend requests\n",
+ INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu resume requests\n",
read_mpidr(),
tsp_stats[linear_id].smc_count,
tsp_stats[linear_id].eret_count,
- tsp_stats[linear_id].cpu_suspend_count);
+ tsp_stats[linear_id].cpu_resume_count);
spin_unlock(&console_lock);
#endif
/* Indicate to the SPD that we have completed this request */
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 802dafcd8..2bf5eb7ba 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -53,7 +53,6 @@ Amlogic Meson S905x (GXL) platform port
:M: Remi Pommarel <repk@triplefau.lt>
:G: `remi-triplefault`_
:F: docs/plat/meson-gxl.rst
-:F: drivers/amlogic/gxl
:F: plat/amlogic/gxl/
Amlogic Meson S905X2 (G12A) platform port
@@ -61,7 +60,6 @@ Amlogic Meson S905X2 (G12A) platform port
:M: Carlo Caione <ccaione@baylibre.com>
:G: `carlocaione`_
:F: docs/plat/meson-g12a.rst
-:F: drivers/amlogic/g12a
:F: plat/amlogic/g12a/
Amlogic Meson A113D (AXG) platform port
@@ -69,7 +67,6 @@ 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
@@ -152,7 +149,7 @@ Marvell platform ports and SoC drivers
--------------------------------------
:M: Konstantin Porotchkin <kostap@marvell.com>
:G: `kostapr`_
-:F: docs/marvell/
+:F: docs/plat/marvell/
:F: plat/marvell/
:F: drivers/marvell/
:F: tools/marvell/
@@ -197,14 +194,14 @@ NXP i.MX8M platform port
------------------------
:M: Jacky Bai <ping.bai@nxp.com>
:G: `JackyBai`_
-:F: doc/plat/imx8m.rst
+:F: docs/plat/imx8m.rst
:F: plat/imx/imx8m/
OP-TEE dispatcher
-----------------
:M: Jens Wiklander <jens.wiklander@linaro.org>
:G: `jenswi-linaro`_
-:F: docs/spd/optee-dispatcher.rst
+:F: docs/components/spd/optee-dispatcher.rst
:F: services/spd/opteed/
QEMU platform port
@@ -219,7 +216,7 @@ Raspberry Pi 3 platform port
:M: Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
:G: `grandpaul`_
:F: docs/plat/rpi3.rst
-:F: plat/rpi3/
+:F: plat/rpi/rpi3/
:F: drivers/rpi3/
:F: include/drivers/rpi3/
@@ -273,8 +270,8 @@ TLK/Trusty secure payloads
--------------------------
:M: Varun Wadekar <vwadekar@nvidia.com>
:G: `vwadekar`_
-:F: docs/spd/tlk-dispatcher.rst
-:F: docs/spd/trusty-dispatcher.rst
+:F: docs/components/spd/tlk-dispatcher.rst
+:F: docs/components/spd/trusty-dispatcher.rst
:F: include/bl32/payloads/tlk.h
:F: services/spd/tlkd/
:F: services/spd/trusty/
diff --git a/docs/change-log-upcoming.rst b/docs/change-log-upcoming.rst
index 14280cbf7..15f39de63 100644
--- a/docs/change-log-upcoming.rst
+++ b/docs/change-log-upcoming.rst
@@ -33,6 +33,7 @@ New Features
- Libraries
- Example: "Introduce BTI support in Library at ROM (romlib)"
+ - Add Firmware Configuration Framework (fconf).
- New Platforms Support
- Example: "qemu/qemu_sbsa: New platform support added for QEMU SBSA platform"
@@ -45,6 +46,7 @@ New Features
- Security
- Example: "UBSAN support and handlers"
+ - Add support for optional firmware encryption feature (experimental).
- Tools
- Example: "fiptool: Add support to build fiptool on Windows."
diff --git a/docs/design/auth-framework.rst b/docs/design/auth-framework.rst
index 93f691b7b..1a53e2292 100644
--- a/docs/design/auth-framework.rst
+++ b/docs/design/auth-framework.rst
@@ -621,7 +621,7 @@ The TBBR CoT
The CoT can be found in ``drivers/auth/tbbr/tbbr_cot.c``. This CoT consists of
an array of pointers to image descriptors and it is registered in the framework
-using the macro ``REGISTER_COT(cot_desc)``, where 'cot_desc' must be the name
+using the macro ``REGISTER_COT(cot_desc)``, where ``cot_desc`` must be the name
of the array (passing a pointer or any other type of indirection will cause the
registration process to fail).
@@ -870,32 +870,32 @@ Once the signature has been checked and the certificate authenticated, the
Trusted World public key needs to be extracted from the certificate. A new entry
is created in the ``authenticated_data`` array for that purpose. In that entry,
the corresponding parameter descriptor must be specified along with the buffer
-address to store the parameter value. In this case, the ``tz_world_pk`` descriptor
-is used to extract the public key from an x509v3 extension with OID
+address to store the parameter value. In this case, the ``trusted_world_pk``
+descriptor is used to extract the public key from an x509v3 extension with OID
``TRUSTED_WORLD_PK_OID``. The BL31 key certificate will use this descriptor as
parameter in the signature authentication method. The key is stored in the
-``plat_tz_world_pk_buf`` buffer.
+``trusted_world_pk_buf`` buffer.
The **BL31 Key certificate** is authenticated by checking its digital signature
using the Trusted World public key obtained previously from the Trusted Key
certificate. In the image descriptor, we specify a single authentication method
-by signature whose public key is the ``tz_world_pk``. Once this certificate has
-been authenticated, we have to extract the BL31 public key, stored in the
-extension specified by ``bl31_content_pk``. This key will be copied to the
-``plat_content_pk`` buffer.
+by signature whose public key is the ``trusted_world_pk``. Once this certificate
+has been authenticated, we have to extract the BL31 public key, stored in the
+extension specified by ``soc_fw_content_pk``. This key will be copied to the
+``content_pk_buf`` buffer.
The **BL31 certificate** is authenticated by checking its digital signature
using the BL31 public key obtained previously from the BL31 Key certificate.
-We specify the authentication method using ``bl31_content_pk`` as public key.
+We specify the authentication method using ``soc_fw_content_pk`` as public key.
After authentication, we need to extract the BL31 hash, stored in the extension
-specified by ``bl31_hash``. This hash will be copied to the ``plat_bl31_hash_buf``
-buffer.
+specified by ``soc_fw_hash``. This hash will be copied to the
+``soc_fw_hash_buf`` buffer.
The **BL31 image** is authenticated by calculating its hash and matching it
with the hash obtained from the BL31 certificate. The image descriptor contains
a single authentication method by hash. The parameters to the hash method are
-the reference hash, ``bl31_hash``, and the data to be hashed. In this case, it is
-the whole image, so we specify ``raw_data``.
+the reference hash, ``soc_fw_hash``, and the data to be hashed. In this case,
+it is the whole image, so we specify ``raw_data``.
The image parser library
~~~~~~~~~~~~~~~~~~~~~~~~
@@ -934,7 +934,7 @@ i.e. verify a hash or a digital signature. Arm platforms will use a library
based on mbed TLS, which can be found in
``drivers/auth/mbedtls/mbedtls_crypto.c``. This library is registered in the
authentication framework using the macro ``REGISTER_CRYPTO_LIB()`` and exports
-three functions:
+four functions:
.. code:: c
@@ -945,6 +945,11 @@ three functions:
void *pk_ptr, unsigned int pk_len);
int verify_hash(void *data_ptr, unsigned int data_len,
void *digest_info_ptr, unsigned int digest_info_len);
+ int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
+ size_t len, const void *key, unsigned int key_len,
+ unsigned int key_flags, const void *iv,
+ unsigned int iv_len, const void *tag,
+ unsigned int tag_len)
The mbedTLS library algorithm support is configured by both the
``TF_MBEDTLS_KEY_ALG`` and ``TF_MBEDTLS_KEY_SIZE`` variables.
@@ -957,6 +962,9 @@ The mbedTLS library algorithm support is configured by both the
- ``TF_MBEDTLS_KEY_SIZE`` sets the supported RSA key size for TFA. Valid values
include 1024, 2048, 3072 and 4096.
+- ``TF_MBEDTLS_USE_AES_GCM`` enables the authenticated decryption support based
+ on AES-GCM algorithm. Valid values are 0 and 1.
+
.. note::
If code size is a concern, the build option ``MBEDTLS_SHA256_SMALLER`` can
be defined in the platform Makefile. It will make mbed TLS use an
@@ -965,6 +973,6 @@ The mbedTLS library algorithm support is configured by both the
--------------
-*Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.*
.. _TBBR-Client specification: https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
diff --git a/docs/design/trusted-board-boot.rst b/docs/design/trusted-board-boot.rst
index 49e8adb98..4802c97f3 100644
--- a/docs/design/trusted-board-boot.rst
+++ b/docs/design/trusted-board-boot.rst
@@ -229,6 +229,34 @@ library that is required is given in the :ref:`Prerequisites` document.
Instructions for building and using the tool can be found at
:ref:`tools_build_cert_create`.
+Authenticated Encryption Framework
+----------------------------------
+
+The authenticated encryption framework included in TF-A provides support to
+implement the optional firmware encryption feature. This feature can be
+optionally enabled on platforms to implement the optional requirement:
+R060_TBBR_FUNCTION as specified in the `Trusted Board Boot Requirements (TBBR)`_
+document.
+
+Note that due to security considerations and complexity of this feature, it is
+marked as experimental.
+
+Firmware Encryption Tool
+------------------------
+
+The ``encrypt_fw`` tool is built and runs on the host machine as part of the
+TF-A build process when ``DECRYPTION_SUPPORT != none``. It takes the plain
+firmware image as input and generates the encrypted firmware image which can
+then be passed as input to the ``fiptool`` utility for creating the FIP.
+
+The encrypted firmwares are also stored individually in the output build
+directory.
+
+The tool resides in the ``tools/encrypt_fw`` directory. It uses OpenSSL SSL
+library version 1.0.1 or later to do authenticated encryption operation.
+Instructions for building and using the tool can be found in the
+:ref:`tools_build_enctool`.
+
--------------
*Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 8854a7989..f138feb4c 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -160,6 +160,12 @@ Common build options
- ``DEBUG``: Chooses between a debug and release build. It can take either 0
(release) or 1 (debug) as values. 0 is the default.
+- ``DECRYPTION_SUPPORT``: This build flag enables the user to select the
+ authenticated decryption algorithm to be used to decrypt firmware/s during
+ boot. It accepts 2 values: ``aes_gcm`` and ``none``. The default value of
+ this flag is ``none`` to disable firmware decryption which is an optional
+ feature as per TBBR. Also, it is an experimental feature.
+
- ``DISABLE_BIN_GENERATION``: Boolean option to disable the generation
of the binary image. If set to 1, then only the ELF image is built.
0 is the default.
@@ -257,6 +263,22 @@ Common build options
platform hook needs to be implemented. The value is passed as the last
component of the option ``-fstack-protector-$ENABLE_STACK_PROTECTOR``.
+- ``ENCRYPT_BL31``: Binary flag to enable encryption of BL31 firmware. This
+ flag depends on ``DECRYPTION_SUPPORT`` build flag which is marked as
+ experimental.
+
+- ``ENCRYPT_BL32``: Binary flag to enable encryption of Secure BL32 payload.
+ This flag depends on ``DECRYPTION_SUPPORT`` build flag which is marked as
+ experimental.
+
+- ``ENC_KEY``: A 32-byte (256-bit) symmetric key in hex string format. It could
+ either be SSK or BSSK depending on ``FW_ENC_STATUS`` flag. This value depends
+ on ``DECRYPTION_SUPPORT`` build flag which is marked as experimental.
+
+- ``ENC_NONCE``: A 12-byte (96-bit) encryption nonce or Initialization Vector
+ (IV) in hex string format. This value depends on ``DECRYPTION_SUPPORT``
+ build flag which is marked as experimental.
+
- ``ERROR_DEPRECATED``: This option decides whether to treat the usage of
deprecated platform APIs, helper functions or drivers within Trusted
Firmware as error. It can take the value 1 (flag the use of deprecated
@@ -281,6 +303,18 @@ Common build options
- ``FWU_FIP_NAME``: This is an optional build option which specifies the FWU
FIP filename for the ``fwu_fip`` target. Default is ``fwu_fip.bin``.
+- ``FW_ENC_STATUS``: Top level firmware's encryption numeric flag, values:
+
+ ::
+
+ 0: Encryption is done with Secret Symmetric Key (SSK) which is common
+ for a class of devices.
+ 1: Encryption is done with Binding Secret Symmetric Key (BSSK) which is
+ unique per device.
+
+ This flag depends on ``DECRYPTION_SUPPORT`` build flag which is marked as
+ experimental.
+
- ``GENERATE_COT``: Boolean flag used to build and execute the ``cert_create``
tool to create certificates as per the Chain of Trust described in
:ref:`Trusted Board Boot`. The build system then calls ``fiptool`` to
@@ -340,6 +374,11 @@ Common build options
translation library (xlat tables v2) must be used; version 1 of translation
library is not supported.
+- ``INVERTED_MEMMAP``: memmap tool print by default lower addresses at the
+ bottom, higher addresses at the top. This buid flag can be set to '1' to
+ invert this behavior. Lower addresses will be printed at the top and higher
+ addresses at the bottom.
+
- ``JUNO_AARCH32_EL3_RUNTIME``: This build flag enables you to execute EL3
runtime software in AArch32 mode, which is required to run AArch32 on Juno.
By default this flag is set to '0'. Enabling this flag builds BL1 and BL2 in
@@ -522,6 +561,11 @@ Common build options
- ``SPM_MM`` : Boolean option to enable the Management Mode (MM)-based Secure
Partition Manager (SPM) implementation. The default value is ``0``.
+- ``SP_LAYOUT_FILE``: Platform provided path to JSON file containing the
+ description of secure partitions. Build system will parse this file and
+ package all secure partition blobs in FIP. This file not necessarily be
+ part of TF-A tree. Only avaialbe when ``SPD=spmd``.
+
- ``SP_MIN_WITH_SECURE_FIQ``: Boolean flag to indicate the SP_MIN handles
secure interrupts (caught through the FIQ line). Platforms can enable
this directive if they need to handle such interruption. When enabled,
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index e8357b385..d634d2e70 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -872,6 +872,35 @@ twice.
On success the function should return 0 and a negative error code otherwise.
+Function : plat_get_enc_key_info() [when FW_ENC_STATUS == 0 or 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Arguments : enum fw_enc_status_t fw_enc_status, uint8_t *key,
+ size_t *key_len, unsigned int *flags, const uint8_t *img_id,
+ size_t img_id_len
+ Return : int
+
+This function provides a symmetric key (either SSK or BSSK depending on
+fw_enc_status) which is invoked during runtime decryption of encrypted
+firmware images. `plat/common/plat_bl_common.c` provides a dummy weak
+implementation for testing purposes which must be overridden by the platform
+trying to implement a real world firmware encryption use-case.
+
+It also allows the platform to pass symmetric key identifier rather than
+actual symmetric key which is useful in cases where the crypto backend provides
+secure storage for the symmetric key. So in this case ``ENC_KEY_IS_IDENTIFIER``
+flag must be set in ``flags``.
+
+In addition to above a platform may also choose to provide an image specific
+symmetric key/identifier using img_id.
+
+On success the function should return 0 and a negative error code otherwise.
+
+Note that this API depends on ``DECRYPTION_SUPPORT`` build flag which is
+marked as experimental.
+
Common optional modifications
-----------------------------
diff --git a/docs/getting_started/tools-build.rst b/docs/getting_started/tools-build.rst
index bb707cb7c..c050f5851 100644
--- a/docs/getting_started/tools-build.rst
+++ b/docs/getting_started/tools-build.rst
@@ -135,6 +135,33 @@ verbose. The following command should be used to obtain help about the tool:
./tools/cert_create/cert_create -h
+.. _tools_build_enctool:
+
+Building the Firmware Encryption Tool
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``encrypt_fw`` tool is built as part of the TF-A build process when the
+``fip`` make target is specified, DECRYPTION_SUPPORT and TBB are enabled, but
+it can also be built separately with the following command:
+
+.. code:: shell
+
+ make PLAT=<platform> [DEBUG=1] [V=1] enctool
+
+``DEBUG=1`` builds the tool in debug mode. ``V=1`` makes the build process more
+verbose. The following command should be used to obtain help about the tool:
+
+.. code:: shell
+
+ ./tools/encrypt_fw/encrypt_fw -h
+
+Note that the enctool in its current implementation only supports encryption
+key to be provided in plain format. A typical implementation can very well
+extend this tool to support custom techniques to protect encryption key.
+
+Also, a user may choose to provide encryption key or nonce as an input file
+via using ``cat <filename>`` instead of a hex string.
+
--------------
*Copyright (c) 2019, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
index 40e966117..169b6f366 100644
--- a/docs/plat/arm/fvp/index.rst
+++ b/docs/plat/arm/fvp/index.rst
@@ -26,6 +26,8 @@ Arm FVPs without shifted affinities, and that do not support threaded CPU cores
- ``FVP_Base_Cortex-A57x2-A53x4``
- ``FVP_Base_Cortex-A57x4-A53x4``
- ``FVP_Base_Cortex-A57x4``
+- ``FVP_Base_Cortex-A65x4`` (Version 11.9 build 41)
+- ``FVP_Base_Cortex-A65AEx8`` (Version 11.9 build 41)
- ``FVP_Base_Cortex-A72x4-A53x4``
- ``FVP_Base_Cortex-A72x4``
- ``FVP_Base_Cortex-A73x4-A53x4``
@@ -628,7 +630,7 @@ boot Linux with 4 CPUs using the AArch32 build of TF-A.
--------------
-*Copyright (c) 2019, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
.. _TB_FW_CONFIG for FVP: ../plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
.. _Arm's website: `FVP models`_
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index 63d29a9be..a6ef1884b 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -9,6 +9,7 @@ Platform Ports
allwinner
arm/index
+ meson-axg
meson-gxbb
meson-gxl
meson-g12a
@@ -53,4 +54,4 @@ documentation associated with them.
--------------
-*Copyright (c) 2019, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/docs/plat/qemu.rst b/docs/plat/qemu.rst
index 88196bc93..afa32c11b 100644
--- a/docs/plat/qemu.rst
+++ b/docs/plat/qemu.rst
@@ -21,11 +21,13 @@ Current limitations:
- Only cold boot is supported
- No build instructions for QEMU\_EFI.fd and rootfs-arm64.cpio.gz
-- 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_GCC5/QEMU_EFI.fd
+Booting via semi-hosting option
+-------------------------------
+
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
is conveniently achieved with symlinks the local names as:
@@ -50,3 +52,52 @@ To start (QEMU v4.1.0):
-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
+
+Booting via flash based firmwares
+---------------------------------
+
+Boot firmwares are loaded via secure FLASH0 device so ``bl1.bin`` and
+``fip.bin`` should be concatenated to create a ``flash.bin`` that is flashed
+onto secure FLASH0.
+
+- ``bl32.bin`` -> BL32 (``tee-header_v2.bin``)
+- ``bl32_extra1.bin`` -> BL32 Extra1 (``tee-pager_v2.bin``)
+- ``bl32_extra2.bin`` -> BL32 Extra2 (``tee-pageable_v2.bin``)
+- ``bl33.bin`` -> BL33 (``QEMU_EFI.fd``)
+- ``Image`` -> linux/arch/arm64/boot/Image
+
+To build:
+
+.. code:: shell
+
+ make CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu BL32=bl32.bin \
+ BL32_EXTRA1=bl32_extra1.bin BL32_EXTRA2=bl32_extra2.bin \
+ BL33=bl33.bin BL32_RAM_LOCATION=tdram SPD=opteed all fip
+
+To build with TBBR enabled, BL31 and BL32 encrypted with test key:
+
+.. code:: shell
+
+ make CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu BL32=bl32.bin \
+ BL32_EXTRA1=bl32_extra1.bin BL32_EXTRA2=bl32_extra2.bin \
+ BL33=bl33.bin BL32_RAM_LOCATION=tdram SPD=opteed all fip \
+ MBEDTLS_DIR=<path-to-mbedtls-repo> TRUSTED_BOARD_BOOT=1 \
+ GENERATE_COT=1 DECRYPTION_SUPPORT=aes_gcm FW_ENC_STATUS=0 \
+ ENCRYPT_BL31=1 ENCRYPT_BL32=1
+
+To build flash.bin:
+
+.. code:: shell
+
+ dd if=build/qemu/release/bl1.bin of=flash.bin bs=4096 conv=notrunc
+ dd if=build/qemu/release/fip.bin of=flash.bin seek=64 bs=4096 conv=notrunc
+
+To start (QEMU v2.6.0):
+
+.. code:: shell
+
+ qemu-system-aarch64 -nographic -machine virt,secure=on -cpu cortex-a57 \
+ -kernel Image -no-acpi \
+ -append 'console=ttyAMA0,38400 keep_bootcon root=/dev/vda2' \
+ -initrd rootfs-arm64.cpio.gz -smp 2 -m 1024 -bios flash.bin \
+ -d unimp
diff --git a/drivers/allwinner/sunxi_msgbox.c b/drivers/allwinner/sunxi_msgbox.c
new file mode 100644
index 000000000..cc4a6ffcb
--- /dev/null
+++ b/drivers/allwinner/sunxi_msgbox.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+
+#include <drivers/delay_timer.h>
+#include <lib/bakery_lock.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+#include <sunxi_mmap.h>
+
+#define REMOTE_IRQ_EN_REG 0x0040
+#define REMOTE_IRQ_STAT_REG 0x0050
+#define LOCAL_IRQ_EN_REG 0x0060
+#define LOCAL_IRQ_STAT_REG 0x0070
+
+#define RX_IRQ(n) BIT(0 + 2 * (n))
+#define TX_IRQ(n) BIT(1 + 2 * (n))
+
+#define FIFO_STAT_REG(n) (0x0100 + 0x4 * (n))
+#define FIFO_STAT_MASK GENMASK(0, 0)
+
+#define MSG_STAT_REG(n) (0x0140 + 0x4 * (n))
+#define MSG_STAT_MASK GENMASK(2, 0)
+
+#define MSG_DATA_REG(n) (0x0180 + 0x4 * (n))
+
+#define RX_CHAN 1
+#define TX_CHAN 0
+
+#define MHU_MAX_SLOT_ID 31
+
+#define MHU_TIMEOUT_DELAY 10
+#define MHU_TIMEOUT_ITERS 10000
+
+static DEFINE_BAKERY_LOCK(mhu_secure_message_lock);
+
+static bool sunxi_msgbox_last_tx_done(unsigned int chan)
+{
+ uint32_t stat = mmio_read_32(SUNXI_MSGBOX_BASE + REMOTE_IRQ_STAT_REG);
+
+ return (stat & RX_IRQ(chan)) == 0U;
+}
+
+static bool sunxi_msgbox_peek_data(unsigned int chan)
+{
+ uint32_t stat = mmio_read_32(SUNXI_MSGBOX_BASE + MSG_STAT_REG(chan));
+
+ return (stat & MSG_STAT_MASK) != 0U;
+}
+
+void mhu_secure_message_start(unsigned int slot_id __unused)
+{
+ uint32_t timeout = MHU_TIMEOUT_ITERS;
+
+ bakery_lock_get(&mhu_secure_message_lock);
+
+ /* Wait for all previous messages to be acknowledged. */
+ while (!sunxi_msgbox_last_tx_done(TX_CHAN) && --timeout)
+ udelay(MHU_TIMEOUT_DELAY);
+}
+
+void mhu_secure_message_send(unsigned int slot_id)
+{
+ mmio_write_32(SUNXI_MSGBOX_BASE + MSG_DATA_REG(TX_CHAN), BIT(slot_id));
+}
+
+uint32_t mhu_secure_message_wait(void)
+{
+ uint32_t timeout = MHU_TIMEOUT_ITERS;
+ uint32_t msg = 0;
+
+ /* Wait for a message from the SCP. */
+ while (!sunxi_msgbox_peek_data(RX_CHAN) && --timeout)
+ udelay(MHU_TIMEOUT_DELAY);
+
+ /* Return the most recent message in the FIFO. */
+ while (sunxi_msgbox_peek_data(RX_CHAN))
+ msg = mmio_read_32(SUNXI_MSGBOX_BASE + MSG_DATA_REG(RX_CHAN));
+
+ return msg;
+}
+
+void mhu_secure_message_end(unsigned int slot_id)
+{
+ /* Acknowledge a response by clearing the IRQ status. */
+ mmio_write_32(SUNXI_MSGBOX_BASE + LOCAL_IRQ_STAT_REG, RX_IRQ(RX_CHAN));
+
+ bakery_lock_release(&mhu_secure_message_lock);
+}
diff --git a/drivers/amlogic/console/aarch64/meson_console.S b/drivers/amlogic/console/aarch64/meson_console.S
index e645cbab8..39c2545e7 100644
--- a/drivers/amlogic/console/aarch64/meson_console.S
+++ b/drivers/amlogic/console/aarch64/meson_console.S
@@ -46,14 +46,14 @@
/* -----------------------------------------------
* int console_meson_register(uintptr_t base,
* uint32_t clk, uint32_t baud,
- * console_meson_t *console);
+ * console_t *console);
* Function to initialize and register a new MESON
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
* In: x0 - UART register base address
* w1 - UART clock in Hz
* w2 - Baud rate
- * x3 - pointer to empty console_meson_t struct
+ * x3 - pointer to empty console_t struct
* Out: return 1 on success, 0 on error
* Clobber list : x0, x1, x2, x6, x7, x14
* -----------------------------------------------
@@ -62,7 +62,7 @@ func console_meson_register
mov x7, x30
mov x6, x3
cbz x6, register_fail
- str x0, [x6, #CONSOLE_T_MESON_BASE]
+ str x0, [x6, #CONSOLE_T_BASE]
bl console_meson_init
cbz x0, register_fail
@@ -128,7 +128,7 @@ init_fail:
endfunc console_meson_init
/* --------------------------------------------------------
- * int console_meson_putc(int c, console_meson_t *console)
+ * int console_meson_putc(int c, console_t *console)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : w0 - character to be printed
@@ -142,7 +142,7 @@ func console_meson_putc
cmp x1, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr x1, [x1, #CONSOLE_T_MESON_BASE]
+ ldr x1, [x1, #CONSOLE_T_BASE]
b console_meson_core_putc
endfunc console_meson_putc
@@ -179,7 +179,7 @@ func console_meson_core_putc
endfunc console_meson_core_putc
/* ---------------------------------------------
- * int console_meson_getc(console_meson_t *console)
+ * int console_meson_getc(console_t *console)
* Function to get a character from the console.
* It returns the character grabbed on success
* or -1 if no character is available.
@@ -193,7 +193,7 @@ func console_meson_getc
cmp x0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr x0, [x0, #CONSOLE_T_MESON_BASE]
+ ldr x0, [x0, #CONSOLE_T_BASE]
b console_meson_core_getc
endfunc console_meson_getc
@@ -224,7 +224,7 @@ func console_meson_core_getc
endfunc console_meson_core_getc
/* ---------------------------------------------
- * int console_meson_flush(console_meson_t *console)
+ * int console_meson_flush(console_t *console)
* Function to force a write of all buffered
* data that hasn't been output.
* In : x0 - pointer to console_t structure
@@ -237,7 +237,7 @@ func console_meson_flush
cmp x0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr x0, [x0, #CONSOLE_T_MESON_BASE]
+ ldr x0, [x0, #CONSOLE_T_BASE]
b console_meson_core_flush
endfunc console_meson_flush
diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c
index 097d2eb2b..aeb7eda30 100644
--- a/drivers/arm/css/scp/css_pm_scmi.c
+++ b/drivers/arm/css/scp/css_pm_scmi.c
@@ -224,8 +224,8 @@ 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 && (core_pos < PLATFORM_CORE_COUNT));
+ core_pos = (unsigned int)plat_core_pos_by_mpidr(mpidr);
+ assert(core_pos < PLATFORM_CORE_COUNT);
css_scp_core_pos_to_scmi_channel(core_pos, &domain_id,
&channel_id);
@@ -256,8 +256,8 @@ int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level)
return PSCI_E_INVALID_PARAMS;
}
- cpu_idx = plat_core_pos_by_mpidr(mpidr);
- assert(cpu_idx > -1);
+ cpu_idx = (unsigned int)plat_core_pos_by_mpidr(mpidr);
+ assert(cpu_idx < PLATFORM_CORE_COUNT);
css_scp_core_pos_to_scmi_channel(cpu_idx, &domain_id, &channel_id);
ret = scmi_pwr_state_get(scmi_handles[channel_id],
diff --git a/drivers/arm/css/scpi/css_scpi.c b/drivers/arm/css/scpi/css_scpi.c
index c56b7c41b..416356bf2 100644
--- a/drivers/arm/css/scpi/css_scpi.c
+++ b/drivers/arm/css/scpi/css_scpi.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
*/
@@ -51,7 +51,7 @@ static void scpi_secure_message_send(size_t payload_size)
mhu_secure_message_send(SCPI_MHU_SLOT_ID);
}
-static void scpi_secure_message_receive(scpi_cmd_t *cmd)
+static int scpi_secure_message_receive(scpi_cmd_t *cmd)
{
uint32_t mhu_status;
@@ -63,7 +63,7 @@ static void scpi_secure_message_receive(scpi_cmd_t *cmd)
if (mhu_status != (1 << SCPI_MHU_SLOT_ID)) {
ERROR("MHU: Unexpected protocol (MHU status: 0x%x)\n",
mhu_status);
- panic();
+ return -1;
}
/*
@@ -74,6 +74,8 @@ static void scpi_secure_message_receive(scpi_cmd_t *cmd)
dmbld();
memcpy(cmd, (void *) SCPI_SHARED_MEM_SCP_TO_AP, sizeof(*cmd));
+
+ return 0;
}
static void scpi_secure_message_end(void)
@@ -84,14 +86,19 @@ static void scpi_secure_message_end(void)
int scpi_wait_ready(void)
{
scpi_cmd_t scpi_cmd;
+ int rc;
VERBOSE("Waiting for SCP_READY command...\n");
/* Get a message from the SCP */
scpi_secure_message_start();
- scpi_secure_message_receive(&scpi_cmd);
+ rc = scpi_secure_message_receive(&scpi_cmd);
scpi_secure_message_end();
+ /* If no message was received, don't send a response */
+ if (rc != 0)
+ return rc;
+
/* We are expecting 'SCP Ready', produce correct error if it's not */
scpi_status_t status = SCP_OK;
if (scpi_cmd.id != SCPI_CMD_SCP_READY) {
@@ -209,7 +216,8 @@ int scpi_get_css_power_state(unsigned int mpidr, unsigned int *cpu_state_p,
* Send message and wait for SCP's response
*/
scpi_secure_message_send(0);
- scpi_secure_message_receive(&response);
+ if (scpi_secure_message_receive(&response) != 0)
+ goto exit;
if (response.status != SCP_OK)
goto exit;
@@ -254,7 +262,9 @@ uint32_t scpi_sys_power_state(scpi_system_state_t system_state)
*payload_addr = system_state & 0xff;
scpi_secure_message_send(sizeof(*payload_addr));
- scpi_secure_message_receive(&response);
+ /* If no response is received, fill in an error status */
+ if (scpi_secure_message_receive(&response) != 0)
+ response.status = SCP_E_TIMEOUT;
scpi_secure_message_end();
diff --git a/drivers/arm/pl011/aarch32/pl011_console.S b/drivers/arm/pl011/aarch32/pl011_console.S
index 05c8250dc..93045f03d 100644
--- a/drivers/arm/pl011/aarch32/pl011_console.S
+++ b/drivers/arm/pl011/aarch32/pl011_console.S
@@ -91,14 +91,14 @@ endfunc console_pl011_core_init
/* -------------------------------------------------------
* int console_pl011_register(uintptr_t baseaddr,
* uint32_t clock, uint32_t baud,
- * console_pl011_t *console);
+ * console_t *console);
* Function to initialize and register a new PL011
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
* In: r0 - UART register base address
* r1 - UART clock in Hz
* r2 - Baud rate
- * r3 - pointer to empty console_pl011_t struct
+ * r3 - pointer to empty console_t struct
* Out: return 1 on success, 0 on error
* Clobber list : r0, r1, r2
* -------------------------------------------------------
@@ -108,7 +108,7 @@ func console_pl011_register
mov r4, r3
cmp r4, #0
beq register_fail
- str r0, [r4, #CONSOLE_T_PL011_BASE]
+ str r0, [r4, #CONSOLE_T_BASE]
bl console_pl011_core_init
cmp r0, #0
@@ -159,7 +159,7 @@ putc_error:
endfunc console_pl011_core_putc
/* --------------------------------------------------------
- * int console_pl011_putc(int c, console_pl011_t *console)
+ * int console_pl011_putc(int c, console_t *console)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In: r0 - character to be printed
@@ -173,7 +173,7 @@ func console_pl011_putc
cmp r1, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr r1, [r1, #CONSOLE_T_PL011_BASE]
+ ldr r1, [r1, #CONSOLE_T_BASE]
b console_pl011_core_putc
endfunc console_pl011_putc
@@ -203,7 +203,7 @@ getc_error:
endfunc console_pl011_core_getc
/* ------------------------------------------------
- * int console_pl011_getc(console_pl011_t *console)
+ * int console_pl011_getc(console_t *console)
* Function to get a character from the console.
* It returns the character grabbed on success
* or -1 if no character is available.
@@ -217,7 +217,7 @@ func console_pl011_getc
cmp r0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr r0, [r0, #CONSOLE_T_PL011_BASE]
+ ldr r0, [r0, #CONSOLE_T_BASE]
b console_pl011_core_getc
endfunc console_pl011_getc
@@ -248,7 +248,7 @@ flush_error:
endfunc console_pl011_core_flush
/* ---------------------------------------------
- * int console_pl011_flush(console_pl011_t *console)
+ * int console_pl011_flush(console_t *console)
* Function to force a write of all buffered
* data that hasn't been output.
* In : r0 - pointer to console_t structure
@@ -261,6 +261,6 @@ func console_pl011_flush
cmp r0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr r0, [r0, #CONSOLE_T_PL011_BASE]
+ ldr r0, [r0, #CONSOLE_T_BASE]
b console_pl011_core_flush
endfunc console_pl011_flush
diff --git a/drivers/arm/pl011/aarch64/pl011_console.S b/drivers/arm/pl011/aarch64/pl011_console.S
index 04de99fbc..3a2a3cdb4 100644
--- a/drivers/arm/pl011/aarch64/pl011_console.S
+++ b/drivers/arm/pl011/aarch64/pl011_console.S
@@ -80,14 +80,14 @@ endfunc console_pl011_core_init
/* -----------------------------------------------
* int console_pl011_register(uintptr_t baseaddr,
* uint32_t clock, uint32_t baud,
- * console_pl011_t *console);
+ * console_t *console);
* Function to initialize and register a new PL011
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
* In: x0 - UART register base address
* w1 - UART clock in Hz
* w2 - Baud rate
- * x3 - pointer to empty console_pl011_t struct
+ * x3 - pointer to empty console_t struct
* Out: return 1 on success, 0 on error
* Clobber list : x0, x1, x2, x6, x7, x14
* -----------------------------------------------
@@ -96,7 +96,7 @@ func console_pl011_register
mov x7, x30
mov x6, x3
cbz x6, register_fail
- str x0, [x6, #CONSOLE_T_PL011_BASE]
+ str x0, [x6, #CONSOLE_T_BASE]
bl console_pl011_core_init
cbz x0, register_fail
@@ -143,7 +143,7 @@ func console_pl011_core_putc
endfunc console_pl011_core_putc
/* --------------------------------------------------------
- * int console_pl011_putc(int c, console_pl011_t *console)
+ * int console_pl011_putc(int c, console_t *console)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : w0 - character to be printed
@@ -157,7 +157,7 @@ func console_pl011_putc
cmp x1, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr x1, [x1, #CONSOLE_T_PL011_BASE]
+ ldr x1, [x1, #CONSOLE_T_BASE]
b console_pl011_core_putc
endfunc console_pl011_putc
@@ -189,7 +189,7 @@ no_char:
endfunc console_pl011_core_getc
/* ---------------------------------------------
- * int console_pl011_getc(console_pl011_t *console)
+ * int console_pl011_getc(console_t *console)
* Function to get a character from the console.
* It returns the character grabbed on success
* or -1 if no character is available.
@@ -203,7 +203,7 @@ func console_pl011_getc
cmp x0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr x0, [x0, #CONSOLE_T_PL011_BASE]
+ ldr x0, [x0, #CONSOLE_T_BASE]
b console_pl011_core_getc
endfunc console_pl011_getc
@@ -231,7 +231,7 @@ func console_pl011_core_flush
endfunc console_pl011_core_flush
/* ---------------------------------------------
- * int console_pl011_flush(console_pl011_t *console)
+ * int console_pl011_flush(console_t *console)
* Function to force a write of all buffered
* data that hasn't been output.
* In : x0 - pointer to console_t structure
@@ -244,6 +244,6 @@ func console_pl011_flush
cmp x0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr x0, [x0, #CONSOLE_T_PL011_BASE]
+ ldr x0, [x0, #CONSOLE_T_BASE]
b console_pl011_core_flush
endfunc console_pl011_flush
diff --git a/drivers/auth/crypto_mod.c b/drivers/auth/crypto_mod.c
index 110c5045f..c63ff080f 100644
--- a/drivers/auth/crypto_mod.c
+++ b/drivers/auth/crypto_mod.c
@@ -124,3 +124,35 @@ int crypto_mod_calc_hash(unsigned int alg, void *data_ptr,
return crypto_lib_desc.calc_hash(alg, data_ptr, data_len, output);
}
#endif /* MEASURED_BOOT */
+
+/*
+ * Authenticated decryption of data
+ *
+ * Parameters:
+ *
+ * dec_algo: authenticated decryption algorithm
+ * data_ptr, len: data to be decrypted (inout param)
+ * key, key_len, key_flags: symmetric decryption key
+ * iv, iv_len: initialization vector
+ * tag, tag_len: authentication tag
+ */
+int crypto_mod_auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
+ size_t len, const void *key, unsigned int key_len,
+ unsigned int key_flags, const void *iv,
+ unsigned int iv_len, const void *tag,
+ unsigned int tag_len)
+{
+ assert(crypto_lib_desc.auth_decrypt != NULL);
+ assert(data_ptr != NULL);
+ assert(len != 0U);
+ assert(key != NULL);
+ assert(key_len != 0U);
+ assert(iv != NULL);
+ assert((iv_len != 0U) && (iv_len <= CRYPTO_MAX_IV_SIZE));
+ assert(tag != NULL);
+ assert((tag_len != 0U) && (tag_len <= CRYPTO_MAX_TAG_SIZE));
+
+ return crypto_lib_desc.auth_decrypt(dec_algo, data_ptr, len, key,
+ key_len, key_flags, iv, iv_len, tag,
+ tag_len);
+}
diff --git a/drivers/auth/cryptocell/712/cryptocell_crypto.c b/drivers/auth/cryptocell/712/cryptocell_crypto.c
index 25eb6bcb6..cf4317534 100644
--- a/drivers/auth/cryptocell/712/cryptocell_crypto.c
+++ b/drivers/auth/cryptocell/712/cryptocell_crypto.c
@@ -301,5 +301,5 @@ static int verify_hash(void *data_ptr, unsigned int data_len,
/*
* Register crypto library descriptor
*/
-REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash);
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL);
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index 4b8301541..044b368bc 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -23,13 +23,17 @@ MBEDTLS_SOURCES += drivers/auth/mbedtls/mbedtls_common.c
LIBMBEDTLS_SRCS := $(addprefix ${MBEDTLS_DIR}/library/, \
+ aes.c \
asn1parse.c \
asn1write.c \
+ cipher.c \
+ cipher_wrap.c \
memory_buffer_alloc.c \
oid.c \
platform.c \
platform_util.c \
bignum.c \
+ gcm.c \
md.c \
md_wrap.c \
pk.c \
@@ -87,11 +91,17 @@ else
$(error "TF_MBEDTLS_KEY_ALG=${TF_MBEDTLS_KEY_ALG} not supported on mbed TLS")
endif
+ifeq (${DECRYPTION_SUPPORT}, aes_gcm)
+ TF_MBEDTLS_USE_AES_GCM := 1
+else
+ TF_MBEDTLS_USE_AES_GCM := 0
+endif
+
# Needs to be set to drive mbed TLS configuration correctly
$(eval $(call add_define,TF_MBEDTLS_KEY_ALG_ID))
$(eval $(call add_define,TF_MBEDTLS_KEY_SIZE))
$(eval $(call add_define,TF_MBEDTLS_HASH_ALG_ID))
-
+$(eval $(call add_define,TF_MBEDTLS_USE_AES_GCM))
$(eval $(call MAKE_LIB,mbedtls))
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c
index 04fbc648b..2a9801497 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_crypto.c
@@ -4,10 +4,12 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
#include <stddef.h>
#include <string.h>
/* mbed TLS headers */
+#include <mbedtls/gcm.h>
#include <mbedtls/md.h>
#include <mbedtls/memory_buffer_alloc.h>
#include <mbedtls/oid.h>
@@ -17,6 +19,7 @@
#include <drivers/auth/crypto_mod.h>
#include <drivers/auth/mbedtls/mbedtls_common.h>
#include <drivers/auth/mbedtls/mbedtls_config.h>
+#include <plat/common/platform.h>
#define LIB_NAME "mbed TLS"
@@ -226,11 +229,121 @@ int calc_hash(unsigned int alg, void *data_ptr,
}
#endif /* MEASURED_BOOT */
+#if TF_MBEDTLS_USE_AES_GCM
+/*
+ * Stack based buffer allocation for decryption operation. It could
+ * be configured to balance stack usage vs execution speed.
+ */
+#define DEC_OP_BUF_SIZE 128
+
+static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key,
+ unsigned int key_len, const void *iv,
+ unsigned int iv_len, const void *tag,
+ unsigned int tag_len)
+{
+ mbedtls_gcm_context ctx;
+ mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
+ unsigned char buf[DEC_OP_BUF_SIZE];
+ unsigned char tag_buf[CRYPTO_MAX_TAG_SIZE];
+ unsigned char *pt = data_ptr;
+ size_t dec_len;
+ int diff, i, rc;
+
+ mbedtls_gcm_init(&ctx);
+
+ rc = mbedtls_gcm_setkey(&ctx, cipher, key, key_len * 8);
+ if (rc != 0) {
+ rc = CRYPTO_ERR_DECRYPTION;
+ goto exit_gcm;
+ }
+
+ rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len, NULL, 0);
+ if (rc != 0) {
+ rc = CRYPTO_ERR_DECRYPTION;
+ goto exit_gcm;
+ }
+
+ while (len > 0) {
+ dec_len = MIN(sizeof(buf), len);
+
+ rc = mbedtls_gcm_update(&ctx, dec_len, pt, buf);
+ if (rc != 0) {
+ rc = CRYPTO_ERR_DECRYPTION;
+ goto exit_gcm;
+ }
+
+ memcpy(pt, buf, dec_len);
+ pt += dec_len;
+ len -= dec_len;
+ }
+
+ rc = mbedtls_gcm_finish(&ctx, tag_buf, sizeof(tag_buf));
+ if (rc != 0) {
+ rc = CRYPTO_ERR_DECRYPTION;
+ goto exit_gcm;
+ }
+
+ /* Check tag in "constant-time" */
+ for (diff = 0, i = 0; i < tag_len; i++)
+ diff |= ((const unsigned char *)tag)[i] ^ tag_buf[i];
+
+ if (diff != 0) {
+ rc = CRYPTO_ERR_DECRYPTION;
+ goto exit_gcm;
+ }
+
+ /* GCM decryption success */
+ rc = CRYPTO_SUCCESS;
+
+exit_gcm:
+ mbedtls_gcm_free(&ctx);
+ return rc;
+}
+
+/*
+ * Authenticated decryption of an image
+ */
+static int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
+ size_t len, const void *key, unsigned int key_len,
+ unsigned int key_flags, const void *iv,
+ unsigned int iv_len, const void *tag,
+ unsigned int tag_len)
+{
+ int rc;
+
+ assert((key_flags & ENC_KEY_IS_IDENTIFIER) == 0);
+
+ switch (dec_algo) {
+ case CRYPTO_GCM_DECRYPT:
+ rc = aes_gcm_decrypt(data_ptr, len, key, key_len, iv, iv_len,
+ tag, tag_len);
+ if (rc != 0)
+ return rc;
+ break;
+ default:
+ return CRYPTO_ERR_DECRYPTION;
+ }
+
+ return CRYPTO_SUCCESS;
+}
+#endif /* TF_MBEDTLS_USE_AES_GCM */
+
/*
* Register crypto library descriptor
*/
#if MEASURED_BOOT
-REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash);
+#if TF_MBEDTLS_USE_AES_GCM
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
+ auth_decrypt);
+#else
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
+ NULL);
+#endif
+#else /* MEASURED_BOOT */
+#if TF_MBEDTLS_USE_AES_GCM
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash,
+ auth_decrypt);
#else
-REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash);
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL);
+#endif
#endif /* MEASURED_BOOT */
diff --git a/drivers/cadence/uart/aarch64/cdns_console.S b/drivers/cadence/uart/aarch64/cdns_console.S
index ecd0c478d..8e5d6a1aa 100644
--- a/drivers/cadence/uart/aarch64/cdns_console.S
+++ b/drivers/cadence/uart/aarch64/cdns_console.S
@@ -56,14 +56,14 @@ endfunc console_cdns_core_init
/* -----------------------------------------------
* int console_cdns_register(uintptr_t baseaddr,
* uint32_t clock, uint32_t baud,
- * console_cdns_t *console);
+ * console_t *console);
* Function to initialize and register a new CDNS
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
* In: x0 - UART register base address
* w1 - UART clock in Hz
* w2 - Baud rate
- * x3 - pointer to empty console_16550_t struct
+ * x3 - pointer to empty console_t struct
* Out: return 1 on success, 0 on error
* Clobber list : x0, x1, x2, x6, x7, x14
* -----------------------------------------------
@@ -72,7 +72,7 @@ func console_cdns_register
mov x7, x30
mov x6, x3
cbz x6, register_fail
- str x0, [x6, #CONSOLE_T_CDNS_BASE]
+ str x0, [x6, #CONSOLE_T_BASE]
bl console_cdns_core_init
cbz x0, register_fail
@@ -119,7 +119,7 @@ func console_cdns_core_putc
endfunc console_cdns_core_putc
/* --------------------------------------------------------
- * int console_cdns_putc(int c, console_cdns_t *cdns)
+ * int console_cdns_putc(int c, console_t *cdns)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : w0 - character to be printed
@@ -133,7 +133,7 @@ func console_cdns_putc
cmp x1, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr x1, [x1, #CONSOLE_T_CDNS_BASE]
+ ldr x1, [x1, #CONSOLE_T_BASE]
b console_cdns_core_putc
endfunc console_cdns_putc
@@ -165,7 +165,7 @@ no_char:
endfunc console_cdns_core_getc
/* ---------------------------------------------
- * int console_cdns_getc(console_cdns_t *console)
+ * int console_cdns_getc(console_t *console)
* Function to get a character from the console.
* It returns the character grabbed on success
* or -1 if no character is available.
@@ -179,7 +179,7 @@ func console_cdns_getc
cmp x0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr x0, [x0, #CONSOLE_T_CDNS_BASE]
+ ldr x0, [x0, #CONSOLE_T_BASE]
b console_cdns_core_getc
endfunc console_cdns_getc
@@ -203,7 +203,7 @@ func console_cdns_core_flush
endfunc console_cdns_core_flush
/* ---------------------------------------------
- * int console_cdns_flush(console_pl011_t *console)
+ * int console_cdns_flush(console_t *console)
* Function to force a write of all buffered
* data that hasn't been output.
* In : x0 - pointer to console_t structure
@@ -216,6 +216,6 @@ func console_cdns_flush
cmp x0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr x0, [x0, #CONSOLE_T_CDNS_BASE]
+ ldr x0, [x0, #CONSOLE_T_BASE]
b console_cdns_core_flush
endfunc console_cdns_flush
diff --git a/drivers/console/aarch32/skeleton_console.S b/drivers/console/aarch32/skeleton_console.S
index 45ad13927..c594f7edf 100644
--- a/drivers/console/aarch32/skeleton_console.S
+++ b/drivers/console/aarch32/skeleton_console.S
@@ -50,7 +50,7 @@ func console_xxx_register
* by later console callback (e.g. putc).
* Example:
*/
- str r1, [r0, #CONSOLE_T_XXX_BASE]
+ str r1, [r0, #CONSOLE_T_BASE]
str r2, [r0, #CONSOLE_T_XXX_SOME_OTHER_VALUE]
/*
@@ -87,7 +87,7 @@ func console_xxx_putc
* console_xxx_t structure pointed to by r1.
* Example:
*/
- ldr r1, [r1, #CONSOLE_T_XXX_BASE]
+ ldr r1, [r1, #CONSOLE_T_BASE]
/*
* Write r0 to hardware.
@@ -125,7 +125,7 @@ func console_xxx_getc
* console_xxx_t structure pointed to by r0.
* Example:
*/
- ldr r1, [r0, #CONSOLE_T_XXX_BASE]
+ ldr r1, [r0, #CONSOLE_T_BASE]
/*
* Try to read character into r0 from hardware.
@@ -159,7 +159,7 @@ func console_xxx_flush
* console_xxx_t structure pointed to by r0.
* Example:
*/
- ldr r1, [r0, #CONSOLE_T_XXX_BASE]
+ ldr r1, [r0, #CONSOLE_T_BASE]
/*
* Flush all remaining output from hardware FIFOs. Do not return until
diff --git a/drivers/console/aarch64/skeleton_console.S b/drivers/console/aarch64/skeleton_console.S
index 957ed83a9..9a8586775 100644
--- a/drivers/console/aarch64/skeleton_console.S
+++ b/drivers/console/aarch64/skeleton_console.S
@@ -50,7 +50,7 @@ func console_xxx_register
* by later console callback (e.g. putc).
* Example:
*/
- str x1, [x0, #CONSOLE_T_XXX_BASE]
+ str x1, [x0, #CONSOLE_T_BASE]
str x2, [x0, #CONSOLE_T_XXX_SOME_OTHER_VALUE]
/*
@@ -87,7 +87,7 @@ func console_xxx_putc
* console_xxx_t structure pointed to by x1.
* Example:
*/
- ldr x1, [x1, #CONSOLE_T_XXX_BASE]
+ ldr x1, [x1, #CONSOLE_T_BASE]
/*
* Write w0 to hardware.
@@ -125,7 +125,7 @@ func console_xxx_getc
* console_xxx_t structure pointed to by x0.
* Example:
*/
- ldr x1, [x0, #CONSOLE_T_XXX_BASE]
+ ldr x1, [x0, #CONSOLE_T_BASE]
/*
* Try to read character into w0 from hardware.
@@ -159,7 +159,7 @@ func console_xxx_flush
* console_xxx_t structure pointed to by x0.
* Example:
*/
- ldr x1, [x0, #CONSOLE_T_XXX_BASE]
+ ldr x1, [x0, #CONSOLE_T_BASE]
/*
* Flush all remaining output from hardware FIFOs. Do not return until
diff --git a/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S b/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S
index fd04c2e7e..a4a7bf8f3 100644
--- a/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S
+++ b/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S
@@ -35,7 +35,7 @@
* -----------------------------------------------
*/
func console_cbmc_register
- str x0, [x1, #CONSOLE_T_CBMC_BASE]
+ str x0, [x1, #CONSOLE_T_BASE]
ldr w2, [x0]
str w2, [x1, #CONSOLE_T_CBMC_SIZE]
mov x0, x1
@@ -54,7 +54,7 @@ endfunc console_cbmc_register
*/
func console_cbmc_putc
ldr w2, [x1, #CONSOLE_T_CBMC_SIZE]
- ldr x1, [x1, #CONSOLE_T_CBMC_BASE]
+ ldr x1, [x1, #CONSOLE_T_BASE]
add x1, x1, #8 /* keep address of body in x1 */
ldr w16, [x1, #-4] /* load cursor (one u32 before body) */
@@ -93,7 +93,7 @@ endfunc console_cbmc_putc
func console_cbmc_flush
mov x5, x30
ldr x1, [x0, #CONSOLE_T_CBMC_SIZE]
- ldr x0, [x0, #CONSOLE_T_CBMC_BASE]
+ ldr x0, [x0, #CONSOLE_T_BASE]
add x1, x1, #8 /* add size of console header */
bl clean_dcache_range /* (clobbers x2 and x3) */
mov x0, #0
diff --git a/drivers/imx/uart/imx_uart.h b/drivers/imx/uart/imx_uart.h
index 4f6d3de2e..a13302484 100644
--- a/drivers/imx/uart/imx_uart.h
+++ b/drivers/imx/uart/imx_uart.h
@@ -154,15 +154,10 @@
#ifndef __ASSEMBLER__
-typedef struct {
- console_t console;
- uintptr_t base;
-} console_imx_uart_t;
-
int console_imx_uart_register(uintptr_t baseaddr,
uint32_t clock,
uint32_t baud,
- console_imx_uart_t *console);
+ console_t *console);
#endif /*__ASSEMBLER__*/
#endif /* IMX_UART_H */
diff --git a/drivers/io/io_encrypted.c b/drivers/io/io_encrypted.c
new file mode 100644
index 000000000..744ca8356
--- /dev/null
+++ b/drivers/io/io_encrypted.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2020, Linaro Limited. All rights reserved.
+ * Author: Sumit Garg <sumit.garg@linaro.org>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <platform_def.h>
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/auth/crypto_mod.h>
+#include <drivers/io/io_driver.h>
+#include <drivers/io/io_encrypted.h>
+#include <drivers/io/io_storage.h>
+#include <lib/utils.h>
+#include <plat/common/platform.h>
+#include <tools_share/firmware_encrypted.h>
+#include <tools_share/uuid.h>
+
+static uintptr_t backend_dev_handle;
+static uintptr_t backend_dev_spec;
+static uintptr_t backend_handle;
+static uintptr_t backend_image_spec;
+
+static io_dev_info_t enc_dev_info;
+
+/* Encrypted firmware driver functions */
+static int enc_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
+static int enc_file_open(io_dev_info_t *dev_info, const uintptr_t spec,
+ io_entity_t *entity);
+static int enc_file_len(io_entity_t *entity, size_t *length);
+static int enc_file_read(io_entity_t *entity, uintptr_t buffer, size_t length,
+ size_t *length_read);
+static int enc_file_close(io_entity_t *entity);
+static int enc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params);
+static int enc_dev_close(io_dev_info_t *dev_info);
+
+static inline int is_valid_header(struct fw_enc_hdr *header)
+{
+ if (header->magic == ENC_HEADER_MAGIC)
+ return 1;
+ else
+ return 0;
+}
+
+static io_type_t device_type_enc(void)
+{
+ return IO_TYPE_ENCRYPTED;
+}
+
+static const io_dev_connector_t enc_dev_connector = {
+ .dev_open = enc_dev_open
+};
+
+static const io_dev_funcs_t enc_dev_funcs = {
+ .type = device_type_enc,
+ .open = enc_file_open,
+ .seek = NULL,
+ .size = enc_file_len,
+ .read = enc_file_read,
+ .write = NULL,
+ .close = enc_file_close,
+ .dev_init = enc_dev_init,
+ .dev_close = enc_dev_close,
+};
+
+static int enc_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info)
+{
+ assert(dev_info != NULL);
+
+ enc_dev_info.funcs = &enc_dev_funcs;
+ *dev_info = &enc_dev_info;
+
+ return 0;
+}
+
+static int enc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params)
+{
+ int result;
+ unsigned int image_id = (unsigned int)init_params;
+
+ /* Obtain a reference to the image by querying the platform layer */
+ result = plat_get_image_source(image_id, &backend_dev_handle,
+ &backend_dev_spec);
+ if (result != 0) {
+ WARN("Failed to obtain reference to image id=%u (%i)\n",
+ image_id, result);
+ return -ENOENT;
+ }
+
+ return result;
+}
+
+static int enc_dev_close(io_dev_info_t *dev_info)
+{
+ backend_dev_handle = (uintptr_t)NULL;
+ backend_dev_spec = (uintptr_t)NULL;
+
+ return 0;
+}
+
+static int enc_file_open(io_dev_info_t *dev_info, const uintptr_t spec,
+ io_entity_t *entity)
+{
+ int result;
+
+ assert(spec != 0);
+ assert(entity != NULL);
+
+ backend_image_spec = spec;
+
+ result = io_open(backend_dev_handle, backend_image_spec,
+ &backend_handle);
+ if (result != 0) {
+ WARN("Failed to open backend device (%i)\n", result);
+ result = -ENOENT;
+ }
+
+ return result;
+}
+
+static int enc_file_len(io_entity_t *entity, size_t *length)
+{
+ int result;
+
+ assert(entity != NULL);
+ assert(length != NULL);
+
+ result = io_size(backend_handle, length);
+ if (result != 0) {
+ WARN("Failed to read blob length (%i)\n", result);
+ return -ENOENT;
+ }
+
+ /*
+ * Encryption header is attached at the beginning of the encrypted file
+ * and is not considered a part of the payload.
+ */
+ if (*length < sizeof(struct fw_enc_hdr))
+ return -EIO;
+
+ *length -= sizeof(struct fw_enc_hdr);
+
+ return result;
+}
+
+static int enc_file_read(io_entity_t *entity, uintptr_t buffer, size_t length,
+ size_t *length_read)
+{
+ int result;
+ struct fw_enc_hdr header;
+ enum fw_enc_status_t fw_enc_status;
+ size_t bytes_read;
+ uint8_t key[ENC_MAX_KEY_SIZE];
+ size_t key_len = sizeof(key);
+ unsigned int key_flags = 0;
+ const io_uuid_spec_t *uuid_spec = (io_uuid_spec_t *)backend_image_spec;
+
+ assert(entity != NULL);
+ assert(length_read != NULL);
+
+ result = io_read(backend_handle, (uintptr_t)&header, sizeof(header),
+ &bytes_read);
+ if (result != 0) {
+ WARN("Failed to read encryption header (%i)\n", result);
+ return -ENOENT;
+ }
+
+ if (!is_valid_header(&header)) {
+ WARN("Encryption header check failed.\n");
+ return -ENOENT;
+ }
+
+ VERBOSE("Encryption header looks OK.\n");
+ fw_enc_status = header.flags & FW_ENC_STATUS_FLAG_MASK;
+
+ if ((header.iv_len > ENC_MAX_IV_SIZE) ||
+ (header.tag_len > ENC_MAX_TAG_SIZE)) {
+ WARN("Incorrect IV or tag length\n");
+ return -ENOENT;
+ }
+
+ result = io_read(backend_handle, buffer, length, &bytes_read);
+ if (result != 0) {
+ WARN("Failed to read encrypted payload (%i)\n", result);
+ return -ENOENT;
+ }
+
+ *length_read = bytes_read;
+
+ result = plat_get_enc_key_info(fw_enc_status, key, &key_len, &key_flags,
+ (uint8_t *)&uuid_spec->uuid,
+ sizeof(uuid_t));
+ if (result != 0) {
+ WARN("Failed to obtain encryption key (%i)\n", result);
+ return -ENOENT;
+ }
+
+ result = crypto_mod_auth_decrypt(header.dec_algo,
+ (void *)buffer, *length_read, key,
+ key_len, key_flags, header.iv,
+ header.iv_len, header.tag,
+ header.tag_len);
+ memset(key, 0, key_len);
+
+ if (result != 0) {
+ ERROR("File decryption failed (%i)\n", result);
+ return -ENOENT;
+ }
+
+ return result;
+}
+
+static int enc_file_close(io_entity_t *entity)
+{
+ io_close(backend_handle);
+
+ backend_image_spec = (uintptr_t)NULL;
+ entity->info = 0;
+
+ return 0;
+}
+
+/* Exported functions */
+
+/* Register the Encrypted Firmware driver with the IO abstraction */
+int register_io_dev_enc(const io_dev_connector_t **dev_con)
+{
+ int result;
+
+ assert(dev_con != NULL);
+
+ result = io_register_device(&enc_dev_info);
+ if (result == 0)
+ *dev_con = &enc_dev_connector;
+
+ return result;
+}
diff --git a/drivers/marvell/uart/a3700_console.S b/drivers/marvell/uart/a3700_console.S
index da1ce351c..ecd494ca7 100644
--- a/drivers/marvell/uart/a3700_console.S
+++ b/drivers/marvell/uart/a3700_console.S
@@ -110,7 +110,7 @@ endfunc console_a3700_core_init
.globl console_a3700_register
/* -----------------------------------------------
- * int console_a3700_register(console_16550_t *console,
+ * int console_a3700_register(console_t *console,
uintptr_t base, uint32_t clk, uint32_t baud)
* Function to initialize and register a new a3700
* console. Storage passed in for the console struct
@@ -118,7 +118,7 @@ endfunc console_a3700_core_init
* In: x0 - UART register base address
* w1 - UART clock in Hz
* w2 - Baud rate
- * x3 - pointer to empty console_a3700_t struct
+ * x3 - pointer to empty console_t struct
* Out: return 1 on success, 0 on error
* Clobber list : x0, x1, x2, x6, x7, x14
* -----------------------------------------------
@@ -127,7 +127,7 @@ func console_a3700_register
mov x7, x30
mov x6, x3
cbz x6, register_fail
- str x0, [x6, #CONSOLE_T_A3700_BASE]
+ str x0, [x6, #CONSOLE_T_BASE]
bl console_a3700_core_init
cbz x0, register_fail
@@ -178,7 +178,7 @@ putc_error:
endfunc console_a3700_core_putc
/* --------------------------------------------------------
- * int console_a3700_putc(int c, console_a3700_t *console)
+ * int console_a3700_putc(int c, console_t *console)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : w0 - character to be printed
@@ -188,7 +188,7 @@ endfunc console_a3700_core_putc
* --------------------------------------------------------
*/
func console_a3700_putc
- ldr x1, [x1, #CONSOLE_T_A3700_BASE]
+ ldr x1, [x1, #CONSOLE_T_BASE]
b console_a3700_core_putc
endfunc console_a3700_putc
@@ -208,7 +208,7 @@ func console_a3700_core_getc
endfunc console_a3700_core_getc
/* ---------------------------------------------
- * int console_a3700_getc(console_a3700_t *console)
+ * int console_a3700_getc(console_t *console)
* Function to get a character from the console.
* It returns the character grabbed on success
* or -1 on if no character is available.
@@ -218,7 +218,7 @@ endfunc console_a3700_core_getc
* ---------------------------------------------
*/
func console_a3700_getc
- ldr x0, [x0, #CONSOLE_T_A3700_BASE]
+ ldr x0, [x0, #CONSOLE_T_BASE]
b console_a3700_core_getc
endfunc console_a3700_getc
@@ -237,7 +237,7 @@ func console_a3700_core_flush
endfunc console_a3700_core_flush
/* ---------------------------------------------
- * int console_a3700_flush(console_a3700_t *console)
+ * int console_a3700_flush(console_t *console)
* Function to force a write of all buffered
* data that hasn't been output.
* In : x0 - pointer to console_t structure
@@ -246,7 +246,7 @@ endfunc console_a3700_core_flush
* ---------------------------------------------
*/
func console_a3700_flush
- ldr x0, [x0, #CONSOLE_T_A3700_BASE]
+ ldr x0, [x0, #CONSOLE_T_BASE]
b console_a3700_core_flush
endfunc console_a3700_flush
diff --git a/drivers/renesas/rcar/console/rcar_console.S b/drivers/renesas/rcar/console/rcar_console.S
index 859efeceb..4d006b703 100644
--- a/drivers/renesas/rcar/console/rcar_console.S
+++ b/drivers/renesas/rcar/console/rcar_console.S
@@ -20,14 +20,14 @@
/* -----------------------------------------------
* int console_rcar_register(
* uintptr_t base, uint32_t clk, uint32_t baud,
- * console_rcar_t *console)
+ * console_t *console)
* Function to initialize and register a new rcar
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
* In: x0 - UART register base address
* w1 - UART clock in Hz
* w2 - Baud rate
- * x3 - pointer to empty console_rcar_t struct
+ * x3 - pointer to empty console_t struct
* Out: return 1 on success, 0 on error
* Clobber list : x0, x1, x2, x6, x7, x14
* -----------------------------------------------
@@ -36,7 +36,7 @@ func console_rcar_register
mov x7, x30
mov x6, x3
cbz x6, register_fail
- str x0, [x6, #CONSOLE_T_RCAR_BASE]
+ str x0, [x6, #CONSOLE_T_BASE]
bl rcar_log_init
cbz x0, register_fail
@@ -68,11 +68,11 @@ func console_rcar_init
endfunc console_rcar_init
/* --------------------------------------------------------
- * int console_rcar_putc(int c, console_rcar_t *console)
+ * int console_rcar_putc(int c, console_t *console)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : w0 - character to be printed
- * x1 - pointer to console_rcar_t structure
+ * x1 - pointer to console_t structure
* Out : return -1 on error else return character.
* Clobber list : x2
* --------------------------------------------------------
diff --git a/drivers/renesas/rcar/scif/scif.S b/drivers/renesas/rcar/scif/scif.S
index 8309bb26e..064aba471 100644
--- a/drivers/renesas/rcar/scif/scif.S
+++ b/drivers/renesas/rcar/scif/scif.S
@@ -126,14 +126,14 @@
/* -----------------------------------------------
* int console_rcar_register(
* uintptr_t base, uint32_t clk, uint32_t baud,
- * console_rcar_t *console)
+ * console_t *console)
* Function to initialize and register a new rcar
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
* In: x0 - UART register base address
* w1 - UART clock in Hz
* w2 - Baud rate
- * x3 - pointer to empty console_rcar_t struct
+ * x3 - pointer to empty console_t struct
* Out: return 1 on success, 0 on error
* Clobber list : x0, x1, x2, x6, x7, x14
* -----------------------------------------------
@@ -142,7 +142,7 @@ func console_rcar_register
mov x7, x30
mov x6, x3
cbz x6, register_fail
- str x0, [x6, #CONSOLE_T_RCAR_BASE]
+ str x0, [x6, #CONSOLE_T_BASE]
bl console_rcar_init
diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S
index ca3c1f618..0ed37d1bd 100644
--- a/drivers/st/uart/aarch32/stm32_console.S
+++ b/drivers/st/uart/aarch32/stm32_console.S
@@ -91,14 +91,14 @@ endfunc console_stm32_core_init
/* -------------------------------------------------------
* int console_stm32_register(uintptr_t baseaddr,
* uint32_t clock, uint32_t baud,
- * struct console_stm32 *console);
+ * console_t *console);
* Function to initialize and register a new STM32
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
* In: r0 - UART register base address
* r1 - UART clock in Hz
* r2 - Baud rate
- * r3 - pointer to empty console_stm32 struct
+ * r3 - pointer to empty console_t struct
* Out: return 1 on success, 0 on error
* Clobber list : r0, r1, r2
* -------------------------------------------------------
@@ -108,7 +108,7 @@ func console_stm32_register
mov r4, r3
cmp r4, #0
beq register_fail
- str r0, [r4, #CONSOLE_T_STM32_BASE]
+ str r0, [r4, #CONSOLE_T_BASE]
bl console_stm32_core_init
cmp r0, #0
@@ -157,7 +157,7 @@ putc_error:
endfunc console_stm32_core_putc
/* ------------------------------------------------------------
- * int console_stm32_putc(int c, struct console_stm32 *console)
+ * int console_stm32_putc(int c, console_t *console)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In: r0 - character to be printed
@@ -171,7 +171,7 @@ func console_stm32_putc
cmp r1, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr r1, [r1, #CONSOLE_T_STM32_BASE]
+ ldr r1, [r1, #CONSOLE_T_BASE]
b console_stm32_core_putc
endfunc console_stm32_putc
@@ -219,7 +219,7 @@ flush_error:
endfunc console_stm32_core_flush
/* ------------------------------------------------------
- * int console_stm32_flush(struct console_stm32 *console)
+ * int console_stm32_flush(console_t *console)
* Function to force a write of all buffered
* data that hasn't been output.
* In : r0 - pointer to console_t structure
@@ -232,6 +232,6 @@ func console_stm32_flush
cmp r0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr r0, [r0, #CONSOLE_T_STM32_BASE]
+ ldr r0, [r0, #CONSOLE_T_BASE]
b console_stm32_core_flush
endfunc console_stm32_flush
diff --git a/drivers/ti/uart/aarch32/16550_console.S b/drivers/ti/uart/aarch32/16550_console.S
index 5cd9b30cd..bc0b3ab1c 100644
--- a/drivers/ti/uart/aarch32/16550_console.S
+++ b/drivers/ti/uart/aarch32/16550_console.S
@@ -91,7 +91,7 @@ endfunc console_16550_core_init
/* -------------------------------------------------------
* int console_16550_register(uintptr_t baseaddr,
* uint32_t clock, uint32_t baud,
- * console_16550_t *console);
+ * console_t *console);
* Function to initialize and register a new 16550
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
@@ -101,7 +101,7 @@ endfunc console_16550_core_init
* In: r0 - UART register base address
* r1 - UART clock in Hz
* r2 - Baud rate (ignored if r1 is 0)
- * r3 - pointer to empty console_16550_t struct
+ * r3 - pointer to empty console_t struct
* Out: return 1 on success, 0 on error
* Clobber list : r0, r1, r2
* -------------------------------------------------------
@@ -111,7 +111,7 @@ func console_16550_register
mov r4, r3
cmp r4, #0
beq register_fail
- str r0, [r4, #CONSOLE_T_16550_BASE]
+ str r0, [r4, #CONSOLE_T_BASE]
/* A clock rate of zero means to skip the initialisation. */
cmp r1, #0
@@ -167,7 +167,7 @@ func console_16550_core_putc
endfunc console_16550_core_putc
/* --------------------------------------------------------
- * int console_16550_putc(int c, console_16550_t *console)
+ * int console_16550_putc(int c, console_t *console)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : r0 - character to be printed
@@ -181,7 +181,7 @@ func console_16550_putc
cmp r1, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr r1, [r1, #CONSOLE_T_16550_BASE]
+ ldr r1, [r1, #CONSOLE_T_BASE]
b console_16550_core_putc
endfunc console_16550_putc
@@ -213,7 +213,7 @@ no_char:
endfunc console_16550_core_getc
/* ---------------------------------------------
- * int console_16550_getc(console_16550_t *console)
+ * int console_16550_getc(console_t *console)
* Function to get a character from the console.
* It returns the character grabbed on success
* or -1 on if no character is available.
@@ -227,7 +227,7 @@ func console_16550_getc
cmp r0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr r0, [r0, #CONSOLE_T_16550_BASE]
+ ldr r0, [r0, #CONSOLE_T_BASE]
b console_16550_core_getc
endfunc console_16550_getc
@@ -257,7 +257,7 @@ func console_16550_core_flush
endfunc console_16550_core_flush
/* ---------------------------------------------
- * int console_16550_flush(console_pl011_t *console)
+ * int console_16550_flush(console_t *console)
* Function to force a write of all buffered
* data that hasn't been output.
* In : r0 - pointer to console_t structure
@@ -270,6 +270,6 @@ func console_16550_flush
cmp r0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr r0, [r0, #CONSOLE_T_16550_BASE]
+ ldr r0, [r0, #CONSOLE_T_BASE]
b console_16550_core_flush
endfunc console_16550_flush
diff --git a/drivers/ti/uart/aarch64/16550_console.S b/drivers/ti/uart/aarch64/16550_console.S
index 80c1b8646..064022798 100644
--- a/drivers/ti/uart/aarch64/16550_console.S
+++ b/drivers/ti/uart/aarch64/16550_console.S
@@ -88,7 +88,7 @@ endfunc console_16550_core_init
/* -----------------------------------------------
* int console_16550_register(uintptr_t baseaddr,
* uint32_t clock, uint32_t baud,
- * console_16550_t *console);
+ * console_t *console);
* Function to initialize and register a new 16550
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
@@ -98,7 +98,7 @@ endfunc console_16550_core_init
* In: x0 - UART register base address
* w1 - UART clock in Hz
* w2 - Baud rate (ignored if w1 is 0)
- * x3 - pointer to empty console_16550_t struct
+ * x3 - pointer to empty console_t struct
* Out: return 1 on success, 0 on error
* Clobber list : x0, x1, x2, x6, x7, x14
* -----------------------------------------------
@@ -107,7 +107,7 @@ func console_16550_register
mov x7, x30
mov x6, x3
cbz x6, register_fail
- str x0, [x6, #CONSOLE_T_16550_BASE]
+ str x0, [x6, #CONSOLE_T_BASE]
/* A clock rate of zero means to skip the initialisation. */
cbz w1, register_16550
@@ -161,7 +161,7 @@ func console_16550_core_putc
endfunc console_16550_core_putc
/* --------------------------------------------------------
- * int console_16550_putc(int c, console_16550_t *console)
+ * int console_16550_putc(int c, console_t *console)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : w0 - character to be printed
@@ -175,7 +175,7 @@ func console_16550_putc
cmp x1, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr x1, [x1, #CONSOLE_T_16550_BASE]
+ ldr x1, [x1, #CONSOLE_T_BASE]
b console_16550_core_putc
endfunc console_16550_putc
@@ -206,7 +206,7 @@ no_char:
endfunc console_16550_core_getc
/* ---------------------------------------------
- * int console_16550_getc(console_16550_t *console)
+ * int console_16550_getc(console_t *console)
* Function to get a character from the console.
* It returns the character grabbed on success
* or -1 on if no character is available.
@@ -220,7 +220,7 @@ func console_16550_getc
cmp x1, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr x0, [x0, #CONSOLE_T_16550_BASE]
+ ldr x0, [x0, #CONSOLE_T_BASE]
b console_16550_core_getc
endfunc console_16550_getc
@@ -250,7 +250,7 @@ func console_16550_core_flush
endfunc console_16550_core_flush
/* ---------------------------------------------
- * int console_16550_flush(console_pl011_t *console)
+ * int console_16550_flush(console_t *console)
* Function to force a write of all buffered
* data that hasn't been output.
* In : x0 - pointer to console_t structure
@@ -263,6 +263,6 @@ func console_16550_flush
cmp x0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr x0, [x0, #CONSOLE_T_16550_BASE]
+ ldr x0, [x0, #CONSOLE_T_BASE]
b console_16550_core_flush
endfunc console_16550_flush
diff --git a/fdts/a5ds.dts b/fdts/a5ds.dts
index 31d635ac8..7334c4559 100644
--- a/fdts/a5ds.dts
+++ b/fdts/a5ds.dts
@@ -136,4 +136,23 @@
reg = <0x1a050000 0x1000>;
};
};
+ v2m_fixed_3v3: fixed-regulator-0 {
+ compatible = "regulator-fixed";
+ regulator-name = "3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ethernet@4020000 {
+ compatible = "smsc,lan9220", "smsc,lan9115";
+ reg = <0x40200000 0x10000>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 43 0xf04>;
+ reg-io-width = <4>;
+ phy-mode = "mii";
+ smsc,irq-active-high;
+ vdd33a-supply = <&v2m_fixed_3v3>;
+ vddvario-supply = <&v2m_fixed_3v3>;
+ };
};
diff --git a/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts b/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts
index daa2e66ce..6e63b4351 100644
--- a/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts
+++ b/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts
@@ -8,34 +8,181 @@
#include "fvp-base-gicv3-psci-dynamiq-common.dtsi"
-&CPU0 {
- reg = <0x0 0x0>;
-};
+&CPU_MAP {
+ /delete-node/ cluster0;
-&CPU1 {
- reg = <0x0 0x1>;
+ cluster0 {
+ core0 {
+ thread0 {
+ cpu = <&CPU0>;
+ };
+ thread1 {
+ cpu = <&CPU1>;
+ };
+ };
+ core1 {
+ thread0 {
+ cpu = <&CPU2>;
+ };
+ thread1 {
+ cpu = <&CPU3>;
+ };
+ };
+ core2 {
+ thread0 {
+ cpu = <&CPU4>;
+ };
+ thread1 {
+ cpu = <&CPU5>;
+ };
+ };
+ core3 {
+ thread0 {
+ cpu = <&CPU6>;
+ };
+ thread1 {
+ cpu = <&CPU7>;
+ };
+ };
+ core4 {
+ thread0 {
+ cpu = <&CPU8>;
+ };
+ thread1 {
+ cpu = <&CPU9>;
+ };
+ };
+ core5 {
+ thread0 {
+ cpu = <&CPU10>;
+ };
+ thread1 {
+ cpu = <&CPU11>;
+ };
+ };
+ core6 {
+ thread0 {
+ cpu = <&CPU12>;
+ };
+ thread1 {
+ cpu = <&CPU13>;
+ };
+ };
+ core7 {
+ thread0 {
+ cpu = <&CPU14>;
+ };
+ thread1 {
+ cpu = <&CPU15>;
+ };
+ };
+ };
};
-&CPU2 {
- reg = <0x0 0x100>;
-};
+/ {
+ cpus {
+ CPU0:cpu@0 {
+ reg = <0x0 0x0>;
+ };
-&CPU3 {
- reg = <0x0 0x101>;
-};
+ CPU1:cpu@1 {
+ reg = <0x0 0x1>;
+ };
-&CPU4 {
- reg = <0x0 0x200>;
-};
+ CPU2:cpu@2 {
+ reg = <0x0 0x100>;
+ };
-&CPU5 {
- reg = <0x0 0x201>;
-};
+ CPU3:cpu@3 {
+ reg = <0x0 0x101>;
+ };
-&CPU6 {
- reg = <0x0 0x300>;
-};
+ CPU4:cpu@100 {
+ reg = <0x0 0x200>;
+ };
+
+ CPU5:cpu@101 {
+ reg = <0x0 0x201>;
+ };
+
+ CPU6:cpu@102 {
+ reg = <0x0 0x300>;
+ };
+
+ CPU7:cpu@103 {
+ reg = <0x0 0x301>;
+ };
+
+ CPU8:cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x400>;
+ enable-method = "psci";
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ next-level-cache = <&L2_0>;
+ };
+
+ CPU9:cpu@201 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x401>;
+ enable-method = "psci";
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ next-level-cache = <&L2_0>;
+ };
+
+ CPU10:cpu@202 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x500>;
+ enable-method = "psci";
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ next-level-cache = <&L2_0>;
+ };
+
+ CPU11:cpu@203 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x501>;
+ enable-method = "psci";
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ next-level-cache = <&L2_0>;
+ };
+
+ CPU12:cpu@300 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x600>;
+ enable-method = "psci";
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ next-level-cache = <&L2_0>;
+ };
+
+ CPU13:cpu@301 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x601>;
+ enable-method = "psci";
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ next-level-cache = <&L2_0>;
+ };
+
+ CPU14:cpu@302 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x700>;
+ enable-method = "psci";
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ next-level-cache = <&L2_0>;
+ };
-&CPU7 {
- reg = <0x0 0x301>;
+ CPU15:cpu@303 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x701>;
+ enable-method = "psci";
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+ next-level-cache = <&L2_0>;
+ };
+ };
};
diff --git a/include/arch/aarch32/asm_macros.S b/include/arch/aarch32/asm_macros.S
index 8cfa21231..ea1636e24 100644
--- a/include/arch/aarch32/asm_macros.S
+++ b/include/arch/aarch32/asm_macros.S
@@ -95,11 +95,24 @@
#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
/*
+ * Macro for mitigating against speculative execution.
* ARMv7 cores without Virtualization extension do not support the
* eret instruction.
*/
- .macro eret
+ .macro exception_return
movs pc, lr
+ dsb nsh
+ isb
+ .endm
+
+#else
+ /*
+ * Macro for mitigating against speculative execution beyond ERET.
+ */
+ .macro exception_return
+ eret
+ dsb nsh
+ isb
.endm
#endif
diff --git a/include/arch/aarch32/smccc_macros.S b/include/arch/aarch32/smccc_macros.S
index 4ec229218..ea7835a42 100644
--- a/include/arch/aarch32/smccc_macros.S
+++ b/include/arch/aarch32/smccc_macros.S
@@ -235,7 +235,7 @@
/* Restore the rest of the general purpose registers */
ldm r0, {r0-r12}
- eret
+ exception_return
.endm
#endif /* SMCCC_MACROS_S */
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 1faddbedc..b0c265047 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -97,6 +97,32 @@
#define ICC_SGI0R_EL1 S3_0_c12_c11_7
/*******************************************************************************
+ * Definitions for EL2 system registers for save/restore routine
+ ******************************************************************************/
+
+#define CNTPOFF_EL2 S3_4_C14_C0_6
+#define HAFGRTR_EL2 S3_4_C3_C1_6
+#define HDFGRTR_EL2 S3_4_C3_C1_4
+#define HDFGWTR_EL2 S3_4_C3_C1_5
+#define HFGITR_EL2 S3_4_C1_C1_6
+#define HFGRTR_EL2 S3_4_C1_C1_4
+#define HFGWTR_EL2 S3_4_C1_C1_5
+#define ICH_HCR_EL2 S3_4_C12_C11_0
+#define ICH_VMCR_EL2 S3_4_C12_C11_7
+#define MPAMVPM0_EL2 S3_4_C10_C5_0
+#define MPAMVPM1_EL2 S3_4_C10_C5_1
+#define MPAMVPM2_EL2 S3_4_C10_C5_2
+#define MPAMVPM3_EL2 S3_4_C10_C5_3
+#define MPAMVPM4_EL2 S3_4_C10_C5_4
+#define MPAMVPM5_EL2 S3_4_C10_C5_5
+#define MPAMVPM6_EL2 S3_4_C10_C5_6
+#define MPAMVPM7_EL2 S3_4_C10_C5_7
+#define MPAMVPMV_EL2 S3_4_C10_C4_1
+#define TRFCR_EL2 S3_4_C1_C2_1
+#define PMSCR_EL2 S3_4_C9_C9_0
+#define TFSR_EL2 S3_4_C5_C6_0
+
+/*******************************************************************************
* Generic timer memory mapped registers & offsets
******************************************************************************/
#define CNTCR_OFF U(0x000)
diff --git a/include/drivers/amlogic/meson_console.h b/include/drivers/amlogic/meson_console.h
index 70e3b0bd4..8d52d794b 100644
--- a/include/drivers/amlogic/meson_console.h
+++ b/include/drivers/amlogic/meson_console.h
@@ -9,17 +9,10 @@
#include <drivers/console.h>
-#define CONSOLE_T_MESON_BASE CONSOLE_T_DRVDATA
-
#ifndef __ASSEMBLER__
#include <stdint.h>
-typedef struct {
- console_t console;
- uintptr_t base;
-} console_meson_t;
-
/*
* Initialize a new meson console instance and register it with the console
* framework. The |console| pointer must point to storage that will be valid
@@ -30,7 +23,7 @@ typedef struct {
* order to make this function future-proof.
*/
int console_meson_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
- console_meson_t *console);
+ console_t *console);
#endif /*__ASSEMBLER__*/
diff --git a/include/drivers/arm/pl011.h b/include/drivers/arm/pl011.h
index 8733d1964..ebc664348 100644
--- a/include/drivers/arm/pl011.h
+++ b/include/drivers/arm/pl011.h
@@ -81,17 +81,10 @@
#endif /* !PL011_GENERIC_UART */
-#define CONSOLE_T_PL011_BASE CONSOLE_T_DRVDATA
-
#ifndef __ASSEMBLER__
#include <stdint.h>
-typedef struct {
- console_t console;
- uintptr_t base;
-} console_pl011_t;
-
/*
* Initialize a new PL011 console instance and register it with the console
* framework. The |console| pointer must point to storage that will be valid
@@ -99,7 +92,7 @@ typedef struct {
* Its contents will be reinitialized from scratch.
*/
int console_pl011_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
- console_pl011_t *console);
+ console_t *console);
#endif /*__ASSEMBLER__*/
diff --git a/include/drivers/auth/crypto_mod.h b/include/drivers/auth/crypto_mod.h
index f211035d7..71cf67306 100644
--- a/include/drivers/auth/crypto_mod.h
+++ b/include/drivers/auth/crypto_mod.h
@@ -13,9 +13,18 @@ enum crypto_ret_value {
CRYPTO_ERR_INIT,
CRYPTO_ERR_HASH,
CRYPTO_ERR_SIGNATURE,
+ CRYPTO_ERR_DECRYPTION,
CRYPTO_ERR_UNKNOWN
};
+#define CRYPTO_MAX_IV_SIZE 16U
+#define CRYPTO_MAX_TAG_SIZE 16U
+
+/* Decryption algorithm */
+enum crypto_dec_algo {
+ CRYPTO_GCM_DECRYPT = 0
+};
+
/*
* Cryptographic library descriptor
*/
@@ -44,6 +53,15 @@ typedef struct crypto_lib_desc_s {
unsigned int data_len, unsigned char *output);
#endif /* MEASURED_BOOT */
+ /*
+ * Authenticated decryption. Return one of the
+ * 'enum crypto_ret_value' options.
+ */
+ int (*auth_decrypt)(enum crypto_dec_algo dec_algo, void *data_ptr,
+ size_t len, const void *key, unsigned int key_len,
+ unsigned int key_flags, const void *iv,
+ unsigned int iv_len, const void *tag,
+ unsigned int tag_len);
} crypto_lib_desc_t;
/* Public functions */
@@ -54,6 +72,11 @@ int crypto_mod_verify_signature(void *data_ptr, unsigned int data_len,
void *pk_ptr, unsigned int pk_len);
int crypto_mod_verify_hash(void *data_ptr, unsigned int data_len,
void *digest_info_ptr, unsigned int digest_info_len);
+int crypto_mod_auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
+ size_t len, const void *key, unsigned int key_len,
+ unsigned int key_flags, const void *iv,
+ unsigned int iv_len, const void *tag,
+ unsigned int tag_len);
#if MEASURED_BOOT
int crypto_mod_calc_hash(unsigned int alg, void *data_ptr,
@@ -61,21 +84,24 @@ int crypto_mod_calc_hash(unsigned int alg, void *data_ptr,
/* Macro to register a cryptographic library */
#define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash, \
- _calc_hash) \
+ _calc_hash, _auth_decrypt) \
const crypto_lib_desc_t crypto_lib_desc = { \
.name = _name, \
.init = _init, \
.verify_signature = _verify_signature, \
.verify_hash = _verify_hash, \
- .calc_hash = _calc_hash \
+ .calc_hash = _calc_hash, \
+ .auth_decrypt = _auth_decrypt \
}
#else
-#define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash) \
+#define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash, \
+ _auth_decrypt) \
const crypto_lib_desc_t crypto_lib_desc = { \
.name = _name, \
.init = _init, \
.verify_signature = _verify_signature, \
- .verify_hash = _verify_hash \
+ .verify_hash = _verify_hash, \
+ .auth_decrypt = _auth_decrypt \
}
#endif /* MEASURED_BOOT */
diff --git a/include/drivers/auth/mbedtls/mbedtls_config.h b/include/drivers/auth/mbedtls/mbedtls_config.h
index 6e179bbd1..dc00da7d6 100644
--- a/include/drivers/auth/mbedtls/mbedtls_config.h
+++ b/include/drivers/auth/mbedtls/mbedtls_config.h
@@ -79,6 +79,12 @@
#define MBEDTLS_X509_USE_C
#define MBEDTLS_X509_CRT_PARSE_C
+#if TF_MBEDTLS_USE_AES_GCM
+#define MBEDTLS_AES_C
+#define MBEDTLS_CIPHER_C
+#define MBEDTLS_GCM_C
+#endif
+
/* MPI / BIGNUM options */
#define MBEDTLS_MPI_WINDOW_SIZE 2
diff --git a/include/drivers/cadence/cdns_uart.h b/include/drivers/cadence/cdns_uart.h
index 64a062ca1..46ba4663e 100644
--- a/include/drivers/cadence/cdns_uart.h
+++ b/include/drivers/cadence/cdns_uart.h
@@ -25,17 +25,10 @@
#define R_UART_TX 0x30
#define R_UART_RX 0x30
-#define CONSOLE_T_CDNS_BASE CONSOLE_T_DRVDATA
-
#ifndef __ASSEMBLER__
#include <stdint.h>
-typedef struct {
- console_t console;
- uintptr_t base;
-} console_cdns_t;
-
/*
* Initialize a new Cadence console instance and register it with the console
* framework. The |console| pointer must point to storage that will be valid
@@ -43,7 +36,7 @@ typedef struct {
* Its contents will be reinitialized from scratch.
*/
int console_cdns_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
- console_cdns_t *console);
+ console_t *console);
#endif /*__ASSEMBLER__*/
diff --git a/include/drivers/console.h b/include/drivers/console.h
index a4859d80f..761816ac7 100644
--- a/include/drivers/console.h
+++ b/include/drivers/console.h
@@ -14,7 +14,8 @@
#define CONSOLE_T_PUTC (U(2) * REGSZ)
#define CONSOLE_T_GETC (U(3) * REGSZ)
#define CONSOLE_T_FLUSH (U(4) * REGSZ)
-#define CONSOLE_T_DRVDATA (U(5) * REGSZ)
+#define CONSOLE_T_BASE (U(5) * REGSZ)
+#define CONSOLE_T_DRVDATA (U(6) * REGSZ)
#define CONSOLE_FLAG_BOOT (U(1) << 0)
#define CONSOLE_FLAG_RUNTIME (U(1) << 1)
@@ -43,6 +44,7 @@ typedef struct console {
int (*const putc)(int character, struct console *console);
int (*const getc)(struct console *console);
int (*const flush)(struct console *console);
+ uintptr_t base;
/* Additional private driver data may follow here. */
} console_t;
diff --git a/include/drivers/coreboot/cbmem_console.h b/include/drivers/coreboot/cbmem_console.h
index 40c90e6bb..30b39f14d 100644
--- a/include/drivers/coreboot/cbmem_console.h
+++ b/include/drivers/coreboot/cbmem_console.h
@@ -9,14 +9,12 @@
#include <drivers/console.h>
-#define CONSOLE_T_CBMC_BASE CONSOLE_T_DRVDATA
-#define CONSOLE_T_CBMC_SIZE (CONSOLE_T_DRVDATA + REGSZ)
+#define CONSOLE_T_CBMC_SIZE CONSOLE_T_DRVDATA
#ifndef __ASSEMBLER__
typedef struct {
console_t console;
- uintptr_t base;
uint32_t size;
} console_cbmc_t;
diff --git a/include/drivers/io/io_encrypted.h b/include/drivers/io/io_encrypted.h
new file mode 100644
index 000000000..9dcf061b4
--- /dev/null
+++ b/include/drivers/io/io_encrypted.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2020, Linaro Limited. All rights reserved.
+ * Author: Sumit Garg <sumit.garg@linaro.org>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IO_ENCRYPTED_H
+#define IO_ENCRYPTED_H
+
+struct io_dev_connector;
+
+int register_io_dev_enc(const struct io_dev_connector **dev_con);
+
+#endif /* IO_ENCRYPTED_H */
diff --git a/include/drivers/io/io_storage.h b/include/drivers/io/io_storage.h
index a301ad563..f2d641c2d 100644
--- a/include/drivers/io/io_storage.h
+++ b/include/drivers/io/io_storage.h
@@ -25,6 +25,7 @@ typedef enum {
IO_TYPE_MTD,
IO_TYPE_MMC,
IO_TYPE_STM32IMAGE,
+ IO_TYPE_ENCRYPTED,
IO_TYPE_MAX
} io_type_t;
diff --git a/include/drivers/marvell/uart/a3700_console.h b/include/drivers/marvell/uart/a3700_console.h
index 517f01a8f..5e3ab0515 100644
--- a/include/drivers/marvell/uart/a3700_console.h
+++ b/include/drivers/marvell/uart/a3700_console.h
@@ -54,17 +54,10 @@
#define UART_CTRL_TXFIFO_RESET (1 << 15)
#define UARTLSR_TXFIFOEMPTY (1 << 6)
-#define CONSOLE_T_A3700_BASE CONSOLE_T_DRVDATA
-
#ifndef __ASSEMBLER__
#include <stdint.h>
-typedef struct {
- console_t console;
- uintptr_t base;
-} console_a3700_t;
-
/*
* Initialize a new a3700 console instance and register it with the console
* framework. The |console| pointer must point to storage that will be valid
@@ -72,7 +65,7 @@ typedef struct {
* Its contents will be reinitialized from scratch.
*/
int console_a3700_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
- console_a3700_t *console);
+ console_t *console);
#endif /*__ASSEMBLER__*/
diff --git a/include/drivers/renesas/rcar/console/console.h b/include/drivers/renesas/rcar/console/console.h
index 0e4ed8f35..7d5b5d3ce 100644
--- a/include/drivers/renesas/rcar/console/console.h
+++ b/include/drivers/renesas/rcar/console/console.h
@@ -7,17 +7,10 @@
#ifndef RCAR_PRINTF_H
#define RCAR_PRINTF_H
-#define CONSOLE_T_RCAR_BASE CONSOLE_T_DRVDATA
-
#ifndef __ASSEMBLER__
#include <stdint.h>
-typedef struct {
- console_t console;
- uintptr_t base;
-} console_rcar_t;
-
/*
* Initialize a new rcar console instance and register it with the console
* framework. The |console| pointer must point to storage that will be valid
@@ -25,7 +18,7 @@ typedef struct {
* Its contents will be reinitialized from scratch.
*/
int console_rcar_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
- console_rcar_t *console);
+ console_t *console);
#endif /*__ASSEMBLER__*/
diff --git a/include/drivers/st/stm32_console.h b/include/drivers/st/stm32_console.h
index a2ad87cb5..8d9187d2a 100644
--- a/include/drivers/st/stm32_console.h
+++ b/include/drivers/st/stm32_console.h
@@ -9,17 +9,10 @@
#include <drivers/console.h>
-#define CONSOLE_T_STM32_BASE CONSOLE_T_DRVDATA
-
#ifndef __ASSEMBLER__
#include <stdint.h>
-struct console_stm32 {
- console_t console;
- uintptr_t base;
-};
-
/*
* Initialize a new STM32 console instance and register it with the console
* framework. The |console| pointer must point to storage that will be valid
@@ -27,7 +20,7 @@ struct console_stm32 {
* Its contents will be reinitialized from scratch.
*/
int console_stm32_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
- struct console_stm32 *console);
+ console_t *console);
#endif /*__ASSEMBLER__*/
diff --git a/include/drivers/ti/uart/uart_16550.h b/include/drivers/ti/uart/uart_16550.h
index 2b95fa33a..bddd9970c 100644
--- a/include/drivers/ti/uart/uart_16550.h
+++ b/include/drivers/ti/uart/uart_16550.h
@@ -71,17 +71,10 @@
#define UARTLSR_RDR_BIT (0) /* Rx Data Ready Bit */
#define UARTLSR_RDR (1 << UARTLSR_RDR_BIT) /* Rx Data Ready */
-#define CONSOLE_T_16550_BASE CONSOLE_T_DRVDATA
-
#ifndef __ASSEMBLER__
#include <stdint.h>
-typedef struct {
- console_t console;
- uintptr_t base;
-} console_16550_t;
-
/*
* Initialize a new 16550 console instance and register it with the console
* framework. The |console| pointer must point to storage that will be valid
@@ -94,7 +87,7 @@ typedef struct {
* case as well.
*/
int console_16550_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
- console_16550_t *console);
+ console_t *console);
#endif /*__ASSEMBLER__*/
diff --git a/include/export/common/tbbr/tbbr_img_def_exp.h b/include/export/common/tbbr/tbbr_img_def_exp.h
index ff0d16c73..89dbc58fe 100644
--- a/include/export/common/tbbr/tbbr_img_def_exp.h
+++ b/include/export/common/tbbr/tbbr_img_def_exp.h
@@ -85,7 +85,15 @@
/* Binary with STM32 header */
#define STM32_IMAGE_ID U(29)
+/* Encrypted image identifier */
+#define ENC_IMAGE_ID U(30)
+
/* Define size of the array */
-#define MAX_NUMBER_IDS U(30)
+#if defined(SPD_spmd)
+#define MAX_SP_IDS U(8)
+#define MAX_NUMBER_IDS MAX_SP_IDS + U(31)
+#else
+#define MAX_NUMBER_IDS U(31)
+#endif
#endif /* ARM_TRUSTED_FIRMWARE_EXPORT_COMMON_TBBR_TBBR_IMG_DEF_EXP_H */
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 4158c023e..e061950c8 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -68,7 +68,7 @@
* registers are only 32-bits wide but are stored as 64-bit values for
* convenience
******************************************************************************/
-#define CTX_SYSREGS_OFFSET (CTX_EL3STATE_OFFSET + CTX_EL3STATE_END)
+#define CTX_EL1_SYSREGS_OFFSET (CTX_EL3STATE_OFFSET + CTX_EL3STATE_END)
#define CTX_SPSR_EL1 U(0x0)
#define CTX_ELR_EL1 U(0x8)
#define CTX_SCTLR_EL1 U(0x10)
@@ -138,13 +138,118 @@
/*
* End of system registers.
*/
-#define CTX_SYSREGS_END CTX_MTE_REGS_END
+#define CTX_EL1_SYSREGS_END CTX_MTE_REGS_END
+
+/*
+ * EL2 register set
+ */
+
+#if CTX_INCLUDE_EL2_REGS
+/* For later discussion
+ * ICH_AP0R<n>_EL2
+ * ICH_AP1R<n>_EL2
+ * AMEVCNTVOFF0<n>_EL2
+ * AMEVCNTVOFF1<n>_EL2
+ * ICH_LR<n>_EL2
+ */
+#define CTX_EL2_SYSREGS_OFFSET (CTX_EL1_SYSREGS_OFFSET + CTX_EL1_SYSREGS_END)
+
+#define CTX_ACTLR_EL2 U(0x0)
+#define CTX_AFSR0_EL2 U(0x8)
+#define CTX_AFSR1_EL2 U(0x10)
+#define CTX_AMAIR_EL2 U(0x18)
+#define CTX_CNTHCTL_EL2 U(0x20)
+#define CTX_CNTHP_CTL_EL2 U(0x28)
+#define CTX_CNTHP_CVAL_EL2 U(0x30)
+#define CTX_CNTHP_TVAL_EL2 U(0x38)
+#define CTX_CNTVOFF_EL2 U(0x40)
+#define CTX_CPTR_EL2 U(0x48)
+#define CTX_DBGVCR32_EL2 U(0x50)
+#define CTX_ELR_EL2 U(0x58)
+#define CTX_ESR_EL2 U(0x60)
+#define CTX_FAR_EL2 U(0x68)
+#define CTX_FPEXC32_EL2 U(0x70)
+#define CTX_HACR_EL2 U(0x78)
+#define CTX_HCR_EL2 U(0x80)
+#define CTX_HPFAR_EL2 U(0x88)
+#define CTX_HSTR_EL2 U(0x90)
+#define CTX_ICC_SRE_EL2 U(0x98)
+#define CTX_ICH_HCR_EL2 U(0xa0)
+#define CTX_ICH_VMCR_EL2 U(0xa8)
+#define CTX_MAIR_EL2 U(0xb0)
+#define CTX_MDCR_EL2 U(0xb8)
+#define CTX_PMSCR_EL2 U(0xc0)
+#define CTX_SCTLR_EL2 U(0xc8)
+#define CTX_SPSR_EL2 U(0xd0)
+#define CTX_SP_EL2 U(0xd8)
+#define CTX_TCR_EL2 U(0xe0)
+#define CTX_TRFCR_EL2 U(0xe8)
+#define CTX_TTBR0_EL2 U(0xf0)
+#define CTX_VBAR_EL2 U(0xf8)
+#define CTX_VMPIDR_EL2 U(0x100)
+#define CTX_VPIDR_EL2 U(0x108)
+#define CTX_VTCR_EL2 U(0x110)
+#define CTX_VTTBR_EL2 U(0x118)
+
+// Only if MTE registers in use
+#define CTX_TFSR_EL2 U(0x120)
+
+// Only if ENABLE_MPAM_FOR_LOWER_ELS==1
+#define CTX_MPAM2_EL2 U(0x128)
+#define CTX_MPAMHCR_EL2 U(0x130)
+#define CTX_MPAMVPM0_EL2 U(0x138)
+#define CTX_MPAMVPM1_EL2 U(0x140)
+#define CTX_MPAMVPM2_EL2 U(0x148)
+#define CTX_MPAMVPM3_EL2 U(0x150)
+#define CTX_MPAMVPM4_EL2 U(0x158)
+#define CTX_MPAMVPM5_EL2 U(0x160)
+#define CTX_MPAMVPM6_EL2 U(0x168)
+#define CTX_MPAMVPM7_EL2 U(0x170)
+#define CTX_MPAMVPMV_EL2 U(0x178)
+
+// Starting with Armv8.6
+#define CTX_HAFGRTR_EL2 U(0x180)
+#define CTX_HDFGRTR_EL2 U(0x188)
+#define CTX_HDFGWTR_EL2 U(0x190)
+#define CTX_HFGITR_EL2 U(0x198)
+#define CTX_HFGRTR_EL2 U(0x1a0)
+#define CTX_HFGWTR_EL2 U(0x1a8)
+#define CTX_CNTPOFF_EL2 U(0x1b0)
+
+// Starting with Armv8.4
+#define CTX_CNTHPS_CTL_EL2 U(0x1b8)
+#define CTX_CNTHPS_CVAL_EL2 U(0x1c0)
+#define CTX_CNTHPS_TVAL_EL2 U(0x1c8)
+#define CTX_CNTHVS_CTL_EL2 U(0x1d0)
+#define CTX_CNTHVS_CVAL_EL2 U(0x1d8)
+#define CTX_CNTHVS_TVAL_EL2 U(0x1e0)
+#define CTX_CNTHV_CTL_EL2 U(0x1e8)
+#define CTX_CNTHV_CVAL_EL2 U(0x1f0)
+#define CTX_CNTHV_TVAL_EL2 U(0x1f8)
+#define CTX_CONTEXTIDR_EL2 U(0x200)
+#define CTX_SDER32_EL2 U(0x208)
+#define CTX_TTBR1_EL2 U(0x210)
+#define CTX_VDISR_EL2 U(0x218)
+#define CTX_VNCR_EL2 U(0x220)
+#define CTX_VSESR_EL2 U(0x228)
+#define CTX_VSTCR_EL2 U(0x230)
+#define CTX_VSTTBR_EL2 U(0x238)
+
+// Starting with Armv8.5
+#define CTX_SCXTNUM_EL2 U(0x240)
+/* Align to the next 16 byte boundary */
+#define CTX_EL2_SYSREGS_END U(0x250)
+#endif /* CTX_INCLUDE_EL2_REGS */
/*******************************************************************************
* Constants that allow assembler code to access members of and the 'fp_regs'
* structure at their correct offsets.
******************************************************************************/
-#define CTX_FPREGS_OFFSET (CTX_SYSREGS_OFFSET + CTX_SYSREGS_END)
+#if CTX_INCLUDE_EL2_REGS
+# define CTX_FPREGS_OFFSET (CTX_EL2_SYSREGS_OFFSET + CTX_EL2_SYSREGS_END)
+#else
+# define CTX_FPREGS_OFFSET (CTX_EL1_SYSREGS_OFFSET + CTX_EL1_SYSREGS_END)
+#endif
#if CTX_INCLUDE_FPREGS
#define CTX_FP_Q0 U(0x0)
#define CTX_FP_Q1 U(0x10)
@@ -235,7 +340,10 @@
/* Constants to determine the size of individual context structures */
#define CTX_GPREG_ALL (CTX_GPREGS_END >> DWORD_SHIFT)
-#define CTX_SYSREG_ALL (CTX_SYSREGS_END >> DWORD_SHIFT)
+#define CTX_EL1_SYSREGS_ALL (CTX_EL1_SYSREGS_END >> DWORD_SHIFT)
+#if CTX_INCLUDE_EL2_REGS
+# define CTX_EL2_SYSREGS_ALL (CTX_EL2_SYSREGS_END >> DWORD_SHIFT)
+#endif
#if CTX_INCLUDE_FPREGS
# define CTX_FPREG_ALL (CTX_FPREGS_END >> DWORD_SHIFT)
#endif
@@ -256,10 +364,18 @@ DEFINE_REG_STRUCT(gp_regs, CTX_GPREG_ALL);
/*
* AArch64 EL1 system register context structure for preserving the
- * architectural state during switches from one security state to
- * another in EL1.
+ * architectural state during world switches.
+ */
+DEFINE_REG_STRUCT(el1_sysregs, CTX_EL1_SYSREGS_ALL);
+
+
+/*
+ * AArch64 EL2 system register context structure for preserving the
+ * architectural state during world switches.
*/
-DEFINE_REG_STRUCT(el1_sys_regs, CTX_SYSREG_ALL);
+#if CTX_INCLUDE_EL2_REGS
+DEFINE_REG_STRUCT(el2_sysregs, CTX_EL2_SYSREGS_ALL);
+#endif
/*
* AArch64 floating point register context structure for preserving
@@ -304,7 +420,10 @@ DEFINE_REG_STRUCT(pauth, CTX_PAUTH_REGS_ALL);
typedef struct cpu_context {
gp_regs_t gpregs_ctx;
el3_state_t el3state_ctx;
- el1_sys_regs_t sysregs_ctx;
+ el1_sysregs_t el1_sysregs_ctx;
+#if CTX_INCLUDE_EL2_REGS
+ el2_sysregs_t el2_sysregs_ctx;
+#endif
#if CTX_INCLUDE_FPREGS
fp_regs_t fpregs_ctx;
#endif
@@ -319,7 +438,10 @@ typedef struct cpu_context {
#if CTX_INCLUDE_FPREGS
# define get_fpregs_ctx(h) (&((cpu_context_t *) h)->fpregs_ctx)
#endif
-#define get_sysregs_ctx(h) (&((cpu_context_t *) h)->sysregs_ctx)
+#define get_el1_sysregs_ctx(h) (&((cpu_context_t *) h)->el1_sysregs_ctx)
+#if CTX_INCLUDE_EL2_REGS
+# define get_el2_sysregs_ctx(h) (&((cpu_context_t *) h)->el2_sysregs_ctx)
+#endif
#define get_gpregs_ctx(h) (&((cpu_context_t *) h)->gpregs_ctx)
#define get_cve_2018_3639_ctx(h) (&((cpu_context_t *) h)->cve_2018_3639_ctx)
#if CTX_INCLUDE_PAUTH_REGS
@@ -333,8 +455,12 @@ typedef struct cpu_context {
*/
CASSERT(CTX_GPREGS_OFFSET == __builtin_offsetof(cpu_context_t, gpregs_ctx), \
assert_core_context_gp_offset_mismatch);
-CASSERT(CTX_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, sysregs_ctx), \
- assert_core_context_sys_offset_mismatch);
+CASSERT(CTX_EL1_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el1_sysregs_ctx), \
+ assert_core_context_el1_sys_offset_mismatch);
+#if CTX_INCLUDE_EL2_REGS
+CASSERT(CTX_EL2_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el2_sysregs_ctx), \
+ assert_core_context_el2_sys_offset_mismatch);
+#endif
#if CTX_INCLUDE_FPREGS
CASSERT(CTX_FPREGS_OFFSET == __builtin_offsetof(cpu_context_t, fpregs_ctx), \
assert_core_context_fp_offset_mismatch);
@@ -387,8 +513,14 @@ CASSERT(CTX_PAUTH_REGS_OFFSET == __builtin_offsetof(cpu_context_t, pauth_ctx), \
/*******************************************************************************
* Function prototypes
******************************************************************************/
-void el1_sysregs_context_save(el1_sys_regs_t *regs);
-void el1_sysregs_context_restore(el1_sys_regs_t *regs);
+void el1_sysregs_context_save(el1_sysregs_t *regs);
+void el1_sysregs_context_restore(el1_sysregs_t *regs);
+
+#if CTX_INCLUDE_EL2_REGS
+void el2_sysregs_context_save(el2_sysregs_t *regs);
+void el2_sysregs_context_restore(el2_sysregs_t *regs);
+#endif
+
#if CTX_INCLUDE_FPREGS
void fpregs_context_save(fp_regs_t *regs);
void fpregs_context_restore(fp_regs_t *regs);
diff --git a/include/lib/el3_runtime/context_mgmt.h b/include/lib/el3_runtime/context_mgmt.h
index 17955e3a8..b36cd3d70 100644
--- a/include/lib/el3_runtime/context_mgmt.h
+++ b/include/lib/el3_runtime/context_mgmt.h
@@ -36,6 +36,11 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep);
void cm_prepare_el3_exit(uint32_t security_state);
#ifdef __aarch64__
+#if CTX_INCLUDE_EL2_REGS
+void cm_el2_sysregs_context_save(uint32_t security_state);
+void cm_el2_sysregs_context_restore(uint32_t security_state);
+#endif
+
void cm_el1_sysregs_context_save(uint32_t security_state);
void cm_el1_sysregs_context_restore(uint32_t security_state);
void cm_set_elr_el3(uint32_t security_state, uintptr_t entrypoint);
diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h
index f58ff5710..0401e5c06 100644
--- a/include/lib/fconf/fconf.h
+++ b/include/lib/fconf/fconf.h
@@ -14,9 +14,9 @@
#define FCONF_REGISTER_POPULATOR(name, callback) \
__attribute__((used, section(".fconf_populator"))) \
- const struct fconf_populator name##__populator = { \
- .info = #name, \
- .populate = callback \
+ const struct fconf_populator (name##__populator) = { \
+ .info = (#name), \
+ .populate = (callback) \
};
/*
diff --git a/include/lib/object_pool.h b/include/lib/object_pool.h
index 0f85331a8..66e8c4780 100644
--- a/include/lib/object_pool.h
+++ b/include/lib/object_pool.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
*/
@@ -56,13 +56,13 @@ struct object_pool {
*/
static inline void *pool_alloc_n(struct object_pool *pool, size_t count)
{
- if (pool->used + count > pool->capacity) {
+ if ((pool->used + count) > pool->capacity) {
ERROR("Cannot allocate %zu objects out of pool (%zu objects left).\n",
count, pool->capacity - pool->used);
panic();
}
- void *obj = (char *)(pool->objects) + pool->obj_size * pool->used;
+ void *obj = (char *)(pool->objects) + (pool->obj_size * pool->used);
pool->used += count;
return obj;
}
diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h
index 0e099987e..a80fab073 100644
--- a/include/lib/xlat_tables/xlat_tables_v2.h
+++ b/include/lib/xlat_tables/xlat_tables_v2.h
@@ -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
*/
@@ -345,6 +345,16 @@ int xlat_change_mem_attributes_ctx(const xlat_ctx_t *ctx, uintptr_t base_va,
size_t size, uint32_t attr);
int xlat_change_mem_attributes(uintptr_t base_va, size_t size, uint32_t attr);
+#if PLAT_RO_XLAT_TABLES
+/*
+ * Change the memory attributes of the memory region encompassing the higher
+ * level translation tables to secure read-only data.
+ *
+ * Return 0 on success, a negative error code on error.
+ */
+int xlat_make_tables_readonly(void);
+#endif
+
/*
* Query the memory attributes of a memory page in a set of translation tables.
*
diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
index b17b71a87..c88fa4dd5 100644
--- a/include/lib/xlat_tables/xlat_tables_v2_helpers.h
+++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
@@ -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
*/
@@ -70,6 +70,9 @@ struct xlat_ctx {
*/
uint64_t (*tables)[XLAT_TABLE_ENTRIES];
int tables_num;
+#if PLAT_RO_XLAT_TABLES
+ bool readonly_tables;
+#endif
/*
* Keep track of how many regions are mapped in each table. The base
* table can't be unmapped so it isn't needed to keep track of it.
@@ -122,6 +125,14 @@ struct xlat_ctx {
/* do nothing */
#endif /* PLAT_XLAT_TABLES_DYNAMIC */
+#if PLAT_RO_XLAT_TABLES
+#define XLAT_CTX_INIT_TABLE_ATTR() \
+ .readonly_tables = false,
+#else
+#define XLAT_CTX_INIT_TABLE_ATTR()
+ /* do nothing */
+#endif
+
#define REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count, \
_xlat_tables_count, _virt_addr_space_size, \
_phy_addr_space_size, _xlat_regime, _section_name)\
@@ -142,22 +153,63 @@ struct xlat_ctx {
XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \
\
static xlat_ctx_t _ctx_name##_xlat_ctx = { \
- .va_max_address = (_virt_addr_space_size) - 1UL, \
.pa_max_address = (_phy_addr_space_size) - 1ULL, \
+ .va_max_address = (_virt_addr_space_size) - 1UL, \
.mmap = _ctx_name##_mmap, \
.mmap_num = (_mmap_count), \
- .base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),\
+ .tables = _ctx_name##_xlat_tables, \
+ .tables_num = _xlat_tables_count, \
+ XLAT_CTX_INIT_TABLE_ATTR() \
+ XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name) \
+ .next_table = 0, \
.base_table = _ctx_name##_base_xlat_table, \
.base_table_entries = \
GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size),\
+ .max_pa = 0U, \
+ .max_va = 0U, \
+ .base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),\
+ .initialized = false, \
+ .xlat_regime = (_xlat_regime) \
+ }
+
+#define REGISTER_XLAT_CONTEXT_RO_BASE_TABLE(_ctx_name, _mmap_count, \
+ _xlat_tables_count, _virt_addr_space_size, \
+ _phy_addr_space_size, _xlat_regime, _section_name)\
+ CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size), \
+ assert_invalid_physical_addr_space_sizefor_##_ctx_name);\
+ \
+ static mmap_region_t _ctx_name##_mmap[_mmap_count + 1]; \
+ \
+ static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count] \
+ [XLAT_TABLE_ENTRIES] \
+ __aligned(XLAT_TABLE_SIZE) __section(_section_name); \
+ \
+ static uint64_t _ctx_name##_base_xlat_table \
+ [GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)] \
+ __aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)\
+ * sizeof(uint64_t)) \
+ __section(".rodata"); \
+ \
+ XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \
+ \
+ static xlat_ctx_t _ctx_name##_xlat_ctx = { \
+ .pa_max_address = (_phy_addr_space_size) - 1ULL, \
+ .va_max_address = (_virt_addr_space_size) - 1UL, \
+ .mmap = _ctx_name##_mmap, \
+ .mmap_num = (_mmap_count), \
.tables = _ctx_name##_xlat_tables, \
.tables_num = _xlat_tables_count, \
+ XLAT_CTX_INIT_TABLE_ATTR() \
XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name) \
- .xlat_regime = (_xlat_regime), \
+ .next_table = 0, \
+ .base_table = _ctx_name##_base_xlat_table, \
+ .base_table_entries = \
+ GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size),\
.max_pa = 0U, \
.max_va = 0U, \
- .next_table = 0, \
+ .base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),\
.initialized = false, \
+ .xlat_regime = (_xlat_regime) \
}
#endif /*__ASSEMBLER__*/
diff --git a/include/plat/arm/board/common/board_css_def.h b/include/plat/arm/board/common/board_css_def.h
index 4637b6785..b79e0d572 100644
--- a/include/plat/arm/board/common/board_css_def.h
+++ b/include/plat/arm/board/common/board_css_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
*/
@@ -50,13 +50,6 @@
#define PLAT_ARM_NVM_BASE V2M_FLASH0_BASE
#define PLAT_ARM_NVM_SIZE (V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
-/*
- * Required platform porting definitions common to all ARM CSS-based
- * development platforms
- */
-#define PLAT_ARM_DRAM2_BASE ULL(0x880000000)
-#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000)
-
/* UART related constants */
#define PLAT_ARM_BOOT_UART_BASE SOC_CSS_UART0_BASE
#define PLAT_ARM_BOOT_UART_CLK_IN_HZ SOC_CSS_UART0_CLK_IN_HZ
diff --git a/include/plat/arm/common/fconf_arm_sp_getter.h b/include/plat/arm/common/fconf_arm_sp_getter.h
new file mode 100644
index 000000000..38c30fbf9
--- /dev/null
+++ b/include/plat/arm/common/fconf_arm_sp_getter.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FCONF_ARM_SP_GETTER_H
+#define FCONF_ARM_SP_GETTER_H
+
+#include <lib/fconf/fconf.h>
+#include <tools_share/uuid.h>
+
+/* arm_sp getter */
+#define arm__sp_getter(prop) arm_sp.prop
+
+#define ARM_SP_MAX_SIZE U(0x10000)
+
+struct arm_sp_t {
+ unsigned int number_of_sp;
+ union uuid_helper_t uuids[MAX_SP_IDS];
+ uintptr_t load_addr[MAX_SP_IDS];
+};
+
+int fconf_populate_arm_sp(uintptr_t config);
+
+extern struct arm_sp_t arm_sp;
+
+extern bl_mem_params_node_t sp_mem_params_descs[MAX_SP_IDS];
+
+#endif /* FCONF_ARM_SP_GETTER_H */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 025a64fa2..ff1b9799a 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -152,7 +152,8 @@ void arm_setup_romlib(void);
int arm_io_setup(void);
/* Security utility functions */
-void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions);
+void arm_tzc400_setup(uintptr_t tzc_base,
+ const arm_tzc_regions_info_t *tzc_regions);
struct tzc_dmc500_driver_data;
void arm_tzc_dmc500_setup(struct tzc_dmc500_driver_data *plat_driver_data,
const arm_tzc_regions_info_t *tzc_regions);
@@ -237,6 +238,11 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size);
void arm_free_init_memory(void);
/*
+ * Make the higher level translation tables read-only
+ */
+void arm_xlat_make_tables_readonly(void);
+
+/*
* Mandatory functions required in ARM standard platforms
*/
unsigned int plat_arm_get_cluster_core_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 7b6148445..d59935266 100644
--- a/include/plat/arm/css/common/css_def.h
+++ b/include/plat/arm/css/common/css_def.h
@@ -189,9 +189,6 @@
/* Load address of Non-Secure Image for CSS platform ports */
#define PLAT_ARM_NS_IMAGE_BASE U(0xE0000000)
-/* TZC related constants */
-#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT_ALL
-
/*
* Parsing of CPU and Cluster states, as returned by 'Get CSS Power State' SCP
* command
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index f5bd298c5..5b5ebb973 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -27,6 +27,7 @@ struct bl_params;
struct mmap_region;
struct spm_mm_boot_info;
struct sp_res_desc;
+enum fw_enc_status_t;
/*******************************************************************************
* plat_get_rotpk_info() flags
@@ -37,6 +38,15 @@ struct sp_res_desc;
#define ROTPK_NOT_DEPLOYED (1 << 1)
/*******************************************************************************
+ * plat_get_enc_key_info() flags
+ ******************************************************************************/
+/*
+ * Flag used to notify caller that information provided in key buffer is an
+ * identifier rather than an actual key.
+ */
+#define ENC_KEY_IS_IDENTIFIER (1 << 0)
+
+/*******************************************************************************
* Function declarations
******************************************************************************/
/*******************************************************************************
@@ -265,6 +275,9 @@ int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr);
int plat_set_nv_ctr2(void *cookie, const struct auth_img_desc_s *img_desc,
unsigned int nv_ctr);
int get_mbedtls_heap_helper(void **heap_addr, size_t *heap_size);
+int plat_get_enc_key_info(enum fw_enc_status_t fw_enc_status, uint8_t *key,
+ size_t *key_len, unsigned int *flags,
+ const uint8_t *img_id, size_t img_id_len);
/*******************************************************************************
* Secure Partitions functions
diff --git a/include/services/spm_core_manifest.h b/include/services/spm_core_manifest.h
index 06ecc1391..78748826d 100644
--- a/include/services/spm_core_manifest.h
+++ b/include/services/spm_core_manifest.h
@@ -21,13 +21,6 @@ typedef struct spm_core_manifest_sect_attribute {
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
diff --git a/include/services/spmd_svc.h b/include/services/spmd_svc.h
index 6e4caf266..a766dcf8f 100644
--- a/include/services/spmd_svc.h
+++ b/include/services/spmd_svc.h
@@ -11,7 +11,7 @@
#include <services/spci_svc.h>
#include <stdint.h>
-int32_t spmd_setup(void);
+int spmd_setup(void);
uint64_t spmd_smc_handler(uint32_t smc_fid,
uint64_t x1,
uint64_t x2,
diff --git a/include/tools_share/firmware_encrypted.h b/include/tools_share/firmware_encrypted.h
new file mode 100644
index 000000000..7ca634f5e
--- /dev/null
+++ b/include/tools_share/firmware_encrypted.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2020, Linaro Limited. All rights reserved.
+ * Author: Sumit Garg <sumit.garg@linaro.org>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FIRMWARE_ENCRYPTED_H
+#define FIRMWARE_ENCRYPTED_H
+
+#include <stdint.h>
+
+/* This is used as a signature to validate the encryption header */
+#define ENC_HEADER_MAGIC 0xAA640001U
+
+/* Firmware encryption status flag mask */
+#define FW_ENC_STATUS_FLAG_MASK 0x1
+
+/*
+ * SSK: Secret Symmetric Key
+ * BSSK: Binding Secret Symmetric Key
+ */
+enum fw_enc_status_t {
+ FW_ENC_WITH_SSK = 0,
+ FW_ENC_WITH_BSSK = 1,
+};
+
+#define ENC_MAX_IV_SIZE 16U
+#define ENC_MAX_TAG_SIZE 16U
+#define ENC_MAX_KEY_SIZE 32U
+
+struct fw_enc_hdr {
+ uint32_t magic;
+ uint16_t dec_algo;
+ uint16_t flags;
+ uint16_t iv_len;
+ uint16_t tag_len;
+ uint8_t iv[ENC_MAX_IV_SIZE];
+ uint8_t tag[ENC_MAX_TAG_SIZE];
+};
+
+#endif /* FIRMWARE_ENCRYPTED_H */
diff --git a/lib/aarch64/cache_helpers.S b/lib/aarch64/cache_helpers.S
index 9ef8ca79b..de9c8e4f0 100644
--- a/lib/aarch64/cache_helpers.S
+++ b/lib/aarch64/cache_helpers.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
*/
@@ -30,7 +30,7 @@ loop_\op:
dc \op, x0
add x0, x0, x2
cmp x0, x1
- b.lo loop_\op
+ b.lo loop_\op
dsb sy
exit_loop_\op:
ret
@@ -140,7 +140,7 @@ loop3_\_op:
level_done:
add x10, x10, #2 // increment cache number
cmp x3, x10
- b.hi loop1
+ b.hi loop1
msr csselr_el1, xzr // select cache level 0 in csselr
dsb sy // barrier to complete final cache operation
isb
diff --git a/lib/coreboot/coreboot_table.c b/lib/coreboot/coreboot_table.c
index 63bdc6359..253fac2ac 100644
--- a/lib/coreboot/coreboot_table.c
+++ b/lib/coreboot/coreboot_table.c
@@ -75,7 +75,7 @@ static void expand_and_mmap(uintptr_t baseaddr, size_t size)
static void setup_cbmem_console(uintptr_t baseaddr)
{
static console_cbmc_t console;
- assert(!console.base); /* should only have one CBMEM console */
+ assert(!console.console.base); /* should only have one CBMEM console */
/* CBMEM console structure stores its size in first header field. */
uint32_t size = *(uint32_t *)baseaddr;
diff --git a/lib/cpus/aarch64/denver.S b/lib/cpus/aarch64/denver.S
index c377b28b4..e260f8d28 100644
--- a/lib/cpus/aarch64/denver.S
+++ b/lib/cpus/aarch64/denver.S
@@ -156,12 +156,12 @@ endfunc denver_disable_ext_debug
* ----------------------------------------------------
*/
func denver_enable_dco
- mov x3, x30
+ mov x18, x30
bl plat_my_core_pos
mov x1, #1
lsl x1, x1, x0
msr s3_0_c15_c0_2, x1
- mov x30, x3
+ mov x30, x18
ret
endfunc denver_enable_dco
@@ -171,7 +171,7 @@ endfunc denver_enable_dco
*/
func denver_disable_dco
- mov x3, x30
+ mov x18, x30
/* turn off background work */
bl plat_my_core_pos
@@ -188,7 +188,7 @@ func denver_disable_dco
and x2, x2, x1
cbnz x2, 1b
- mov x30, x3
+ mov x30, x18
ret
endfunc denver_disable_dco
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 9bd25bac9..30ad7b7d1 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.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
*/
@@ -9,6 +9,11 @@
#include <assert_macros.S>
#include <context.h>
+#if CTX_INCLUDE_EL2_REGS
+ .global el2_sysregs_context_save
+ .global el2_sysregs_context_restore
+#endif
+
.global el1_sysregs_context_save
.global el1_sysregs_context_restore
#if CTX_INCLUDE_FPREGS
@@ -19,6 +24,385 @@
.global restore_gp_pmcr_pauth_regs
.global el3_exit
+#if CTX_INCLUDE_EL2_REGS
+
+/* -----------------------------------------------------
+ * The following function strictly follows the AArch64
+ * PCS to use x9-x17 (temporary caller-saved registers)
+ * to save EL2 system register context. It assumes that
+ * 'x0' is pointing to a 'el2_sys_regs' structure where
+ * the register context will be saved.
+ *
+ * The following registers are not added.
+ * AMEVCNTVOFF0<n>_EL2
+ * AMEVCNTVOFF1<n>_EL2
+ * ICH_AP0R<n>_EL2
+ * ICH_AP1R<n>_EL2
+ * ICH_LR<n>_EL2
+ * -----------------------------------------------------
+ */
+
+func el2_sysregs_context_save
+ mrs x9, actlr_el2
+ mrs x10, afsr0_el2
+ stp x9, x10, [x0, #CTX_ACTLR_EL2]
+
+ mrs x11, afsr1_el2
+ mrs x12, amair_el2
+ stp x11, x12, [x0, #CTX_AFSR1_EL2]
+
+ mrs x13, cnthctl_el2
+ mrs x14, cnthp_ctl_el2
+ stp x13, x14, [x0, #CTX_CNTHCTL_EL2]
+
+ mrs x15, cnthp_cval_el2
+ mrs x16, cnthp_tval_el2
+ stp x15, x16, [x0, #CTX_CNTHP_CVAL_EL2]
+
+ mrs x17, cntvoff_el2
+ mrs x9, cptr_el2
+ stp x17, x9, [x0, #CTX_CNTVOFF_EL2]
+
+ mrs x10, dbgvcr32_el2
+ mrs x11, elr_el2
+ stp x10, x11, [x0, #CTX_DBGVCR32_EL2]
+
+ mrs x14, esr_el2
+ mrs x15, far_el2
+ stp x14, x15, [x0, #CTX_ESR_EL2]
+
+ mrs x16, fpexc32_el2
+ mrs x17, hacr_el2
+ stp x16, x17, [x0, #CTX_FPEXC32_EL2]
+
+ mrs x9, hcr_el2
+ mrs x10, hpfar_el2
+ stp x9, x10, [x0, #CTX_HCR_EL2]
+
+ mrs x11, hstr_el2
+ mrs x12, ICC_SRE_EL2
+ stp x11, x12, [x0, #CTX_HSTR_EL2]
+
+ mrs x13, ICH_HCR_EL2
+ mrs x14, ICH_VMCR_EL2
+ stp x13, x14, [x0, #CTX_ICH_HCR_EL2]
+
+ mrs x15, mair_el2
+ mrs x16, mdcr_el2
+ stp x15, x16, [x0, #CTX_MAIR_EL2]
+
+ mrs x17, PMSCR_EL2
+ mrs x9, sctlr_el2
+ stp x17, x9, [x0, #CTX_PMSCR_EL2]
+
+ mrs x10, spsr_el2
+ mrs x11, sp_el2
+ stp x10, x11, [x0, #CTX_SPSR_EL2]
+
+ mrs x12, tcr_el2
+ mrs x13, TRFCR_EL2
+ stp x12, x13, [x0, #CTX_TCR_EL2]
+
+ mrs x14, ttbr0_el2
+ mrs x15, vbar_el2
+ stp x14, x15, [x0, #CTX_TTBR0_EL2]
+
+ mrs x16, vmpidr_el2
+ mrs x17, vpidr_el2
+ stp x16, x17, [x0, #CTX_VMPIDR_EL2]
+
+ mrs x9, vtcr_el2
+ mrs x10, vttbr_el2
+ stp x9, x10, [x0, #CTX_VTCR_EL2]
+
+#if CTX_INCLUDE_MTE_REGS
+ mrs x11, TFSR_EL2
+ str x11, [x0, #CTX_TFSR_EL2]
+#endif
+
+#if ENABLE_MPAM_FOR_LOWER_ELS
+ mrs x9, MPAM2_EL2
+ mrs x10, MPAMHCR_EL2
+ stp x9, x10, [x0, #CTX_MPAM2_EL2]
+
+ mrs x11, MPAMVPM0_EL2
+ mrs x12, MPAMVPM1_EL2
+ stp x11, x12, [x0, #CTX_MPAMVPM0_EL2]
+
+ mrs x13, MPAMVPM2_EL2
+ mrs x14, MPAMVPM3_EL2
+ stp x13, x14, [x0, #CTX_MPAMVPM2_EL2]
+
+ mrs x15, MPAMVPM4_EL2
+ mrs x16, MPAMVPM5_EL2
+ stp x15, x16, [x0, #CTX_MPAMVPM4_EL2]
+
+ mrs x17, MPAMVPM6_EL2
+ mrs x9, MPAMVPM7_EL2
+ stp x17, x9, [x0, #CTX_MPAMVPM6_EL2]
+
+ mrs x10, MPAMVPMV_EL2
+ str x10, [x0, #CTX_MPAMVPMV_EL2]
+#endif
+
+
+#if ARM_ARCH_AT_LEAST(8, 6)
+ mrs x11, HAFGRTR_EL2
+ mrs x12, HDFGRTR_EL2
+ stp x11, x12, [x0, #CTX_HAFGRTR_EL2]
+
+ mrs x13, HDFGWTR_EL2
+ mrs x14, HFGITR_EL2
+ stp x13, x14, [x0, #CTX_HDFGWTR_EL2]
+
+ mrs x15, HFGRTR_EL2
+ mrs x16, HFGWTR_EL2
+ stp x15, x16, [x0, #CTX_HFGRTR_EL2]
+
+ mrs x17, CNTPOFF_EL2
+ str x17, [x0, #CTX_CNTPOFF_EL2]
+#endif
+
+#if ARM_ARCH_AT_LEAST(8, 4)
+ mrs x9, cnthps_ctl_el2
+ mrs x10, cnthps_cval_el2
+ stp x9, x10, [x0, #CTX_CNTHPS_CTL_EL2]
+
+ mrs x11, cnthps_tval_el2
+ mrs x12, cnthvs_ctl_el2
+ stp x11, x12, [x0, #CTX_CNTHPS_TVAL_EL2]
+
+ mrs x13, cnthvs_cval_el2
+ mrs x14, cnthvs_tval_el2
+ stp x13, x14, [x0, #CTX_CNTHVS_CVAL_EL2]
+
+ mrs x15, cnthv_ctl_el2
+ mrs x16, cnthv_cval_el2
+ stp x15, x16, [x0, #CTX_CNTHV_CTL_EL2]
+
+ mrs x17, cnthv_tval_el2
+ mrs x9, contextidr_el2
+ stp x17, x9, [x0, #CTX_CNTHV_TVAL_EL2]
+
+ mrs x10, sder32_el2
+ str x10, [x0, #CTX_SDER32_EL2]
+
+ mrs x11, ttbr1_el2
+ str x11, [x0, #CTX_TTBR1_EL2]
+
+ mrs x12, vdisr_el2
+ str x12, [x0, #CTX_VDISR_EL2]
+
+ mrs x13, vncr_el2
+ str x13, [x0, #CTX_VNCR_EL2]
+
+ mrs x14, vsesr_el2
+ str x14, [x0, #CTX_VSESR_EL2]
+
+ mrs x15, vstcr_el2
+ str x15, [x0, #CTX_VSTCR_EL2]
+
+ mrs x16, vsttbr_el2
+ str x16, [x0, #CTX_VSTTBR_EL2]
+#endif
+
+#if ARM_ARCH_AT_LEAST(8, 5)
+ mrs x17, scxtnum_el2
+ str x17, [x0, #CTX_SCXTNUM_EL2]
+#endif
+
+ ret
+endfunc el2_sysregs_context_save
+
+/* -----------------------------------------------------
+ * The following function strictly follows the AArch64
+ * PCS to use x9-x17 (temporary caller-saved registers)
+ * to restore EL2 system register context. It assumes
+ * that 'x0' is pointing to a 'el2_sys_regs' structure
+ * from where the register context will be restored
+
+ * The following registers are not restored
+ * AMEVCNTVOFF0<n>_EL2
+ * AMEVCNTVOFF1<n>_EL2
+ * ICH_AP0R<n>_EL2
+ * ICH_AP1R<n>_EL2
+ * ICH_LR<n>_EL2
+ * -----------------------------------------------------
+ */
+func el2_sysregs_context_restore
+
+ ldp x9, x10, [x0, #CTX_ACTLR_EL2]
+ msr actlr_el2, x9
+ msr afsr0_el2, x10
+
+ ldp x11, x12, [x0, #CTX_AFSR1_EL2]
+ msr afsr1_el2, x11
+ msr amair_el2, x12
+
+ ldp x13, x14, [x0, #CTX_CNTHCTL_EL2]
+ msr cnthctl_el2, x13
+ msr cnthp_ctl_el2, x14
+
+ ldp x15, x16, [x0, #CTX_CNTHP_CVAL_EL2]
+ msr cnthp_cval_el2, x15
+ msr cnthp_tval_el2, x16
+
+ ldp x17, x9, [x0, #CTX_CNTVOFF_EL2]
+ msr cntvoff_el2, x17
+ msr cptr_el2, x9
+
+ ldp x10, x11, [x0, #CTX_DBGVCR32_EL2]
+ msr dbgvcr32_el2, x10
+ msr elr_el2, x11
+
+ ldp x14, x15, [x0, #CTX_ESR_EL2]
+ msr esr_el2, x14
+ msr far_el2, x15
+
+ ldp x16, x17, [x0, #CTX_FPEXC32_EL2]
+ msr fpexc32_el2, x16
+ msr hacr_el2, x17
+
+ ldp x9, x10, [x0, #CTX_HCR_EL2]
+ msr hcr_el2, x9
+ msr hpfar_el2, x10
+
+ ldp x11, x12, [x0, #CTX_HSTR_EL2]
+ msr hstr_el2, x11
+ msr ICC_SRE_EL2, x12
+
+ ldp x13, x14, [x0, #CTX_ICH_HCR_EL2]
+ msr ICH_HCR_EL2, x13
+ msr ICH_VMCR_EL2, x14
+
+ ldp x15, x16, [x0, #CTX_MAIR_EL2]
+ msr mair_el2, x15
+ msr mdcr_el2, x16
+
+ ldp x17, x9, [x0, #CTX_PMSCR_EL2]
+ msr PMSCR_EL2, x17
+ msr sctlr_el2, x9
+
+ ldp x10, x11, [x0, #CTX_SPSR_EL2]
+ msr spsr_el2, x10
+ msr sp_el2, x11
+
+ ldp x12, x13, [x0, #CTX_TCR_EL2]
+ msr tcr_el2, x12
+ msr TRFCR_EL2, x13
+
+ ldp x14, x15, [x0, #CTX_TTBR0_EL2]
+ msr ttbr0_el2, x14
+ msr vbar_el2, x15
+
+ ldp x16, x17, [x0, #CTX_VMPIDR_EL2]
+ msr vmpidr_el2, x16
+ msr vpidr_el2, x17
+
+ ldp x9, x10, [x0, #CTX_VTCR_EL2]
+ msr vtcr_el2, x9
+ msr vttbr_el2, x10
+
+#if CTX_INCLUDE_MTE_REGS
+ ldr x11, [x0, #CTX_TFSR_EL2]
+ msr TFSR_EL2, x11
+#endif
+
+#if ENABLE_MPAM_FOR_LOWER_ELS
+ ldp x9, x10, [x0, #CTX_MPAM2_EL2]
+ msr MPAM2_EL2, x9
+ msr MPAMHCR_EL2, x10
+
+ ldp x11, x12, [x0, #CTX_MPAMVPM0_EL2]
+ msr MPAMVPM0_EL2, x11
+ msr MPAMVPM1_EL2, x12
+
+ ldp x13, x14, [x0, #CTX_MPAMVPM2_EL2]
+ msr MPAMVPM2_EL2, x13
+ msr MPAMVPM3_EL2, x14
+
+ ldp x15, x16, [x0, #CTX_MPAMVPM4_EL2]
+ msr MPAMVPM4_EL2, x15
+ msr MPAMVPM5_EL2, x16
+
+ ldp x17, x9, [x0, #CTX_MPAMVPM6_EL2]
+ msr MPAMVPM6_EL2, x17
+ msr MPAMVPM7_EL2, x9
+
+ ldr x10, [x0, #CTX_MPAMVPMV_EL2]
+ msr MPAMVPMV_EL2, x10
+#endif
+
+#if ARM_ARCH_AT_LEAST(8, 6)
+ ldp x11, x12, [x0, #CTX_HAFGRTR_EL2]
+ msr HAFGRTR_EL2, x11
+ msr HDFGRTR_EL2, x12
+
+ ldp x13, x14, [x0, #CTX_HDFGWTR_EL2]
+ msr HDFGWTR_EL2, x13
+ msr HFGITR_EL2, x14
+
+ ldp x15, x16, [x0, #CTX_HFGRTR_EL2]
+ msr HFGRTR_EL2, x15
+ msr HFGWTR_EL2, x16
+
+ ldr x17, [x0, #CTX_CNTPOFF_EL2]
+ msr CNTPOFF_EL2, x17
+#endif
+
+#if ARM_ARCH_AT_LEAST(8, 4)
+ ldp x9, x10, [x0, #CTX_CNTHPS_CTL_EL2]
+ msr cnthps_ctl_el2, x9
+ msr cnthps_cval_el2, x10
+
+ ldp x11, x12, [x0, #CTX_CNTHPS_TVAL_EL2]
+ msr cnthps_tval_el2, x11
+ msr cnthvs_ctl_el2, x12
+
+ ldp x13, x14, [x0, #CTX_CNTHVS_CVAL_EL2]
+ msr cnthvs_cval_el2, x13
+ msr cnthvs_tval_el2, x14
+
+ ldp x15, x16, [x0, #CTX_CNTHV_CTL_EL2]
+ msr cnthv_ctl_el2, x15
+ msr cnthv_cval_el2, x16
+
+ ldp x17, x9, [x0, #CTX_CNTHV_TVAL_EL2]
+ msr cnthv_tval_el2, x17
+ msr contextidr_el2, x9
+
+ ldr x10, [x0, #CTX_SDER32_EL2]
+ msr sder32_el2, x10
+
+ ldr x11, [x0, #CTX_TTBR1_EL2]
+ msr ttbr1_el2, x11
+
+ ldr x12, [x0, #CTX_VDISR_EL2]
+ msr vdisr_el2, x12
+
+ ldr x13, [x0, #CTX_VNCR_EL2]
+ msr vncr_el2, x13
+
+ ldr x14, [x0, #CTX_VSESR_EL2]
+ msr vsesr_el2, x14
+
+ ldr x15, [x0, #CTX_VSTCR_EL2]
+ msr vstcr_el2, x15
+
+ ldr x16, [x0, #CTX_VSTTBR_EL2]
+ msr vsttbr_el2, x16
+#endif
+
+#if ARM_ARCH_AT_LEAST(8, 5)
+ ldr x17, [x0, #CTX_SCXTNUM_EL2]
+ msr scxtnum_el2, x17
+#endif
+
+ ret
+endfunc el2_sysregs_context_restore
+
+#endif /* CTX_INCLUDE_EL2_REGS */
+
/* ------------------------------------------------------------------
* The following function strictly follows the AArch64 PCS to use
* x9-x17 (temporary caller-saved registers) to save EL1 system
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 546e39e16..0314a8511 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -234,7 +234,7 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
* and other EL2 registers are set up by cm_prepare_ns_entry() as they
* are not part of the stored cpu_context.
*/
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx);
+ write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx);
/*
* Base the context ACTLR_EL1 on the current value, as it is
@@ -244,7 +244,7 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
* be zero.
*/
actlr_elx = read_actlr_el1();
- write_ctx_reg((get_sysregs_ctx(ctx)), (CTX_ACTLR_EL1), (actlr_elx));
+ write_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1), (actlr_elx));
/*
* Populate EL3 state so that we've the right context
@@ -336,7 +336,7 @@ void cm_prepare_el3_exit(uint32_t security_state)
CTX_SCR_EL3);
if ((scr_el3 & SCR_HCE_BIT) != 0U) {
/* Use SCTLR_EL1.EE value to initialise sctlr_el2 */
- sctlr_elx = read_ctx_reg(get_sysregs_ctx(ctx),
+ sctlr_elx = read_ctx_reg(get_el1_sysregs_ctx(ctx),
CTX_SCTLR_EL1);
sctlr_elx &= SCTLR_EE_BIT;
sctlr_elx |= SCTLR_EL2_RES1;
@@ -530,6 +530,52 @@ void cm_prepare_el3_exit(uint32_t security_state)
cm_set_next_eret_context(security_state);
}
+#if CTX_INCLUDE_EL2_REGS
+/*******************************************************************************
+ * Save EL2 sysreg context
+ ******************************************************************************/
+void cm_el2_sysregs_context_save(uint32_t security_state)
+{
+ u_register_t scr_el3 = read_scr();
+
+ /*
+ * Always save the non-secure EL2 context, only save the
+ * S-EL2 context if S-EL2 is enabled.
+ */
+ if ((security_state == NON_SECURE) ||
+ ((scr_el3 & SCR_EEL2_BIT) != 0U)) {
+ cpu_context_t *ctx;
+
+ ctx = cm_get_context(security_state);
+ assert(ctx != NULL);
+
+ el2_sysregs_context_save(get_el2_sysregs_ctx(ctx));
+ }
+}
+
+/*******************************************************************************
+ * Restore EL2 sysreg context
+ ******************************************************************************/
+void cm_el2_sysregs_context_restore(uint32_t security_state)
+{
+ u_register_t scr_el3 = read_scr();
+
+ /*
+ * Always restore the non-secure EL2 context, only restore the
+ * S-EL2 context if S-EL2 is enabled.
+ */
+ if ((security_state == NON_SECURE) ||
+ ((scr_el3 & SCR_EEL2_BIT) != 0U)) {
+ cpu_context_t *ctx;
+
+ ctx = cm_get_context(security_state);
+ assert(ctx != NULL);
+
+ el2_sysregs_context_restore(get_el2_sysregs_ctx(ctx));
+ }
+}
+#endif /* CTX_INCLUDE_EL2_REGS */
+
/*******************************************************************************
* The next four functions are used by runtime services to save and restore
* EL1 context on the 'cpu_context' structure for the specified security
@@ -542,7 +588,7 @@ void cm_el1_sysregs_context_save(uint32_t security_state)
ctx = cm_get_context(security_state);
assert(ctx != NULL);
- el1_sysregs_context_save(get_sysregs_ctx(ctx));
+ el1_sysregs_context_save(get_el1_sysregs_ctx(ctx));
#if IMAGE_BL31
if (security_state == SECURE)
@@ -559,7 +605,7 @@ void cm_el1_sysregs_context_restore(uint32_t security_state)
ctx = cm_get_context(security_state);
assert(ctx != NULL);
- el1_sysregs_context_restore(get_sysregs_ctx(ctx));
+ el1_sysregs_context_restore(get_el1_sysregs_ctx(ctx));
#if IMAGE_BL31
if (security_state == SECURE)
diff --git a/lib/xlat_tables_v2/ro_xlat_tables.mk b/lib/xlat_tables_v2/ro_xlat_tables.mk
new file mode 100644
index 000000000..7991e1afd
--- /dev/null
+++ b/lib/xlat_tables_v2/ro_xlat_tables.mk
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2020, ARM Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifeq (${USE_DEBUGFS}, 1)
+ $(error "Debugfs requires functionality from the dynamic translation \
+ library and is incompatible with ALLOW_RO_XLAT_TABLES.")
+endif
+
+ifeq (${ARCH},aarch32)
+ ifeq (${RESET_TO_SP_MIN},1)
+ $(error "RESET_TO_SP_MIN requires functionality from the dynamic \
+ translation library and is incompatible with \
+ ALLOW_RO_XLAT_TABLES.")
+ endif
+else # if AArch64
+ ifeq (${PLAT},tegra)
+ $(error "Tegra requires functionality from the dynamic translation \
+ library and is incompatible with ALLOW_RO_XLAT_TABLES.")
+ endif
+ ifeq (${RESET_TO_BL31},1)
+ $(error "RESET_TO_BL31 requires functionality from the dynamic \
+ translation library and is incompatible with \
+ ALLOW_RO_XLAT_TABLES.")
+ endif
+ ifeq (${SPD},trusty)
+ $(error "Trusty requires functionality from the dynamic translation \
+ library and is incompatible with ALLOW_RO_XLAT_TABLES.")
+ endif
+ ifeq (${SPM_MM},1)
+ $(error "SPM_MM requires functionality to change memory region \
+ attributes, which is not possible once the translation tables \
+ have been made read-only.")
+ endif
+endif
diff --git a/lib/xlat_tables_v2/xlat_tables.mk b/lib/xlat_tables_v2/xlat_tables.mk
index c946315bf..bcc3e68d8 100644
--- a/lib/xlat_tables_v2/xlat_tables.mk
+++ b/lib/xlat_tables_v2/xlat_tables.mk
@@ -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
#
@@ -13,3 +13,7 @@ XLAT_TABLES_LIB_SRCS := $(addprefix lib/xlat_tables_v2/, \
XLAT_TABLES_LIB_V2 := 1
$(eval $(call add_define,XLAT_TABLES_LIB_V2))
+
+ifeq (${ALLOW_RO_XLAT_TABLES}, 1)
+ include lib/xlat_tables_v2/ro_xlat_tables.mk
+endif
diff --git a/lib/xlat_tables_v2/xlat_tables_context.c b/lib/xlat_tables_v2/xlat_tables_context.c
index f4b64b33f..adca57875 100644
--- a/lib/xlat_tables_v2/xlat_tables_context.c
+++ b/lib/xlat_tables_v2/xlat_tables_context.c
@@ -1,9 +1,10 @@
/*
- * 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
*/
+#include <arch_helpers.h>
#include <assert.h>
#include <platform_def.h>
@@ -24,8 +25,14 @@ uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
* Allocate and initialise the default translation context for the BL image
* currently executing.
*/
+#if PLAT_RO_XLAT_TABLES
+REGISTER_XLAT_CONTEXT_RO_BASE_TABLE(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES,
+ PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE,
+ EL_REGIME_INVALID, "xlat_table");
+#else
REGISTER_XLAT_CONTEXT(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES,
PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE);
+#endif
void mmap_add_region(unsigned long long base_pa, uintptr_t base_va, size_t size,
unsigned int attr)
@@ -119,6 +126,75 @@ int xlat_change_mem_attributes(uintptr_t base_va, size_t size, uint32_t attr)
return xlat_change_mem_attributes_ctx(&tf_xlat_ctx, base_va, size, attr);
}
+#if PLAT_RO_XLAT_TABLES
+/* Change the memory attributes of the descriptors which resolve the address
+ * range that belongs to the translation tables themselves, which are by default
+ * mapped as part of read-write data in the BL image's memory.
+ *
+ * Since the translation tables map themselves via these level 3 (page)
+ * descriptors, any change applied to them with the MMU on would introduce a
+ * chicken and egg problem because of the break-before-make sequence.
+ * Eventually, it would reach the descriptor that resolves the very table it
+ * belongs to and the invalidation (break step) would cause the subsequent write
+ * (make step) to it to generate an MMU fault. Therefore, the MMU is disabled
+ * before making the change.
+ *
+ * No assumption is made about what data this function needs, therefore all the
+ * caches are flushed in order to ensure coherency. A future optimization would
+ * be to only flush the required data to main memory.
+ */
+int xlat_make_tables_readonly(void)
+{
+ assert(tf_xlat_ctx.initialized == true);
+#ifdef __aarch64__
+ if (tf_xlat_ctx.xlat_regime == EL1_EL0_REGIME) {
+ disable_mmu_el1();
+ } else if (tf_xlat_ctx.xlat_regime == EL3_REGIME) {
+ disable_mmu_el3();
+ } else {
+ assert(tf_xlat_ctx.xlat_regime == EL2_REGIME);
+ return -1;
+ }
+
+ /* Flush all caches. */
+ dcsw_op_all(DCCISW);
+#else /* !__aarch64__ */
+ assert(tf_xlat_ctx.xlat_regime == EL1_EL0_REGIME);
+ /* On AArch32, we flush the caches before disabling the MMU. The reason
+ * for this is that the dcsw_op_all AArch32 function pushes some
+ * registers onto the stack under the assumption that it is writing to
+ * cache, which is not true with the MMU off. This would result in the
+ * stack becoming corrupted and a wrong/junk value for the LR being
+ * restored at the end of the routine.
+ */
+ dcsw_op_all(DC_OP_CISW);
+ disable_mmu_secure();
+#endif
+
+ int rc = xlat_change_mem_attributes_ctx(&tf_xlat_ctx,
+ (uintptr_t)tf_xlat_ctx.tables,
+ tf_xlat_ctx.tables_num * XLAT_TABLE_SIZE,
+ MT_RO_DATA | MT_SECURE);
+
+#ifdef __aarch64__
+ if (tf_xlat_ctx.xlat_regime == EL1_EL0_REGIME) {
+ enable_mmu_el1(0U);
+ } else {
+ assert(tf_xlat_ctx.xlat_regime == EL3_REGIME);
+ enable_mmu_el3(0U);
+ }
+#else /* !__aarch64__ */
+ enable_mmu_svc_mon(0U);
+#endif
+
+ if (rc == 0) {
+ tf_xlat_ctx.readonly_tables = true;
+ }
+
+ return rc;
+}
+#endif /* PLAT_RO_XLAT_TABLES */
+
/*
* If dynamic allocation of new regions is disabled then by the time we call the
* function enabling the MMU, we'll have registered all the memory regions to
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index b6925d3b1..20a36fe08 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -79,36 +79,52 @@ $(if $(word $(2), $($(1))),\
endef
# IMG_LINKERFILE defines the linker script corresponding to a BL stage
-# $(1) = BL stage (2, 30, 31, 32, 33)
+# $(1) = BL stage (1, 2, 2u, 31, 32)
define IMG_LINKERFILE
${BUILD_DIR}/bl$(1).ld
endef
# IMG_MAPFILE defines the output file describing the memory map corresponding
# to a BL stage
-# $(1) = BL stage (2, 30, 31, 32, 33)
+# $(1) = BL stage (1, 2, 2u, 31, 32)
define IMG_MAPFILE
${BUILD_DIR}/bl$(1).map
endef
# IMG_ELF defines the elf file corresponding to a BL stage
-# $(1) = BL stage (2, 30, 31, 32, 33)
+# $(1) = BL stage (1, 2, 2u, 31, 32)
define IMG_ELF
${BUILD_DIR}/bl$(1).elf
endef
# IMG_DUMP defines the symbols dump file corresponding to a BL stage
-# $(1) = BL stage (2, 30, 31, 32, 33)
+# $(1) = BL stage (1, 2, 2u, 31, 32)
define IMG_DUMP
${BUILD_DIR}/bl$(1).dump
endef
# IMG_BIN defines the default image file corresponding to a BL stage
-# $(1) = BL stage (2, 30, 31, 32, 33)
+# $(1) = BL stage (1, 2, 2u, 31, 32)
define IMG_BIN
${BUILD_PLAT}/bl$(1).bin
endef
+# IMG_ENC_BIN defines the default encrypted image file corresponding to a
+# BL stage
+# $(1) = BL stage (2, 30, 31, 32, 33)
+define IMG_ENC_BIN
+ ${BUILD_PLAT}/bl$(1)_enc.bin
+endef
+
+# ENCRYPT_FW invokes enctool to encrypt firmware binary
+# $(1) = input firmware binary
+# $(2) = output encrypted firmware binary
+define ENCRYPT_FW
+$(2): $(1) enctool
+ $$(ECHO) " ENC $$<"
+ $$(Q)$$(ENCTOOL) $$(ENC_ARGS) -i $$< -o $$@
+endef
+
# TOOL_ADD_PAYLOAD appends the command line arguments required by fiptool to
# package a new payload and/or by cert_create to generate certificate.
# Optionally, it adds the dependency on this payload
@@ -116,11 +132,17 @@ endef
# $(2) = command line option for the specified payload (i.e. --soc-fw)
# $(3) = tool target dependency (optional) (ex. build/fvp/release/bl31.bin)
# $(4) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
+# $(5) = encrypted payload (optional) (ex. build/fvp/release/bl31_enc.bin)
define TOOL_ADD_PAYLOAD
+ifneq ($(5),)
+ $(4)FIP_ARGS += $(2) $(5)
+ $(if $(3),$(4)CRT_DEPS += $(1))
+else
$(4)FIP_ARGS += $(2) $(1)
+ $(if $(3),$(4)CRT_DEPS += $(3))
+endif
$(if $(3),$(4)FIP_DEPS += $(3))
$(4)CRT_ARGS += $(2) $(1)
- $(if $(3),$(4)CRT_DEPS += $(3))
endef
# TOOL_ADD_IMG_PAYLOAD works like TOOL_ADD_PAYLOAD, but applies image filters
@@ -130,6 +152,7 @@ endef
# $(3) = command line option for the specified payload (ex. --soc-fw)
# $(4) = tool target dependency (optional) (ex. build/fvp/release/bl31.bin)
# $(5) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
+# $(6) = encrypted payload (optional) (ex. build/fvp/release/bl31_enc.bin)
define TOOL_ADD_IMG_PAYLOAD
@@ -143,10 +166,10 @@ $(call $(PRE_TOOL_FILTER)_RULE,$(PROCESSED_PATH),$(2))
$(PROCESSED_PATH): $(4)
-$(call TOOL_ADD_PAYLOAD,$(PROCESSED_PATH),$(3),$(PROCESSED_PATH),$(5))
+$(call TOOL_ADD_PAYLOAD,$(PROCESSED_PATH),$(3),$(PROCESSED_PATH),$(5),$(6))
else
-$(call TOOL_ADD_PAYLOAD,$(2),$(3),$(4),$(5))
+$(call TOOL_ADD_PAYLOAD,$(2),$(3),$(4),$(5),$(6))
endif
endef
@@ -164,6 +187,7 @@ endef
# $(1) = image_type (scp_bl2, bl33, etc.)
# $(2) = command line option for fiptool (--scp-fw, --nt-fw, etc)
# $(3) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
+# $(4) = Image encryption flag (optional) (0, 1)
# Example:
# $(eval $(call TOOL_ADD_IMG,bl33,--nt-fw))
define TOOL_ADD_IMG
@@ -173,7 +197,14 @@ define TOOL_ADD_IMG
$(3)CRT_DEPS += check_$(1)
$(3)FIP_DEPS += check_$(1)
+ifeq ($(4),1)
+ $(eval ENC_BIN := ${BUILD_PLAT}/$(1)_enc.bin)
+ $(call ENCRYPT_FW,$(value $(_V)),$(ENC_BIN))
+ $(call TOOL_ADD_IMG_PAYLOAD,$(1),$(value $(_V)),$(2),$(ENC_BIN),$(3), \
+ $(ENC_BIN))
+else
$(call TOOL_ADD_IMG_PAYLOAD,$(1),$(value $(_V)),$(2),,$(3))
+endif
.PHONY: check_$(1)
check_$(1):
@@ -237,7 +268,7 @@ endef
# MAKE_C builds a C source file and generates the dependency file
# $(1) = output directory
# $(2) = source file (%.c)
-# $(3) = BL stage (2, 2u, 30, 31, 32, 33)
+# $(3) = BL stage (1, 2, 2u, 31, 32)
define MAKE_C
$(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
@@ -257,7 +288,7 @@ endef
# MAKE_S builds an assembly source file and generates the dependency file
# $(1) = output directory
# $(2) = assembly file (%.S)
-# $(3) = BL stage (2, 2u, 30, 31, 32, 33)
+# $(3) = BL stage (1, 2, 2u, 31, 32)
define MAKE_S
$(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
@@ -276,7 +307,7 @@ endef
# MAKE_LD generate the linker script using the C preprocessor
# $(1) = output linker script
# $(2) = input template
-# $(3) = BL stage (2, 2u, 30, 31, 32, 33)
+# $(3) = BL stage (1, 2, 2u, 31, 32)
define MAKE_LD
$(eval DEP := $(1).d)
@@ -310,7 +341,7 @@ endef
# MAKE_OBJS builds both C and assembly source files
# $(1) = output directory
# $(2) = list of source files (both C and assembly)
-# $(3) = BL stage (2, 30, 31, 32, 33)
+# $(3) = BL stage (1, 2, 2u, 31, 32)
define MAKE_OBJS
$(eval C_OBJS := $(filter %.c,$(2)))
$(eval REMAIN := $(filter-out %.c,$(2)))
@@ -387,9 +418,10 @@ endef
# MAKE_BL macro defines the targets and options to build each BL image.
# Arguments:
-# $(1) = BL stage (2, 2u, 30, 31, 32, 33)
+# $(1) = BL stage (1, 2, 2u, 31, 32)
# $(2) = FIP command line option (if empty, image will not be included in the FIP)
# $(3) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
+# $(4) = BL encryption flag (optional) (0, 1)
define MAKE_BL
$(eval BUILD_DIR := ${BUILD_PLAT}/bl$(1))
$(eval BL_SOURCES := $(BL$(call uppercase,$(1))_SOURCES))
@@ -400,6 +432,7 @@ define MAKE_BL
$(eval ELF := $(call IMG_ELF,$(1)))
$(eval DUMP := $(call IMG_DUMP,$(1)))
$(eval BIN := $(call IMG_BIN,$(1)))
+ $(eval ENC_BIN := $(call IMG_ENC_BIN,$(1)))
$(eval BL_LINKERFILE := $(BL$(call uppercase,$(1))_LINKERFILE))
$(eval BL_LIBS := $(BL$(call uppercase,$(1))_LIBS))
# We use sort only to get a list of unique object directory names.
@@ -480,7 +513,13 @@ endif
all: bl$(1)
+ifeq ($(4),1)
+$(call ENCRYPT_FW,$(BIN),$(ENC_BIN))
+$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,bl$(1),$(BIN),--$(2),$(ENC_BIN),$(3), \
+ $(ENC_BIN)))
+else
$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,bl$(1),$(BIN),--$(2),$(BIN),$(3)))
+endif
endef
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index e8e990d45..03322db19 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -65,6 +65,9 @@ CTX_INCLUDE_PAUTH_REGS := 0
# Debug build
DEBUG := 0
+# By default disable authenticated decryption support.
+DECRYPTION_SUPPORT := none
+
# Build platform
DEFAULT_PLAT := fvp
@@ -106,6 +109,18 @@ ENABLE_BTI := 0
# Use BRANCH_PROTECTION to enable PAUTH.
ENABLE_PAUTH := 0
+# By default BL31 encryption disabled
+ENCRYPT_BL31 := 0
+
+# By default BL32 encryption disabled
+ENCRYPT_BL32 := 0
+
+# Default dummy firmware encryption key
+ENC_KEY := 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
+
+# Default dummy nonce for firmware encryption
+ENC_NONCE := 1234567890abcdef12345678
+
# Build flag to treat usage of deprecated platform and framework APIs as error.
ERROR_DEPRECATED := 0
@@ -121,6 +136,9 @@ FIP_NAME := fip.bin
# Default FWU_FIP file name
FWU_FIP_NAME := fwu_fip.bin
+# By default firmware encryption with SSK
+FW_ENC_STATUS := 0
+
# For Chain of Trust
GENERATE_COT := 0
@@ -188,6 +206,9 @@ SPD := none
# Enable the Management Mode (MM)-based Secure Partition Manager implementation
SPM_MM := 0
+# Use SPM at S-EL2 as a default config for SPMD
+SPMD_SPM_AT_SEL2 := 1
+
# Flag to introduce an infinite loop in BL1 just before it exits into the next
# image. This is meant to help debugging the post-BL2 phase.
SPIN_ON_BL1_EXIT := 0
@@ -207,6 +228,13 @@ USE_FCONF_BASED_IO := 0
# Build option to choose whether Trusted Firmware uses library at ROM
USE_ROMLIB := 0
+# Build option to choose whether the xlat tables of BL images can be read-only.
+# Note that this only serves as a higher level option to PLAT_RO_XLAT_TABLES,
+# which is the per BL-image option that actually enables the read-only tables
+# API. The reason for having this additional option is to have a common high
+# level makefile where we can check for incompatible features/build options.
+ALLOW_RO_XLAT_TABLES := 0
+
# Chain of trust.
COT := tbbr
@@ -255,3 +283,8 @@ USE_SPINLOCK_CAS := 0
# Enable Link Time Optimization
ENABLE_LTO := 0
+
+# Build flag to include EL2 registers in cpu context save and restore during
+# S-EL2 firmware entry/exit. This flag is to be used with SPD=spmd option.
+# Default is 0.
+CTX_INCLUDE_EL2_REGS := 0
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
index 98bcf3e22..e60ebc6f2 100644
--- a/plat/allwinner/common/allwinner-common.mk
+++ b/plat/allwinner/common/allwinner-common.mk
@@ -20,6 +20,8 @@ PLAT_BL_COMMON_SOURCES := drivers/ti/uart/${ARCH}/16550_console.S \
${AW_PLAT}/common/sunxi_common.c
BL31_SOURCES += drivers/allwinner/axp/common.c \
+ drivers/allwinner/sunxi_msgbox.c \
+ drivers/arm/css/scpi/css_scpi.c \
drivers/arm/gic/common/gic_common.c \
drivers/arm/gic/v2/gicv2_helpers.c \
drivers/arm/gic/v2/gicv2_main.c \
diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h
index 32a7c0408..975cc48d5 100644
--- a/plat/allwinner/common/include/platform_def.h
+++ b/plat/allwinner/common/include/platform_def.h
@@ -13,8 +13,13 @@
#include <sunxi_mmap.h>
-#define BL31_BASE SUNXI_SRAM_A2_BASE
-#define BL31_LIMIT (SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE)
+#define BL31_BASE (SUNXI_SRAM_A2_BASE + 0x4000)
+#define BL31_LIMIT (SUNXI_SRAM_A2_BASE + \
+ SUNXI_SRAM_A2_SIZE - SUNXI_SCP_SIZE)
+
+/* The SCP firmware is allocated the last 16KiB of SRAM A2. */
+#define SUNXI_SCP_BASE BL31_LIMIT
+#define SUNXI_SCP_SIZE 0x4000
/* Overwrite U-Boot SPL, but reserve the first page for the SPL header. */
#define BL31_NOBITS_BASE (SUNXI_SRAM_A1_BASE + 0x1000)
@@ -35,6 +40,9 @@
#define MAX_MMAP_REGIONS (3 + PLATFORM_MMAP_REGIONS)
#define MAX_XLAT_TABLES 1
+#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE \
+ (SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE - 0x200)
+
#define PLAT_MAX_PWR_LVL_STATES U(2)
#define PLAT_MAX_RET_STATE U(1)
#define PLAT_MAX_OFF_STATE U(2)
@@ -51,7 +59,7 @@
#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * \
PLATFORM_MAX_CPUS_PER_CLUSTER)
#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4)
-#define PLATFORM_MMAP_REGIONS 4
+#define PLATFORM_MMAP_REGIONS 5
#define PLATFORM_STACK_SIZE (0x1000 / PLATFORM_CORE_COUNT)
#ifndef SPD_none
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
index a24527c5d..e836a345b 100644
--- a/plat/allwinner/common/sunxi_bl31_setup.c
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -28,7 +28,7 @@
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
-static console_16550_t console;
+static console_t console;
static const gicv2_driver_data_t sunxi_gic_data = {
.gicd_base = SUNXI_GICD_BASE,
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
index 3759c285e..0ca18adc3 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -21,6 +21,8 @@
static const mmap_region_t sunxi_mmap[PLATFORM_MMAP_REGIONS + 1] = {
MAP_REGION_FLAT(SUNXI_SRAM_BASE, SUNXI_SRAM_SIZE,
MT_RW_DATA | MT_SECURE),
+ MAP_REGION_FLAT(SUNXI_SCP_BASE, SUNXI_SCP_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER),
MAP_REGION_FLAT(SUNXI_DEV_BASE, SUNXI_DEV_SIZE,
MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER),
MAP_REGION(SUNXI_DRAM_BASE, SUNXI_DRAM_VIRT_BASE, SUNXI_DRAM_SEC_SIZE,
@@ -175,7 +177,7 @@ DEFINE_BAKERY_LOCK(arisc_lock);
*/
void sunxi_execute_arisc_code(uint32_t *code, size_t size, uint16_t param)
{
- uintptr_t arisc_reset_vec = SUNXI_SRAM_A2_BASE - 0x4000 + 0x100;
+ uintptr_t arisc_reset_vec = SUNXI_SRAM_A2_BASE + 0x100;
do {
bakery_lock_get(&arisc_lock);
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
index 9b074d2ac..e0fa5b3ec 100644
--- a/plat/allwinner/common/sunxi_pm.c
+++ b/plat/allwinner/common/sunxi_pm.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
*/
@@ -10,6 +10,7 @@
#include <arch_helpers.h>
#include <common/debug.h>
+#include <drivers/arm/css/css_scpi.h>
#include <drivers/arm/gicv2.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
@@ -17,6 +18,7 @@
#include <plat/common/platform.h>
#include <sunxi_cpucfg.h>
+#include <sunxi_def.h>
#include <sunxi_mmap.h>
#include <sunxi_private.h>
@@ -24,25 +26,88 @@
#define SUNXI_WDOG0_CFG_REG (SUNXI_R_WDOG_BASE + 0x0014)
#define SUNXI_WDOG0_MODE_REG (SUNXI_R_WDOG_BASE + 0x0018)
-#define mpidr_is_valid(mpidr) ( \
- MPIDR_AFFLVL3_VAL(mpidr) == 0 && \
- MPIDR_AFFLVL2_VAL(mpidr) == 0 && \
- MPIDR_AFFLVL1_VAL(mpidr) < PLATFORM_CLUSTER_COUNT && \
- MPIDR_AFFLVL0_VAL(mpidr) < PLATFORM_MAX_CPUS_PER_CLUSTER)
+#define CPU_PWR_LVL MPIDR_AFFLVL0
+#define CLUSTER_PWR_LVL MPIDR_AFFLVL1
+#define SYSTEM_PWR_LVL MPIDR_AFFLVL2
+
+#define CPU_PWR_STATE(state) \
+ ((state)->pwr_domain_state[CPU_PWR_LVL])
+#define CLUSTER_PWR_STATE(state) \
+ ((state)->pwr_domain_state[CLUSTER_PWR_LVL])
+#define SYSTEM_PWR_STATE(state) \
+ ((state)->pwr_domain_state[SYSTEM_PWR_LVL])
+
+#define mpidr_is_valid(mpidr) (plat_core_pos_by_mpidr(mpidr) >= 0)
+
+/*
+ * The addresses for the SCP exception vectors are defined in the or1k
+ * architecture specification.
+ */
+#define OR1K_VEC_FIRST 0x01
+#define OR1K_VEC_LAST 0x0e
+#define OR1K_VEC_ADDR(n) (0x100 * (n))
+
+/*
+ * This magic value is the little-endian representation of the or1k
+ * instruction "l.mfspr r2, r0, 0x12", which is guaranteed to be the
+ * first instruction in the SCP firmware.
+ */
+#define SCP_FIRMWARE_MAGIC 0xb4400012
+
+static bool scpi_available;
+
+static inline scpi_power_state_t scpi_map_state(plat_local_state_t psci_state)
+{
+ if (is_local_state_run(psci_state))
+ return scpi_power_on;
+ if (is_local_state_retn(psci_state))
+ return scpi_power_retention;
+ return scpi_power_off;
+}
+
+static void sunxi_cpu_standby(plat_local_state_t cpu_state)
+{
+ u_register_t scr = read_scr_el3();
+
+ assert(is_local_state_retn(cpu_state));
+
+ write_scr_el3(scr | SCR_IRQ_BIT);
+ wfi();
+ write_scr_el3(scr);
+}
static int sunxi_pwr_domain_on(u_register_t mpidr)
{
if (mpidr_is_valid(mpidr) == 0)
return PSCI_E_INTERN_FAIL;
- sunxi_cpu_on(mpidr);
+ if (scpi_available) {
+ scpi_set_css_power_state(mpidr,
+ scpi_power_on,
+ scpi_power_on,
+ scpi_power_on);
+ } else {
+ sunxi_cpu_on(mpidr);
+ }
return PSCI_E_SUCCESS;
}
static void sunxi_pwr_domain_off(const psci_power_state_t *target_state)
{
- gicv2_cpuif_disable();
+ plat_local_state_t cpu_pwr_state = CPU_PWR_STATE(target_state);
+ plat_local_state_t cluster_pwr_state = CLUSTER_PWR_STATE(target_state);
+ plat_local_state_t system_pwr_state = SYSTEM_PWR_STATE(target_state);
+
+ if (is_local_state_off(cpu_pwr_state))
+ gicv2_cpuif_disable();
+
+ if (scpi_available) {
+ scpi_set_css_power_state(read_mpidr(),
+ scpi_map_state(cpu_pwr_state),
+ scpi_map_state(cluster_pwr_state),
+ scpi_map_state(system_pwr_state));
+ }
}
static void __dead2 sunxi_pwr_down_wfi(const psci_power_state_t *target_state)
@@ -55,12 +120,26 @@ static void __dead2 sunxi_pwr_down_wfi(const psci_power_state_t *target_state)
static void sunxi_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
- gicv2_pcpu_distif_init();
- gicv2_cpuif_enable();
+ if (is_local_state_off(SYSTEM_PWR_STATE(target_state)))
+ gicv2_distif_init();
+ if (is_local_state_off(CPU_PWR_STATE(target_state))) {
+ gicv2_pcpu_distif_init();
+ gicv2_cpuif_enable();
+ }
}
static void __dead2 sunxi_system_off(void)
{
+ gicv2_cpuif_disable();
+
+ if (scpi_available) {
+ /* Send the power down request to the SCP */
+ uint32_t ret = scpi_sys_power_state(scpi_system_shutdown);
+
+ if (ret != SCP_OK)
+ ERROR("PSCI: SCPI %s failed: %d\n", "shutdown", ret);
+ }
+
/* Turn off all secondary CPUs */
sunxi_disable_secondary_cpus(read_mpidr());
@@ -74,6 +153,16 @@ static void __dead2 sunxi_system_off(void)
static void __dead2 sunxi_system_reset(void)
{
+ gicv2_cpuif_disable();
+
+ if (scpi_available) {
+ /* Send the system reset request to the SCP */
+ uint32_t ret = scpi_sys_power_state(scpi_system_reboot);
+
+ if (ret != SCP_OK)
+ ERROR("PSCI: SCPI %s failed: %d\n", "reboot", ret);
+ }
+
/* Reset the whole system when the watchdog times out */
mmio_write_32(SUNXI_WDOG0_CFG_REG, 1);
/* Enable the watchdog with the shortest timeout (0.5 seconds) */
@@ -86,6 +175,40 @@ static void __dead2 sunxi_system_reset(void)
panic();
}
+static int sunxi_validate_power_state(unsigned int power_state,
+ psci_power_state_t *req_state)
+{
+ unsigned int power_level = psci_get_pstate_pwrlvl(power_state);
+ unsigned int type = psci_get_pstate_type(power_state);
+
+ assert(req_state != NULL);
+
+ if (power_level > PLAT_MAX_PWR_LVL)
+ return PSCI_E_INVALID_PARAMS;
+
+ if (type == PSTATE_TYPE_STANDBY) {
+ /* Only one retention power state is supported. */
+ if (psci_get_pstate_id(power_state) > 0)
+ return PSCI_E_INVALID_PARAMS;
+ /* The SoC cannot be suspended without losing state */
+ if (power_level == SYSTEM_PWR_LVL)
+ return PSCI_E_INVALID_PARAMS;
+ for (unsigned int i = 0; i <= power_level; ++i)
+ req_state->pwr_domain_state[i] = PLAT_MAX_RET_STATE;
+ } else {
+ /* Only one off power state is supported. */
+ if (psci_get_pstate_id(power_state) > 0)
+ return PSCI_E_INVALID_PARAMS;
+ for (unsigned int i = 0; i <= power_level; ++i)
+ req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+ }
+ /* Higher power domain levels should all remain running */
+ for (unsigned int i = power_level + 1; i <= PLAT_MAX_PWR_LVL; ++i)
+ req_state->pwr_domain_state[i] = PSCI_LOCAL_STATE_RUN;
+
+ return PSCI_E_SUCCESS;
+}
+
static int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint)
{
/* The non-secure entry point must be in DRAM */
@@ -95,13 +218,45 @@ static int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint)
return PSCI_E_INVALID_ADDRESS;
}
+static void sunxi_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+ assert(req_state);
+
+ for (unsigned int i = 0; i <= PLAT_MAX_PWR_LVL; ++i)
+ req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+}
+
+static int sunxi_get_node_hw_state(u_register_t mpidr,
+ unsigned int power_level)
+{
+ unsigned int cluster_state, cpu_state;
+ unsigned int cpu = MPIDR_AFFLVL0_VAL(mpidr);
+
+ /* SoC power level (always on if PSCI works). */
+ if (power_level == SYSTEM_PWR_LVL)
+ return HW_ON;
+ if (scpi_get_css_power_state(mpidr, &cpu_state, &cluster_state))
+ return PSCI_E_NOT_SUPPORTED;
+ /* Cluster power level (full power state available). */
+ if (power_level == CLUSTER_PWR_LVL) {
+ if (cluster_state == scpi_power_on)
+ return HW_ON;
+ if (cluster_state == scpi_power_retention)
+ return HW_STANDBY;
+ return HW_OFF;
+ }
+ /* CPU power level (one bit boolean for on or off). */
+ return ((cpu_state & BIT(cpu)) != 0) ? HW_ON : HW_OFF;
+}
+
static plat_psci_ops_t sunxi_psci_ops = {
+ .cpu_standby = sunxi_cpu_standby,
.pwr_domain_on = sunxi_pwr_domain_on,
.pwr_domain_off = sunxi_pwr_domain_off,
- .pwr_domain_pwr_down_wfi = sunxi_pwr_down_wfi,
.pwr_domain_on_finish = sunxi_pwr_domain_on_finish,
.system_off = sunxi_system_off,
.system_reset = sunxi_system_reset,
+ .validate_power_state = sunxi_validate_power_state,
.validate_ns_entrypoint = sunxi_validate_ns_entrypoint,
};
@@ -110,13 +265,44 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
{
assert(psci_ops);
- for (int cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu += 1) {
+ /* Program all CPU entry points. */
+ for (unsigned int cpu = 0; cpu < PLATFORM_CORE_COUNT; ++cpu) {
mmio_write_32(SUNXI_CPUCFG_RVBAR_LO_REG(cpu),
sec_entrypoint & 0xffffffff);
mmio_write_32(SUNXI_CPUCFG_RVBAR_HI_REG(cpu),
sec_entrypoint >> 32);
}
+ /* Check for a valid SCP firmware, and boot the SCP if found. */
+ if (mmio_read_32(SUNXI_SCP_BASE) == SCP_FIRMWARE_MAGIC) {
+ /* Program SCP exception vectors to the firmware entrypoint. */
+ for (unsigned int i = OR1K_VEC_FIRST; i <= OR1K_VEC_LAST; ++i) {
+ uint32_t vector = SUNXI_SRAM_A2_BASE + OR1K_VEC_ADDR(i);
+ uint32_t offset = SUNXI_SCP_BASE - vector;
+
+ mmio_write_32(vector, offset >> 2);
+ clean_dcache_range(vector, sizeof(uint32_t));
+ }
+ /* Take the SCP out of reset. */
+ mmio_setbits_32(SUNXI_R_CPUCFG_BASE, BIT(0));
+ /* Wait for the SCP firmware to boot. */
+ if (scpi_wait_ready() == 0)
+ scpi_available = true;
+ }
+
+ NOTICE("PSCI: System suspend is %s\n",
+ scpi_available ? "available via SCPI" : "unavailable");
+ if (scpi_available) {
+ /* Suspend is only available via SCPI. */
+ sunxi_psci_ops.pwr_domain_suspend = sunxi_pwr_domain_off;
+ sunxi_psci_ops.pwr_domain_suspend_finish = sunxi_pwr_domain_on_finish;
+ sunxi_psci_ops.get_sys_suspend_power_state = sunxi_get_sys_suspend_power_state;
+ sunxi_psci_ops.get_node_hw_state = sunxi_get_node_hw_state;
+ } else {
+ /* This is only needed when SCPI is unavailable. */
+ sunxi_psci_ops.pwr_domain_pwr_down_wfi = sunxi_pwr_down_wfi;
+ }
+
*psci_ops = &sunxi_psci_ops;
return 0;
diff --git a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
index db4409118..9d2542fce 100644
--- a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,8 +14,8 @@
#define SUNXI_SRAM_SIZE 0x00044000
#define SUNXI_SRAM_A1_BASE 0x00010000
#define SUNXI_SRAM_A1_SIZE 0x00008000
-#define SUNXI_SRAM_A2_BASE 0x00044000
-#define SUNXI_SRAM_A2_SIZE 0x00010000
+#define SUNXI_SRAM_A2_BASE 0x00040000
+#define SUNXI_SRAM_A2_SIZE 0x00014000
#define SUNXI_SRAM_C_BASE 0x00018000
#define SUNXI_SRAM_C_SIZE 0x0001c000
#define SUNXI_DEV_BASE 0x01000000
diff --git a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
index f36491a8a..0e204d0f0 100644
--- a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,8 +14,8 @@
#define SUNXI_SRAM_SIZE 0x000f8000
#define SUNXI_SRAM_A1_BASE 0x00020000
#define SUNXI_SRAM_A1_SIZE 0x00008000
-#define SUNXI_SRAM_A2_BASE 0x00104000
-#define SUNXI_SRAM_A2_SIZE 0x00014000
+#define SUNXI_SRAM_A2_BASE 0x00100000
+#define SUNXI_SRAM_A2_SIZE 0x00018000
#define SUNXI_SRAM_C_BASE 0x00028000
#define SUNXI_SRAM_C_SIZE 0x0001e000
#define SUNXI_DEV_BASE 0x01000000
diff --git a/plat/amlogic/common/aml_console.c b/plat/amlogic/common/aml_console.c
index 352279b6c..e21d707a0 100644
--- a/plat/amlogic/common/aml_console.c
+++ b/plat/amlogic/common/aml_console.c
@@ -11,7 +11,7 @@
/*******************************************************************************
* Function that sets up the console
******************************************************************************/
-static console_meson_t aml_console;
+static console_t aml_console;
void aml_console_init(void)
{
@@ -28,6 +28,6 @@ void aml_console_init(void)
panic();
}
- console_set_scope(&aml_console.console,
+ console_set_scope(&aml_console,
CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
}
diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
index d0f60331d..9a4a05799 100644
--- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
@@ -69,6 +69,12 @@
mbedtls_heap_size = <0x0>;
};
+ /*
+ * Though TF-A is UUID RFC 4122 compliant meaning fields are stored in
+ * network order (big endian), UUID's mentioned in this file are are
+ * stored in machine order (little endian).
+ * This will be fixed in future.
+ */
arm-io_policies {
fip-handles {
compatible = "arm,io-fip-handle";
@@ -93,4 +99,17 @@
nt_fw_content_cert_uuid = <0xf3c1c48e 0x11e4635d 0xee87a9a7 0xa73fb240>;
};
};
+
+ secure-partitions {
+ compatible = "arm,sp";
+ cactus {
+ uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>;
+ load-address = <0x7000000>;
+ };
+
+ ivy {
+ uuid = <0x092358d1 0xb94723f0 0x64447c82 0xc88f57f5>;
+ load-address = <0x7100000>;
+ };
+ };
};
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
index e1c106f1e..c94a209fd 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
@@ -11,7 +11,6 @@
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_def.h b/plat/arm/board/fvp/fvp_def.h
index 347ba2e1e..909b68717 100644
--- a/plat/arm/board/fvp/fvp_def.h
+++ b/plat/arm/board/fvp/fvp_def.h
@@ -52,8 +52,10 @@
#define DEVICE1_BASE UL(0x2e000000)
#define DEVICE1_SIZE UL(0x1A00000)
#else
-#define DEVICE1_BASE UL(0x2f000000)
-#define DEVICE1_SIZE UL(0x200000)
+/* GICv2 and GICv3 mapping: GICD + CORE_COUNT * 128KB */
+#define DEVICE1_BASE BASE_GICD_BASE
+#define DEVICE1_SIZE ((BASE_GICR_BASE - BASE_GICD_BASE) + \
+ (PLATFORM_CORE_COUNT * 0x20000))
#define NSRAM_BASE UL(0x2e000000)
#define NSRAM_SIZE UL(0x10000)
#endif
@@ -110,7 +112,7 @@
#define FVP_SP810_CTRL_TIM3_OV BIT_32(22)
/*******************************************************************************
- * GIC-400 & interrupt handling related constants
+ * GIC & interrupt handling related constants
******************************************************************************/
/* VE compatible GIC memory map */
#define VE_GICD_BASE UL(0x2c001000)
@@ -128,7 +130,6 @@
#define FVP_IRQ_TZ_WDOG 56
#define FVP_IRQ_SEC_SYS_TIMER 57
-
/*******************************************************************************
* TrustZone address space controller related constants
******************************************************************************/
diff --git a/plat/arm/board/fvp/fvp_security.c b/plat/arm/board/fvp/fvp_security.c
index 80ec2171b..937f09f6e 100644
--- a/plat/arm/board/fvp/fvp_security.c
+++ b/plat/arm/board/fvp/fvp_security.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
*/
@@ -22,5 +22,5 @@ void plat_arm_security_setup(void)
*/
if ((get_arm_config()->flags & ARM_CONFIG_HAS_TZC) != 0U)
- arm_tzc400_setup(NULL);
+ arm_tzc400_setup(PLAT_ARM_TZC_BASE, NULL);
}
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 4176968f8..05c11ce52 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -292,7 +292,7 @@ ifeq (${ARCH},aarch32)
ifeq (${RESET_TO_SP_MIN},1)
BL32_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
endif
-else # if AArch64
+else # AArch64
ifeq (${RESET_TO_BL31},1)
BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
endif
@@ -301,6 +301,17 @@ else # if AArch64
endif
endif
+ifeq (${ALLOW_RO_XLAT_TABLES}, 1)
+ ifeq (${ARCH},aarch32)
+ BL32_CFLAGS += -DPLAT_RO_XLAT_TABLES=1
+ else # AArch64
+ BL31_CFLAGS += -DPLAT_RO_XLAT_TABLES=1
+ ifeq (${SPD},tspd)
+ BL32_CFLAGS += -DPLAT_RO_XLAT_TABLES=1
+ endif
+ endif
+endif
+
ifeq (${USE_DEBUGFS},1)
BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
endif
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index eddd7e570..cfac80182 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -50,6 +50,9 @@
#define NSRAM_BASE UL(0x2e000000)
#define NSRAM_SIZE UL(0x00008000) /* 32KB */
+#define PLAT_ARM_DRAM2_BASE ULL(0x880000000)
+#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000)
+
/* virtual address used by dynamic mem_protect for chunk_base */
#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000)
@@ -212,6 +215,9 @@
TZC_REGION_ACCESS_RDWR(TZC400_NSAID_GPU) | \
TZC_REGION_ACCESS_RDWR(TZC400_NSAID_CORESIGHT))
+/* TZC related constants */
+#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT_ALL
+
/*
* Required ARM CSS based platform porting definitions
*/
diff --git a/plat/arm/board/juno/juno_security.c b/plat/arm/board/juno/juno_security.c
index 32823e01c..1e64c029d 100644
--- a/plat/arm/board/juno/juno_security.c
+++ b/plat/arm/board/juno/juno_security.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
*/
@@ -127,13 +127,13 @@ void plat_arm_security_setup(void)
init_debug_cfg();
/* Initialize the TrustZone Controller */
#ifdef JUNO_TZMP1
- arm_tzc400_setup(juno_tzmp1_tzc_regions);
+ arm_tzc400_setup(PLAT_ARM_TZC_BASE, juno_tzmp1_tzc_regions);
INFO("TZC protected shared memory base address for TZMP usecase: %p\n",
(void *)JUNO_AP_TZC_SHARE_DRAM1_BASE);
INFO("TZC protected shared memory end address for TZMP usecase: %p\n",
(void *)JUNO_AP_TZC_SHARE_DRAM1_END);
#else
- arm_tzc400_setup(NULL);
+ arm_tzc400_setup(PLAT_ARM_TZC_BASE, NULL);
#endif
/* Do ARM CSS internal NIC setup */
css_init_nic400();
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 27650d266..f07c1b163 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -155,6 +155,14 @@ else
endif
endif
+ifeq (${ALLOW_RO_XLAT_TABLES}, 1)
+ ifeq (${JUNO_AARCH32_EL3_RUNTIME}, 1)
+ BL32_CFLAGS += -DPLAT_RO_XLAT_TABLES=1
+ else
+ BL31_CFLAGS += -DPLAT_RO_XLAT_TABLES=1
+ endif
+endif
+
# Add the FDT_SOURCES and options for Dynamic Config
FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_fw_config.dts
TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
diff --git a/plat/arm/board/rddaniel/include/platform_def.h b/plat/arm/board/rddaniel/include/platform_def.h
index 516360278..790ed696b 100644
--- a/plat/arm/board/rddaniel/include/platform_def.h
+++ b/plat/arm/board/rddaniel/include/platform_def.h
@@ -21,6 +21,21 @@
#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2
#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
+/* TZC Related Constants */
+#define PLAT_ARM_TZC_BASE UL(0x21830000)
+#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0)
+
+#define TZC400_OFFSET UL(0x1000000)
+#define TZC400_COUNT 4
+
+#define TZC400_BASE(n) (PLAT_ARM_TZC_BASE + \
+ (n * TZC400_OFFSET))
+
+#define TZC_NSAID_ALL_AP U(0)
+
+#define PLAT_ARM_TZC_NS_DEV_ACCESS \
+ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP))
+
/*
* Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
*/
diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk
index c7e3c7dd8..ca2647418 100644
--- a/plat/arm/board/rddaniel/platform.mk
+++ b/plat/arm/board/rddaniel/platform.mk
@@ -18,6 +18,8 @@ BL2_SOURCES += ${RDDANIEL_BASE}/rddaniel_plat.c \
${RDDANIEL_BASE}/rddaniel_security.c \
${RDDANIEL_BASE}/rddaniel_err.c \
lib/utils/mem_region.c \
+ drivers/arm/tzc/tzc400.c \
+ plat/arm/common/arm_tzc400.c \
plat/arm/common/arm_nor_psci_mem_protect.c
BL31_SOURCES += ${SGI_CPU_SOURCES} \
diff --git a/plat/arm/board/rddaniel/rddaniel_security.c b/plat/arm/board/rddaniel/rddaniel_security.c
index 6aa38c822..1247db860 100644
--- a/plat/arm/board/rddaniel/rddaniel_security.c
+++ b/plat/arm/board/rddaniel/rddaniel_security.c
@@ -4,9 +4,19 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <plat/arm/common/plat_arm.h>
#include <platform_def.h>
+static const arm_tzc_regions_info_t tzc_regions[] = {
+ ARM_TZC_REGIONS_DEF,
+ {}
+};
+
/* Initialize the secure environment */
void plat_arm_security_setup(void)
{
+ int i;
+
+ for (i = 0; i < TZC400_COUNT; i++)
+ arm_tzc400_setup(TZC400_BASE(i), tzc_regions);
}
diff --git a/plat/arm/board/sgm775/include/platform_def.h b/plat/arm/board/sgm775/include/platform_def.h
index d165ff9ed..e83cd5764 100644
--- a/plat/arm/board/sgm775/include/platform_def.h
+++ b/plat/arm/board/sgm775/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
*/
@@ -12,6 +12,9 @@
#define PLAT_MAX_CPUS_PER_CLUSTER U(8)
#define PLAT_MAX_PE_PER_CPU U(1)
+#define PLAT_ARM_DRAM2_BASE ULL(0x880000000)
+#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000)
+
/*
* Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
*/
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index dd392085d..136e65a1f 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -205,6 +205,13 @@ int arm_bl2_handle_post_image_load(unsigned int image_id)
******************************************************************************/
int arm_bl2_plat_handle_post_image_load(unsigned int image_id)
{
+#if defined(SPD_spmd)
+ /* For Secure Partitions we don't need post processing */
+ if ((image_id >= (MAX_NUMBER_IDS - MAX_SP_IDS)) &&
+ (image_id < MAX_NUMBER_IDS)) {
+ return 0;
+ }
+#endif
return arm_bl2_handle_post_image_load(image_id);
}
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index c135d7f2d..85535c11a 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -256,9 +256,14 @@ void arm_bl31_plat_runtime_setup(void)
/* Initialize the runtime console */
arm_console_runtime_init();
+
#if RECLAIM_INIT_CODE
arm_free_init_memory();
#endif
+
+#if PLAT_RO_XLAT_TABLES
+ arm_xlat_make_tables_readonly();
+#endif
}
#if RECLAIM_INIT_CODE
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index d1e9620de..d1eee08d1 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -25,6 +25,26 @@
* conflicts with the definition in plat/common. */
#pragma weak plat_get_syscnt_freq2
+/*******************************************************************************
+ * Changes the memory attributes for the region of mapped memory where the BL
+ * image's translation tables are located such that the tables will have
+ * read-only permissions.
+ ******************************************************************************/
+#if PLAT_RO_XLAT_TABLES
+void arm_xlat_make_tables_readonly(void)
+{
+ int rc = xlat_make_tables_readonly();
+
+ if (rc != 0) {
+ ERROR("Failed to make translation tables read-only at EL%u.\n",
+ get_current_el());
+ panic();
+ }
+
+ INFO("Translation tables are now read-only at EL%u.\n",
+ get_current_el());
+}
+#endif
void arm_setup_romlib(void)
{
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 17058d1a5..4fb85fbee 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -182,6 +182,9 @@ 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
+ifeq (${SPD},spmd)
+ARM_IO_SOURCES += plat/arm/common/fconf/arm_fconf_sp.c
+endif
endif
BL1_SOURCES += drivers/io/io_fip.c \
diff --git a/plat/arm/common/arm_console.c b/plat/arm/common/arm_console.c
index 123811d71..0cac5d999 100644
--- a/plat/arm/common/arm_console.c
+++ b/plat/arm/common/arm_console.c
@@ -16,8 +16,8 @@
/*******************************************************************************
* Functions that set up the console
******************************************************************************/
-static console_pl011_t arm_boot_console;
-static console_pl011_t arm_runtime_console;
+static console_t arm_boot_console;
+static console_t arm_runtime_console;
/* Initialize the console to provide early debug support */
void __init arm_console_boot_init(void)
@@ -35,13 +35,13 @@ void __init arm_console_boot_init(void)
panic();
}
- console_set_scope(&arm_boot_console.console, CONSOLE_FLAG_BOOT);
+ console_set_scope(&arm_boot_console, CONSOLE_FLAG_BOOT);
}
void arm_console_boot_end(void)
{
(void)console_flush();
- (void)console_unregister(&arm_boot_console.console);
+ (void)console_unregister(&arm_boot_console);
}
/* Initialize the runtime console */
@@ -54,7 +54,7 @@ void arm_console_runtime_init(void)
if (rc == 0)
panic();
- console_set_scope(&arm_runtime_console.console, CONSOLE_FLAG_RUNTIME);
+ console_set_scope(&arm_runtime_console, CONSOLE_FLAG_RUNTIME);
}
void arm_console_runtime_end(void)
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index 443d40fe8..df7530733 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -21,7 +21,6 @@
#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>
#if TRUSTED_BOARD_BOOT
diff --git a/plat/arm/common/arm_fconf_io_storage.c b/plat/arm/common/arm_fconf_io_storage.c
index 341622a0b..6fcfbd6fb 100644
--- a/plat/arm/common/arm_fconf_io_storage.c
+++ b/plat/arm/common/arm_fconf_io_storage.c
@@ -12,7 +12,6 @@
#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>
diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c
index 2faaa76c4..593199d46 100644
--- a/plat/arm/common/arm_image_load.c
+++ b/plat/arm/common/arm_image_load.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
*/
@@ -7,6 +7,9 @@
#include <assert.h>
#include <common/bl_common.h>
#include <common/desc_image_load.h>
+#if defined(SPD_spmd)
+#include <plat/arm/common/fconf_arm_sp_getter.h>
+#endif
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
@@ -29,12 +32,62 @@ void plat_flush_next_bl_params(void)
next_bl_params_cpy_ptr);
}
+#if defined(SPD_spmd)
+/*******************************************************************************
+ * This function appends Secure Partitions to list of loadable images.
+ ******************************************************************************/
+void plat_add_sp_images_load_info(struct bl_load_info *load_info)
+{
+ bl_load_info_node_t *node_info = load_info->head;
+ unsigned int index = 0;
+
+ if (sp_mem_params_descs[index].image_id == 0) {
+ ERROR("No Secure Partition Image available\n");
+ return;
+ }
+
+ /* Traverse through the bl images list */
+ do {
+ node_info = node_info->next_load_info;
+ } while (node_info->next_load_info != NULL);
+
+ for (; index < MAX_SP_IDS; index++) {
+ /* Populate the image information */
+ node_info->image_id = sp_mem_params_descs[index].image_id;
+ node_info->image_info = &sp_mem_params_descs[index].image_info;
+
+ if ((index + 1U) == MAX_SP_IDS) {
+ INFO("Reached Max number of SPs\n");
+ return;
+ }
+
+ if (sp_mem_params_descs[index + 1U].image_id == 0) {
+ return;
+ }
+
+ node_info->next_load_info =
+ &sp_mem_params_descs[index + 1U].load_node_mem;
+ node_info = node_info->next_load_info;
+
+ }
+}
+#endif
+
/*******************************************************************************
* This function returns the list of loadable images.
******************************************************************************/
struct bl_load_info *plat_get_bl_image_load_info(void)
{
+#if defined(SPD_spmd)
+ bl_load_info_t *bl_load_info;
+
+ bl_load_info = get_bl_load_info_from_mem_params_desc();
+ plat_add_sp_images_load_info(bl_load_info);
+
+ return bl_load_info;
+#else
return get_bl_load_info_from_mem_params_desc();
+#endif
}
/*******************************************************************************
diff --git a/plat/arm/common/arm_tzc400.c b/plat/arm/common/arm_tzc400.c
index 34e650f19..370ef0a86 100644
--- a/plat/arm/common/arm_tzc400.c
+++ b/plat/arm/common/arm_tzc400.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
*/
@@ -19,7 +19,8 @@
* When booting an EL3 payload, this is simplified: we configure region 0 with
* secure access only and do not enable any other region.
******************************************************************************/
-void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions)
+void arm_tzc400_setup(uintptr_t tzc_base,
+ const arm_tzc_regions_info_t *tzc_regions)
{
#ifndef EL3_PAYLOAD_BASE
unsigned int region_index = 1U;
@@ -32,7 +33,7 @@ void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions)
INFO("Configuring TrustZone Controller\n");
- tzc400_init(PLAT_ARM_TZC_BASE);
+ tzc400_init(tzc_base);
/* Disable filters. */
tzc400_disable_filters();
@@ -74,5 +75,5 @@ void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions)
void plat_arm_security_setup(void)
{
- arm_tzc400_setup(NULL);
+ arm_tzc400_setup(PLAT_ARM_TZC_BASE, NULL);
}
diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c
index 3c0586fd0..cfcddc2b2 100644
--- a/plat/arm/common/fconf/arm_fconf_io.c
+++ b/plat/arm/common/fconf/arm_fconf_io.c
@@ -59,9 +59,9 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = {
#ifdef IMAGE_BL2
#if TRUSTED_BOARD_BOOT
-#define FCONF_ARM_IO_UUID_NUMBER 19
+#define FCONF_ARM_IO_UUID_NUMBER U(19)
#else
-#define FCONF_ARM_IO_UUID_NUMBER 10
+#define FCONF_ARM_IO_UUID_NUMBER U(10)
#endif
static io_uuid_spec_t fconf_arm_uuids[FCONF_ARM_IO_UUID_NUMBER];
diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c
new file mode 100644
index 000000000..bb88aff6f
--- /dev/null
+++ b/plat/arm/common/fconf/arm_fconf_sp.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <common/fdt_wrappers.h>
+#include <drivers/io/io_storage.h>
+#include <lib/object_pool.h>
+#include <libfdt.h>
+#include <plat/arm/common/arm_fconf_getter.h>
+#include <plat/arm/common/arm_fconf_io_storage.h>
+#include <plat/arm/common/fconf_arm_sp_getter.h>
+#include <platform_def.h>
+#include <tools_share/firmware_image_package.h>
+
+#ifdef IMAGE_BL2
+
+bl_mem_params_node_t sp_mem_params_descs[MAX_SP_IDS];
+
+struct arm_sp_t arm_sp;
+
+int fconf_populate_arm_sp(uintptr_t config)
+{
+ int sp_node, node, err;
+ union uuid_helper_t uuid_helper;
+ unsigned int index = 0;
+ const unsigned int sp_start_index = MAX_NUMBER_IDS - MAX_SP_IDS;
+
+ /* As libfdt use void *, we can't avoid this cast */
+ const void *dtb = (void *)config;
+
+ /* Assert the node offset point to "arm,sp" compatible property */
+ const char *compatible_str = "arm,sp";
+
+ node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
+ if (node < 0) {
+ ERROR("FCONF: Can't find %s in dtb\n", compatible_str);
+ return node;
+ }
+
+ fdt_for_each_subnode(sp_node, dtb, node) {
+ err = fdtw_read_array(dtb, sp_node, "uuid", 4,
+ &uuid_helper.word);
+ if (err < 0) {
+ ERROR("FCONF: cannot read SP uuid\n");
+ return -1;
+ }
+
+ arm_sp.uuids[index] = uuid_helper;
+
+ err = fdtw_read_cells(dtb, sp_node, "load-address", 1,
+ &arm_sp.load_addr[index]);
+ if (err < 0) {
+ ERROR("FCONF: cannot read SP load address\n");
+ return -1;
+ }
+
+ VERBOSE("FCONF: %s UUID %x-%x-%x-%x load_addr=%lx\n",
+ __func__,
+ uuid_helper.word[0],
+ uuid_helper.word[1],
+ uuid_helper.word[2],
+ uuid_helper.word[3],
+ arm_sp.load_addr[index]);
+
+ /* Add SP information in mem param descriptor */
+ sp_mem_params_descs[index].image_id = sp_start_index + index;
+ SET_PARAM_HEAD(&sp_mem_params_descs[index].image_info,
+ PARAM_IMAGE_BINARY, VERSION_2, 0);
+ sp_mem_params_descs[index].image_info.image_max_size =
+ ARM_SP_MAX_SIZE;
+ sp_mem_params_descs[index].next_handoff_image_id =
+ INVALID_IMAGE_ID;
+ sp_mem_params_descs[index].image_info.image_base =
+ arm_sp.load_addr[index];
+
+ /* Add SP information in IO policies structure */
+ policies[sp_start_index + index].image_spec =
+ (uintptr_t)&arm_sp.uuids[index];
+ policies[sp_start_index + index].dev_handle = &fip_dev_handle;
+ policies[sp_start_index + index].check = open_fip;
+
+ index++;
+
+ if (index >= MAX_SP_IDS) {
+ ERROR("FCONF: reached max number of SPs\n");
+ return -1;
+ }
+ }
+
+ if ((sp_node < 0) && (sp_node != -FDT_ERR_NOTFOUND)) {
+ ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node);
+ return sp_node;
+ }
+
+ arm_sp.number_of_sp = index;
+ return 0;
+}
+
+FCONF_REGISTER_POPULATOR(arm_sp, fconf_populate_arm_sp);
+
+#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 0cc746b10..cbbdfa21b 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -167,6 +167,10 @@ void arm_sp_min_plat_runtime_setup(void)
{
/* Initialize the runtime console */
arm_console_runtime_init();
+
+#if PLAT_RO_XLAT_TABLES
+ arm_xlat_make_tables_readonly();
+#endif
}
/*******************************************************************************
diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c
index aefdf89c7..a4da8c35e 100644
--- a/plat/arm/common/tsp/arm_tsp_setup.c
+++ b/plat/arm/common/tsp/arm_tsp_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
*/
@@ -28,7 +28,7 @@
/*******************************************************************************
* Initialize the UART
******************************************************************************/
-static console_pl011_t arm_tsp_runtime_console;
+static console_t arm_tsp_runtime_console;
void arm_tsp_early_platform_setup(void)
{
@@ -43,7 +43,7 @@ void arm_tsp_early_platform_setup(void)
if (rc == 0)
panic();
- console_set_scope(&arm_tsp_runtime_console.console,
+ console_set_scope(&arm_tsp_runtime_console,
CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
}
@@ -79,4 +79,8 @@ void tsp_plat_arch_setup(void)
setup_page_tables(bl_regions, plat_arm_get_mmap());
enable_mmu_el1(0);
+
+#if PLAT_RO_XLAT_TABLES
+ arm_xlat_make_tables_readonly();
+#endif
}
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 4986378e9..9a482d0c0 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -123,6 +123,9 @@
#define PLAT_ARM_NSRAM_BASE 0x06000000
#define PLAT_ARM_NSRAM_SIZE 0x00080000 /* 512KB */
+#define PLAT_ARM_DRAM2_BASE ULL(0x8080000000)
+#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000)
+
#define PLAT_ARM_G1S_IRQ_PROPS(grp) CSS_G1S_IRQ_PROPS(grp)
#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp)
diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c
index 6070db235..de6c1d176 100644
--- a/plat/common/plat_bl_common.c
+++ b/plat/common/plat_bl_common.c
@@ -11,6 +11,7 @@
#include <common/debug.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat/common/platform.h>
+#include <tools_share/firmware_encrypted.h>
/*
* The following platform functions are weakly defined. The Platforms
@@ -22,6 +23,7 @@
#pragma weak bl2_plat_handle_pre_image_load
#pragma weak bl2_plat_handle_post_image_load
#pragma weak plat_try_next_boot_source
+#pragma weak plat_get_enc_key_info
void bl2_el3_plat_prepare_exit(void)
{
@@ -53,6 +55,31 @@ int plat_try_next_boot_source(void)
}
/*
+ * Weak implementation to provide dummy decryption key only for test purposes,
+ * platforms must override this API for any real world firmware encryption
+ * use-case.
+ */
+int plat_get_enc_key_info(enum fw_enc_status_t fw_enc_status, uint8_t *key,
+ size_t *key_len, unsigned int *flags,
+ const uint8_t *img_id, size_t img_id_len)
+{
+#define DUMMY_FIP_ENC_KEY { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, \
+ 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, \
+ 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, \
+ 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef }
+
+ const uint8_t dummy_key[] = DUMMY_FIP_ENC_KEY;
+
+ assert(*key_len >= sizeof(dummy_key));
+
+ *key_len = sizeof(dummy_key);
+ memcpy(key, dummy_key, *key_len);
+ *flags = 0;
+
+ return 0;
+}
+
+/*
* Set up the page tables for the generic and platform-specific memory regions.
* The size of the Trusted SRAM seen by the BL image must be specified as well
* as an array specifying the generic memory regions which can be;
diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c
index 4c789795e..9c3dc7177 100644
--- a/plat/common/plat_spmd_manifest.c
+++ b/plat/common/plat_spmd_manifest.c
@@ -37,12 +37,6 @@ static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr,
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");
@@ -61,7 +55,6 @@ static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr,
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);
diff --git a/plat/hisilicon/hikey/hikey_bl1_setup.c b/plat/hisilicon/hikey/hikey_bl1_setup.c
index a97d76320..86e4fd637 100644
--- a/plat/hisilicon/hikey/hikey_bl1_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl1_setup.c
@@ -26,7 +26,7 @@
/* Data structure which holds the extents of the trusted RAM for BL1 */
static meminfo_t bl1_tzram_layout;
-static console_pl011_t console;
+static console_t console;
enum {
BOOT_NORMAL = 0,
diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c
index 96136ec12..feb7f8a46 100644
--- a/plat/hisilicon/hikey/hikey_bl2_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl2_setup.c
@@ -32,7 +32,7 @@
#define BL2_RW_BASE (BL_CODE_END)
static meminfo_t bl2_el3_tzram_layout;
-static console_pl011_t console;
+static console_t console;
enum {
BOOT_MODE_RECOVERY = 0,
diff --git a/plat/hisilicon/hikey/hikey_bl31_setup.c b/plat/hisilicon/hikey/hikey_bl31_setup.c
index 0326e9f3d..7d008e741 100644
--- a/plat/hisilicon/hikey/hikey_bl31_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl31_setup.c
@@ -27,7 +27,7 @@
static entry_point_info_t bl32_ep_info;
static entry_point_info_t bl33_ep_info;
-static console_pl011_t console;
+static console_t console;
/******************************************************************************
* On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
diff --git a/plat/hisilicon/hikey960/hikey960_bl1_setup.c b/plat/hisilicon/hikey960/hikey960_bl1_setup.c
index 4a7036cfc..0a2d062a5 100644
--- a/plat/hisilicon/hikey960/hikey960_bl1_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl1_setup.c
@@ -41,7 +41,7 @@ enum {
/* Data structure which holds the extents of the trusted RAM for BL1 */
static meminfo_t bl1_tzram_layout;
-static console_pl011_t console;
+static console_t console;
/******************************************************************************
* On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
diff --git a/plat/hisilicon/hikey960/hikey960_bl2_setup.c b/plat/hisilicon/hikey960/hikey960_bl2_setup.c
index 35d76921d..c1c2a8c59 100644
--- a/plat/hisilicon/hikey960/hikey960_bl2_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl2_setup.c
@@ -32,7 +32,7 @@
#define BL2_RW_BASE (BL_CODE_END)
static meminfo_t bl2_el3_tzram_layout;
-static console_pl011_t console;
+static console_t console;
extern int load_lpm3(void);
enum {
diff --git a/plat/hisilicon/hikey960/hikey960_bl31_setup.c b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
index 9383265ec..d3b4e4f68 100644
--- a/plat/hisilicon/hikey960/hikey960_bl31_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
@@ -29,7 +29,7 @@
static entry_point_info_t bl32_ep_info;
static entry_point_info_t bl33_ep_info;
-static console_pl011_t console;
+static console_t console;
/******************************************************************************
* On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
diff --git a/plat/hisilicon/hikey960/hikey960_pm.c b/plat/hisilicon/hikey960/hikey960_pm.c
index ede893ecb..9f96fc398 100644
--- a/plat/hisilicon/hikey960/hikey960_pm.c
+++ b/plat/hisilicon/hikey960/hikey960_pm.c
@@ -33,7 +33,7 @@
#define AXI_CONF_BASE 0x820
static unsigned int uart_base;
-static console_pl011_t console;
+static console_t console;
static uintptr_t hikey960_sec_entrypoint;
static void hikey960_pwr_domain_standby(plat_local_state_t cpu_state)
diff --git a/plat/hisilicon/poplar/bl1_plat_setup.c b/plat/hisilicon/poplar/bl1_plat_setup.c
index 08ad67c59..047ba6291 100644
--- a/plat/hisilicon/poplar/bl1_plat_setup.c
+++ b/plat/hisilicon/poplar/bl1_plat_setup.c
@@ -28,7 +28,7 @@
/* Data structure which holds the extents of the trusted RAM for BL1 */
static meminfo_t bl1_tzram_layout;
static meminfo_t bl2_tzram_layout;
-static console_pl011_t console;
+static console_t console;
/*
* Cannot use default weak implementation in bl1_main.c because BL1 RW data is
diff --git a/plat/hisilicon/poplar/bl2_plat_setup.c b/plat/hisilicon/poplar/bl2_plat_setup.c
index cc9d9754e..482935c4a 100644
--- a/plat/hisilicon/poplar/bl2_plat_setup.c
+++ b/plat/hisilicon/poplar/bl2_plat_setup.c
@@ -25,7 +25,7 @@
#include "plat_private.h"
static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
-static console_pl011_t console;
+static console_t console;
/*******************************************************************************
* Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol.
diff --git a/plat/hisilicon/poplar/bl31_plat_setup.c b/plat/hisilicon/poplar/bl31_plat_setup.c
index 981ef376b..a4e17cabc 100644
--- a/plat/hisilicon/poplar/bl31_plat_setup.c
+++ b/plat/hisilicon/poplar/bl31_plat_setup.c
@@ -29,7 +29,7 @@
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
-static console_pl011_t console;
+static console_t console;
static void hisi_tzpc_sec_init(void)
{
diff --git a/plat/imx/common/aarch32/imx_uart_console.S b/plat/imx/common/aarch32/imx_uart_console.S
index 1c729b1d7..1a1229aab 100644
--- a/plat/imx/common/aarch32/imx_uart_console.S
+++ b/plat/imx/common/aarch32/imx_uart_console.S
@@ -20,7 +20,7 @@ func console_imx_uart_register
mov r4, r3
cmp r4, #0
beq register_fail
- str r0, [r4, #CONSOLE_T_DRVDATA]
+ str r0, [r4, #CONSOLE_T_BASE]
bl console_imx_uart_core_init
cmp r0, #0
@@ -35,16 +35,16 @@ register_fail:
endfunc console_imx_uart_register
func console_imx_uart_putc
- ldr r1, [r1, #CONSOLE_T_DRVDATA]
+ ldr r1, [r1, #CONSOLE_T_BASE]
b console_imx_uart_core_putc
endfunc console_imx_uart_putc
func console_imx_uart_getc
- ldr r0, [r0, #CONSOLE_T_DRVDATA]
+ ldr r0, [r0, #CONSOLE_T_BASE]
b console_imx_uart_core_getc
endfunc console_imx_uart_getc
func console_imx_uart_flush
- ldr r0, [r0, #CONSOLE_T_DRVDATA]
+ ldr r0, [r0, #CONSOLE_T_BASE]
b console_imx_uart_core_flush
endfunc console_imx_uart_flush
diff --git a/plat/imx/common/imx_uart_console.S b/plat/imx/common/imx_uart_console.S
index 3bdeea26c..0cb4fb870 100644
--- a/plat/imx/common/imx_uart_console.S
+++ b/plat/imx/common/imx_uart_console.S
@@ -25,7 +25,7 @@ func console_imx_uart_register
mov x7, x30
mov x6, x3
cbz x6, register_fail
- str x0, [x6, #CONSOLE_T_DRVDATA]
+ str x0, [x6, #CONSOLE_T_BASE]
bl console_imx_uart_init
cbz x0, register_fail
@@ -44,7 +44,7 @@ func console_imx_uart_init
endfunc console_imx_uart_init
func console_imx_uart_putc
- ldr x1, [x1, #CONSOLE_T_DRVDATA]
+ ldr x1, [x1, #CONSOLE_T_BASE]
cbz x1, putc_error
/* Prepare '\r' to '\n' */
@@ -68,7 +68,7 @@ putc_error:
endfunc console_imx_uart_putc
func console_imx_uart_getc
- ldr x0, [x0, #CONSOLE_T_DRVDATA]
+ ldr x0, [x0, #CONSOLE_T_BASE]
cbz x0, getc_error
1:
ldr w1, [x0, #UTS]
diff --git a/plat/imx/common/include/imx8_lpuart.h b/plat/imx/common/include/imx8_lpuart.h
index 0ea284fdf..26470e040 100644
--- a/plat/imx/common/include/imx8_lpuart.h
+++ b/plat/imx/common/include/imx8_lpuart.h
@@ -54,13 +54,8 @@
#include <stdint.h>
-typedef struct {
- console_t console;
- uintptr_t base;
-} console_lpuart_t;
-
int console_lpuart_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
- console_lpuart_t *console);
+ console_t *console);
#endif /*__ASSEMBLER__*/
#endif /* IMX8_LPUART_H */
diff --git a/plat/imx/common/include/imx_uart.h b/plat/imx/common/include/imx_uart.h
index cc1b5318e..6c4d62f57 100644
--- a/plat/imx/common/include/imx_uart.h
+++ b/plat/imx/common/include/imx_uart.h
@@ -11,13 +11,8 @@
#ifndef __ASSEMBLER__
-typedef struct {
- console_t console;
- uintptr_t base;
-} console_uart_t;
-
int console_imx_uart_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
- console_uart_t *console);
+ console_t *console);
#endif /*__ASSEMBLER__*/
#endif /* IMX_UART_H */
diff --git a/plat/imx/common/lpuart_console.S b/plat/imx/common/lpuart_console.S
index d8dac2cea..98b358807 100644
--- a/plat/imx/common/lpuart_console.S
+++ b/plat/imx/common/lpuart_console.S
@@ -20,7 +20,7 @@ func console_lpuart_register
mov x7, x30
mov x6, x3
cbz x6, register_fail
- str x0, [x6, #CONSOLE_T_DRVDATA]
+ str x0, [x6, #CONSOLE_T_BASE]
bl console_lpuart_init
cbz x0, register_fail
@@ -39,7 +39,7 @@ func console_lpuart_init
endfunc console_lpuart_init
func console_lpuart_putc
- ldr x1, [x1, #CONSOLE_T_DRVDATA]
+ ldr x1, [x1, #CONSOLE_T_BASE]
cbz x1, putc_error
/* Prepare '\r' to '\n' */
cmp w0, #0xA
@@ -62,7 +62,7 @@ putc_error:
endfunc console_lpuart_putc
func console_lpuart_getc
- ldr x0, [x0, #CONSOLE_T_DRVDATA]
+ ldr x0, [x0, #CONSOLE_T_BASE]
cbz x0, getc_error
/* Check if the receive FIFO state */
ret
diff --git a/plat/imx/imx7/common/imx7_bl2_el3_common.c b/plat/imx/imx7/common/imx7_bl2_el3_common.c
index a1e2aafd4..7f156e306 100644
--- a/plat/imx/imx7/common/imx7_bl2_el3_common.c
+++ b/plat/imx/imx7/common/imx7_bl2_el3_common.c
@@ -150,7 +150,7 @@ static void imx7_setup_wdog_clocks(void)
void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2,
u_register_t arg3, u_register_t arg4)
{
- static console_imx_uart_t console;
+ static console_t console;
int console_scope = CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME;
/* Initialize common components */
@@ -170,7 +170,7 @@ void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2,
PLAT_IMX7_BOOT_UART_CLK_IN_HZ,
PLAT_IMX7_CONSOLE_BAUDRATE,
&console);
- console_set_scope(&console.console, console_scope);
+ console_set_scope(&console, console_scope);
/* Open handles to persistent storage */
plat_imx7_io_setup();
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
index 4c5f4f0d1..40110d778 100644
--- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
@@ -97,7 +97,7 @@ void bl31_tzc380_setup(void)
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
- static console_uart_t console;
+ static console_t console;
int i;
/* Enable CSU NS access permission */
@@ -114,7 +114,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
IMX_CONSOLE_BAUDRATE, &console);
/* This console is only used for boot stage */
- console_set_scope(&console.console, CONSOLE_FLAG_BOOT);
+ console_set_scope(&console, CONSOLE_FLAG_BOOT);
/*
* tell BL3-1 where the non-secure software image is located
diff --git a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
index a347389a2..05b59705f 100644
--- a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
@@ -133,7 +133,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
imx8m_caam_init();
#if DEBUG_CONSOLE
- static console_uart_t console;
+ static console_t console;
console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
IMX_CONSOLE_BAUDRATE, &console);
diff --git a/plat/imx/imx8m/include/imx_rdc.h b/plat/imx/imx8m/include/imx_rdc.h
index 6be8550da..e25b0e6d4 100644
--- a/plat/imx/imx8m/include/imx_rdc.h
+++ b/plat/imx/imx8m/include/imx_rdc.h
@@ -13,9 +13,9 @@
#define MDAn(x) (IMX_RDC_BASE + 0x200 + (x) * 4)
#define PDAPn(x) (IMX_RDC_BASE + 0x400 + (x) * 4)
-#define MRSAn(x) (IMX_RDC_BASE + 0x800 + (x) * 4)
-#define MREAn(x) (IMX_RDC_BASE + 0x804 + (x) * 4)
-#define MRCn(x) (IMX_RDC_BASE + 0x808 + (x) * 4)
+#define MRSAn(x) (IMX_RDC_BASE + 0x800 + (x) * 0x10)
+#define MREAn(x) (IMX_RDC_BASE + 0x804 + (x) * 0x10)
+#define MRCn(x) (IMX_RDC_BASE + 0x808 + (x) * 0x10)
#define LCK BIT(31)
#define SREQ BIT(30)
diff --git a/plat/imx/imx8qm/imx8qm_bl31_setup.c b/plat/imx/imx8qm/imx8qm_bl31_setup.c
index 9232cbc2d..cffb140fb 100644
--- a/plat/imx/imx8qm/imx8qm_bl31_setup.c
+++ b/plat/imx/imx8qm/imx8qm_bl31_setup.c
@@ -295,7 +295,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
#if DEBUG_CONSOLE
- static console_lpuart_t console;
+ static console_t console;
#endif
if (sc_ipc_open(&ipc_handle, SC_IPC_BASE) != SC_ERR_NONE)
panic();
diff --git a/plat/imx/imx8qx/imx8qx_bl31_setup.c b/plat/imx/imx8qx/imx8qx_bl31_setup.c
index 58c82ce60..97d222787 100644
--- a/plat/imx/imx8qx/imx8qx_bl31_setup.c
+++ b/plat/imx/imx8qx/imx8qx_bl31_setup.c
@@ -255,7 +255,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
#if DEBUG_CONSOLE
- static console_lpuart_t console;
+ static console_t console;
#endif
if (sc_ipc_open(&ipc_handle, SC_IPC_BASE) != SC_ERR_NONE)
panic();
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index f32820777..a87dea8b3 100644
--- a/plat/intel/soc/agilex/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex/bl2_plat_setup.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,6 +20,7 @@
#include "agilex_pinmux.h"
#include "ccu/ncore_ccu.h"
#include "qspi/cadence_qspi.h"
+#include "socfpga_emac.h"
#include "socfpga_handoff.h"
#include "socfpga_mailbox.h"
#include "socfpga_private.h"
@@ -51,7 +52,7 @@ boot_source_type boot_source = BOOT_SOURCE;
void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
u_register_t x2, u_register_t x4)
{
- static console_16550_t console;
+ static console_t console;
handoff reverse_handoff_ptr;
generic_delay_timer_init();
@@ -72,6 +73,7 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
socfpga_delay_timer_init();
init_ncore_ccu();
+ socfpga_emac_init();
init_hard_memory_controller();
mailbox_init();
diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c
index 4b1144095..6f32aff4a 100644
--- a/plat/intel/soc/agilex/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex/bl31_plat_setup.c
@@ -37,7 +37,7 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
- static console_16550_t console;
+ static console_t console;
console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE,
&console);
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index f47c3f113..0a91c23dd 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -1,6 +1,6 @@
#
-# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
-# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -42,6 +42,7 @@ BL2_SOURCES += \
plat/intel/soc/common/socfpga_delay_timer.c \
plat/intel/soc/common/socfpga_image_load.c \
plat/intel/soc/common/socfpga_storage.c \
+ plat/intel/soc/common/soc/socfpga_emac.c \
plat/intel/soc/common/soc/socfpga_handoff.c \
plat/intel/soc/common/soc/socfpga_mailbox.c \
plat/intel/soc/common/soc/socfpga_reset_manager.c \
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index 8a681e69d..046d13880 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -169,6 +169,14 @@
#define PLAT_UART_CLOCK (100000000)
/*******************************************************************************
+ * PHY related constants
+ ******************************************************************************/
+
+#define EMAC0_PHY_MODE PHY_INTERFACE_MODE_RGMII
+#define EMAC1_PHY_MODE PHY_INTERFACE_MODE_RGMII
+#define EMAC2_PHY_MODE PHY_INTERFACE_MODE_RGMII
+
+/*******************************************************************************
* System counter frequency related constants
******************************************************************************/
#define PLAT_SYS_COUNTER_FREQ_IN_TICKS (400000000)
diff --git a/plat/intel/soc/common/include/socfpga_emac.h b/plat/intel/soc/common/include/socfpga_emac.h
new file mode 100644
index 000000000..5b98006a3
--- /dev/null
+++ b/plat/intel/soc/common/include/socfpga_emac.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_EMAC_H
+#define SOCFPGA_EMAC_H
+
+/* EMAC PHY Mode */
+
+#define PHY_INTERFACE_MODE_GMII_MII 0
+#define PHY_INTERFACE_MODE_RGMII 1
+#define PHY_INTERFACE_MODE_RMII 2
+#define PHY_INTERFACE_MODE_RESET 3
+
+/* Mask Definitions */
+
+#define PHY_INTF_SEL_MSK 0x3
+#define FPGAINTF_EN_3_EMAC_MSK(x) (1 << (x * 8))
+
+void socfpga_emac_init(void);
+
+#endif /* SOCFPGA_EMAC_H */
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index 7d725b0ad..3c56d15bf 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -126,9 +126,9 @@ int mailbox_init(void);
void mailbox_set_qspi_close(void);
void mailbox_set_qspi_open(void);
void mailbox_set_qspi_direct(void);
-int mailbox_send_cmd(int job_id, unsigned int cmd, uint64_t *args,
+int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args,
int len, int urgent, uint32_t *response, int resp_len);
-int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint64_t *args,
+int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args,
int len, int urgent);
int mailbox_read_response(int job_id, uint32_t *response, int resp_len);
int mailbox_get_qspi_clock(void);
@@ -140,7 +140,7 @@ 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(uint64_t *flash_offset);
-int mailbox_hps_stage_notify(uint64_t execution_stage);
+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 2b1d9837c..19a52f7b9 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -10,9 +10,11 @@
/* SiP status response */
#define INTEL_SIP_SMC_STATUS_OK 0
-#define INTEL_SIP_SMC_STATUS_ERROR 0x4
#define INTEL_SIP_SMC_STATUS_BUSY 0x1
#define INTEL_SIP_SMC_STATUS_REJECTED 0x2
+#define INTEL_SIP_SMC_STATUS_ERROR 0x4
+#define INTEL_SIP_SMC_RSU_ERROR 0x7
+
/* SMC SiP service function identifier */
#define INTEL_SIP_SMC_FPGA_CONFIG_START 0xC2000001
diff --git a/plat/intel/soc/common/include/socfpga_system_manager.h b/plat/intel/soc/common/include/socfpga_system_manager.h
index 68e30b894..76565bc93 100644
--- a/plat/intel/soc/common/include/socfpga_system_manager.h
+++ b/plat/intel/soc/common/include/socfpga_system_manager.h
@@ -13,6 +13,11 @@
#define SOCFPGA_SYSMGR_SDMMC 0x28
+#define SOCFPGA_SYSMGR_EMAC_0 0x44
+#define SOCFPGA_SYSMGR_EMAC_1 0x48
+#define SOCFPGA_SYSMGR_EMAC_2 0x4c
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_3 0x70
+
#define SOCFPGA_SYSMGR_NOC_TIMEOUT 0xc0
#define SOCFPGA_SYSMGR_NOC_IDLEREQ_SET 0xc4
#define SOCFPGA_SYSMGR_NOC_IDLEREQ_CLR 0xc8
diff --git a/plat/intel/soc/common/soc/socfpga_emac.c b/plat/intel/soc/common/soc/socfpga_emac.c
new file mode 100644
index 000000000..cacfd53c4
--- /dev/null
+++ b/plat/intel/soc/common/soc/socfpga_emac.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2020, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include "socfpga_emac.h"
+#include "socfpga_reset_manager.h"
+#include "socfpga_system_manager.h"
+
+void socfpga_emac_init(void)
+{
+ mmio_setbits_32(SOCFPGA_RSTMGR(PER0MODRST),
+ RSTMGR_PER0MODRST_EMAC0 |
+ RSTMGR_PER0MODRST_EMAC1 |
+ RSTMGR_PER0MODRST_EMAC2);
+
+ mmio_clrsetbits_32(SOCFPGA_SYSMGR(EMAC_0),
+ PHY_INTF_SEL_MSK, EMAC0_PHY_MODE);
+ mmio_clrsetbits_32(SOCFPGA_SYSMGR(EMAC_1),
+ PHY_INTF_SEL_MSK, EMAC1_PHY_MODE);
+ mmio_clrsetbits_32(SOCFPGA_SYSMGR(EMAC_2),
+ PHY_INTF_SEL_MSK, EMAC2_PHY_MODE);
+
+ mmio_clrbits_32(SOCFPGA_SYSMGR(FPGAINTF_EN_3),
+ FPGAINTF_EN_3_EMAC_MSK(0) |
+ FPGAINTF_EN_3_EMAC_MSK(1) |
+ FPGAINTF_EN_3_EMAC_MSK(2));
+
+ mmio_clrbits_32(SOCFPGA_RSTMGR(PER0MODRST),
+ RSTMGR_PER0MODRST_EMAC0 |
+ RSTMGR_PER0MODRST_EMAC1 |
+ RSTMGR_PER0MODRST_EMAC2);
+}
+
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index 8ce40a742..d066f27b5 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -11,7 +11,7 @@
#include "socfpga_mailbox.h"
#include "socfpga_sip_svc.h"
-static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint64_t *args,
+static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args,
int len)
{
uint32_t cmd_free_offset;
@@ -167,7 +167,7 @@ int mailbox_poll_response(int job_id, int urgent, uint32_t *response,
}
}
-int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint64_t *args,
+int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args,
int len, int urgent)
{
if (urgent)
@@ -184,7 +184,7 @@ int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint64_t *args,
return 0;
}
-int mailbox_send_cmd(int job_id, unsigned int cmd, uint64_t *args,
+int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args,
int len, int urgent, uint32_t *response, int resp_len)
{
int status = 0;
@@ -252,7 +252,7 @@ int mailbox_get_qspi_clock(void)
void mailbox_qspi_set_cs(int device_select)
{
- uint64_t cs_setting = device_select;
+ uint32_t cs_setting = device_select;
/* QSPI device select settings at 31:28 */
cs_setting = (cs_setting << 28);
@@ -304,13 +304,13 @@ int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len)
return ret;
}
-int mailbox_rsu_update(uint64_t *flash_offset)
+int mailbox_rsu_update(uint32_t *flash_offset)
{
return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE,
flash_offset, 2, 0, NULL, 0);
}
-int mailbox_hps_stage_notify(uint64_t execution_stage)
+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);
diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c
index d48fb5dd0..4b57b8f31 100644
--- a/plat/intel/soc/common/socfpga_psci.c
+++ b/plat/intel/soc/common/socfpga_psci.c
@@ -134,8 +134,13 @@ extern uint64_t intel_rsu_update_address;
static void __dead2 socfpga_system_reset(void)
{
+ uint32_t addr_buf[2];
+
+ memcpy(addr_buf, &intel_rsu_update_address,
+ sizeof(intel_rsu_update_address));
+
if (intel_rsu_update_address)
- mailbox_rsu_update(&intel_rsu_update_address);
+ mailbox_rsu_update(addr_buf);
else
mailbox_reset_cold();
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index 1c3d45bee..a20baab4c 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -61,7 +61,7 @@ struct fpga_config_info fpga_config_buffers[FPGA_CONFIG_BUFFER_SIZE];
static int intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer)
{
- uint64_t args[3];
+ uint32_t args[3];
while (max_blocks > 0 && buffer->size > buffer->size_written) {
args[0] = (1<<8);
@@ -374,7 +374,7 @@ 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_RSU_ERROR;
return INTEL_SIP_SMC_STATUS_OK;
}
@@ -385,10 +385,10 @@ static uint32_t intel_rsu_update(uint64_t update_address)
return INTEL_SIP_SMC_STATUS_OK;
}
-static uint32_t intel_rsu_notify(uint64_t execution_stage)
+static uint32_t intel_rsu_notify(uint32_t execution_stage)
{
if (mailbox_hps_stage_notify(execution_stage) < 0)
- return INTEL_SIP_SMC_STATUS_ERROR;
+ return INTEL_SIP_SMC_RSU_ERROR;
return INTEL_SIP_SMC_STATUS_OK;
}
@@ -397,14 +397,14 @@ 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;
+ return INTEL_SIP_SMC_RSU_ERROR;
*ret_stat = respbuf[8];
return INTEL_SIP_SMC_STATUS_OK;
}
/* Mailbox services */
-static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint64_t *args, int len,
+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)
@@ -542,7 +542,7 @@ uintptr_t sip_smc_handler(uint32_t smc_fid,
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, (uint64_t *)x2, x3, x4,
+ 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);
diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c
index 78ca253e7..721a6903c 100644
--- a/plat/intel/soc/stratix10/bl2_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl2_plat_setup.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,6 +16,7 @@
#include <lib/xlat_tables/xlat_tables.h>
#include "qspi/cadence_qspi.h"
+#include "socfpga_emac.h"
#include "socfpga_handoff.h"
#include "socfpga_mailbox.h"
#include "socfpga_private.h"
@@ -50,7 +51,7 @@ boot_source_type boot_source = BOOT_SOURCE;
void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
u_register_t x2, u_register_t x4)
{
- static console_16550_t console;
+ static console_t console;
handoff reverse_handoff_ptr;
generic_delay_timer_init();
@@ -69,6 +70,7 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
console_16550_register(PLAT_UART0_BASE, get_uart_clk(), PLAT_BAUDRATE,
&console);
+ socfpga_emac_init();
socfpga_delay_timer_init();
init_hard_memory_controller();
mailbox_init();
diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c
index 4c3123815..5813c8f8c 100644
--- a/plat/intel/soc/stratix10/bl31_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl31_plat_setup.c
@@ -45,7 +45,7 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
- static console_16550_t console;
+ static console_t console;
console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE,
&console);
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index efbab24b3..112317b7b 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -1,6 +1,6 @@
#
-# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
-# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -42,6 +42,7 @@ BL2_SOURCES += \
plat/intel/soc/common/socfpga_delay_timer.c \
plat/intel/soc/common/socfpga_image_load.c \
plat/intel/soc/common/socfpga_storage.c \
+ plat/intel/soc/common/soc/socfpga_emac.c \
plat/intel/soc/common/soc/socfpga_handoff.c \
plat/intel/soc/common/soc/socfpga_mailbox.c \
plat/intel/soc/common/soc/socfpga_reset_manager.c \
diff --git a/plat/layerscape/common/aarch64/ls_console.S b/plat/layerscape/common/aarch64/ls_console.S
index f8948b4ab..c1bd3f731 100644
--- a/plat/layerscape/common/aarch64/ls_console.S
+++ b/plat/layerscape/common/aarch64/ls_console.S
@@ -81,7 +81,7 @@ endfunc console_ls_16550_core_init
.globl console_ls_16550_register
/* -----------------------------------------------
- * int console_ls_16550_register(console_ls_16550_t *console,
+ * int console_ls_16550_register(console_t *console,
* uintptr_t base, uint32_t clk, uint32_t baud)
* Function to initialize and register a new 16550
* console. Storage passed in for the console struct
@@ -89,7 +89,7 @@ endfunc console_ls_16550_core_init
* In: x0 - UART register base address
* w1 - UART clock in Hz
* w2 - Baud rate
- * x3 - pointer to empty console_ls_16550_t struct
+ * x3 - pointer to empty console_t struct
* Out: return 1 on success, 0 on error
* Clobber list : x0, x1, x2, x6, x7, x14
* -----------------------------------------------
@@ -98,7 +98,7 @@ func console_ls_16550_register
mov x7, x30
mov x6, x3
cbz x6, register_fail
- str x0, [x6, #CONSOLE_T_16550_BASE]
+ str x0, [x6, #CONSOLE_T_BASE]
bl console_ls_16550_core_init
cbz x0, register_fail
@@ -150,7 +150,7 @@ func console_ls_16550_core_putc
endfunc console_ls_16550_core_putc
/* --------------------------------------------------------
- * int console_16550_putc(int c, console_ls_16550_t *console)
+ * int console_16550_putc(int c, console_t *console)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : w0 - character to be printed
@@ -164,7 +164,7 @@ func console_ls_16550_putc
cmp x1, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr x1, [x1, #CONSOLE_T_16550_BASE]
+ ldr x1, [x1, #CONSOLE_T_BASE]
b console_ls_16550_core_putc
endfunc console_ls_16550_putc
@@ -195,7 +195,7 @@ no_char:
endfunc console_ls_16550_core_getc
/* ---------------------------------------------
- * int console_ls_16550_getc(console_ls_16550_t *console)
+ * int console_ls_16550_getc(console_t *console)
* Function to get a character from the console.
* It returns the character grabbed on success
* or -1 on if no character is available.
@@ -209,7 +209,7 @@ func console_ls_16550_getc
cmp x1, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr x0, [x0, #CONSOLE_T_16550_BASE]
+ ldr x0, [x0, #CONSOLE_T_BASE]
b console_ls_16550_core_getc
endfunc console_ls_16550_getc
@@ -239,7 +239,7 @@ func console_ls_16550_core_flush
endfunc console_ls_16550_core_flush
/* ---------------------------------------------
- * int console_ls_16550_flush(console_ls_16550_t *console)
+ * int console_ls_16550_flush(console_t *console)
* Function to force a write of all buffered
* data that hasn't been output.
* In : x0 - pointer to console_t structure
@@ -252,6 +252,6 @@ func console_ls_16550_flush
cmp x0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr x0, [x0, #CONSOLE_T_16550_BASE]
+ ldr x0, [x0, #CONSOLE_T_BASE]
b console_ls_16550_core_flush
endfunc console_ls_16550_flush
diff --git a/plat/layerscape/common/include/ls_16550.h b/plat/layerscape/common/include/ls_16550.h
index cb4514f3f..95a64ad34 100644
--- a/plat/layerscape/common/include/ls_16550.h
+++ b/plat/layerscape/common/include/ls_16550.h
@@ -61,17 +61,10 @@
#define UARTLSR_OVRF (1 << 2) /* Rx Overrun Error */
#define UARTLSR_RDR (1 << 2) /* Rx Data Ready */
-#define CONSOLE_T_16550_BASE CONSOLE_T_DRVDATA
-
#ifndef __ASSEMBLER__
#include <stdint.h>
-typedef struct {
- console_t console;
- uintptr_t base;
-} console_ls_16550_t;
-
/*
* Initialize a new 16550 console instance and register it with the console
* framework. The |console| pointer must point to storage that will be valid
@@ -79,7 +72,7 @@ typedef struct {
* Its contents will be reinitialized from scratch.
*/
int console_ls_16550_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
- console_ls_16550_t *console);
+ console_t *console);
#endif /*__ASSEMBLER__*/
diff --git a/plat/layerscape/common/ls_bl1_setup.c b/plat/layerscape/common/ls_bl1_setup.c
index fff065efd..fa69be2e6 100644
--- a/plat/layerscape/common/ls_bl1_setup.c
+++ b/plat/layerscape/common/ls_bl1_setup.c
@@ -23,7 +23,7 @@ meminfo_t *bl1_plat_sec_mem_layout(void)
******************************************************************************/
void ls_bl1_early_platform_setup(void)
{
- static console_ls_16550_t console;
+ static console_t console;
#if !LS1043_DISABLE_TRUSTED_WDOG
/* TODO: Enable watchdog */
diff --git a/plat/layerscape/common/ls_bl2_setup.c b/plat/layerscape/common/ls_bl2_setup.c
index 35f42e1fb..6ca66bd47 100644
--- a/plat/layerscape/common/ls_bl2_setup.c
+++ b/plat/layerscape/common/ls_bl2_setup.c
@@ -23,7 +23,7 @@ static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
******************************************************************************/
void ls_bl2_early_platform_setup(meminfo_t *mem_layout)
{
- static console_ls_16550_t console;
+ static console_t console;
/* Initialize the console to provide early debug support */
console_ls_16550_register(LS_TF_UART_BASE, LS_TF_UART_CLOCK,
diff --git a/plat/layerscape/common/ls_bl31_setup.c b/plat/layerscape/common/ls_bl31_setup.c
index 03e580768..7a91aef81 100644
--- a/plat/layerscape/common/ls_bl31_setup.c
+++ b/plat/layerscape/common/ls_bl31_setup.c
@@ -67,7 +67,7 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
void ls_bl31_early_platform_setup(void *from_bl2,
void *plat_params_from_bl2)
{
- static console_ls_16550_t console;
+ static console_t console;
/* Initialize the console to provide early debug support */
console_ls_16550_register(LS_TF_UART_BASE, LS_TF_UART_CLOCK,
@@ -182,7 +182,7 @@ void ls_bl31_platform_setup(void)
******************************************************************************/
void ls_bl31_plat_runtime_setup(void)
{
- static console_ls_16550_t console;
+ static console_t console;
/* Initialize the runtime console */
console_ls_16550_register(PLAT_LS1043_UART_BASE, PLAT_LS1043_UART_CLOCK,
diff --git a/plat/layerscape/common/tsp/ls_tsp_setup.c b/plat/layerscape/common/tsp/ls_tsp_setup.c
index f3b60276c..969d0b83b 100644
--- a/plat/layerscape/common/tsp/ls_tsp_setup.c
+++ b/plat/layerscape/common/tsp/ls_tsp_setup.c
@@ -30,7 +30,7 @@ gicv2_driver_data_t ls_gic_data = {
******************************************************************************/
void ls_tsp_early_platform_setup(void)
{
- static console_ls_16550_t console;
+ static console_t console;
/*
* Initialize a different console than already in use to display
* messages from TSP
diff --git a/plat/marvell/common/marvell_console.c b/plat/marvell/common/marvell_console.c
index 22c5eb3af..17166618a 100644
--- a/plat/marvell/common/marvell_console.c
+++ b/plat/marvell/common/marvell_console.c
@@ -14,16 +14,15 @@
#ifdef PLAT_a3700
#include <drivers/marvell/uart/a3700_console.h>
-
-static console_a3700_t marvell_boot_console;
-static console_a3700_t marvell_runtime_console;
+#define console_marvell_register console_a3700_register
#else
#include <drivers/ti/uart/uart_16550.h>
-
-static console_16550_t marvell_boot_console;
-static console_16550_t marvell_runtime_console;
+#define console_marvell_register console_16550_register
#endif
+static console_t marvell_boot_console;
+static console_t marvell_runtime_console;
+
/*******************************************************************************
* Functions that set up the console
******************************************************************************/
@@ -32,15 +31,10 @@ static console_16550_t marvell_runtime_console;
void marvell_console_boot_init(void)
{
int rc =
-#ifdef PLAT_a3700
- console_a3700_register(
-#else
- console_16550_register(
-#endif
- PLAT_MARVELL_BOOT_UART_BASE,
- PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
- MARVELL_CONSOLE_BAUDRATE,
- &marvell_boot_console);
+ console_marvell_register(PLAT_MARVELL_BOOT_UART_BASE,
+ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
+ MARVELL_CONSOLE_BAUDRATE,
+ &marvell_boot_console);
if (rc == 0) {
/*
* The crash console doesn't use the multi console API, it uses
@@ -50,40 +44,33 @@ void marvell_console_boot_init(void)
panic();
}
- console_set_scope(&marvell_boot_console.console,
- CONSOLE_FLAG_BOOT);
+ console_set_scope(&marvell_boot_console, CONSOLE_FLAG_BOOT);
}
void marvell_console_boot_end(void)
{
(void)console_flush();
- (void)console_unregister(&marvell_boot_console.console);
+ (void)console_unregister(&marvell_boot_console);
}
/* Initialize the runtime console */
void marvell_console_runtime_init(void)
{
int rc =
-#ifdef PLAT_a3700
- console_a3700_register(
-#else
- console_16550_register(
-#endif
- PLAT_MARVELL_BOOT_UART_BASE,
- PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
- MARVELL_CONSOLE_BAUDRATE,
- &marvell_runtime_console);
+ console_marvell_register(PLAT_MARVELL_BOOT_UART_BASE,
+ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
+ MARVELL_CONSOLE_BAUDRATE,
+ &marvell_runtime_console);
if (rc == 0)
panic();
- console_set_scope(&marvell_runtime_console.console,
- CONSOLE_FLAG_RUNTIME);
+ console_set_scope(&marvell_runtime_console, CONSOLE_FLAG_RUNTIME);
}
void marvell_console_runtime_end(void)
{
(void)console_flush();
- (void)console_unregister(&marvell_runtime_console.console);
+ (void)console_unregister(&marvell_runtime_console);
}
diff --git a/plat/mediatek/mt8173/bl31_plat_setup.c b/plat/mediatek/mt8173/bl31_plat_setup.c
index 73a479b50..bd7d0b0ee 100644
--- a/plat/mediatek/mt8173/bl31_plat_setup.c
+++ b/plat/mediatek/mt8173/bl31_plat_setup.c
@@ -100,7 +100,7 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
- static console_16550_t console;
+ static console_t console;
console_16550_register(MT8173_UART0_BASE, MT8173_UART_CLOCK, MT8173_BAUDRATE, &console);
diff --git a/plat/mediatek/mt8173/drivers/wdt/wdt.c b/plat/mediatek/mt8173/drivers/wdt/wdt.c
new file mode 100644
index 000000000..40f57eed2
--- /dev/null
+++ b/plat/mediatek/mt8173/drivers/wdt/wdt.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2020, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <mt8173_def.h>
+#include <plat_sip_calls.h>
+#include <lib/psci/psci.h>
+#include <smccc_helpers.h>
+#include <wdt.h>
+
+#define WDT_BASE (RGU_BASE + 0)
+#define WDT_MODE (WDT_BASE + 0x00)
+#define WDT_LENGTH (WDT_BASE + 0x04)
+#define WDT_RESTART (WDT_BASE + 0x08)
+#define WDT_SWRST (WDT_BASE + 0x14)
+
+#define WDT_MODE_DUAL_MODE 0x40
+#define WDT_MODE_IRQ 0x8
+#define WDT_MODE_KEY 0x22000000
+#define WDT_MODE_EXTEN 0x4
+#define WDT_MODE_EN 0x1
+#define WDT_LENGTH_KEY 0x8
+#define WDT_RESTART_KEY 0x1971
+#define WDT_SWRST_KEY 0x1209
+
+
+#define WDT_MIN_TIMEOUT 1
+#define WDT_MAX_TIMEOUT 31
+
+enum smcwd_call {
+ SMCWD_INFO = 0,
+ SMCWD_SET_TIMEOUT = 1,
+ SMCWD_ENABLE = 2,
+ SMCWD_PET = 3,
+};
+
+static int wdt_enabled_before_suspend;
+
+/*
+ * We expect the WDT registers to be correctly initialized by BL2 firmware
+ * (which may be board specific), so we do not reinitialize them here.
+ */
+
+void wdt_trigger_reset(void)
+{
+ mmio_write_32(WDT_SWRST, WDT_SWRST_KEY);
+}
+
+void wdt_pet(void)
+{
+ mmio_write_32(WDT_RESTART, WDT_RESTART_KEY);
+}
+
+int wdt_set_timeout(uint32_t timeout)
+{
+ /* One tick here equals 512 32KHz ticks. 512 / 32000 * 125 / 2 = 1 */
+ uint32_t ticks = timeout * 125 / 2;
+
+ if (timeout < WDT_MIN_TIMEOUT || timeout > WDT_MAX_TIMEOUT)
+ return PSCI_E_INVALID_PARAMS;
+
+ mmio_write_32(WDT_LENGTH, ticks << 5 | WDT_LENGTH_KEY);
+
+ return PSCI_E_SUCCESS;
+}
+
+void wdt_set_enable(int enable)
+{
+ if (enable)
+ wdt_pet();
+ mmio_clrsetbits_32(WDT_MODE, WDT_MODE_EN,
+ WDT_MODE_KEY | (enable ? WDT_MODE_EN : 0));
+}
+
+void wdt_suspend(void)
+{
+ wdt_enabled_before_suspend = mmio_read_32(WDT_MODE) & WDT_MODE_EN;
+ if (wdt_enabled_before_suspend)
+ wdt_set_enable(0);
+}
+
+void wdt_resume(void)
+{
+ if (wdt_enabled_before_suspend)
+ wdt_set_enable(1);
+}
+
+uint64_t wdt_smc_handler(uint32_t x1,
+ uint32_t x2,
+ void *handle)
+{
+ int ret;
+
+ switch (x1) {
+ case SMCWD_INFO:
+ SMC_RET3(handle, PSCI_E_SUCCESS,
+ WDT_MIN_TIMEOUT, WDT_MAX_TIMEOUT);
+ case SMCWD_SET_TIMEOUT:
+ ret = wdt_set_timeout(x2);
+ SMC_RET1(handle, ret);
+ case SMCWD_ENABLE:
+ wdt_set_enable(x2 > 0);
+ SMC_RET1(handle, PSCI_E_SUCCESS);
+ case SMCWD_PET:
+ wdt_pet();
+ SMC_RET1(handle, PSCI_E_SUCCESS);
+ default:
+ ERROR("Unimplemented SMCWD call (%d)\n", x1);
+ SMC_RET1(handle, PSCI_E_NOT_SUPPORTED);
+ }
+}
diff --git a/plat/mediatek/mt8173/drivers/wdt/wdt.h b/plat/mediatek/mt8173/drivers/wdt/wdt.h
new file mode 100644
index 000000000..7262a5717
--- /dev/null
+++ b/plat/mediatek/mt8173/drivers/wdt/wdt.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2020, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef WDT_H
+#define WDT_H
+
+#include "stdint.h"
+
+void wdt_pet(void);
+void wdt_resume(void);
+void wdt_set_enable(int enable);
+int wdt_set_timeout(uint32_t timeout);
+uint64_t wdt_smc_handler(uint32_t x1, uint32_t x2, void *handle);
+void wdt_suspend(void);
+void wdt_trigger_reset(void);
+
+#endif /* WDT_H */
diff --git a/plat/mediatek/mt8173/include/mt8173_def.h b/plat/mediatek/mt8173/include/mt8173_def.h
index 58962f03d..378b4da55 100644
--- a/plat/mediatek/mt8173/include/mt8173_def.h
+++ b/plat/mediatek/mt8173/include/mt8173_def.h
@@ -80,18 +80,6 @@
#define PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX 4
#define PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX 3
-/*******************************************************************************
- * WDT related constants
- ******************************************************************************/
-#define MTK_WDT_BASE (RGU_BASE + 0)
-#define MTK_WDT_SWRST (MTK_WDT_BASE + 0x0014)
-
-#define MTK_WDT_MODE_DUAL_MODE 0x0040
-#define MTK_WDT_MODE_IRQ 0x0008
-#define MTK_WDT_MODE_KEY 0x22000000
-#define MTK_WDT_MODE_EXTEN 0x0004
-#define MTK_WDT_SWRST_KEY 0x1209
-
/* FIQ platform related define */
#define MT_IRQ_SEC_SGI_0 8
#define MT_IRQ_SEC_SGI_1 9
diff --git a/plat/mediatek/mt8173/include/plat_sip_calls.h b/plat/mediatek/mt8173/include/plat_sip_calls.h
index 88202cc55..ce9951a67 100644
--- a/plat/mediatek/mt8173/include/plat_sip_calls.h
+++ b/plat/mediatek/mt8173/include/plat_sip_calls.h
@@ -10,7 +10,7 @@
/*******************************************************************************
* Plat SiP function constants
******************************************************************************/
-#define MTK_PLAT_SIP_NUM_CALLS 6
+#define MTK_PLAT_SIP_NUM_CALLS 7
#define MTK_SIP_PWR_ON_MTCMOS 0x82000402
#define MTK_SIP_PWR_OFF_MTCMOS 0x82000403
@@ -18,5 +18,6 @@
#define MTK_SIP_SET_HDCP_KEY_NUM 0x82000405
#define MTK_SIP_CLR_HDCP_KEY 0x82000406
#define MTK_SIP_SET_HDCP_KEY_EX 0x82000407
+#define MTK_SIP_SMC_WATCHDOG 0x82003D06
#endif /* PLAT_SIP_CALLS_H */
diff --git a/plat/mediatek/mt8173/plat_pm.c b/plat/mediatek/mt8173/plat_pm.c
index 67f1c731b..e72a3434e 100644
--- a/plat/mediatek/mt8173/plat_pm.c
+++ b/plat/mediatek/mt8173/plat_pm.c
@@ -27,6 +27,7 @@
#include <spm_hotplug.h>
#include <spm_mcdi.h>
#include <spm_suspend.h>
+#include <wdt.h>
#define MTK_PWR_LVL0 0
#define MTK_PWR_LVL1 1
@@ -350,6 +351,7 @@ static void plat_power_domain_suspend(const psci_power_state_t *state)
}
if (MTK_SYSTEM_PWR_STATE(state) == MTK_LOCAL_STATE_OFF) {
+ wdt_suspend();
disable_scu(mpidr);
generic_timer_backup();
spm_system_suspend();
@@ -409,6 +411,7 @@ static void plat_power_domain_suspend_finish(const psci_power_state_t *state)
plat_arm_gic_init();
spm_system_suspend_finish();
enable_scu(mpidr);
+ wdt_resume();
}
/* Perform the common cluster specific operations */
@@ -455,11 +458,7 @@ static void __dead2 plat_system_reset(void)
/* Write the System Configuration Control Register */
INFO("MTK System Reset\n");
- mmio_clrsetbits_32(MTK_WDT_BASE,
- (MTK_WDT_MODE_DUAL_MODE | MTK_WDT_MODE_IRQ),
- MTK_WDT_MODE_KEY);
- mmio_setbits_32(MTK_WDT_BASE, (MTK_WDT_MODE_KEY | MTK_WDT_MODE_EXTEN));
- mmio_setbits_32(MTK_WDT_SWRST, MTK_WDT_SWRST_KEY);
+ wdt_trigger_reset();
wfi();
ERROR("MTK System Reset: operation not handled.\n");
diff --git a/plat/mediatek/mt8173/plat_sip_calls.c b/plat/mediatek/mt8173/plat_sip_calls.c
index 102feb22a..da9b91dd6 100644
--- a/plat/mediatek/mt8173/plat_sip_calls.c
+++ b/plat/mediatek/mt8173/plat_sip_calls.c
@@ -12,6 +12,7 @@
#include <mtcmos.h>
#include <mtk_sip_svc.h>
#include <plat_sip_calls.h>
+#include <wdt.h>
/* Authorized secure register list */
enum {
@@ -102,6 +103,9 @@ uint64_t mediatek_plat_sip_handler(uint32_t smc_fid,
ret = crypt_clear_hdcp_key();
SMC_RET1(handle, ret);
+ case MTK_SIP_SMC_WATCHDOG:
+ return wdt_smc_handler(x1, x2, handle);
+
default:
ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
break;
diff --git a/plat/mediatek/mt8173/platform.mk b/plat/mediatek/mt8173/platform.mk
index a66c49bb4..f62802cb9 100644
--- a/plat/mediatek/mt8173/platform.mk
+++ b/plat/mediatek/mt8173/platform.mk
@@ -15,6 +15,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
-I${MTK_PLAT_SOC}/drivers/rtc/ \
-I${MTK_PLAT_SOC}/drivers/spm/ \
-I${MTK_PLAT_SOC}/drivers/timer/ \
+ -I${MTK_PLAT_SOC}/drivers/wdt/ \
-I${MTK_PLAT_SOC}/include/
PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \
@@ -50,6 +51,7 @@ BL31_SOURCES += common/desc_image_load.c \
${MTK_PLAT_SOC}/drivers/spm/spm_mcdi.c \
${MTK_PLAT_SOC}/drivers/spm/spm_suspend.c \
${MTK_PLAT_SOC}/drivers/timer/mt_cpuxgpt.c \
+ ${MTK_PLAT_SOC}/drivers/wdt/wdt.c \
${MTK_PLAT_SOC}/plat_pm.c \
${MTK_PLAT_SOC}/plat_sip_calls.c \
${MTK_PLAT_SOC}/plat_topology.c \
diff --git a/plat/mediatek/mt8183/bl31_plat_setup.c b/plat/mediatek/mt8183/bl31_plat_setup.c
index 8204d7717..e96b4ad0c 100644
--- a/plat/mediatek/mt8183/bl31_plat_setup.c
+++ b/plat/mediatek/mt8183/bl31_plat_setup.c
@@ -112,7 +112,7 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
- static console_16550_t console;
+ static console_t console;
params_early_setup(arg1);
diff --git a/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c
index 64d854885..56d2ce26c 100644
--- a/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c
+++ b/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c
@@ -138,15 +138,9 @@ void emi_mpu_init(void)
(FORBIDDEN << 6));
emi_mpu_set_region_protection(0x52900000UL, 0x5FFFFFFFUL, 2,
(FORBIDDEN << 3 | FORBIDDEN << 6));
- emi_mpu_set_region_protection(0x60000000UL, 0x7FFFFFFFUL, 3,
+ emi_mpu_set_region_protection(0x60000000UL, 0xFFFFFFFFUL, 3,
(FORBIDDEN << 3 | FORBIDDEN << 6));
- emi_mpu_set_region_protection(0x80000000UL, 0x9FFFFFFFUL, 4,
- (FORBIDDEN << 3 | FORBIDDEN << 6));
- emi_mpu_set_region_protection(0xA0000000UL, 0xBFFFFFFFUL, 5,
- (FORBIDDEN << 3 | FORBIDDEN << 6));
- emi_mpu_set_region_protection(0xC0000000UL, 0xDFFFFFFFUL, 6,
- (FORBIDDEN << 3 | FORBIDDEN << 6));
- emi_mpu_set_region_protection(0xE0000000UL, 0xFFFFFFFFUL, 7,
+ emi_mpu_set_region_protection(0x100000000UL, 0x23FFFFFFFUL, 4,
(FORBIDDEN << 3 | FORBIDDEN << 6));
dump_emi_mpu_regions();
}
diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
index 13ca6aaa2..7cba3a449 100644
--- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
+++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
@@ -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,21 +19,16 @@
/*******************************************************************************
* Implementation defined ACTLR_EL3 bit definitions
******************************************************************************/
-#define ACTLR_EL3_L2ACTLR_BIT (U(1) << 6)
-#define ACTLR_EL3_L2ECTLR_BIT (U(1) << 5)
-#define ACTLR_EL3_L2CTLR_BIT (U(1) << 4)
-#define ACTLR_EL3_CPUECTLR_BIT (U(1) << 1)
-#define ACTLR_EL3_CPUACTLR_BIT (U(1) << 0)
-#define ACTLR_EL3_ENABLE_ALL_MASK (ACTLR_EL3_L2ACTLR_BIT | \
- ACTLR_EL3_L2ECTLR_BIT | \
- ACTLR_EL3_L2CTLR_BIT | \
- ACTLR_EL3_CPUECTLR_BIT | \
- ACTLR_EL3_CPUACTLR_BIT)
-#define ACTLR_EL3_ENABLE_ALL_ACCESS (ACTLR_EL3_L2ACTLR_BIT | \
- ACTLR_EL3_L2ECTLR_BIT | \
- ACTLR_EL3_L2CTLR_BIT | \
- ACTLR_EL3_CPUECTLR_BIT | \
- ACTLR_EL3_CPUACTLR_BIT)
+#define ACTLR_ELx_L2ACTLR_BIT (U(1) << 6)
+#define ACTLR_ELx_L2ECTLR_BIT (U(1) << 5)
+#define ACTLR_ELx_L2CTLR_BIT (U(1) << 4)
+#define ACTLR_ELx_CPUECTLR_BIT (U(1) << 1)
+#define ACTLR_ELx_CPUACTLR_BIT (U(1) << 0)
+#define ACTLR_ELx_ENABLE_ALL_ACCESS (ACTLR_ELx_L2ACTLR_BIT | \
+ ACTLR_ELx_L2ECTLR_BIT | \
+ ACTLR_ELx_L2CTLR_BIT | \
+ ACTLR_ELx_CPUECTLR_BIT | \
+ ACTLR_ELx_CPUACTLR_BIT)
/* Global functions */
.globl plat_is_my_cpu_primary
@@ -93,15 +89,11 @@
* -------------------------------------------------------
*/
mrs x0, actlr_el3
- mov x1, #ACTLR_EL3_ENABLE_ALL_MASK
- bic x0, x0, x1
- mov x1, #ACTLR_EL3_ENABLE_ALL_ACCESS
+ mov x1, #ACTLR_ELx_ENABLE_ALL_ACCESS
orr x0, x0, x1
msr actlr_el3, x0
mrs x0, actlr_el2
- mov x1, #ACTLR_EL3_ENABLE_ALL_MASK
- bic x0, x0, x1
- mov x1, #ACTLR_EL3_ENABLE_ALL_ACCESS
+ mov x1, #ACTLR_ELx_ENABLE_ALL_ACCESS
orr x0, x0, x1
msr actlr_el2, x0
isb
diff --git a/plat/nvidia/tegra/common/drivers/spe/shared_console.S b/plat/nvidia/tegra/common/drivers/spe/shared_console.S
index 0be34e417..6df73ec24 100644
--- a/plat/nvidia/tegra/common/drivers/spe/shared_console.S
+++ b/plat/nvidia/tegra/common/drivers/spe/shared_console.S
@@ -49,14 +49,14 @@
/* -------------------------------------------------
* int console_spe_register(uintptr_t baseaddr,
* uint32_t clock, uint32_t baud,
- * console_spe_t *console);
+ * console_t *console);
* Function to initialize and register a new spe
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
* In: x0 - UART register base address
* w1 - UART clock in Hz
* w2 - Baud rate
- * x3 - pointer to empty console_spe_t struct
+ * x3 - pointer to empty console_t struct
* Out: return 1 on success, 0 on error
* Clobber list : x0, x1, x2, x6, x7, x14
* -------------------------------------------------
@@ -69,7 +69,7 @@ func console_spe_register
check_if_console_is_ready x0, x1, x2, register_fail
cbz x3, register_fail
- str x0, [x3, #CONSOLE_T_DRVDATA]
+ str x0, [x3, #CONSOLE_T_BASE]
mov x0, x3
finish_console_register spe putc=1, getc=1, flush=1
@@ -122,7 +122,7 @@ putc_error:
endfunc console_spe_core_putc
/* --------------------------------------------------------
- * int console_spe_putc(int c, console_spe_t *console)
+ * int console_spe_putc(int c, console_t *console)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : w0 - character to be printed
@@ -132,12 +132,12 @@ endfunc console_spe_core_putc
* --------------------------------------------------------
*/
func console_spe_putc
- ldr x1, [x1, #CONSOLE_T_DRVDATA]
+ ldr x1, [x1, #CONSOLE_T_BASE]
b console_spe_core_putc
endfunc console_spe_putc
/* ---------------------------------------------
- * int console_spe_getc(console_spe_t *console)
+ * int console_spe_getc(console_t *console)
* Function to get a character from the console.
* It returns the character grabbed on success
* or -1 if no character is available.
@@ -174,7 +174,7 @@ flush_error:
endfunc console_spe_core_flush
/* ---------------------------------------------
- * int console_spe_flush(console_spe_t *console)
+ * int console_spe_flush(console_t *console)
* Function to force a write of all buffered
* data that hasn't been output.
* In : x0 - pointer to console_t structure
@@ -183,6 +183,6 @@ endfunc console_spe_core_flush
* ---------------------------------------------
*/
func console_spe_flush
- ldr x0, [x0, #CONSOLE_T_DRVDATA]
+ ldr x0, [x0, #CONSOLE_T_BASE]
b console_spe_core_flush
endfunc console_spe_flush
diff --git a/plat/nvidia/tegra/common/tegra_fiq_glue.c b/plat/nvidia/tegra/common/tegra_fiq_glue.c
index 60b559556..dee99fb13 100644
--- a/plat/nvidia/tegra/common/tegra_fiq_glue.c
+++ b/plat/nvidia/tegra/common/tegra_fiq_glue.c
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,7 +13,6 @@
#include <common/debug.h>
#include <context.h>
#include <denver.h>
-#include <lib/bakery_lock.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <plat/common/platform.h>
@@ -25,8 +25,6 @@
/* Legacy FIQ used by earlier Tegra platforms */
#define LEGACY_FIQ_PPI_WDT 28U
-static DEFINE_BAKERY_LOCK(tegra_fiq_lock);
-
/*******************************************************************************
* Static variables
******************************************************************************/
@@ -57,8 +55,6 @@ static uint64_t tegra_fiq_interrupt_handler(uint32_t id,
*/
irq = plat_ic_get_pending_interrupt_id();
- bakery_lock_get(&tegra_fiq_lock);
-
/*
* Jump to NS world only if the NS world's FIQ handler has
* been registered
@@ -107,8 +103,6 @@ static uint64_t tegra_fiq_interrupt_handler(uint32_t id,
plat_ic_end_of_interrupt(irq);
}
- bakery_lock_release(&tegra_fiq_lock);
-
return 0;
}
@@ -155,7 +149,7 @@ int32_t tegra_fiq_get_intr_context(void)
{
cpu_context_t *ctx = cm_get_context(NON_SECURE);
gp_regs_t *gpregs_ctx = get_gpregs_ctx(ctx);
- const el1_sys_regs_t *el1state_ctx = get_sysregs_ctx(ctx);
+ const el1_sysregs_t *el1state_ctx = get_el1_sysregs_ctx(ctx);
uint32_t cpu = plat_my_core_pos();
uint64_t val;
diff --git a/plat/nvidia/tegra/include/drivers/pmc.h b/plat/nvidia/tegra/include/drivers/pmc.h
index 32252a28b..8752b84c6 100644
--- a/plat/nvidia/tegra/include/drivers/pmc.h
+++ b/plat/nvidia/tegra/include/drivers/pmc.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
*/
@@ -18,27 +19,37 @@
#define PMC_DPD_ENABLE_0 U(0x24)
#define PMC_PWRGATE_STATUS U(0x38)
#define PMC_PWRGATE_TOGGLE U(0x30)
-#define PMC_SECURE_SCRATCH0 U(0xb0)
-#define PMC_SECURE_SCRATCH5 U(0xc4)
+#define PMC_SCRATCH1 U(0x54)
#define PMC_CRYPTO_OP_0 U(0xf4)
#define PMC_TOGGLE_START U(0x100)
+#define PMC_SCRATCH31 U(0x118)
+#define PMC_SCRATCH32 U(0x11C)
+#define PMC_SCRATCH33 U(0x120)
#define PMC_SCRATCH39 U(0x138)
+#define PMC_SCRATCH40 U(0x13C)
#define PMC_SCRATCH41 U(0x140)
-#define PMC_SECURE_SCRATCH6 U(0x224)
-#define PMC_SECURE_SCRATCH7 U(0x228)
-#define PMC_SECURE_DISABLE2 U(0x2c4)
+#define PMC_SCRATCH42 U(0x144)
+#define PMC_SCRATCH43 U(0x22C)
+#define PMC_SCRATCH44 U(0x230)
+#define PMC_SCRATCH45 U(0x234)
+#define PMC_SCRATCH46 U(0x238)
+#define PMC_SCRATCH47 U(0x23C)
+#define PMC_SCRATCH48 U(0x240)
+#define PMC_SCRATCH50 U(0x248)
+#define PMC_SCRATCH51 U(0x24C)
+#define PMC_TSC_MULT_0 U(0x2B4)
+#define PMC_STICKY_BIT U(0x2C0)
+#define PMC_SECURE_DISABLE2 U(0x2C4)
#define PMC_SECURE_DISABLE2_WRITE22_ON (U(1) << 28)
-#define PMC_SECURE_SCRATCH8 U(0x300)
-#define PMC_SECURE_SCRATCH79 U(0x41c)
#define PMC_FUSE_CONTROL_0 U(0x450)
-#define PMC_SECURE_SCRATCH22 U(0x338)
-#define PMC_SECURE_DISABLE3 U(0x2d8)
+#define PMC_SECURE_DISABLE3 U(0x2D8)
#define PMC_SECURE_DISABLE3_WRITE34_ON (U(1) << 20)
#define PMC_SECURE_DISABLE3_WRITE35_ON (U(1) << 22)
+#define PMC_SECURE_SCRATCH22 U(0x338)
#define PMC_SECURE_SCRATCH34 U(0x368)
#define PMC_SECURE_SCRATCH35 U(0x36c)
-#define PMC_SECURE_SCRATCH80 U(0xa98)
-#define PMC_SECURE_SCRATCH119 U(0xb34)
+#define PMC_SCRATCH56 U(0x600)
+#define PMC_SCRATCH57 U(0x604)
#define PMC_SCRATCH201 U(0x844)
static inline uint32_t tegra_pmc_read_32(uint32_t off)
diff --git a/plat/nvidia/tegra/include/drivers/security_engine.h b/plat/nvidia/tegra/include/drivers/security_engine.h
index 8a249249b..5ae625793 100644
--- a/plat/nvidia/tegra/include/drivers/security_engine.h
+++ b/plat/nvidia/tegra/include/drivers/security_engine.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -55,5 +55,6 @@ void tegra_se_init(void);
int tegra_se_suspend(void);
void tegra_se_resume(void);
int tegra_se_save_tzram(void);
+int32_t tegra_se_save_sha256_hash(uint64_t bl31_base, uint32_t src_len_inbyte);
#endif /* SECURITY_ENGINE_H */
diff --git a/plat/nvidia/tegra/include/drivers/spe.h b/plat/nvidia/tegra/include/drivers/spe.h
index 0d6d69d10..e0f871408 100644
--- a/plat/nvidia/tegra/include/drivers/spe.h
+++ b/plat/nvidia/tegra/include/drivers/spe.h
@@ -11,11 +11,6 @@
#include <drivers/console.h>
-typedef struct {
- console_t console;
- uintptr_t base;
-} console_spe_t;
-
/*
* Initialize a new spe console instance and register it with the console
* framework. The |console| pointer must point to storage that will be valid
@@ -23,6 +18,6 @@ typedef struct {
* Its contents will be reinitialized from scratch.
*/
int console_spe_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
- console_spe_t *console);
+ console_t *console);
#endif /* SPE_H */
diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h
index f2a2334ef..3d037e134 100644
--- a/plat/nvidia/tegra/include/t186/tegra_def.h
+++ b/plat/nvidia/tegra/include/t186/tegra_def.h
@@ -213,6 +213,14 @@
#define RNG_MUTEX_WATCHDOG_NS_LIMIT U(0xFE0)
/*******************************************************************************
+ * Tegra HSP doorbell #0 constants
+ ******************************************************************************/
+#define TEGRA_HSP_DBELL_BASE U(0x03C90000)
+#define HSP_DBELL_1_ENABLE U(0x104)
+#define HSP_DBELL_3_TRIGGER U(0x300)
+#define HSP_DBELL_3_ENABLE U(0x304)
+
+/*******************************************************************************
* Tegra Clock and Reset Controller constants
******************************************************************************/
#define TEGRA_CAR_RESET_BASE U(0x05000000)
@@ -238,6 +246,7 @@
* Tegra scratch registers constants
******************************************************************************/
#define TEGRA_SCRATCH_BASE U(0x0C390000)
+#define SECURE_SCRATCH_RSV0_HI U(0x654)
#define SECURE_SCRATCH_RSV1_LO U(0x658)
#define SECURE_SCRATCH_RSV1_HI U(0x65C)
#define SECURE_SCRATCH_RSV6 U(0x680)
@@ -247,6 +256,15 @@
#define SECURE_SCRATCH_RSV53_HI U(0x7FC)
#define SECURE_SCRATCH_RSV55_LO U(0x808)
#define SECURE_SCRATCH_RSV55_HI U(0x80C)
+#define SECURE_SCRATCH_RSV63_LO U(0x848)
+#define SECURE_SCRATCH_RSV63_HI U(0x84C)
+#define SECURE_SCRATCH_RSV64_LO U(0x850)
+#define SECURE_SCRATCH_RSV64_HI U(0x854)
+#define SECURE_SCRATCH_RSV65_LO U(0x858)
+#define SECURE_SCRATCH_RSV65_HI U(0x85c)
+#define SECURE_SCRATCH_RSV66_LO U(0x860)
+#define SECURE_SCRATCH_RSV66_HI U(0x864)
+#define SECURE_SCRATCH_RSV68_LO U(0x870)
#define SCRATCH_RESET_VECTOR_LO SECURE_SCRATCH_RSV1_LO
#define SCRATCH_RESET_VECTOR_HI SECURE_SCRATCH_RSV1_HI
@@ -281,6 +299,13 @@
#define TEGRA_TZRAM_SIZE U(0x40000)
/*******************************************************************************
+ * Tegra CCPLEX-BPMP IPC constants
+ ******************************************************************************/
+#define TEGRA_BPMP_IPC_TX_PHYS_BASE U(0x3004C000)
+#define TEGRA_BPMP_IPC_RX_PHYS_BASE U(0x3004D000)
+#define TEGRA_BPMP_IPC_CH_MAP_SIZE U(0x1000) /* 4KB */
+
+/*******************************************************************************
* Tegra DRAM memory base address
******************************************************************************/
#define TEGRA_DRAM_BASE ULL(0x80000000)
diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h
index 4a39aa1fb..e8bce5e05 100644
--- a/plat/nvidia/tegra/include/t210/tegra_def.h
+++ b/plat/nvidia/tegra/include/t210/tegra_def.h
@@ -144,6 +144,9 @@
#define SE_CLK_ENB_BIT (U(1) << 31)
#define TEGRA_CLK_OUT_ENB_W U(0x364)
#define ENTROPY_RESET_BIT (U(1) << 21)
+#define TEGRA_CLK_RST_CTL_CLK_SRC_SE U(0x42C)
+#define SE_CLK_SRC_MASK (U(7) << 29)
+#define SE_CLK_SRC_CLK_M (U(6) << 29)
#define TEGRA_RST_DEV_SET_V U(0x430)
#define SE_RESET_BIT (U(1) << 31)
#define HDA_RESET_BIT (U(1) << 29)
diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c
index 4bfc2de0e..43acdd642 100644
--- a/plat/nvidia/tegra/soc/t132/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t132/plat_setup.c
@@ -92,7 +92,7 @@ static uint32_t tegra132_uart_addresses[TEGRA132_MAX_UART_PORTS + 1] = {
******************************************************************************/
void plat_enable_console(int32_t id)
{
- static console_16550_t uart_console;
+ static console_t uart_console;
uint32_t console_clock;
if ((id > 0) && (id < TEGRA132_MAX_UART_PORTS)) {
@@ -109,7 +109,7 @@ void plat_enable_console(int32_t id)
console_clock,
TEGRA_CONSOLE_BAUDRATE,
&uart_console);
- console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT |
+ console_set_scope(&uart_console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
}
}
diff --git a/plat/nvidia/tegra/soc/t186/drivers/se/se.c b/plat/nvidia/tegra/soc/t186/drivers/se/se.c
new file mode 100644
index 000000000..dfb9de882
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t186/drivers/se/se.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <drivers/delay_timer.h>
+#include <errno.h>
+#include <string.h>
+
+#include <bpmp_ipc.h>
+#include <pmc.h>
+#include <security_engine.h>
+#include <tegra186_private.h>
+#include <tegra_private.h>
+
+#include "se_private.h"
+
+/*******************************************************************************
+ * Constants and Macros
+ ******************************************************************************/
+#define SE0_MAX_BUSY_TIMEOUT_MS U(100) /* 100ms */
+#define BYTES_IN_WORD U(4)
+#define SHA256_MAX_HASH_RESULT U(7)
+#define SHA256_DST_SIZE U(32)
+#define SHA_FIRST_OP U(1)
+#define MAX_SHA_ENGINE_CHUNK_SIZE U(0xFFFFFF)
+#define SHA256_MSG_LENGTH_ONETIME U(0xffff)
+
+/*
+ * Check that SE operation has completed after kickoff
+ * This function is invoked after an SE operation has been started,
+ * and it checks the following conditions:
+ * 1. SE0_INT_STATUS = SE0_OP_DONE
+ * 2. SE0_STATUS = IDLE
+ * 3. SE0_ERR_STATUS is clean.
+ */
+static int32_t tegra_se_operation_complete(void)
+{
+ uint32_t val = 0U;
+
+ /* Read SE0 interrupt register to ensure H/W operation complete */
+ val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET);
+ if (SE0_INT_OP_DONE(val) == SE0_INT_OP_DONE_CLEAR) {
+ ERROR("%s: Engine busy state too many times! val = 0x%x\n",
+ __func__, val);
+ return -ETIMEDOUT;
+ }
+
+ /* Read SE0 status idle to ensure H/W operation complete */
+ val = tegra_se_read_32(SE0_SHA_STATUS_0);
+ if (val != SE0_SHA_STATUS_IDLE) {
+ ERROR("%s: Idle state timeout! val = 0x%x\n", __func__,
+ val);
+ return -ETIMEDOUT;
+ }
+
+ /* Ensure that no errors are thrown during operation */
+ val = tegra_se_read_32(SE0_ERR_STATUS_REG_OFFSET);
+ if (val != SE0_ERR_STATUS_CLEAR) {
+ ERROR("%s: Error during SE operation! val = 0x%x",
+ __func__, val);
+ return -ENOTSUP;
+ }
+
+ return 0;
+}
+
+/*
+ * Security engine primitive normal operations
+ */
+static int32_t tegra_se_start_normal_operation(uint64_t src_addr,
+ uint32_t nbytes, uint32_t last_buf, uint32_t src_len_inbytes)
+{
+ int32_t ret = 0;
+ uint32_t val = 0U;
+ uint32_t src_in_lo;
+ uint32_t src_in_msb;
+ uint32_t src_in_hi;
+
+ if ((src_addr == 0UL) || (nbytes == 0U))
+ return -EINVAL;
+
+ src_in_lo = (uint32_t)src_addr;
+ src_in_msb = ((uint32_t)(src_addr >> 32U) & 0xffU);
+ src_in_hi = ((src_in_msb << SE0_IN_HI_ADDR_HI_0_MSB_SHIFT) |
+ (nbytes & 0xffffffU));
+
+ /* set SRC_IN_ADDR_LO and SRC_IN_ADDR_HI*/
+ tegra_se_write_32(SE0_IN_ADDR, src_in_lo);
+ tegra_se_write_32(SE0_IN_HI_ADDR_HI, src_in_hi);
+
+ val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET);
+ if (val > 0U) {
+ tegra_se_write_32(SE0_INT_STATUS_REG_OFFSET, 0x00000U);
+ }
+
+ /* Enable SHA interrupt for SE0 Operation */
+ tegra_se_write_32(SE0_SHA_INT_ENABLE, 0x1aU);
+
+ /* flush to DRAM for SE to use the updated contents */
+ flush_dcache_range(src_addr, src_len_inbytes);
+
+ /* Start SHA256 operation */
+ if (last_buf == 1U) {
+ tegra_se_write_32(SE0_OPERATION_REG_OFFSET, SE0_OP_START |
+ SE0_UNIT_OPERATION_PKT_LASTBUF_FIELD);
+ } else {
+ tegra_se_write_32(SE0_OPERATION_REG_OFFSET, SE0_OP_START);
+ }
+
+ /* Wait for SE-operation to finish */
+ udelay(SE0_MAX_BUSY_TIMEOUT_MS * 100U);
+
+ /* Check SE0 operation status */
+ ret = tegra_se_operation_complete();
+ if (ret != 0) {
+ ERROR("SE operation complete Failed! 0x%x", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int32_t tegra_se_calculate_sha256_hash(uint64_t src_addr,
+ uint32_t src_len_inbyte)
+{
+ uint32_t val, last_buf, i;
+ int32_t ret = 0;
+ uint32_t operations;
+ uint64_t src_len_inbits;
+ uint32_t len_bits_msb;
+ uint32_t len_bits_lsb;
+ uint32_t number_of_operations, max_bytes, bytes_left, remaining_bytes;
+
+ if (src_len_inbyte > MAX_SHA_ENGINE_CHUNK_SIZE) {
+ ERROR("SHA input chunk size too big: 0x%x\n", src_len_inbyte);
+ return -EINVAL;
+ }
+
+ if (src_addr == 0UL) {
+ return -EINVAL;
+ }
+
+ /* number of bytes per operation */
+ max_bytes = SHA256_HASH_SIZE_BYTES * SHA256_MSG_LENGTH_ONETIME;
+
+ src_len_inbits = src_len_inbyte * 8U;
+ len_bits_msb = (uint32_t)(src_len_inbits >> 32U);
+ len_bits_lsb = (uint32_t)(src_len_inbits & 0xFFFFFFFF);
+
+ /* program SE0_CONFIG for SHA256 operation */
+ val = SE0_CONFIG_ENC_ALG_SHA | SE0_CONFIG_ENC_MODE_SHA256 |
+ SE0_CONFIG_DEC_ALG_NOP | SE0_CONFIG_DST_HASHREG;
+ tegra_se_write_32(SE0_SHA_CONFIG, val);
+
+ /* set SE0_SHA_MSG_LENGTH registers */
+ tegra_se_write_32(SE0_SHA_MSG_LENGTH_0, len_bits_lsb);
+ tegra_se_write_32(SE0_SHA_MSG_LEFT_0, len_bits_lsb);
+ tegra_se_write_32(SE0_SHA_MSG_LENGTH_1, len_bits_msb);
+
+ /* zero out unused SE0_SHA_MSG_LENGTH and SE0_SHA_MSG_LEFT */
+ tegra_se_write_32(SE0_SHA_MSG_LENGTH_2, 0U);
+ tegra_se_write_32(SE0_SHA_MSG_LENGTH_3, 0U);
+ tegra_se_write_32(SE0_SHA_MSG_LEFT_1, 0U);
+ tegra_se_write_32(SE0_SHA_MSG_LEFT_2, 0U);
+ tegra_se_write_32(SE0_SHA_MSG_LEFT_3, 0U);
+
+ number_of_operations = src_len_inbyte / max_bytes;
+ remaining_bytes = src_len_inbyte % max_bytes;
+ if (remaining_bytes > 0U) {
+ number_of_operations += 1U;
+ }
+
+ /*
+ * 1. Operations == 1: program SE0_SHA_TASK register to initiate SHA256
+ * hash generation by setting
+ * 1(SE0_SHA_CONFIG_HW_INIT_HASH) to SE0_SHA_TASK
+ * and start SHA256-normal operation.
+ * 2. 1 < Operations < number_of_operations: program SE0_SHA_TASK to
+ * 0(SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE) to load
+ * intermediate SHA256 digest result from
+ * HASH_RESULT register to continue SHA256
+ * generation and start SHA256-normal operation.
+ * 3. Operations == number_of_operations: continue with step 2 and set
+ * max_bytes to bytes_left to process final
+ * hash-result generation and
+ * start SHA256-normal operation.
+ */
+ bytes_left = src_len_inbyte;
+ for (operations = 1U; operations <= number_of_operations;
+ operations++) {
+ if (operations == SHA_FIRST_OP) {
+ val = SE0_SHA_CONFIG_HW_INIT_HASH;
+ } else {
+ /* Load intermediate SHA digest result to
+ * SHA:HASH_RESULT(0..7) to continue the SHA
+ * calculation and tell the SHA engine to use it.
+ */
+ for (i = 0U; (i / BYTES_IN_WORD) <=
+ SHA256_MAX_HASH_RESULT; i += BYTES_IN_WORD) {
+ val = tegra_se_read_32(SE0_SHA_HASH_RESULT_0 +
+ i);
+ tegra_se_write_32(SE0_SHA_HASH_RESULT_0 + i,
+ val);
+ }
+ val = SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE;
+ if (len_bits_lsb <= (max_bytes * 8U)) {
+ len_bits_lsb = (remaining_bytes * 8U);
+ } else {
+ len_bits_lsb -= (max_bytes * 8U);
+ }
+ tegra_se_write_32(SE0_SHA_MSG_LEFT_0, len_bits_lsb);
+ }
+ tegra_se_write_32(SE0_SHA_TASK_CONFIG, val);
+
+ max_bytes = (SHA256_HASH_SIZE_BYTES *
+ SHA256_MSG_LENGTH_ONETIME);
+ if (bytes_left < max_bytes) {
+ max_bytes = bytes_left;
+ last_buf = 1U;
+ } else {
+ bytes_left = bytes_left - max_bytes;
+ last_buf = 0U;
+ }
+ /* start operation */
+ ret = tegra_se_start_normal_operation(src_addr, max_bytes,
+ last_buf, src_len_inbyte);
+ if (ret != 0) {
+ ERROR("Error during SE operation! 0x%x", ret);
+ return -EINVAL;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * Handler to generate SHA256 and save SHA256 hash to PMC-Scratch register.
+ */
+int32_t tegra_se_save_sha256_hash(uint64_t bl31_base, uint32_t src_len_inbyte)
+{
+ int32_t ret = 0;
+ uint32_t val = 0U, hash_offset = 0U, scratch_offset = 0U, security;
+
+ /*
+ * Set SE_SOFT_SETTINGS=SE_SECURE to prevent NS process to change SE
+ * registers.
+ */
+ security = tegra_se_read_32(SE0_SECURITY);
+ tegra_se_write_32(SE0_SECURITY, security | SE0_SECURITY_SE_SOFT_SETTING);
+
+ ret = tegra_se_calculate_sha256_hash(bl31_base, src_len_inbyte);
+ if (ret != 0L) {
+ ERROR("%s: SHA256 generation failed\n", __func__);
+ return ret;
+ }
+
+ /*
+ * Reset SE_SECURE to previous value.
+ */
+ tegra_se_write_32(SE0_SECURITY, security);
+
+ /* read SHA256_HASH_RESULT and save to PMC Scratch registers */
+ scratch_offset = SECURE_SCRATCH_TZDRAM_SHA256_HASH_START;
+ while (scratch_offset <= SECURE_SCRATCH_TZDRAM_SHA256_HASH_END) {
+
+ val = tegra_se_read_32(SE0_SHA_HASH_RESULT_0 + hash_offset);
+ mmio_write_32(TEGRA_SCRATCH_BASE + scratch_offset, val);
+
+ hash_offset += BYTES_IN_WORD;
+ scratch_offset += BYTES_IN_WORD;
+ }
+
+ return ret;
+}
+
diff --git a/plat/nvidia/tegra/soc/t186/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t186/drivers/se/se_private.h
new file mode 100644
index 000000000..7aa0dd691
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t186/drivers/se/se_private.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SE_PRIVATE_H
+#define SE_PRIVATE_H
+
+#include <lib/utils_def.h>
+
+/* SE0 security register */
+#define SE0_SECURITY U(0x18)
+#define SE0_SECURITY_SE_SOFT_SETTING (((uint32_t)1) << 16U)
+
+/* SE0 config register */
+#define SE0_SHA_CONFIG U(0x104)
+#define SE0_SHA_TASK_CONFIG U(0x108)
+#define SE0_SHA_CONFIG_HW_INIT_HASH ((1U) << 0U)
+#define SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE U(0)
+
+#define SE0_CONFIG_ENC_ALG_SHIFT U(12)
+#define SE0_CONFIG_ENC_ALG_SHA \
+ (((uint32_t)3) << SE0_CONFIG_ENC_ALG_SHIFT)
+#define SE0_CONFIG_DEC_ALG_SHIFT U(8)
+#define SE0_CONFIG_DEC_ALG_NOP \
+ (((uint32_t)0) << SE0_CONFIG_DEC_ALG_SHIFT)
+#define SE0_CONFIG_DST_SHIFT U(2)
+#define SE0_CONFIG_DST_HASHREG \
+ (((uint32_t)1) << SE0_CONFIG_DST_SHIFT)
+#define SHA256_HASH_SIZE_BYTES U(256)
+
+#define SE0_CONFIG_ENC_MODE_SHIFT U(24)
+#define SE0_CONFIG_ENC_MODE_SHA256 \
+ (((uint32_t)5) << SE0_CONFIG_ENC_MODE_SHIFT)
+
+/* SHA input message length */
+#define SE0_SHA_MSG_LENGTH_0 U(0x11c)
+#define SE0_SHA_MSG_LENGTH_1 U(0x120)
+#define SE0_SHA_MSG_LENGTH_2 U(0x124)
+#define SE0_SHA_MSG_LENGTH_3 U(0x128)
+
+/* SHA input message left */
+#define SE0_SHA_MSG_LEFT_0 U(0x12c)
+#define SE0_SHA_MSG_LEFT_1 U(0x130)
+#define SE0_SHA_MSG_LEFT_2 U(0x134)
+#define SE0_SHA_MSG_LEFT_3 U(0x138)
+
+/* SE Hash Result */
+#define SE0_SHA_HASH_RESULT_0 U(0x13c)
+
+/* SE OPERATION */
+#define SE0_OPERATION_REG_OFFSET U(0x17c)
+#define SE0_UNIT_OPERATION_PKT_LASTBUF_SHIFT U(16)
+#define SE0_UNIT_OPERATION_PKT_LASTBUF_FIELD \
+ (((uint32_t)0x1) << SE0_UNIT_OPERATION_PKT_LASTBUF_SHIFT)
+#define SE0_OPERATION_SHIFT U(0)
+#define SE0_OP_START \
+ (((uint32_t)0x1) << SE0_OPERATION_SHIFT)
+
+/* SE Interrupt */
+#define SE0_SHA_INT_ENABLE U(0x180)
+
+#define SE0_INT_STATUS_REG_OFFSET U(0x184)
+#define SE0_INT_OP_DONE_SHIFT U(4)
+#define SE0_INT_OP_DONE_CLEAR \
+ (((uint32_t)0) << SE0_INT_OP_DONE_SHIFT)
+#define SE0_INT_OP_DONE(x) \
+ ((x) & (((uint32_t)0x1) << SE0_INT_OP_DONE_SHIFT))
+
+/* SE SHA status */
+#define SE0_SHA_STATUS_0 U(0x188)
+#define SE0_SHA_STATUS_IDLE U(0)
+
+/* SE error status */
+#define SE0_ERR_STATUS_REG_OFFSET U(0x18c)
+#define SE0_ERR_STATUS_CLEAR U(0)
+#define SE0_IN_ADDR U(0x10c)
+#define SE0_IN_HI_ADDR_HI U(0x110)
+#define SE0_IN_HI_ADDR_HI_0_MSB_SHIFT U(24)
+
+/* SE error status */
+#define SECURE_SCRATCH_TZDRAM_SHA256_HASH_START SECURE_SCRATCH_RSV63_LO
+#define SECURE_SCRATCH_TZDRAM_SHA256_HASH_END SECURE_SCRATCH_RSV66_HI
+
+/*******************************************************************************
+ * Inline functions definition
+ ******************************************************************************/
+
+static inline uint32_t tegra_se_read_32(uint32_t 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(((uint32_t)(TEGRA_SE0_BASE + offset)), val);
+}
+
+#endif /* SE_PRIVATE_H */
diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
index 4ca5e77ad..a97496bd1 100644
--- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c
+++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,7 +11,11 @@
#include <mce.h>
#include <memctrl_v2.h>
#include <tegra_mc_def.h>
+#include <tegra186_private.h>
#include <tegra_platform.h>
+#include <tegra_private.h>
+
+extern uint64_t tegra_bl31_phys_base;
/*******************************************************************************
* Array to hold stream_id override config register offsets
@@ -540,6 +545,13 @@ tegra_mc_settings_t *tegra_get_mc_settings(void)
void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
{
uint32_t val;
+ uint64_t src_base_tzdram;
+ const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+ uint64_t src_len_in_bytes = BL31_END - BL31_START;
+
+ /* base address of BL3-1 source in TZDRAM */
+ src_base_tzdram = params_from_bl2->tzdram_base +
+ tegra186_get_cpu_reset_handler_size();
/*
* Setup the Memory controller to allow only secure accesses to
@@ -569,6 +581,15 @@ void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_TZDRAM_ADDR_HI, val);
/*
+ * save tzdram_addr_lo and ATF-size, this would be used in SC7-RF to
+ * generate SHA256.
+ */
+ mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV68_LO,
+ (uint32_t)src_base_tzdram);
+ mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV0_HI,
+ (uint32_t)src_len_in_bytes);
+
+ /*
* MCE propagates the security configuration values across the
* CCPLEX.
*/
diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
index 2000e53fd..a0879cc0d 100644
--- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
@@ -6,6 +6,7 @@
*/
#include <assert.h>
+#include <stdbool.h>
#include <string.h>
#include <arch.h>
@@ -19,9 +20,10 @@
#include <lib/psci/psci.h>
#include <plat/common/platform.h>
+#include <bpmp_ipc.h>
#include <mce.h>
+#include <security_engine.h>
#include <smmu.h>
-#include <stdbool.h>
#include <t18x_ari.h>
#include <tegra186_private.h>
#include <tegra_private.h>
@@ -280,8 +282,33 @@ 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] &
TEGRA186_STATE_ID_MASK;
uint64_t val;
+ uint64_t src_len_in_bytes = (uint64_t)(((uintptr_t)(&__BL31_END__) -
+ (uintptr_t)BL31_BASE));
+ int32_t ret;
if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+ val = params_from_bl2->tzdram_base +
+ tegra186_get_cpu_reset_handler_size();
+
+ /* Initialise communication channel with BPMP */
+ assert(tegra_bpmp_ipc_init() == 0);
+
+ /* Enable SE clock */
+ ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE);
+ if (ret != 0) {
+ ERROR("Failed to enable clock\n");
+ return ret;
+ }
+
+ /*
+ * Generate/save SHA256 of ATF during SC7 entry
+ */
+ if (tegra_se_save_sha256_hash(BL31_BASE,
+ (uint32_t)src_len_in_bytes) != 0) {
+ ERROR("Hash calculation failed. Reboot\n");
+ (void)tegra_soc_prepare_system_reset();
+ }
+
/*
* The TZRAM loses power when we enter system suspend. To
* allow graceful exit from system suspend, we need to copy
@@ -291,6 +318,12 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta
tegra186_get_cpu_reset_handler_size();
memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE,
(uintptr_t)BL31_END - (uintptr_t)BL31_BASE);
+
+ ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE);
+ if (ret != 0) {
+ ERROR("Failed to disable clock\n");
+ return ret;
+ }
}
return PSCI_E_SUCCESS;
diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c
index 06a328427..e5d0d0133 100644
--- a/plat/nvidia/tegra/soc/t186/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t186/plat_setup.c
@@ -106,6 +106,12 @@ static const mmap_region_t tegra_mmap[] = {
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(TEGRA_SMMU0_BASE, 0x1000000U, /* 64KB */
MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(TEGRA_HSP_DBELL_BASE, 0x10000U, /* 64KB */
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(TEGRA_BPMP_IPC_TX_PHYS_BASE, TEGRA_BPMP_IPC_CH_MAP_SIZE, /* 4KB */
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(TEGRA_BPMP_IPC_RX_PHYS_BASE, TEGRA_BPMP_IPC_CH_MAP_SIZE, /* 4KB */
+ MT_DEVICE | MT_RW | MT_SECURE),
{0}
};
@@ -150,7 +156,7 @@ static uint32_t tegra186_uart_addresses[TEGRA186_MAX_UART_PORTS + 1] = {
******************************************************************************/
void plat_enable_console(int32_t id)
{
- static console_16550_t uart_console;
+ static console_t uart_console;
uint32_t console_clock;
if ((id > 0) && (id < TEGRA186_MAX_UART_PORTS)) {
@@ -167,7 +173,7 @@ void plat_enable_console(int32_t id)
console_clock,
TEGRA_CONSOLE_BAUDRATE,
&uart_console);
- console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT |
+ console_set_scope(&uart_console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
}
}
diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk
index 197e4c6ba..d79155f31 100644
--- a/plat/nvidia/tegra/soc/t186/platform_t186.mk
+++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk
@@ -30,10 +30,10 @@ $(eval $(call add_define,PLATFORM_CLUSTER_COUNT))
PLATFORM_MAX_CPUS_PER_CLUSTER := 4
$(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER))
-MAX_XLAT_TABLES := 24
+MAX_XLAT_TABLES := 25
$(eval $(call add_define,MAX_XLAT_TABLES))
-MAX_MMAP_REGIONS := 25
+MAX_MMAP_REGIONS := 27
$(eval $(call add_define,MAX_MMAP_REGIONS))
# platform files
@@ -42,6 +42,8 @@ PLAT_INCLUDES += -I${SOC_DIR}/drivers/include
BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
lib/cpus/aarch64/denver.S \
lib/cpus/aarch64/cortex_a57.S \
+ ${COMMON_DIR}/drivers/bpmp_ipc/intf.c \
+ ${COMMON_DIR}/drivers/bpmp_ipc/ivc.c \
${COMMON_DIR}/drivers/gpcdma/gpcdma.c \
${COMMON_DIR}/drivers/memctrl/memctrl_v2.c \
${COMMON_DIR}/drivers/smmu/smmu.c \
@@ -49,6 +51,7 @@ BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
${SOC_DIR}/drivers/mce/ari.c \
${SOC_DIR}/drivers/mce/nvg.c \
${SOC_DIR}/drivers/mce/aarch64/nvg_helpers.S \
+ $(SOC_DIR)/drivers/se/se.c \
${SOC_DIR}/plat_memctrl.c \
${SOC_DIR}/plat_psci_handlers.c \
${SOC_DIR}/plat_setup.c \
diff --git a/plat/nvidia/tegra/soc/t194/plat_memctrl.c b/plat/nvidia/tegra/soc/t194/plat_memctrl.c
index 2208b85e7..d5f72b614 100644
--- a/plat/nvidia/tegra/soc/t194/plat_memctrl.c
+++ b/plat/nvidia/tegra/soc/t194/plat_memctrl.c
@@ -138,7 +138,11 @@ const static uint32_t tegra194_streamid_override_regs[] = {
MC_STREAMID_OVERRIDE_CFG_MIU2R,
MC_STREAMID_OVERRIDE_CFG_MIU2W,
MC_STREAMID_OVERRIDE_CFG_MIU3R,
- MC_STREAMID_OVERRIDE_CFG_MIU3W
+ MC_STREAMID_OVERRIDE_CFG_MIU3W,
+ MC_STREAMID_OVERRIDE_CFG_MIU4R,
+ MC_STREAMID_OVERRIDE_CFG_MIU4W,
+ MC_STREAMID_OVERRIDE_CFG_MIU5R,
+ MC_STREAMID_OVERRIDE_CFG_MIU5W
};
/*******************************************************************************
@@ -268,416 +272,13 @@ const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = {
mc_make_sec_cfg(MIU2R, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(MIU2W, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(MIU3R, NON_SECURE, OVERRIDE, DISABLE),
- mc_make_sec_cfg(MIU3W, NON_SECURE, OVERRIDE, DISABLE)
+ mc_make_sec_cfg(MIU3W, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(MIU4R, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(MIU4W, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(MIU5R, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(MIU5W, NON_SECURE, OVERRIDE, DISABLE)
};
-/* To be called by common memctrl_v2.c */
-static void tegra194_memctrl_reconfig_mss_clients(void)
-{
- uint32_t reg_val, wdata_0, wdata_1, wdata_2;
-
- wdata_0 = MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB;
- if (tegra_platform_is_silicon()) {
- wdata_0 |= MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB;
- }
-
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
-
- /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
- do {
- reg_val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
- } while ((reg_val & wdata_0) != wdata_0);
-
- wdata_1 = MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB|
- MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_VIFAL_FLUSH_ENB;
- if (tegra_platform_is_silicon()) {
- wdata_1 |= MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_RCE_FLUSH_ENB;
- }
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
- /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
- do {
- reg_val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
- } while ((reg_val & wdata_1) != wdata_1);
-
- wdata_2 = MC_CLIENT_HOTRESET_CTRL2_PCIE_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_AONDMA_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_BPMPDMA_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_SCEDMA_FLUSH_ENB;
- if (tegra_platform_is_silicon()) {
- wdata_2 |= MC_CLIENT_HOTRESET_CTRL2_RCEDMA_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_PCIE_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_PCIE5A_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_PCIE3A_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_PCIE3_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_PCIE0A_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_PCIE0A2_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_PCIE4A_FLUSH_ENB;
- }
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL2, wdata_2);
- /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
- do {
- reg_val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS2);
- } while ((reg_val & wdata_2) != wdata_2);
-
- /*
- * Change MEMTYPE_OVERRIDE from SO_DEV -> PASSTHRU for boot and
- * strongly ordered MSS clients.
- *
- * MC clients with default SO_DEV override still enabled at TSA:
- * EQOSW, SATAW, XUSB_DEVW, XUSB_HOSTW, PCIe0w, PCIe1w, PCIe2w,
- * PCIe3w, PCIe4w and PCIe5w.
- */
- mc_set_tsa_w_passthrough(AONDMAW);
- mc_set_tsa_w_passthrough(AONW);
- mc_set_tsa_w_passthrough(APEDMAW);
- mc_set_tsa_w_passthrough(APEW);
- mc_set_tsa_w_passthrough(AXISW);
- mc_set_tsa_w_passthrough(BPMPDMAW);
- mc_set_tsa_w_passthrough(BPMPW);
- mc_set_tsa_w_passthrough(EQOSW);
- mc_set_tsa_w_passthrough(ETRW);
- mc_set_tsa_w_passthrough(RCEDMAW);
- mc_set_tsa_w_passthrough(RCEW);
- mc_set_tsa_w_passthrough(SCEDMAW);
- mc_set_tsa_w_passthrough(SCEW);
- mc_set_tsa_w_passthrough(SDMMCW);
- mc_set_tsa_w_passthrough(SDMMCWA);
- mc_set_tsa_w_passthrough(SDMMCWAB);
- mc_set_tsa_w_passthrough(SESWR);
- mc_set_tsa_w_passthrough(TSECSWR);
- mc_set_tsa_w_passthrough(TSECSWRB);
- mc_set_tsa_w_passthrough(UFSHCW);
- mc_set_tsa_w_passthrough(VICSWR);
- mc_set_tsa_w_passthrough(VIFALW);
- /*
- * set HUB2 as SO_DEV_HUBID
- */
- reg_val = tsa_read_32(PCIE0W);
- mc_set_tsa_hub2(reg_val, PCIE0W);
- reg_val = tsa_read_32(PCIE1W);
- mc_set_tsa_hub2(reg_val, PCIE1W);
- reg_val = tsa_read_32(PCIE2AW);
- mc_set_tsa_hub2(reg_val, PCIE2AW);
- reg_val = tsa_read_32(PCIE3W);
- mc_set_tsa_hub2(reg_val, PCIE3W);
- reg_val = tsa_read_32(PCIE4W);
- mc_set_tsa_hub2(reg_val, PCIE4W);
- reg_val = tsa_read_32(SATAW);
- mc_set_tsa_hub2(reg_val, SATAW);
- reg_val = tsa_read_32(XUSB_DEVW);
- mc_set_tsa_hub2(reg_val, XUSB_DEVW);
- reg_val = tsa_read_32(XUSB_HOSTW);
- mc_set_tsa_hub2(reg_val, XUSB_HOSTW);
-
- /*
- * Hw Bug: 200385660, 200394107
- * PCIE datapath hangs when there are more than 28 outstanding
- * requests on data backbone for x1 controller. This is seen
- * on third party PCIE IP, C1 - PCIE1W, C2 - PCIE2AW and C3 - PCIE3W.
- *
- * Setting Reorder depth limit, 16 which is < 28.
- */
- mc_set_tsa_depth_limit(REORDER_DEPTH_LIMIT, PCIE1W);
- mc_set_tsa_depth_limit(REORDER_DEPTH_LIMIT, PCIE2AW);
- mc_set_tsa_depth_limit(REORDER_DEPTH_LIMIT, PCIE3W);
-
- /* Ordered MC Clients on Xavier are EQOS, SATA, XUSB, PCIe1 and PCIe3
- * ISO clients(DISP, VI, EQOS) should never snoop caches and
- * don't need ROC/PCFIFO ordering.
- * ISO clients(EQOS) that need ordering should use PCFIFO ordering
- * and bypass ROC ordering by using FORCE_NON_COHERENT path.
- * FORCE_NON_COHERENT/FORCE_COHERENT config take precedence
- * over SMMU attributes.
- * Force all Normal memory transactions from ISO and non-ISO to be
- * non-coherent(bypass ROC, avoid cache snoop to avoid perf hit).
- * Force the SO_DEV transactions from ordered ISO clients(EQOS) to
- * non-coherent path and enable MC PCFIFO interlock for ordering.
- * Force the SO_DEV transactions from ordered non-ISO clients (PCIe,
- * XUSB, SATA) to coherent so that the transactions are
- * ordered by ROC.
- * PCFIFO ensure write ordering.
- * Read after Write ordering is maintained/enforced by MC clients.
- * Clients that need PCIe type write ordering must
- * go through ROC ordering.
- * Ordering enable for Read clients is not necessary.
- * R5's and A9 would get necessary ordering from AXI and
- * don't need ROC ordering enable:
- * - MMIO ordering is through dev mapping and MMIO
- * accesses bypass SMMU.
- * - Normal memory is accessed through SMMU and ordering is
- * ensured by client and AXI.
- * - Ack point for Normal memory is WCAM in MC.
- * - MMIO's can be early acked and AXI ensures dev memory ordering,
- * Client ensures read/write direction change ordering.
- * - See Bug 200312466 for more details.
- */
- mc_set_txn_override(AONDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(AONDMAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(AONR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(AONW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(APEDMAR, CGID_TAG_ADR, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(APEDMAW, CGID_TAG_ADR, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(APER, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(APEW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(AXISR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(AXISW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(BPMPDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(BPMPDMAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(BPMPR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(BPMPW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(EQOSR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(EQOSW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(ETRR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(ETRW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(HOST1XDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(MPCORER, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MPCOREW, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(NVDISPLAYR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVDISPLAYR1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(PCIE0R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE0R1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE0W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE1R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE1W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- if (tegra_platform_is_silicon()) {
- mc_set_txn_override(PCIE2AR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE2AW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE3R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE3W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE4R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE4W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE5R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE5W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE5R1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- }
- mc_set_txn_override(PTCR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(RCEDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(RCEDMAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(RCER, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(RCEW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SATAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(SATAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(SCEDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SCEDMAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SCER, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SCEW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SDMMCR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SDMMCRAB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SDMMCRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SDMMCW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SDMMCWA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SDMMCWAB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- /*
- * TO DO: make SESRD/WR FORCE_COHERENT once SE+TZ with SMMU is enabled.
- */
- mc_set_txn_override(SESRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(SESWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(TSECSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(TSECSRDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(TSECSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(TSECSWRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(UFSHCR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(UFSHCW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(VICSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(VICSRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(VICSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(VIFALR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(VIFALW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(XUSB_DEVR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(XUSB_DEVW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(XUSB_HOSTR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(XUSB_HOSTW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(AXIAPR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(AXIAPW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA0FALRDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA0FALWRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA0RDA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA0RDA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA0WRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA1FALRDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA1FALWRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA1RDA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA1RDA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA1WRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(HDAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(HDAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(ISPFALR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(ISPFALW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(ISPRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(ISPRA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(ISPWA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(ISPWB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVDEC1SRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVDEC1SRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVDEC1SWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVDECSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVDECSRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVDECSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVENC1SRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVENC1SRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVENC1SWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVENCSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVENCSRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVENCSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVJPGSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVJPGSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA0RDA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA0RDA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA0RDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA0RDB1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA0RDC, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA0WRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA0WRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA0WRC, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA1RDA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA1RDA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA1RDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA1RDB1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA1RDC, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA1WRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA1WRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA1WRC, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(VIW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
-
- if (tegra_platform_is_silicon()) {
- mc_set_txn_override(MIU0R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU0W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU1R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU1W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU2R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU2W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU3R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU3W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU4R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU4W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU5R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU5W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU6R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU6W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU7R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU7W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- }
-
- /*
- * At this point, ordering can occur at SCF. So, remove PCFIFO's
- * control over ordering requests.
- *
- * Change PCFIFO_*_ORDERED_CLIENT from ORDERED -> UNORDERED for
- * boot and strongly ordered MSS clients
- */
- reg_val = MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_HOSTW) &
- mc_set_pcfifo_unordered_boot_so_mss(2, TSECSWR);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG2, reg_val);
-
- reg_val = MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWA) &
- mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCW) &
- mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWAB) &
- mc_set_pcfifo_unordered_boot_so_mss(3, VICSWR) &
- mc_set_pcfifo_unordered_boot_so_mss(3, APEW);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG3, reg_val);
-
- reg_val = MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(4, SESWR) &
- mc_set_pcfifo_unordered_boot_so_mss(4, ETRW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, TSECSWRB) &
- mc_set_pcfifo_unordered_boot_so_mss(4, AXISW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, UFSHCW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, BPMPW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, BPMPDMAW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, AONW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, AONDMAW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, SCEW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, SCEDMAW);
- /* EQOSW has PCFIFO order enabled. */
- reg_val |= mc_set_pcfifo_unordered_boot_so_mss(4, EQOSW);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG4, reg_val);
-
- reg_val = MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(5, APEDMAW) &
- mc_set_pcfifo_unordered_boot_so_mss(5, VIFALW);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG5, reg_val);
-
- reg_val = MC_PCFIFO_CLIENT_CONFIG6_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(6, RCEW) &
- mc_set_pcfifo_unordered_boot_so_mss(6, RCEDMAW) &
- mc_set_pcfifo_unordered_boot_so_mss(6, PCIE0W);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG6, reg_val);
-
- reg_val = MC_PCFIFO_CLIENT_CONFIG7_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(7, PCIE4W) &
- mc_set_pcfifo_unordered_boot_so_mss(7, PCIE5W);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG7, reg_val);
-
- /* Set Order Id only for the clients having non zero order id */
- reg_val = mc_client_order_id(MC_CLIENT_ORDER_ID_9_RESET_VAL, 9, XUSB_HOSTW);
- tegra_mc_write_32(MC_CLIENT_ORDER_ID_9, reg_val);
-
- reg_val = mc_client_order_id(MC_CLIENT_ORDER_ID_27_RESET_VAL, 27, PCIE0W);
- tegra_mc_write_32(MC_CLIENT_ORDER_ID_27, reg_val);
-
- reg_val = mc_client_order_id(MC_CLIENT_ORDER_ID_28_RESET_VAL, 28, PCIE4W);
- reg_val = mc_client_order_id(reg_val, 28, PCIE5W);
- tegra_mc_write_32(MC_CLIENT_ORDER_ID_28, reg_val);
-
- /*
- * Set VC Id only for the clients having different reset values like
- * SDMMCRAB, SDMMCWAB, SESRD, SESWR, TSECSRD,TSECSRDB, TSECSWR and
- * TSECSWRB clients
- */
- reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_0_RESET_VAL, 0, APB);
- tegra_mc_write_32(MC_HUB_PC_VC_ID_0, reg_val);
-
- /* SDMMCRAB and SDMMCWAB clients */
- reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_2_RESET_VAL, 2, SD);
- tegra_mc_write_32(MC_HUB_PC_VC_ID_2, reg_val);
-
- reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_4_RESET_VAL, 4, NIC);
- tegra_mc_write_32(MC_HUB_PC_VC_ID_4, reg_val);
-
- reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_12_RESET_VAL, 12, UFSHCPC2);
- tegra_mc_write_32(MC_HUB_PC_VC_ID_12, reg_val);
-
- wdata_0 = MC_CLIENT_HOTRESET_CTRL0_RESET_VAL;
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
-
- wdata_1 = MC_CLIENT_HOTRESET_CTRL1_RESET_VAL;
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
-
- wdata_2 = MC_CLIENT_HOTRESET_CTRL2_RESET_VAL;
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL2, wdata_2);
-
- reg_val = MC_COALESCE_CTRL_COALESCER_ENABLE;
- tegra_mc_write_32(MC_COALESCE_CTRL, reg_val);
-
- /*
- * WAR to hardware bug 1953865: Coalescer must be disabled
- * for PVA0RDC and PVA1RDC interfaces.
- */
- reg_val = tegra_mc_read_32(MC_COALESCE_CONFIG_6_0);
- reg_val &= ~(MC_COALESCE_CONFIG_6_0_PVA0RDC_COALESCER_ENABLED |
- MC_COALESCE_CONFIG_6_0_PVA1RDC_COALESCER_ENABLED);
- tegra_mc_write_32(MC_COALESCE_CONFIG_6_0, reg_val);
-}
-
/*******************************************************************************
* Struct to hold the memory controller settings
******************************************************************************/
@@ -685,8 +286,7 @@ static tegra_mc_settings_t tegra194_mc_settings = {
.streamid_override_cfg = tegra194_streamid_override_regs,
.num_streamid_override_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_override_regs),
.streamid_security_cfg = tegra194_streamid_sec_cfgs,
- .num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_sec_cfgs),
- .reconfig_mss_clients = tegra194_memctrl_reconfig_mss_clients
+ .num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_sec_cfgs)
};
/*******************************************************************************
diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c
index 3640ade0a..235fba43c 100644
--- a/plat/nvidia/tegra/soc/t194/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t194/plat_setup.c
@@ -163,18 +163,18 @@ void plat_enable_console(int32_t id)
uint32_t console_clock = 0U;
#if ENABLE_CONSOLE_SPE
- static console_spe_t spe_console;
+ static console_t spe_console;
if (id == TEGRA_CONSOLE_SPE_ID) {
(void)console_spe_register(TEGRA_CONSOLE_SPE_BASE,
console_clock,
TEGRA_CONSOLE_BAUDRATE,
&spe_console);
- console_set_scope(&spe_console.console, CONSOLE_FLAG_BOOT |
+ console_set_scope(&spe_console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
}
#else
- static console_16550_t uart_console;
+ static console_t uart_console;
if ((id > 0) && (id < TEGRA194_MAX_UART_PORTS)) {
/*
@@ -190,7 +190,7 @@ void plat_enable_console(int32_t id)
console_clock,
TEGRA_CONSOLE_BAUDRATE,
&uart_console);
- console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT |
+ console_set_scope(&uart_console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
}
#endif
diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
index 352107d2c..c44b0fc46 100644
--- a/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
+++ b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,6 +15,9 @@
* PMC registers
*/
+/* SC7 context save scratch register for T210 */
+#define PMC_SCRATCH43_REG_OFFSET U(0x22C)
+
/* Secure scratch registers */
#define PMC_SECURE_SCRATCH4_OFFSET 0xC0U
#define PMC_SECURE_SCRATCH5_OFFSET 0xC4U
@@ -435,6 +438,7 @@
((x) & ((0x1U) << SE_TZRAM_OP_REQ_SHIFT))
/* SE Interrupt */
+#define SE_INT_ENABLE_REG_OFFSET U(0xC)
#define SE_INT_STATUS_REG_OFFSET 0x10U
#define SE_INT_OP_DONE_SHIFT 4
#define SE_INT_OP_DONE_CLEAR \
diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
index d5e049126..635018dbc 100644
--- a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
+++ b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,8 +20,8 @@
* Constants and Macros
******************************************************************************/
-#define TIMEOUT_100MS 100U // Timeout in 100ms
-#define RNG_AES_KEY_INDEX 1
+#define TIMEOUT_100MS 100U /* Timeout in 100ms */
+#define RNG_AES_KEY_INDEX 1
/*******************************************************************************
* Data structure and global variables
@@ -68,14 +68,12 @@
* #--------------------------------#
*/
-/* Known pattern data */
-static const uint32_t se_ctx_known_pattern_data[SE_CTX_KNOWN_PATTERN_SIZE_WORDS] = {
+/* Known pattern data for T210 */
+static const uint8_t se_ctx_known_pattern_data[SE_CTX_KNOWN_PATTERN_SIZE] = {
/* 128 bit AES block */
- 0x0C0D0E0F,
- 0x08090A0B,
- 0x04050607,
- 0x00010203,
-};
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
+ };
/* SE input and output linked list buffers */
static tegra_se_io_lst_t se1_src_ll_buf;
@@ -85,6 +83,9 @@ static tegra_se_io_lst_t se1_dst_ll_buf;
static tegra_se_io_lst_t se2_src_ll_buf;
static tegra_se_io_lst_t se2_dst_ll_buf;
+/* SE1 context buffer, 132 blocks */
+static __aligned(64) uint8_t se1_ctx_buf[SE_CTX_DRBG_BUFER_SIZE];
+
/* SE1 security engine device handle */
static tegra_se_dev_t se_dev_1 = {
.se_num = 1,
@@ -97,10 +98,10 @@ static tegra_se_dev_t se_dev_1 = {
/* Setup DST buffers for SE operations */
.dst_ll_buf = &se1_dst_ll_buf,
/* Setup context save destination */
- .ctx_save_buf = (uint32_t *)(TEGRA_TZRAM_CARVEOUT_BASE),
+ .ctx_save_buf = (uint32_t *)&se1_ctx_buf
};
-/* SE2 security engine device handle */
+/* SE2 security engine device handle (T210B01 only) */
static tegra_se_dev_t se_dev_2 = {
.se_num = 2,
/* Setup base address for se */
@@ -112,7 +113,7 @@ static tegra_se_dev_t se_dev_2 = {
/* Setup DST buffers for SE operations */
.dst_ll_buf = &se2_dst_ll_buf,
/* Setup context save destination */
- .ctx_save_buf = (uint32_t *)(TEGRA_TZRAM_CARVEOUT_BASE + 0x1000),
+ .ctx_save_buf = (uint32_t *)(TEGRA_TZRAM_CARVEOUT_BASE + 0x1000)
};
static bool ecid_valid;
@@ -202,18 +203,6 @@ static int32_t tegra_se_operation_complete(const tegra_se_dev_t *se_dev)
}
/*
- * Returns true if the SE engine is configured to perform SE context save in
- * hardware.
- */
-static inline bool tegra_se_atomic_save_enabled(const tegra_se_dev_t *se_dev)
-{
- uint32_t val;
-
- val = tegra_se_read_32(se_dev, SE_CTX_SAVE_AUTO_REG_OFFSET);
- return (SE_CTX_SAVE_AUTO_ENABLE(val) == SE_CTX_SAVE_AUTO_EN);
-}
-
-/*
* Wait for SE engine to be idle and clear pending interrupts before
* starting the next SE operation.
*/
@@ -223,6 +212,9 @@ static int32_t tegra_se_operation_prepare(const tegra_se_dev_t *se_dev)
uint32_t val = 0;
uint32_t timeout;
+ /* disable SE interrupt to prevent interrupt issued by SE operation */
+ tegra_se_write_32(se_dev, SE_INT_ENABLE_REG_OFFSET, 0U);
+
/* Wait for previous operation to finish */
val = tegra_se_read_32(se_dev, SE_STATUS_OFFSET);
for (timeout = 0; (val != 0U) && (timeout < TIMEOUT_100MS); timeout++) {
@@ -629,19 +621,19 @@ static int tegra_se_lp_rsakeytable_context_save(tegra_se_dev_t *se_dev)
{
uint32_t val = 0;
int ret = 0;
- /* First the modulus and then the exponent must be
+ /* For T210, First the modulus and then exponent must be
* encrypted and saved. This is repeated for SLOT 0
* and SLOT 1. Hence the order:
- * SLOT 0 exponent : RSA_KEY_INDEX : 0
* SLOT 0 modulus : RSA_KEY_INDEX : 1
- * SLOT 1 exponent : RSA_KEY_INDEX : 2
+ * SLOT 0 exponent : RSA_KEY_INDEX : 0
* SLOT 1 modulus : RSA_KEY_INDEX : 3
+ * SLOT 1 exponent : RSA_KEY_INDEX : 2
*/
const unsigned int key_index_mod[TEGRA_SE_RSA_KEYSLOT_COUNT][2] = {
/* RSA key slot 0 */
- {SE_RSA_KEY_INDEX_SLOT0_EXP, SE_RSA_KEY_INDEX_SLOT0_MOD},
+ {SE_RSA_KEY_INDEX_SLOT0_MOD, SE_RSA_KEY_INDEX_SLOT0_EXP},
/* RSA key slot 1 */
- {SE_RSA_KEY_INDEX_SLOT1_EXP, SE_RSA_KEY_INDEX_SLOT1_MOD},
+ {SE_RSA_KEY_INDEX_SLOT1_MOD, SE_RSA_KEY_INDEX_SLOT1_EXP},
};
se_dev->dst_ll_buf->last_buff_num = 0;
@@ -876,8 +868,8 @@ static int tegra_se_context_save_sw(tegra_se_dev_t *se_dev)
/* Write lp context buffer address into PMC scratch register */
if (se_dev->se_num == 1) {
- /* SE context address */
- mmio_write_32((uint64_t)TEGRA_PMC_BASE + PMC_SECURE_SCRATCH117_OFFSET,
+ /* SE context address, support T210 only */
+ mmio_write_32((uint64_t)TEGRA_PMC_BASE + PMC_SCRATCH43_REG_OFFSET,
((uint64_t)(se_dev->ctx_save_buf)));
} else if (se_dev->se_num == 2) {
/* SE2 & PKA1 context address */
@@ -909,7 +901,10 @@ void tegra_se_init(void)
/* Generate random SRK to initialize DRBG */
tegra_se_generate_srk(&se_dev_1);
- tegra_se_generate_srk(&se_dev_2);
+
+ if (tegra_chipid_is_t210_b01()) {
+ tegra_se_generate_srk(&se_dev_2);
+ }
/* determine if ECID is valid */
val = mmio_read_32(TEGRA_FUSE_BASE + FUSE_JTAG_SECUREID_VALID);
@@ -932,6 +927,18 @@ static void tegra_se_enable_clocks(void)
val &= ~ENTROPY_RESET_BIT;
mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_W, val);
+ if (!tegra_chipid_is_t210_b01()) {
+
+ /*
+ * T210 SE clock source is turned off in kernel, to simplify
+ * SE clock source setting, we switch SE clock source to
+ * CLK_M, SE_CLK_DIVISOR = 0. T210 B01 SE clock source is
+ * always on, so don't need this setting.
+ */
+ mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_RST_CTL_CLK_SRC_SE,
+ SE_CLK_SRC_CLK_M);
+ }
+
/* Enable SE clock */
val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V);
val |= SE_CLK_ENB_BIT;
@@ -975,43 +982,25 @@ int32_t tegra_se_suspend(void)
tegra_se_enable_clocks();
- if (tegra_se_atomic_save_enabled(&se_dev_2) &&
- tegra_se_atomic_save_enabled(&se_dev_1)) {
- /* Atomic context save se2 and pka1 */
+ if (tegra_chipid_is_t210_b01()) {
+ /* It is T210 B01, Atomic context save se2 and pka1 */
INFO("%s: SE2/PKA1 atomic context save\n", __func__);
- if (ret == 0) {
- ret = tegra_se_context_save_atomic(&se_dev_2);
- }
-
- /* Atomic context save se */
- if (ret == 0) {
- INFO("%s: SE1 atomic context save\n", __func__);
- ret = tegra_se_context_save_atomic(&se_dev_1);
+ ret = tegra_se_context_save_atomic(&se_dev_2);
+ if (ret != 0) {
+ ERROR("%s: SE2 ctx save failed (%d)\n", __func__, ret);
}
- if (ret == 0) {
- INFO("%s: SE atomic context save done\n", __func__);
- }
- } else if (!tegra_se_atomic_save_enabled(&se_dev_2) &&
- !tegra_se_atomic_save_enabled(&se_dev_1)) {
- /* SW context save se2 and pka1 */
- INFO("%s: SE2/PKA1 legacy(SW) context save\n", __func__);
- if (ret == 0) {
- ret = tegra_se_context_save_sw(&se_dev_2);
- }
-
- /* SW context save se */
- if (ret == 0) {
- INFO("%s: SE1 legacy(SW) context save\n", __func__);
- ret = tegra_se_context_save_sw(&se_dev_1);
- }
-
- if (ret == 0) {
- INFO("%s: SE SW context save done\n", __func__);
+ ret = tegra_se_context_save_atomic(&se_dev_1);
+ if (ret != 0) {
+ ERROR("%s: SE1 ctx save failed (%d)\n", __func__, ret);
}
} else {
- ERROR("%s: One SE set for atomic CTX save, the other is not\n",
- __func__);
+ /* It is T210, SW context save se */
+ INFO("%s: SE1 legacy(SW) context save\n", __func__);
+ ret = tegra_se_context_save_sw(&se_dev_1);
+ if (ret != 0) {
+ ERROR("%s: SE1 ctx save failed (%d)\n", __func__, ret);
+ }
}
tegra_se_disable_clocks();
@@ -1080,5 +1069,8 @@ static void tegra_se_warm_boot_resume(const tegra_se_dev_t *se_dev)
void tegra_se_resume(void)
{
tegra_se_warm_boot_resume(&se_dev_1);
- tegra_se_warm_boot_resume(&se_dev_2);
+
+ if (tegra_chipid_is_t210_b01()) {
+ tegra_se_warm_boot_resume(&se_dev_2);
+ }
}
diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
index 832b8d647..f29e624ea 100644
--- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
@@ -210,12 +210,9 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
assert((stateid_afflvl1 == PLAT_MAX_OFF_STATE) ||
(stateid_afflvl1 == PSTATE_ID_SOC_POWERDN));
- if (tegra_chipid_is_t210_b01()) {
-
- /* Suspend se/se2 and pka1 */
- if (tegra_se_suspend() != 0) {
- ret = PSCI_E_INTERN_FAIL;
- }
+ /* Suspend se/se2 and pka1 for T210 B01 and se for T210 */
+ if (tegra_se_suspend() != 0) {
+ ret = PSCI_E_INTERN_FAIL;
}
} else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_IDLE) {
diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c
index c32772de8..933e925ec 100644
--- a/plat/nvidia/tegra/soc/t210/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t210/plat_setup.c
@@ -119,7 +119,7 @@ static uint32_t tegra210_uart_addresses[TEGRA210_MAX_UART_PORTS + 1] = {
******************************************************************************/
void plat_enable_console(int32_t id)
{
- static console_16550_t uart_console;
+ static console_t uart_console;
uint32_t console_clock;
if ((id > 0) && (id < TEGRA210_MAX_UART_PORTS)) {
@@ -136,7 +136,7 @@ void plat_enable_console(int32_t id)
console_clock,
TEGRA_CONSOLE_BAUDRATE,
&uart_console);
- console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT |
+ console_set_scope(&uart_console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
}
}
@@ -174,9 +174,7 @@ void plat_early_platform_setup(void)
}
/* Initialize security engine driver */
- if (tegra_chipid_is_t210_b01()) {
- tegra_se_init();
- }
+ tegra_se_init();
}
/* Secure IRQs for Tegra186 */
diff --git a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
index 7e0f5c1d8..7d26fe795 100644
--- a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -50,24 +51,32 @@ int plat_sip_handler(uint32_t smc_fid,
if (!ns)
SMC_RET1(handle, SMC_UNK);
- switch (smc_fid) {
- case TEGRA_SIP_PMC_COMMANDS:
-
+ if (smc_fid == TEGRA_SIP_PMC_COMMANDS) {
/* check the address is within PMC range and is 4byte aligned */
if ((x2 >= TEGRA_PMC_SIZE) || (x2 & 0x3))
return -EINVAL;
- /* pmc_secure_scratch registers are not accessible */
- if (((x2 >= PMC_SECURE_SCRATCH0) && (x2 <= PMC_SECURE_SCRATCH5)) ||
- ((x2 >= PMC_SECURE_SCRATCH6) && (x2 <= PMC_SECURE_SCRATCH7)) ||
- ((x2 >= PMC_SECURE_SCRATCH8) && (x2 <= PMC_SECURE_SCRATCH79)) ||
- ((x2 >= PMC_SECURE_SCRATCH80) && (x2 <= PMC_SECURE_SCRATCH119)))
- return -EFAULT;
-
+ switch (x2) {
+ /* Black listed PMC registers */
+ case PMC_SCRATCH1:
+ case PMC_SCRATCH31 ... PMC_SCRATCH33:
+ case PMC_SCRATCH40:
+ case PMC_SCRATCH42:
+ case PMC_SCRATCH43 ... PMC_SCRATCH48:
+ case PMC_SCRATCH50 ... PMC_SCRATCH51:
+ case PMC_SCRATCH56 ... PMC_SCRATCH57:
/* PMC secure-only registers are not accessible */
- if ((x2 == PMC_DPD_ENABLE_0) || (x2 == PMC_FUSE_CONTROL_0) ||
- (x2 == PMC_CRYPTO_OP_0))
+ case PMC_DPD_ENABLE_0:
+ case PMC_FUSE_CONTROL_0:
+ case PMC_CRYPTO_OP_0:
+ case PMC_TSC_MULT_0:
+ case PMC_STICKY_BIT:
+ ERROR("%s: error offset=0x%llx\n", __func__, x2);
return -EFAULT;
+ default:
+ /* Valid register */
+ break;
+ }
/* Perform PMC read/write */
if (x1 == PMC_READ) {
@@ -78,13 +87,9 @@ int plat_sip_handler(uint32_t smc_fid,
} else {
return -EINVAL;
}
-
- break;
-
- default:
+ } else {
ERROR("%s: unsupported function ID\n", __func__);
return -ENOTSUP;
}
-
return 0;
}
diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk
index 0d27bcdc5..ba827a073 100644
--- a/plat/nvidia/tegra/soc/t210/platform_t210.mk
+++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk
@@ -46,7 +46,6 @@ A57_DISABLE_NON_TEMPORAL_HINT := 1
ERRATA_A57_826974 := 1
ERRATA_A57_826977 := 1
ERRATA_A57_828024 := 1
-ERRATA_A57_829520 := 1
ERRATA_A57_833471 := 1
# Enable workarounds for selected Cortex-A53 erratas.
diff --git a/plat/qemu/common/qemu_console.c b/plat/qemu/common/qemu_console.c
index fec182892..1f00f8a72 100644
--- a/plat/qemu/common/qemu_console.c
+++ b/plat/qemu/common/qemu_console.c
@@ -9,7 +9,7 @@
#include <drivers/console.h>
#include <drivers/arm/pl011.h>
-static console_pl011_t console;
+static console_t console;
void qemu_console_init(void)
{
@@ -17,7 +17,7 @@ void qemu_console_init(void)
PLAT_QEMU_BOOT_UART_CLK_IN_HZ,
PLAT_QEMU_CONSOLE_BAUDRATE, &console);
- console_set_scope(&console.console, CONSOLE_FLAG_BOOT |
+ console_set_scope(&console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME);
}
diff --git a/plat/qemu/common/qemu_io_storage.c b/plat/qemu/common/qemu_io_storage.c
index 0e81cd199..1107e443f 100644
--- a/plat/qemu/common/qemu_io_storage.c
+++ b/plat/qemu/common/qemu_io_storage.c
@@ -12,6 +12,7 @@
#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/io/io_driver.h>
+#include <drivers/io/io_encrypted.h>
#include <drivers/io/io_fip.h>
#include <drivers/io/io_memmap.h>
#include <drivers/io/io_semihosting.h>
@@ -47,6 +48,10 @@ static const io_dev_connector_t *memmap_dev_con;
static uintptr_t memmap_dev_handle;
static const io_dev_connector_t *sh_dev_con;
static uintptr_t sh_dev_handle;
+#ifndef DECRYPTION_SUPPORT_none
+static const io_dev_connector_t *enc_dev_con;
+static uintptr_t enc_dev_handle;
+#endif
static const io_block_spec_t fip_block_spec = {
.offset = PLAT_QEMU_FIP_BASE,
@@ -172,10 +177,11 @@ static const io_file_spec_t sh_file_spec[] = {
#endif /* TRUSTED_BOARD_BOOT */
};
-
-
static int open_fip(const uintptr_t spec);
static int open_memmap(const uintptr_t spec);
+#ifndef DECRYPTION_SUPPORT_none
+static int open_enc_fip(const uintptr_t spec);
+#endif
struct plat_io_policy {
uintptr_t *dev_handle;
@@ -190,16 +196,46 @@ static const struct plat_io_policy policies[] = {
(uintptr_t)&fip_block_spec,
open_memmap
},
+ [ENC_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)NULL,
+ open_fip
+ },
[BL2_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl2_uuid_spec,
open_fip
},
+#if ENCRYPT_BL31 && !defined(DECRYPTION_SUPPORT_none)
+ [BL31_IMAGE_ID] = {
+ &enc_dev_handle,
+ (uintptr_t)&bl31_uuid_spec,
+ open_enc_fip
+ },
+#else
[BL31_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl31_uuid_spec,
open_fip
},
+#endif
+#if ENCRYPT_BL32 && !defined(DECRYPTION_SUPPORT_none)
+ [BL32_IMAGE_ID] = {
+ &enc_dev_handle,
+ (uintptr_t)&bl32_uuid_spec,
+ open_enc_fip
+ },
+ [BL32_EXTRA1_IMAGE_ID] = {
+ &enc_dev_handle,
+ (uintptr_t)&bl32_extra1_uuid_spec,
+ open_enc_fip
+ },
+ [BL32_EXTRA2_IMAGE_ID] = {
+ &enc_dev_handle,
+ (uintptr_t)&bl32_extra2_uuid_spec,
+ open_enc_fip
+ },
+#else
[BL32_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl32_uuid_spec,
@@ -215,6 +251,7 @@ static const struct plat_io_policy policies[] = {
(uintptr_t)&bl32_extra2_uuid_spec,
open_fip
},
+#endif
[BL33_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl33_uuid_spec,
@@ -271,7 +308,7 @@ static int open_fip(const uintptr_t spec)
/* See if a Firmware Image Package is available */
result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
- if (result == 0) {
+ if (result == 0 && spec != (uintptr_t)NULL) {
result = io_open(fip_dev_handle, spec, &local_image_handle);
if (result == 0) {
VERBOSE("Using FIP\n");
@@ -281,6 +318,25 @@ static int open_fip(const uintptr_t spec)
return result;
}
+#ifndef DECRYPTION_SUPPORT_none
+static int open_enc_fip(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ /* See if an encrypted FIP is available */
+ result = io_dev_init(enc_dev_handle, (uintptr_t)ENC_IMAGE_ID);
+ if (result == 0) {
+ result = io_open(enc_dev_handle, spec, &local_image_handle);
+ if (result == 0) {
+ VERBOSE("Using encrypted FIP\n");
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+#endif
+
static int open_memmap(const uintptr_t spec)
{
int result;
@@ -333,6 +389,15 @@ void plat_qemu_io_setup(void)
&memmap_dev_handle);
assert(io_result == 0);
+#ifndef DECRYPTION_SUPPORT_none
+ io_result = register_io_dev_enc(&enc_dev_con);
+ assert(io_result == 0);
+
+ io_result = io_dev_open(enc_dev_con, (uintptr_t)NULL,
+ &enc_dev_handle);
+ assert(io_result == 0);
+#endif
+
/* Register the additional IO devices on this platform */
io_result = register_io_dev_sh(&sh_dev_con);
assert(io_result == 0);
diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h
index cce992ff9..ed4b748af 100644
--- a/plat/qemu/qemu/include/platform_def.h
+++ b/plat/qemu/qemu/include/platform_def.h
@@ -172,7 +172,7 @@
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
#define MAX_MMAP_REGIONS 11
#define MAX_XLAT_TABLES 6
-#define MAX_IO_DEVICES 3
+#define MAX_IO_DEVICES 4
#define MAX_IO_HANDLES 4
/*
@@ -196,8 +196,8 @@
#define QEMU_FLASH1_BASE 0x04000000
#define QEMU_FLASH1_SIZE 0x04000000
-#define PLAT_QEMU_FIP_BASE QEMU_FLASH1_BASE
-#define PLAT_QEMU_FIP_MAX_SIZE QEMU_FLASH1_SIZE
+#define PLAT_QEMU_FIP_BASE 0x00040000
+#define PLAT_QEMU_FIP_MAX_SIZE 0x00400000
#define DEVICE0_BASE 0x08000000
#define DEVICE0_SIZE 0x01000000
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index bc10569ba..928d69a71 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -128,6 +128,11 @@ ifeq ($(add-lib-optee),yes)
BL2_SOURCES += lib/optee/optee_utils.c
endif
+ifneq (${DECRYPTION_SUPPORT},none)
+BL1_SOURCES += drivers/io/io_encrypted.c
+BL2_SOURCES += drivers/io/io_encrypted.c
+endif
+
QEMU_GICV2_SOURCES := drivers/arm/gic/v2/gicv2_helpers.c \
drivers/arm/gic/v2/gicv2_main.c \
drivers/arm/gic/common/gic_common.c \
@@ -165,11 +170,19 @@ endif
# Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images
# in the FIP if the platform requires.
ifneq ($(BL32_EXTRA1),)
+ifneq (${DECRYPTION_SUPPORT},none)
+$(eval $(call TOOL_ADD_IMG,bl32_extra1,--tos-fw-extra1,,$(ENCRYPT_BL32)))
+else
$(eval $(call TOOL_ADD_IMG,bl32_extra1,--tos-fw-extra1))
endif
+endif
ifneq ($(BL32_EXTRA2),)
+ifneq (${DECRYPTION_SUPPORT},none)
+$(eval $(call TOOL_ADD_IMG,bl32_extra2,--tos-fw-extra2,,$(ENCRYPT_BL32)))
+else
$(eval $(call TOOL_ADD_IMG,bl32_extra2,--tos-fw-extra2))
endif
+endif
SEPARATE_CODE_AND_RODATA := 1
ENABLE_STACK_PROTECTOR := 0
diff --git a/plat/renesas/rcar/rcar_common.c b/plat/renesas/rcar/rcar_common.c
index 4ea753f2d..dec7229b3 100644
--- a/plat/renesas/rcar/rcar_common.c
+++ b/plat/renesas/rcar/rcar_common.c
@@ -70,8 +70,8 @@ void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
#include <drivers/renesas/rcar/console/console.h>
-static console_rcar_t rcar_boot_console;
-static console_rcar_t rcar_runtime_console;
+static console_t rcar_boot_console;
+static console_t rcar_runtime_console;
void rcar_console_boot_init(void)
{
@@ -81,7 +81,7 @@ void rcar_console_boot_init(void)
if (!ret)
panic();
- console_set_scope(&rcar_boot_console.console, CONSOLE_FLAG_BOOT);
+ console_set_scope(&rcar_boot_console, CONSOLE_FLAG_BOOT);
}
void rcar_console_boot_end(void)
@@ -96,7 +96,7 @@ void rcar_console_runtime_init(void)
if (!ret)
panic();
- console_set_scope(&rcar_boot_console.console, CONSOLE_FLAG_RUNTIME);
+ console_set_scope(&rcar_boot_console, CONSOLE_FLAG_RUNTIME);
}
void rcar_console_runtime_end(void)
diff --git a/plat/rockchip/common/bl31_plat_setup.c b/plat/rockchip/common/bl31_plat_setup.c
index c4a03592e..98ef415c9 100644
--- a/plat/rockchip/common/bl31_plat_setup.c
+++ b/plat/rockchip/common/bl31_plat_setup.c
@@ -57,7 +57,7 @@ void params_early_setup(u_register_t plat_param_from_bl2)
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
- static console_16550_t console;
+ static console_t console;
params_early_setup(arg1);
diff --git a/plat/rockchip/common/sp_min_plat_setup.c b/plat/rockchip/common/sp_min_plat_setup.c
index 6d15075f2..0237b167f 100644
--- a/plat/rockchip/common/sp_min_plat_setup.c
+++ b/plat/rockchip/common/sp_min_plat_setup.c
@@ -52,7 +52,7 @@ unsigned int plat_is_my_cpu_primary(void);
void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
- static console_16550_t console;
+ static console_t console;
params_early_setup(arg1);
diff --git a/plat/rpi/common/rpi3_common.c b/plat/rpi/common/rpi3_common.c
index ff3369427..27281f2ba 100644
--- a/plat/rpi/common/rpi3_common.c
+++ b/plat/rpi/common/rpi3_common.c
@@ -102,7 +102,7 @@ static const mmap_region_t plat_rpi3_mmap[] = {
/*******************************************************************************
* Function that sets up the console
******************************************************************************/
-static console_16550_t rpi3_console;
+static console_t rpi3_console;
void rpi3_console_init(unsigned int base_clk_rate)
{
@@ -123,7 +123,7 @@ void rpi3_console_init(unsigned int base_clk_rate)
panic();
}
- console_set_scope(&rpi3_console.console, console_scope);
+ console_set_scope(&rpi3_console, console_scope);
}
/*******************************************************************************
diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c
index b86402179..9723ef9f0 100644
--- a/plat/socionext/synquacer/sq_bl31_setup.c
+++ b/plat/socionext/synquacer/sq_bl31_setup.c
@@ -16,7 +16,7 @@
#include <lib/mmio.h>
#include <sq_common.h>
-static console_pl011_t console;
+static console_t console;
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
@@ -69,8 +69,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
PLAT_SQ_BOOT_UART_CLK_IN_HZ,
SQ_CONSOLE_BAUDRATE, &console);
- console_set_scope(&console.console, CONSOLE_FLAG_BOOT |
- CONSOLE_FLAG_RUNTIME);
+ console_set_scope(&console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
/* There are no parameters from BL2 if BL31 is a reset vector */
assert(arg0 == 0U);
diff --git a/plat/socionext/uniphier/uniphier_console.S b/plat/socionext/uniphier/uniphier_console.S
index 1113c6e81..f3dde0cc1 100644
--- a/plat/socionext/uniphier/uniphier_console.S
+++ b/plat/socionext/uniphier/uniphier_console.S
@@ -17,7 +17,7 @@
*/
.globl uniphier_console_putc
func uniphier_console_putc
- ldr x1, [x1, #CONSOLE_T_DRVDATA]
+ ldr x1, [x1, #CONSOLE_T_BASE]
/* Wait until the transmitter FIFO gets empty */
0: ldr w2, [x1, #UNIPHIER_UART_LSR]
@@ -36,7 +36,7 @@ endfunc uniphier_console_putc
*/
.globl uniphier_console_getc
func uniphier_console_getc
- ldr x0, [x0, #CONSOLE_T_DRVDATA]
+ ldr x0, [x0, #CONSOLE_T_BASE]
ldr w1, [x0, #UNIPHIER_UART_LSR]
tbz w1, #UNIPHIER_UART_LSR_DR_BIT, 0f
@@ -55,7 +55,7 @@ endfunc uniphier_console_getc
*/
.global uniphier_console_flush
func uniphier_console_flush
- ldr x0, [x0, #CONSOLE_T_DRVDATA]
+ ldr x0, [x0, #CONSOLE_T_BASE]
/* wait until the transmitter gets empty */
0: ldr w1, [x0, #UNIPHIER_UART_LSR]
diff --git a/plat/socionext/uniphier/uniphier_console_setup.c b/plat/socionext/uniphier/uniphier_console_setup.c
index 1851e4da5..e2ae8bf28 100644
--- a/plat/socionext/uniphier/uniphier_console_setup.c
+++ b/plat/socionext/uniphier/uniphier_console_setup.c
@@ -17,28 +17,21 @@
#define UNIPHIER_UART_OFFSET 0x100
#define UNIPHIER_UART_NR_PORTS 4
-struct uniphier_console {
- struct console console;
- uintptr_t base;
-};
-
/* These callbacks are implemented in assembly to use crash_console_helpers.S */
int uniphier_console_putc(int character, struct console *console);
int uniphier_console_getc(struct console *console);
int uniphier_console_flush(struct console *console);
-static struct uniphier_console uniphier_console = {
- .console = {
- .flags = CONSOLE_FLAG_BOOT |
+static console_t uniphier_console = {
+ .flags = CONSOLE_FLAG_BOOT |
#if DEBUG
- CONSOLE_FLAG_RUNTIME |
+ CONSOLE_FLAG_RUNTIME |
#endif
- CONSOLE_FLAG_CRASH |
- CONSOLE_FLAG_TRANSLATE_CRLF,
- .putc = uniphier_console_putc,
- .getc = uniphier_console_getc,
- .flush = uniphier_console_flush,
- },
+ CONSOLE_FLAG_CRASH |
+ CONSOLE_FLAG_TRANSLATE_CRLF,
+ .putc = uniphier_console_putc,
+ .getc = uniphier_console_getc,
+ .flush = uniphier_console_flush,
};
static const uintptr_t uniphier_uart_base[] = {
@@ -86,7 +79,7 @@ void uniphier_console_setup(unsigned int soc)
plat_error_handler(-EINVAL);
uniphier_console.base = base;
- console_register(&uniphier_console.console);
+ console_register(&uniphier_console);
/*
* The hardware might be still printing characters queued up in the
diff --git a/plat/socionext/uniphier/uniphier_io_storage.c b/plat/socionext/uniphier/uniphier_io_storage.c
index 96180f159..77d1eaf00 100644
--- a/plat/socionext/uniphier/uniphier_io_storage.c
+++ b/plat/socionext/uniphier/uniphier_io_storage.c
@@ -21,9 +21,8 @@
#include "uniphier.h"
#define UNIPHIER_ROM_REGION_BASE 0x00000000ULL
-#define UNIPHIER_ROM_REGION_SIZE 0x10000000ULL
+#define UNIPHIER_ROM_REGION_SIZE 0x04000000ULL
-#define UNIPHIER_OCM_REGION_BASE 0x30000000ULL
#define UNIPHIER_OCM_REGION_SIZE 0x00040000ULL
#define UNIPHIER_BLOCK_BUF_OFFSET 0x04200000UL
@@ -278,12 +277,20 @@ static int uniphier_io_nor_setup(unsigned int soc_id, size_t buffer_offset)
return uniphier_io_memmap_setup(0x70000);
}
-static int uniphier_io_usb_setup(unsigned int soc_id, size_t buffer_offset)
+static const uintptr_t uniphier_ocm_base[] = {
+ [UNIPHIER_SOC_LD11] = 0x30000000,
+ [UNIPHIER_SOC_LD20] = 0x30000000,
+ [UNIPHIER_SOC_PXS3] = 0x30000000,
+};
+
+static int uniphier_io_rom_api_setup(unsigned int soc)
{
- struct io_block_dev_spec *block_dev_spec;
+ uintptr_t ocm_base;
int ret;
- /* use ROM API for loading images from USB storage */
+ assert(soc < ARRAY_SIZE(uniphier_ocm_base));
+ ocm_base = uniphier_ocm_base[soc];
+
ret = mmap_add_dynamic_region(UNIPHIER_ROM_REGION_BASE,
UNIPHIER_ROM_REGION_BASE,
UNIPHIER_ROM_REGION_SIZE,
@@ -296,14 +303,26 @@ static int uniphier_io_usb_setup(unsigned int soc_id, size_t buffer_offset)
* load functions provided by the ROM use this memory region as a work
* area, but do not cater to cache coherency.
*/
- ret = mmap_add_dynamic_region(UNIPHIER_OCM_REGION_BASE,
- UNIPHIER_OCM_REGION_BASE,
+ ret = mmap_add_dynamic_region(ocm_base, ocm_base,
UNIPHIER_OCM_REGION_SIZE,
MT_DEVICE | MT_RW | MT_SECURE);
if (ret)
return ret;
- ret = uniphier_usb_init(soc_id, &block_dev_spec);
+ return 0;
+}
+
+static int uniphier_io_usb_setup(unsigned int soc, size_t buffer_offset)
+{
+ struct io_block_dev_spec *block_dev_spec;
+ int ret;
+
+ /* use ROM API for loading images from USB storage */
+ ret = uniphier_io_rom_api_setup(soc);
+ if (ret)
+ return ret;
+
+ ret = uniphier_usb_init(soc, &block_dev_spec);
if (ret)
return ret;
diff --git a/plat/socionext/uniphier/uniphier_soc_info.c b/plat/socionext/uniphier/uniphier_soc_info.c
index 377532deb..0e7a2d11a 100644
--- a/plat/socionext/uniphier/uniphier_soc_info.c
+++ b/plat/socionext/uniphier/uniphier_soc_info.c
@@ -4,18 +4,25 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <common/bl_common.h>
#include <lib/mmio.h>
#include "uniphier.h"
-#define UNIPHIER_REVISION 0x5f800000
+#define UNIPHIER_REVISION 0x5f800000UL
+#define UNIPHIER_REVISION_NEW 0x1f800000UL
static unsigned int uniphier_get_revision_field(unsigned int mask,
unsigned int shift)
{
- uint32_t revision = mmio_read_32(UNIPHIER_REVISION);
+ uintptr_t reg;
- return (revision >> shift) & mask;
+ if (BL_CODE_BASE >= 0x80000000UL)
+ reg = UNIPHIER_REVISION;
+ else
+ reg = UNIPHIER_REVISION_NEW;
+
+ return (mmio_read_32(reg) >> shift) & mask;
}
unsigned int uniphier_get_soc_type(void)
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index d9e29b4e8..024dbe076 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -31,7 +31,7 @@
#include <stm32mp1_context.h>
#include <stm32mp1_dbgmcu.h>
-static struct console_stm32 console;
+static console_t console;
static struct stm32mp_auth_ops stm32mp1_auth_ops;
static void print_reset_reason(void)
@@ -273,7 +273,7 @@ void bl2_el3_plat_arch_setup(void)
panic();
}
- console_set_scope(&console.console, CONSOLE_FLAG_BOOT |
+ console_set_scope(&console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_CRASH | CONSOLE_FLAG_TRANSLATE_CRLF);
stm32mp_print_cpuinfo();
diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c
index e10dfbfc0..4e74c275d 100644
--- a/plat/st/stm32mp1/sp_min/sp_min_setup.c
+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c
@@ -35,7 +35,7 @@
******************************************************************************/
static entry_point_info_t bl33_image_ep_info;
-static struct console_stm32 console;
+static console_t console;
/*******************************************************************************
* Interrupt handler for FIQ (secure IRQ)
@@ -142,7 +142,7 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
#ifdef DEBUG
console_flags |= CONSOLE_FLAG_RUNTIME;
#endif
- console_set_scope(&console.console, console_flags);
+ console_set_scope(&console, console_flags);
}
}
diff --git a/plat/ti/k3/common/k3_console.c b/plat/ti/k3/common/k3_console.c
index ba0ddacec..8c44c17e2 100644
--- a/plat/ti/k3/common/k3_console.c
+++ b/plat/ti/k3/common/k3_console.c
@@ -13,7 +13,7 @@
void bl31_console_setup(void)
{
- static console_16550_t console;
+ static console_t console;
/* Initialize the console to provide early debug support */
console_16550_register(K3_USART_BASE, K3_USART_CLK_SPEED,
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index a5cf05e9a..03b7fbbb4 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -22,7 +22,7 @@
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
-static console_pl011_t versal_runtime_console;
+static console_t versal_runtime_console;
/*
* Return a pointer to the 'entry_point_info' structure of the next image for
@@ -71,7 +71,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
if (rc == 0)
panic();
- console_set_scope(&versal_runtime_console.console, CONSOLE_FLAG_BOOT |
+ console_set_scope(&versal_runtime_console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME);
/* Initialize the platform config for future decision making */
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 6e0e811d4..b6d8770cc 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -62,12 +62,12 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
{
uint64_t atf_handoff_addr;
/* Register the console to provide early debug support */
- static console_cdns_t bl31_boot_console;
+ static console_t bl31_boot_console;
(void)console_cdns_register(ZYNQMP_UART_BASE,
zynqmp_get_uart_clk(),
ZYNQMP_UART_BAUDRATE,
&bl31_boot_console);
- console_set_scope(&bl31_boot_console.console,
+ console_set_scope(&bl31_boot_console,
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_BOOT);
/* Initialize the platform config for future decision making */
diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
index 7f0ac74cf..5e770f75c 100644
--- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
+++ b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
@@ -21,12 +21,12 @@ void tsp_early_platform_setup(void)
* Register a different console than already in use to display
* messages from TSP
*/
- static console_cdns_t tsp_boot_console;
+ static console_t tsp_boot_console;
(void)console_cdns_register(ZYNQMP_UART_BASE,
zynqmp_get_uart_clk(),
ZYNQMP_UART_BAUDRATE,
&tsp_boot_console);
- console_set_scope(&tsp_boot_console.console,
+ console_set_scope(&tsp_boot_console,
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_BOOT);
/* Initialize the platform config for future decision making */
diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c
index 092ffa8eb..ba2f4a6e4 100644
--- a/services/spd/trusty/trusty.c
+++ b/services/spd/trusty/trusty.c
@@ -150,9 +150,9 @@ static uint64_t trusty_fiq_handler(uint32_t id,
(void)memcpy(&ctx->fiq_gpregs, get_gpregs_ctx(handle), sizeof(ctx->fiq_gpregs));
ctx->fiq_pc = SMC_GET_EL3(handle, CTX_ELR_EL3);
ctx->fiq_cpsr = SMC_GET_EL3(handle, CTX_SPSR_EL3);
- ctx->fiq_sp_el1 = read_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1);
+ ctx->fiq_sp_el1 = read_ctx_reg(get_el1_sysregs_ctx(handle), CTX_SP_EL1);
- write_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_handler_sp);
+ write_ctx_reg(get_el1_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_handler_sp);
cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_handler_pc, (uint32_t)ctx->fiq_handler_cpsr);
SMC_RET0(handle);
@@ -211,7 +211,7 @@ static uint64_t trusty_fiq_exit(void *handle, uint64_t x1, uint64_t x2, uint64_t
*/
(void)memcpy(get_gpregs_ctx(handle), &ctx->fiq_gpregs, sizeof(ctx->fiq_gpregs));
ctx->fiq_handler_active = 0;
- write_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_sp_el1);
+ write_ctx_reg(get_el1_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_sp_el1);
cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_pc, (uint32_t)ctx->fiq_cpsr);
SMC_RET0(handle);
diff --git a/services/std_svc/spm_mm/spm_mm_setup.c b/services/std_svc/spm_mm/spm_mm_setup.c
index ccb2f9058..468e5b3af 100644
--- a/services/std_svc/spm_mm/spm_mm_setup.c
+++ b/services/std_svc/spm_mm/spm_mm_setup.c
@@ -116,17 +116,17 @@ void spm_sp_setup(sp_context_t *sp_ctx)
xlat_ctx->pa_max_address, xlat_ctx->va_max_address,
EL1_EL0_REGIME);
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_MAIR_EL1,
+ write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_MAIR_EL1,
mmu_cfg_params[MMU_CFG_MAIR]);
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_TCR_EL1,
+ write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_TCR_EL1,
mmu_cfg_params[MMU_CFG_TCR]);
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_TTBR0_EL1,
+ write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_TTBR0_EL1,
mmu_cfg_params[MMU_CFG_TTBR0]);
/* Setup SCTLR_EL1 */
- u_register_t sctlr_el1 = read_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1);
+ u_register_t sctlr_el1 = read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1);
sctlr_el1 |=
/*SCTLR_EL1_RES1 |*/
@@ -160,7 +160,7 @@ void spm_sp_setup(sp_context_t *sp_ctx)
SCTLR_UMA_BIT
);
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_el1);
+ write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_el1);
/*
* Setup other system registers
@@ -168,10 +168,10 @@ void spm_sp_setup(sp_context_t *sp_ctx)
*/
/* Shim Exception Vector Base Address */
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_VBAR_EL1,
+ write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_VBAR_EL1,
SPM_SHIM_EXCEPTIONS_PTR);
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_CNTKCTL_EL1,
+ write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_CNTKCTL_EL1,
EL0PTEN_BIT | EL0VTEN_BIT | EL0PCTEN_BIT | EL0VCTEN_BIT);
/*
@@ -181,7 +181,7 @@ void spm_sp_setup(sp_context_t *sp_ctx)
* TTA: Enable access to trace registers.
* ZEN (v8.2): Trap SVE instructions and access to SVE registers.
*/
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_CPACR_EL1,
+ write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_CPACR_EL1,
CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE));
/*
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 677f63968..2cdf4f5ff 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -33,7 +33,23 @@ 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;
+static spmc_manifest_sect_attribute_t spmc_attrs;
+
+/*******************************************************************************
+ * SPM Core entry point information. Discovered on the primary core and reused
+ * on secondary cores.
+ ******************************************************************************/
+static entry_point_info_t *spmc_ep_info;
+
+/*******************************************************************************
+ * Static function declaration.
+ ******************************************************************************/
+static int32_t spmd_init(void);
+static int spmd_spmc_init(void *rd_base, size_t rd_size);
+static uint64_t spmd_spci_error_return(void *handle, int error_code);
+static uint64_t spmd_smc_forward(uint32_t smc_fid, bool secure_origin,
+ uint64_t x1, uint64_t x2, uint64_t x3,
+ uint64_t x4, void *handle);
/*******************************************************************************
* This function takes an SP context pointer and performs a synchronous entry
@@ -49,17 +65,19 @@ uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *spmc_ctx)
/* Restore the context assigned above */
cm_el1_sysregs_context_restore(SECURE);
+#if SPMD_SPM_AT_SEL2
+ cm_el2_sysregs_context_restore(SECURE);
+#endif
cm_set_next_eret_context(SECURE);
- /* Invalidate TLBs at EL1. */
- tlbivmalle1();
- dsbish();
-
- /* Enter Secure Partition */
+ /* Enter SPMC */
rc = spmd_spm_core_enter(&spmc_ctx->c_rt_ctx);
/* Save secure state */
cm_el1_sysregs_context_save(SECURE);
+#if SPMD_SPM_AT_SEL2
+ cm_el2_sysregs_context_save(SECURE);
+#endif
return rc;
}
@@ -109,63 +127,21 @@ static int32_t spmd_init(void)
}
/*******************************************************************************
- * Initialize context of SPM core.
+ * Load SPMC manifest, init SPMC.
******************************************************************************/
-int32_t spmd_setup(void)
+static int spmd_spmc_init(void *rd_base, size_t rd_size)
{
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();
- }
+ unsigned int linear_id = plat_my_core_pos();
+ spmd_spm_core_context_t *spm_ctx = &spm_core_context[linear_id];
/* Load the SPM core manifest */
rc = plat_spm_core_manifest_load(&spmc_attrs, rd_base, rd_size);
- if (rc < 0) {
+ if (rc != 0) {
WARN("No or invalid SPM core manifest image provided by BL2 "
"boot loader. ");
- goto error;
+ return 1;
}
/*
@@ -177,22 +153,14 @@ int32_t spmd_setup(void)
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;
+ return 1;
}
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);
+ INFO("SPM core run time EL%x.\n",
+ SPMD_SPM_AT_SEL2 ? MODE_EL2 : MODE_EL1);
/* Validate the SPM core execution state */
if ((spmc_attrs.exec_state != MODE_RW_64) &&
@@ -200,42 +168,39 @@ int32_t spmd_setup(void)
WARN("Unsupported SPM core execution state %x specified in "
"manifest image provided by BL2 boot loader.\n",
spmc_attrs.exec_state);
- goto error;
+ return 1;
}
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;
+#if SPMD_SPM_AT_SEL2
+ /* Ensure manifest has not requested AArch32 state in S-EL2 */
+ if (spmc_attrs.exec_state == MODE_RW_32) {
+ WARN("AArch32 state at S-EL2 is not supported.\n");
+ return 1;
}
/*
* 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();
+ uint64_t sel2 = read_id_aa64pfr0_el1();
- sel2 >>= ID_AA64PFR0_SEL2_SHIFT;
- sel2 &= ID_AA64PFR0_SEL2_MASK;
+ 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;
- }
+ if (!sel2) {
+ WARN("SPM core run time S-EL2 is not supported.");
+ return 1;
}
+#endif /* SPMD_SPM_AT_SEL2 */
/* Initialise an entrypoint to set up the CPU context */
ep_attr = SECURE | EP_ST_ENABLE;
- if (read_sctlr_el3() & SCTLR_EE_BIT)
+ 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);
@@ -250,14 +215,22 @@ int32_t spmd_setup(void)
DAIF_IRQ_BIT |
DAIF_ABT_BIT);
} else {
- spmc_ep_info->spsr = SPSR_64(spmc_attrs.runtime_el,
+
+#if SPMD_SPM_AT_SEL2
+ static const uint32_t runtime_el = MODE_EL2;
+#else
+ static const uint32_t runtime_el = MODE_EL1;
+#endif
+ spmc_ep_info->spsr = SPSR_64(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);
+ cm_setup_context(&spm_ctx->cpu_ctx, spmc_ep_info);
+
+ /* Reuse PSCI affinity states to mark this SPMC context as off */
+ spm_ctx->state = AFF_STATE_OFF;
INFO("SPM core setup done.\n");
@@ -265,20 +238,119 @@ int32_t spmd_setup(void)
bl31_register_bl32_init(&spmd_init);
return 0;
+}
+
+/*******************************************************************************
+ * Initialize context of SPM core.
+ ******************************************************************************/
+int spmd_setup(void)
+{
+ int rc;
+ void *rd_base;
+ size_t rd_size;
+ uintptr_t rd_base_align;
+ uintptr_t rd_size_align;
-error:
- WARN("Booting device without SPM initialization. "
- "SPCI SMCs destined for SPM core will return "
- "ENOTSUPPORTED\n");
+ 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;
+ }
- rc = mmap_remove_dynamic_region(rd_base_align, rd_size_align);
- if (rc < 0) {
- ERROR("Error while unmapping SPM core manifest (%d).\n",
- rc);
+ /* 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();
}
- return 1;
+ /* 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 manifest, init SPMC */
+ rc = spmd_spmc_init(rd_base, rd_size);
+ if (rc != 0) {
+ int mmap_rc;
+
+ WARN("Booting device without SPM initialization. "
+ "SPCI SMCs destined for SPM core will return "
+ "ENOTSUPPORTED\n");
+
+ mmap_rc = mmap_remove_dynamic_region(rd_base_align,
+ rd_size_align);
+ if (mmap_rc != 0) {
+ ERROR("Error while unmapping SPM core manifest (%d).\n",
+ mmap_rc);
+ panic();
+ }
+
+ return rc;
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Forward SMC to the other security state
+ ******************************************************************************/
+static uint64_t spmd_smc_forward(uint32_t smc_fid, bool secure_origin,
+ uint64_t x1, uint64_t x2, uint64_t x3,
+ uint64_t x4, void *handle)
+{
+ uint32_t secure_state_in = (secure_origin) ? SECURE : NON_SECURE;
+ uint32_t secure_state_out = (!secure_origin) ? SECURE : NON_SECURE;
+
+ /* Save incoming security state */
+ cm_el1_sysregs_context_save(secure_state_in);
+#if SPMD_SPM_AT_SEL2
+ cm_el2_sysregs_context_save(secure_state_in);
+#endif
+
+ /* Restore outgoing security state */
+ cm_el1_sysregs_context_restore(secure_state_out);
+#if SPMD_SPM_AT_SEL2
+ cm_el2_sysregs_context_restore(secure_state_out);
+#endif
+ cm_set_next_eret_context(secure_state_out);
+
+ SMC_RET8(cm_get_context(secure_state_out), 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));
+}
+
+/*******************************************************************************
+ * Return SPCI_ERROR with specified error code
+ ******************************************************************************/
+static uint64_t spmd_spci_error_return(void *handle, int error_code)
+{
+ SMC_RET8(handle, SPCI_ERROR,
+ SPCI_TARGET_INFO_MBZ, error_code,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
+ SPCI_PARAM_MBZ, SPCI_PARAM_MBZ);
}
/*******************************************************************************
@@ -289,19 +361,12 @@ 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()];
+ bool secure_origin;
+ int32_t ret;
/* 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;
- }
+ secure_origin = is_caller_secure(flags);
INFO("SPM: 0x%x, 0x%llx, 0x%llx, 0x%llx, 0x%llx, "
"0x%llx, 0x%llx, 0x%llx\n",
@@ -316,20 +381,12 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
* this CPU. If so, then indicate that the SPM core initialised
* unsuccessfully.
*/
- if ((in_sstate == SECURE) && (ctx->state == SPMC_STATE_RESET))
+ if (secure_origin && (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));
+ return spmd_smc_forward(smc_fid, secure_origin,
+ x1, x2, x3, x4, handle);
break; /* not reached */
case SPCI_VERSION:
@@ -353,29 +410,18 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
*/
/*
- * Check if w1 holds a valid SPCI fid. This is an
+ * Check if x1 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);
+ if (!is_spci_fid(x1)) {
+ return spmd_spci_error_return(handle,
+ SPCI_ERROR_NOT_SUPPORTED);
+ }
/* 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));
+ if (!secure_origin) {
+ return spmd_smc_forward(smc_fid, secure_origin,
+ x1, x2, x3, x4, handle);
} else {
/*
* Return success if call was from secure world i.e. all
@@ -387,6 +433,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
SMC_GET_GP(handle, CTX_GPREG_X6),
SMC_GET_GP(handle, CTX_GPREG_X7));
}
+
break; /* not reached */
case SPCI_RX_RELEASE:
@@ -395,11 +442,9 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
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);
+ if (secure_origin) {
+ return spmd_spci_error_return(handle,
+ SPCI_ERROR_NOT_SUPPORTED);
}
/* Fall through to forward the call to the other world */
@@ -430,17 +475,8 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
* 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));
+ return spmd_smc_forward(smc_fid, secure_origin,
+ x1, x2, x3, x4, handle);
break; /* not reached */
case SPCI_MSG_WAIT:
@@ -449,39 +485,25 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
* 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)) {
+ if (secure_origin && (ctx->state == SPMC_STATE_RESET)) {
spmd_spm_core_sync_exit(0);
}
- /* Intentional fall-through */
+ /* Fall through to forward the call to the other world */
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);
+ if (!secure_origin) {
+ return spmd_spci_error_return(handle,
+ SPCI_ERROR_NOT_SUPPORTED);
}
- /* 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));
+ return spmd_smc_forward(smc_fid, secure_origin,
+ x1, x2, x3, x4, handle);
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);
+ return spmd_spci_error_return(handle, SPCI_ERROR_NOT_SUPPORTED);
}
}
diff --git a/tools/encrypt_fw/Makefile b/tools/encrypt_fw/Makefile
new file mode 100644
index 000000000..cb81d0b2e
--- /dev/null
+++ b/tools/encrypt_fw/Makefile
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2019, Linaro Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PROJECT := encrypt_fw
+V ?= 0
+BUILD_INFO ?= 1
+DEBUG := 0
+BINARY := ${PROJECT}${BIN_EXT}
+OPENSSL_DIR := /usr
+
+OBJECTS := src/encrypt.o \
+ src/cmd_opt.o \
+ src/main.o
+
+HOSTCCFLAGS := -Wall -std=c99
+
+MAKE_HELPERS_DIRECTORY := ../../make_helpers/
+include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
+include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+
+ifeq (${DEBUG},1)
+ HOSTCCFLAGS += -g -O0 -DDEBUG -DLOG_LEVEL=40
+else
+ifeq (${BUILD_INFO},1)
+ HOSTCCFLAGS += -O2 -DLOG_LEVEL=20
+else
+ HOSTCCFLAGS += -O2 -DLOG_LEVEL=10
+endif
+endif
+ifeq (${V},0)
+ Q := @
+else
+ Q :=
+endif
+
+# Make soft links and include from local directory otherwise wrong headers
+# could get pulled in from firmware tree.
+INC_DIR := -I ./include -I ../../include/tools_share -I ${OPENSSL_DIR}/include
+LIB_DIR := -L ${OPENSSL_DIR}/lib
+LIB := -lssl -lcrypto
+
+HOSTCC ?= gcc
+
+.PHONY: all clean realclean
+
+all: clean ${BINARY}
+
+${BINARY}: ${OBJECTS} Makefile
+ @echo " HOSTLD $@"
+ @echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__;' | \
+ ${HOSTCC} -c ${HOSTCCFLAGS} -xc - -o src/build_msg.o
+ ${Q}${HOSTCC} src/build_msg.o ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
+
+%.o: %.c
+ @echo " HOSTCC $<"
+ ${Q}${HOSTCC} -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
+
+clean:
+ $(call SHELL_DELETE_ALL, src/build_msg.o ${OBJECTS})
+
+realclean: clean
+ $(call SHELL_DELETE,${BINARY})
diff --git a/tools/encrypt_fw/include/cmd_opt.h b/tools/encrypt_fw/include/cmd_opt.h
new file mode 100644
index 000000000..bd7d31f03
--- /dev/null
+++ b/tools/encrypt_fw/include/cmd_opt.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019, Linaro Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CMD_OPT_H
+#define CMD_OPT_H
+
+#include <getopt.h>
+
+#define CMD_OPT_MAX_NUM 64
+
+/* Supported long command line option types */
+enum {
+ CMD_OPT_FW
+};
+
+/* Structure to define a command line option */
+typedef struct cmd_opt_s {
+ struct option long_opt;
+ const char *help_msg;
+} cmd_opt_t;
+
+/* Exported API*/
+void cmd_opt_add(const cmd_opt_t *cmd_opt);
+const struct option *cmd_opt_get_array(void);
+const char *cmd_opt_get_name(int idx);
+const char *cmd_opt_get_help_msg(int idx);
+
+#endif /* CMD_OPT_H */
diff --git a/tools/encrypt_fw/include/debug.h b/tools/encrypt_fw/include/debug.h
new file mode 100644
index 000000000..ee8f1f517
--- /dev/null
+++ b/tools/encrypt_fw/include/debug.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#include <stdio.h>
+
+/* The log output macros print output to the console. These macros produce
+ * compiled log output only if the LOG_LEVEL defined in the makefile (or the
+ * make command line) is greater or equal than the level required for that
+ * type of log output.
+ * The format expected is the same as for printf(). For example:
+ * INFO("Info %s.\n", "message") -> INFO: Info message.
+ * WARN("Warning %s.\n", "message") -> WARNING: Warning message.
+ */
+
+#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 LOG_LEVEL >= LOG_LEVEL_NOTICE
+# define NOTICE(...) printf("NOTICE: " __VA_ARGS__)
+#else
+# define NOTICE(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_ERROR
+# define ERROR(...) printf("ERROR: " __VA_ARGS__)
+#else
+# define ERROR(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_WARNING
+# define WARN(...) printf("WARNING: " __VA_ARGS__)
+#else
+# define WARN(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+# define INFO(...) printf("INFO: " __VA_ARGS__)
+#else
+# define INFO(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+# define VERBOSE(...) printf("VERBOSE: " __VA_ARGS__)
+#else
+# define VERBOSE(...)
+#endif
+
+#endif /* DEBUG_H */
diff --git a/tools/encrypt_fw/include/encrypt.h b/tools/encrypt_fw/include/encrypt.h
new file mode 100644
index 000000000..25d301170
--- /dev/null
+++ b/tools/encrypt_fw/include/encrypt.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2019, Linaro Limited. All rights reserved.
+ * Author: Sumit Garg <sumit.garg@linaro.org>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ENCRYPT_H
+#define ENCRYPT_H
+
+/* Supported key algorithms */
+enum {
+ KEY_ALG_GCM /* AES-GCM (default) */
+};
+
+int encrypt_file(unsigned short fw_enc_status, int enc_alg, char *key_string,
+ char *nonce_string, const char *ip_name, const char *op_name);
+
+#endif /* ENCRYPT_H */
diff --git a/tools/encrypt_fw/src/cmd_opt.c b/tools/encrypt_fw/src/cmd_opt.c
new file mode 100644
index 000000000..64180d1f5
--- /dev/null
+++ b/tools/encrypt_fw/src/cmd_opt.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <cmd_opt.h>
+#include <getopt.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include "debug.h"
+
+/* Command line options */
+static struct option long_opt[CMD_OPT_MAX_NUM+1];
+static const char *help_msg[CMD_OPT_MAX_NUM+1];
+static int num_reg_opt;
+
+void cmd_opt_add(const cmd_opt_t *cmd_opt)
+{
+ assert(cmd_opt != NULL);
+
+ if (num_reg_opt >= CMD_OPT_MAX_NUM) {
+ ERROR("Out of memory. Please increase CMD_OPT_MAX_NUM\n");
+ exit(1);
+ }
+
+ long_opt[num_reg_opt].name = cmd_opt->long_opt.name;
+ long_opt[num_reg_opt].has_arg = cmd_opt->long_opt.has_arg;
+ long_opt[num_reg_opt].flag = 0;
+ long_opt[num_reg_opt].val = cmd_opt->long_opt.val;
+
+ help_msg[num_reg_opt] = cmd_opt->help_msg;
+
+ num_reg_opt++;
+}
+
+const struct option *cmd_opt_get_array(void)
+{
+ return long_opt;
+}
+
+const char *cmd_opt_get_name(int idx)
+{
+ if (idx >= num_reg_opt) {
+ return NULL;
+ }
+
+ return long_opt[idx].name;
+}
+
+const char *cmd_opt_get_help_msg(int idx)
+{
+ if (idx >= num_reg_opt) {
+ return NULL;
+ }
+
+ return help_msg[idx];
+}
diff --git a/tools/encrypt_fw/src/encrypt.c b/tools/encrypt_fw/src/encrypt.c
new file mode 100644
index 000000000..18a514cb9
--- /dev/null
+++ b/tools/encrypt_fw/src/encrypt.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2019, Linaro Limited. All rights reserved.
+ * Author: Sumit Garg <sumit.garg@linaro.org>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <firmware_encrypted.h>
+#include <openssl/evp.h>
+#include <stdio.h>
+#include <string.h>
+#include "debug.h"
+#include "encrypt.h"
+
+#define BUFFER_SIZE 256
+#define IV_SIZE 12
+#define IV_STRING_SIZE 24
+#define TAG_SIZE 16
+#define KEY_SIZE 32
+#define KEY_STRING_SIZE 64
+
+static int gcm_encrypt(unsigned short fw_enc_status, char *key_string,
+ char *nonce_string, const char *ip_name,
+ const char *op_name)
+{
+ FILE *ip_file;
+ FILE *op_file;
+ EVP_CIPHER_CTX *ctx;
+ unsigned char data[BUFFER_SIZE], enc_data[BUFFER_SIZE];
+ unsigned char key[KEY_SIZE], iv[IV_SIZE], tag[TAG_SIZE];
+ int bytes, enc_len = 0, i, j, ret = 0;
+ struct fw_enc_hdr header;
+
+ memset(&header, 0, sizeof(struct fw_enc_hdr));
+
+ if (strlen(key_string) != KEY_STRING_SIZE) {
+ ERROR("Unsupported key size: %lu\n", strlen(key_string));
+ return -1;
+ }
+
+ for (i = 0, j = 0; i < KEY_SIZE; i++, j += 2) {
+ if (sscanf(&key_string[j], "%02hhx", &key[i]) != 1) {
+ ERROR("Incorrect key format\n");
+ return -1;
+ }
+ }
+
+ if (strlen(nonce_string) != IV_STRING_SIZE) {
+ ERROR("Unsupported IV size: %lu\n", strlen(nonce_string));
+ return -1;
+ }
+
+ for (i = 0, j = 0; i < IV_SIZE; i++, j += 2) {
+ if (sscanf(&nonce_string[j], "%02hhx", &iv[i]) != 1) {
+ ERROR("Incorrect IV format\n");
+ return -1;
+ }
+ }
+
+ ip_file = fopen(ip_name, "rb");
+ if (ip_file == NULL) {
+ ERROR("Cannot read %s\n", ip_name);
+ return -1;
+ }
+
+ op_file = fopen(op_name, "wb");
+ if (op_file == NULL) {
+ ERROR("Cannot write %s\n", op_name);
+ fclose(ip_file);
+ return -1;
+ }
+
+ ret = fseek(op_file, sizeof(struct fw_enc_hdr), SEEK_SET);
+ if (ret) {
+ ERROR("fseek failed\n");
+ goto out_file;
+ }
+
+ ctx = EVP_CIPHER_CTX_new();
+ if (ctx == NULL) {
+ ERROR("EVP_CIPHER_CTX_new failed\n");
+ ret = -1;
+ goto out_file;
+ }
+
+ ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
+ if (ret != 1) {
+ ERROR("EVP_EncryptInit_ex failed\n");
+ ret = -1;
+ goto out;
+ }
+
+ ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv);
+ if (ret != 1) {
+ ERROR("EVP_EncryptInit_ex failed\n");
+ goto out;
+ }
+
+ while ((bytes = fread(data, 1, BUFFER_SIZE, ip_file)) != 0) {
+ ret = EVP_EncryptUpdate(ctx, enc_data, &enc_len, data, bytes);
+ if (ret != 1) {
+ ERROR("EVP_EncryptUpdate failed\n");
+ ret = -1;
+ goto out;
+ }
+
+ fwrite(enc_data, 1, enc_len, op_file);
+ }
+
+ ret = EVP_EncryptFinal_ex(ctx, enc_data, &enc_len);
+ if (ret != 1) {
+ ERROR("EVP_EncryptFinal_ex failed\n");
+ ret = -1;
+ goto out;
+ }
+
+ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, TAG_SIZE, tag);
+ if (ret != 1) {
+ ERROR("EVP_CIPHER_CTX_ctrl failed\n");
+ ret = -1;
+ goto out;
+ }
+
+ header.magic = ENC_HEADER_MAGIC;
+ header.flags |= fw_enc_status & FW_ENC_STATUS_FLAG_MASK;
+ header.dec_algo = KEY_ALG_GCM;
+ header.iv_len = IV_SIZE;
+ header.tag_len = TAG_SIZE;
+ memcpy(header.iv, iv, IV_SIZE);
+ memcpy(header.tag, tag, TAG_SIZE);
+
+ ret = fseek(op_file, 0, SEEK_SET);
+ if (ret) {
+ ERROR("fseek failed\n");
+ goto out;
+ }
+
+ fwrite(&header, 1, sizeof(struct fw_enc_hdr), op_file);
+
+out:
+ EVP_CIPHER_CTX_free(ctx);
+
+out_file:
+ fclose(ip_file);
+ fclose(op_file);
+
+ /*
+ * EVP_* APIs returns 1 as success but enctool considers
+ * 0 as success.
+ */
+ if (ret == 1)
+ ret = 0;
+
+ return ret;
+}
+
+int encrypt_file(unsigned short fw_enc_status, int enc_alg, char *key_string,
+ char *nonce_string, const char *ip_name, const char *op_name)
+{
+ switch (enc_alg) {
+ case KEY_ALG_GCM:
+ return gcm_encrypt(fw_enc_status, key_string, nonce_string,
+ ip_name, op_name);
+ default:
+ return -1;
+ }
+}
diff --git a/tools/encrypt_fw/src/main.c b/tools/encrypt_fw/src/main.c
new file mode 100644
index 000000000..39b7af761
--- /dev/null
+++ b/tools/encrypt_fw/src/main.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2019, Linaro Limited. All rights reserved.
+ * Author: Sumit Garg <sumit.garg@linaro.org>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include <openssl/conf.h>
+
+#include "cmd_opt.h"
+#include "debug.h"
+#include "encrypt.h"
+#include "firmware_encrypted.h"
+
+#define NUM_ELEM(x) ((sizeof(x)) / (sizeof(x[0])))
+#define HELP_OPT_MAX_LEN 128
+
+/* Global options */
+
+/* Info messages created in the Makefile */
+extern const char build_msg[];
+
+static char *key_algs_str[] = {
+ [KEY_ALG_GCM] = "gcm",
+};
+
+static void print_help(const char *cmd, const struct option *long_opt)
+{
+ int rem, i = 0;
+ const struct option *opt;
+ char line[HELP_OPT_MAX_LEN];
+ char *p;
+
+ assert(cmd != NULL);
+ assert(long_opt != NULL);
+
+ printf("\n\n");
+ printf("The firmware encryption tool loads the binary image and\n"
+ "outputs encrypted binary image using an encryption key\n"
+ "provided as an input hex string.\n");
+ printf("\n");
+ printf("Usage:\n");
+ printf("\t%s [OPTIONS]\n\n", cmd);
+
+ printf("Available options:\n");
+ opt = long_opt;
+ while (opt->name) {
+ p = line;
+ rem = HELP_OPT_MAX_LEN;
+ if (isalpha(opt->val)) {
+ /* Short format */
+ sprintf(p, "-%c,", (char)opt->val);
+ p += 3;
+ rem -= 3;
+ }
+ snprintf(p, rem, "--%s %s", opt->name,
+ (opt->has_arg == required_argument) ? "<arg>" : "");
+ printf("\t%-32s %s\n", line, cmd_opt_get_help_msg(i));
+ opt++;
+ i++;
+ }
+ printf("\n");
+}
+
+static int get_key_alg(const char *key_alg_str)
+{
+ int i;
+
+ for (i = 0 ; i < NUM_ELEM(key_algs_str) ; i++) {
+ if (strcmp(key_alg_str, key_algs_str[i]) == 0) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static void parse_fw_enc_status_flag(const char *arg,
+ unsigned short *fw_enc_status)
+{
+ unsigned long flag;
+ char *endptr;
+
+ flag = strtoul(arg, &endptr, 16);
+ if (*endptr != '\0' || flag > FW_ENC_WITH_BSSK) {
+ ERROR("Invalid fw_enc_status flag '%s'\n", arg);
+ exit(1);
+ }
+
+ *fw_enc_status = flag & FW_ENC_STATUS_FLAG_MASK;
+}
+
+/* Common command line options */
+static const cmd_opt_t common_cmd_opt[] = {
+ {
+ { "help", no_argument, NULL, 'h' },
+ "Print this message and exit"
+ },
+ {
+ { "fw-enc-status", required_argument, NULL, 'f' },
+ "Firmware encryption status flag (with SSK=0 or BSSK=1)."
+ },
+ {
+ { "key-alg", required_argument, NULL, 'a' },
+ "Encryption key algorithm: 'gcm' (default)"
+ },
+ {
+ { "key", required_argument, NULL, 'k' },
+ "Encryption key (for supported algorithm)."
+ },
+ {
+ { "nonce", required_argument, NULL, 'n' },
+ "Nonce or Initialization Vector (for supported algorithm)."
+ },
+ {
+ { "in", required_argument, NULL, 'i' },
+ "Input filename to be encrypted."
+ },
+ {
+ { "out", required_argument, NULL, 'o' },
+ "Encrypted output filename."
+ },
+};
+
+int main(int argc, char *argv[])
+{
+ int i, key_alg, ret;
+ int c, opt_idx = 0;
+ const struct option *cmd_opt;
+ char *key = NULL;
+ char *nonce = NULL;
+ char *in_fn = NULL;
+ char *out_fn = NULL;
+ unsigned short fw_enc_status = 0;
+
+ NOTICE("Firmware Encryption Tool: %s\n", build_msg);
+
+ /* Set default options */
+ key_alg = KEY_ALG_GCM;
+
+ /* Add common command line options */
+ for (i = 0; i < NUM_ELEM(common_cmd_opt); i++) {
+ cmd_opt_add(&common_cmd_opt[i]);
+ }
+
+ /* Get the command line options populated during the initialization */
+ cmd_opt = cmd_opt_get_array();
+
+ while (1) {
+ /* getopt_long stores the option index here. */
+ c = getopt_long(argc, argv, "a:f:hi:k:n:o:", cmd_opt, &opt_idx);
+
+ /* Detect the end of the options. */
+ if (c == -1) {
+ break;
+ }
+
+ switch (c) {
+ case 'a':
+ key_alg = get_key_alg(optarg);
+ if (key_alg < 0) {
+ ERROR("Invalid key algorithm '%s'\n", optarg);
+ exit(1);
+ }
+ break;
+ case 'f':
+ parse_fw_enc_status_flag(optarg, &fw_enc_status);
+ break;
+ case 'k':
+ key = optarg;
+ break;
+ case 'i':
+ in_fn = optarg;
+ break;
+ case 'o':
+ out_fn = optarg;
+ break;
+ case 'n':
+ nonce = optarg;
+ break;
+ case 'h':
+ print_help(argv[0], cmd_opt);
+ exit(0);
+ case '?':
+ default:
+ print_help(argv[0], cmd_opt);
+ exit(1);
+ }
+ }
+
+ if (!key) {
+ ERROR("Key must not be NULL\n");
+ exit(1);
+ }
+
+ if (!nonce) {
+ ERROR("Nonce must not be NULL\n");
+ exit(1);
+ }
+
+ if (!in_fn) {
+ ERROR("Input filename must not be NULL\n");
+ exit(1);
+ }
+
+ if (!out_fn) {
+ ERROR("Output filename must not be NULL\n");
+ exit(1);
+ }
+
+ ret = encrypt_file(fw_enc_status, key_alg, key, nonce, in_fn, out_fn);
+
+ CRYPTO_cleanup_all_ex_data();
+
+ return ret;
+}
diff --git a/tools/memory/print_memory_map.py b/tools/memory/print_memory_map.py
index 35cccd38c..8a84018e7 100755
--- a/tools/memory/print_memory_map.py
+++ b/tools/memory/print_memory_map.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (c) 2019, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -22,6 +22,7 @@ blx_symbols = ['__BL1_RAM_START__', '__BL1_RAM_END__',
'__DATA_START__', '__DATA_END__',
'__STACKS_START__', '__STACKS_END__',
'__BSS_END',
+ '__COHERENT_RAM_START__', '__COHERENT_RAM_END__',
]
# Regex to extract address from map file
@@ -31,8 +32,11 @@ address_pattern = re.compile(r"\b0x\w*")
address_list = []
# Get the directory from command line or use a default one
+inverted_print = True
if len(sys.argv) >= 2:
build_dir = sys.argv[1]
+ if len(sys.argv) >= 3:
+ inverted_print = sys.argv[2] == '0'
else:
build_dir = 'build/fvp/debug'
@@ -43,7 +47,10 @@ for image in bl_images:
with open (file_path, 'rt') as mapfile:
for line in mapfile:
for symbol in blx_symbols:
- if line.find(symbol) > 0 and line.find("ASSERT") < 0:
+ # Regex to find symbol definition
+ line_pattern = re.compile(r"\b0x\w*\s*" + symbol + "\s= .")
+ match = line_pattern.search(line)
+ if match:
# Extract address from line
match = address_pattern.search(line)
if match:
@@ -52,17 +59,21 @@ for image in bl_images:
# Sort by address
address_list.sort(key=operator.itemgetter(0))
+# Invert list for lower address at bottom
+if inverted_print:
+ address_list = reversed(address_list)
+
# Generate memory view
-print('{:-^87}'.format('Memory Map from: ' + build_dir))
-for address in reversed(address_list):
+print('{:-^93}'.format('Memory Map from: ' + build_dir))
+for address in address_list:
if "bl1" in address[2]:
- print(address[0], '+{:-^20}+ |{:^20}| |{:^20}|'.format(address[1], '', ''))
+ print(address[0], '+{:-^22}+ |{:^22}| |{:^22}|'.format(address[1], '', ''))
elif "bl2" in address[2]:
- print(address[0], '|{:^20}| +{:-^20}+ |{:^20}|'.format('', address[1], ''))
+ print(address[0], '|{:^22}| +{:-^22}+ |{:^22}|'.format('', address[1], ''))
elif "bl31" in address[2]:
- print(address[0], '|{:^20}| |{:^20}| +{:-^20}+'.format('', '', address[1]))
+ print(address[0], '|{:^22}| |{:^22}| +{:-^22}+'.format('', '', address[1]))
else:
- print(address[0], '|{:^20}| |{:^20}| +{:-^20}+'.format('', '', address[1]))
+ print(address[0], '|{:^22}| |{:^22}| +{:-^22}+'.format('', '', address[1]))
-print('{:^20}{:_^20} {:_^20} {:_^20}'.format('', '', '', ''))
-print('{:^20}{:^20} {:^20} {:^20}'.format('address', 'bl1', 'bl2', 'bl31'))
+print('{:^20}{:_^22} {:_^22} {:_^22}'.format('', '', '', ''))
+print('{:^20}{:^22} {:^22} {:^22}'.format('address', 'bl1', 'bl2', 'bl31'))
diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py
new file mode 100755
index 000000000..6b6fa1914
--- /dev/null
+++ b/tools/sptool/sp_mk_generator.py
@@ -0,0 +1,100 @@
+#!/usr/bin/python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+"""
+This script is invoked by Make system and generates secure partition makefile.
+It expects platform provided secure partition layout file which contains list
+of Secure Partition Images and Partition manifests(PM).
+Layout file can exist outside of TF-A tree and the paths of Image and PM files
+must be relative to it.
+
+This script parses the layout file and generates a make file which updates
+FDT_SOURCES, FIP_ARGS and SPTOOL_ARGS which are used in later build steps.
+This script also gets SP "uuid" from parsing its PM and converting it to a
+standard format.
+
+param1: Generated mk file "sp_gen.mk"
+param2: "SP_LAYOUT_FILE", json file containing platform provided information
+param3: plat out directory
+
+Generated "sp_gen.mk" file contains triplet of following information for each
+Secure Partition entry
+ FDT_SOURCES += sp1.dts
+ SPTOOL_ARGS += -i sp1.bin:sp1.dtb -o sp1.pkg
+ FIP_ARGS += --blob uuid=XXXXX-XXX...,file=sp1.pkg
+
+A typical SP_LAYOUT_FILE file will look like
+{
+ "SP1" : {
+ "image": "sp1.bin",
+ "pm": "test/sp1.dts"
+ },
+
+ "SP2" : {
+ "image": "sp2.bin",
+ "pm": "test/sp2.dts"
+ }
+
+ ...
+}
+
+"""
+
+import getopt
+import json
+import os
+import re
+import sys
+import uuid
+
+with open(sys.argv[2],'r') as in_file:
+ data = json.load(in_file)
+json_file = os.path.abspath(sys.argv[2])
+json_dir = os.path.dirname(json_file)
+gen_file = sys.argv[1]
+out_dir = sys.argv[3][2:]
+dtb_dir = out_dir + "/fdts/"
+print(dtb_dir)
+
+with open(gen_file, 'w') as out_file:
+ for key in data.keys():
+
+ """
+ Append FDT_SOURCES
+ """
+ dts = os.path.join(json_dir, data[key]['pm'])
+ dtb = dtb_dir + os.path.basename(data[key]['pm'][:-1] + "b")
+ out_file.write("FDT_SOURCES += " + dts + "\n")
+
+ """
+ Update SPTOOL_ARGS
+ """
+ dst = out_dir + "/" + key + ".pkg"
+ src = [ json_dir + "/" + data[key]['image'] , dtb ]
+ out_file.write("SPTOOL_ARGS += -i " + ":".join(src) + " -o " + dst + "\n")
+
+ """
+ Extract uuid from partition manifest
+ """
+ pm_file = open(dts)
+ key = "uuid"
+
+ for line in pm_file:
+ if key in line:
+ uuid_hex = re.findall(r'\<(.+?)\>', line)[0];
+
+ # PM has uuid in format 0xABC... 0x... 0x... 0x...
+ # Get rid of '0x' and spaces and convert to string of hex digits
+ uuid_hex = uuid_hex.replace('0x','').replace(' ','')
+ # make UUID from a string of hex digits
+ uuid_std = uuid.UUID(uuid_hex)
+ # convert UUID to a string of hex digits in standard form
+ uuid_std = str(uuid_std)
+
+ """
+ Append FIP_ARGS
+ """
+ out_file.write("FIP_ARGS += --blob uuid=" + uuid_std + ",file=" + dst + "\n")
+ out_file.write("\n")